问题
Background: I'm using the cl_salv_table
class to generate and modify an ALV. This ALV displays a table of type zpm_et_qual_notif_s
, where every even number row is a delimiter field of type CHAR
length 1
with names DELIM1
, DELIM2
...etc. Since there's no reason to have delimiter columns displayed in the ALV, I'd like to remove them.
Note: I left "ABAP Dictionary/Internal Structure" generic in the title because whether or not I determine the column count from the ABAP Dictionary structure or the internal table I define from it matters not to me.
The easy solution for me would be to have these 15 statements, as there are currently 15 delimiter fields:
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 ).
...
The problem with this is that if new fields are added to the table, my program would also have to be updated. For this reason, and that this approach requires many almost duplicate lines, I find this to be a sloppy solution.
What I believe to be a cleaner solution is to dynamically set the visibility of all of the delimiter columns in a manner like so:
" 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.
This is nice because it's a simple solution and introduces minimal overhead. However, I still have the problem of having to hard code the number of delimiter columns. An ideal solution would let me do this:
" 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.
...but of course, that isn't a thing.
How may I dynamically get the column count of my internal table, or of the ABAP Dictionary structure that it's based upon? Surely there's some dynamic solution to this. Trying to solve this problem myself led me to toying around with cl_abap_structdescr
and cl_abap_tabledescr
, but nothing substantial came of it. If my entire approach is bad, I'm comfortable with changing it in order to follow good practice.
回答1:
First of all, I would tag these columns with set_technical
to prevent them from being displayed entirely. set_visible( abap_false )
only hides them from the current/initial display, but the user can select to show these columns which might be confusing.
Then, I would probably try to distinguish these columns by their data element rather than their position. (Pseudo-)code, untested:
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.
回答2:
The following code snippet determines the number of columns in the active version of a data dictionary structure or table.
SELECT COUNT( * ) INTO @DATA(num_cols)
FROM dd03l
WHERE tabname EQ @p_struct
AND as4local EQ 'A'. " Active
Other solutions can be made using the RTTS framework, or using ASSIGN COMPONENT
.
来源:https://stackoverflow.com/questions/42698675/dynamically-hide-alv-columns-by-data-type