Abap 按数据类型动态隐藏ALV列

Abap 按数据类型动态隐藏ALV列,abap,alv,Abap,Alv,背景:我正在使用cl\u salv\u表类来生成和修改ALV。此ALV显示一个类型为zpm_et_qual_notif_s的表格,其中每个偶数行是一个类型为CHARlength1的分隔符字段,其名称为DELIM1,DELIM2…等。因为没有理由在ALV中显示分隔符列,所以我想删除它们 注意:我在标题中保留了“ABAP Dictionary/Internal Structure”的泛型,因为我是否从ABAP Dictionary结构或从中定义的内部表确定列数对我来说并不重要 对我来说,简单的解决

背景:我正在使用
cl\u salv\u表
类来生成和修改ALV。此ALV显示一个类型为
zpm_et_qual_notif_s
的表格,其中每个偶数行是一个类型为
CHAR
length
1
的分隔符字段,其名称为
DELIM1
DELIM2
…等。因为没有理由在ALV中显示分隔符列,所以我想删除它们

注意:我在标题中保留了“ABAP Dictionary/Internal Structure”的泛型,因为我是否从ABAP Dictionary结构或从中定义的内部表确定列数对我来说并不重要


对我来说,简单的解决方案是使用这15条语句,因为目前有15个分隔符字段:

lv_alv->get_columns( )->get_column( 'DELIM1' )->set_visible( if_salv_c_bool_sap=>false ).
lv_alv->get_columns( )->get_column( 'DELIM2' )->set_visible( if_salv_c_bool_sap=>false ).
lv_alv->get_columns( )->get_column( 'DELIM3' )->set_visible( if_salv_c_bool_sap=>false ).
lv_alv->get_columns( )->get_column( 'DELIM4' )->set_visible( if_salv_c_bool_sap=>false ).
lv_alv->get_columns( )->get_column( 'DELIM5' )->set_visible( if_salv_c_bool_sap=>false ).
...
问题是,如果表中添加了新字段,我的程序也必须更新。出于这个原因,而且这种方法需要许多几乎重复的行,我发现这是一个草率的解决方案


我认为更干净的解决方案是以如下方式动态设置所有分隔符列的可见性:

" Dynamically hide delimiter columns
DATA lv_idx TYPE syst_index VALUE 1.
WHILE lv_idx < 16. " Number of delimiters
    lv_alv->get_columns( )->get_column( |DELIM{ lv_idx }| )->set_visible( if_salv_c_bool_sap=>false ).
    lv_idx = lv_idx + 1.
ENDWHILE.
“动态隐藏分隔符列
数据lv_idx类型系统索引值1。
而lv_idx<16.“分隔符的数量
lv_alv->get_columns()->get_column(|DELIM{lv_idx}})->set_visible(如果salv_c_bool_sap=>false)。
lv_idx=lv_idx+1。
结束时。
这很好,因为它是一个简单的解决方案,并引入最小的开销。但是,我仍然存在必须硬编码分隔符列数的问题。理想的解决方案可以让我这样做:

" Dynamically hide delimiter columns
DATA lv_idx TYPE syst_index VALUE 1.
WHILE lv_idx < ( columns( 'ZPM_ET_QUAL_NOTIF_S' ) / 2 ). " Number of delimiters
    lv_alv->get_columns( )->get_column( |DELIM{ lv_idx }| )->set_visible( if_salv_c_bool_sap=>false ).
    lv_idx = lv_idx + 1.
ENDWHILE.
“动态隐藏分隔符列
数据lv_idx类型系统索引值1。
而lv_idx<(列('ZPM_ET_QUAL_NOTIF_S')/2)。“分隔符的数量
lv_alv->get_columns()->get_column(|DELIM{lv_idx}})->set_visible(如果salv_c_bool_sap=>false)。
lv_idx=lv_idx+1。
结束时。
…但当然,这不是一件事


如何动态获取内部表或其所基于的ABAP字典结构的列计数?当然有一些动态的解决方案。我自己试图解决这个问题,结果我玩弄了
cl\u abap\u structdescr
cl\u abap\u tabledescr
,但没有什么实质性的结果。如果我的整个方法都不好,我很乐意更改它以遵循良好的实践。

以下代码片段确定数据字典结构或表的活动版本中的列数

  SELECT COUNT( * ) INTO @DATA(num_cols)
                    FROM dd03l
                   WHERE tabname EQ @p_struct
                     AND as4local EQ 'A'. " Active

其他解决方案可以使用或使用
ASSIGN组件

首先,我会用
set\u technical
标记这些列,以防止它们完全显示
set\u visible(abap\u false)
仅在当前/初始显示时隐藏它们,但用户可以选择显示这些可能会混淆的列

然后,我可能会尝试通过数据元素而不是位置来区分这些列。(伪)代码,未经测试:

DATA(columns) = my_alv->get_columns( ).
DATA(column_list) = columns->get( ).
LOOP AT column_list ASSIGNING FIELD-SYMBOL(<column>).
  IF <column>-r_column->get_ddic_rollname( ) = 'Z_IRRELEVANT_DELIMITER'.
    <column>-r_column->set_technical( ).
  ENDIF.
ENDLOOP.
DATA(columns)=my\u alv->get\u columns()。
数据(列列表)=列->获取()。
在列_列表指定字段-SYMBOL()处循环。
IF-r\u column->get\u ddic\u rollname()=“Z\u无关的\u分隔符”。
-r\u列->设置\u技术()。
恩迪夫。
结束循环。

如果存在API,我建议不要直接访问存储库/字典表——在这种情况下,存在多个备选方案。另外(尽管与这个问题无关),如果显示不是基于DDIC结构,而是基于程序的本地类型,则此操作将失败。这里有许多很棒的想法-谢谢。我已经修改了我的代码以使用
set\u technical()
,并且我已经将分隔符字段的数据类型更改为
DELIM
,而不是长度
1
CHAR
(我应该首先这样做)。我试图弄清楚如何实际循环列,因为
my_alv->get_columns()
将类型为REF的对象返回给CL_SALV_columns_TABLE,而不是表。原始代码似乎缺少对
get()
的调用,这将使表从
TYPE REF返回到CL_SALV columns_TABLE
是-未测试,正如我写的:-)谢谢你的提醒,我已经添加了这个电话。谢谢你,@vwegert和@Gert Beukema!这是我一直在寻找的干净、简单、动态的解决方案。您是否尝试从文件上载数据以填充此表?@jhamu否,输入数据来自客户数据库表。