ALV 中的特定布局
Specific layout in an ALV
在 ITAB 中我有 3 个字段:ACCOUNT-OBJECT_AMOUNT 示例是:
64000 KAGR1 10
64000 KAGR1 15
64010 KAGR1 20
64010 KAGR2 15
64020 KAGR2 10
64020 KAGR2 10
我希望显示如下所示:
KAGR1 KAGR2
64000 25
64010 20 15
64020 30
有谁知道如何在ALV中显示吗?
谢谢
这是一个通用的解决方案。请注意,方法 show_table_grouped_by
不知道 table 的类型,因此它可以与任何 table 一起使用,尽管我打赌有一些字段类型会破坏动态代码.要显示的数据可以有多个字段用作键(您的示例只有一个)和一个用于列的字段 (i_group_by
) 和一个用于聚合的字段 (i_aggregate_from
).这个程序的大部分想法来自 this blog,但是下面的解决方案更加动态。完整的程序处理问题中提供的数据,并更正最后一行中的值以得出示例中的结果。
如果您知道按字段分组的值将被限制为一定数量的值,您可以制定一个不太动态的解决方案,但可能会更有效。
REPORT zso_group_alv.
TYPES: BEGIN OF ts_data,
field1 TYPE char10,
group TYPE char10,
val TYPE i,
END OF ts_data,
tt_data TYPE STANDARD TABLE OF ts_data.
DATA: gt_data TYPE tt_data.
CLASS lcl_alv_grouped DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
show_table_grouped_by IMPORTING VALUE(it_data) TYPE ANY TABLE
i_group_by TYPE fieldname
i_aggregate_from TYPE fieldname,
group_fld_name IMPORTING i_value TYPE any
RETURNING VALUE(fld_name) TYPE fieldname.
ENDCLASS.
CLASS lcl_alv_grouped IMPLEMENTATION.
METHOD group_fld_name.
" Returns the field name for the group fields
" This is to make sure there are no reserved names used or
" reuse of already existing fields
fld_name = 'fld_' && i_value.
ENDMETHOD.
METHOD show_table_grouped_by.
" Shows the data in table IT_DATA in an ALV
" The data is transposed
" The data from field I_AGGREGATE_FROM is summed into groups
" from the values in the field I_GROUP_BY
" All the other fields in the table are treated as the key
" fields for the transposed table
DATA: ls_component TYPE cl_abap_structdescr=>component,
lt_components TYPE cl_abap_structdescr=>component_table,
lr_struct TYPE REF TO cl_abap_structdescr,
lt_keys TYPE abap_sortorder_tab,
lt_key_components TYPE cl_abap_structdescr=>component_table,
"ls_keys TYPE REF TO data,
lr_trans_table TYPE REF TO data,
lr_trans_wa TYPE REF TO data,
lr_keys_type TYPE REF TO cl_abap_structdescr,
ls_keys TYPE REF TO data,
ls_keys_prev TYPE REF TO data,
lr_salv TYPE REF TO cl_salv_table.
FIELD-SYMBOLS: <trans_table> TYPE STANDARD TABLE.
" Determine the fields in the transposed table
LOOP AT it_data ASSIGNING FIELD-SYMBOL(<data>).
AT FIRST.
" Get field to aggregate
ASSIGN COMPONENT i_aggregate_from OF STRUCTURE <data> TO FIELD-SYMBOL(<aggregate_field>).
IF sy-subrc NE 0.
RETURN. " Would be nice to tell the calling program about this error
ENDIF.
" Gather all the other fields from the data table, these are treated as keys
lr_struct ?= cl_abap_datadescr=>describe_by_data( <data> ).
LOOP AT lr_struct->get_components( ) ASSIGNING FIELD-SYMBOL(<component>).
IF <component>-name NE i_aggregate_from AND
<component>-name NE i_group_by.
APPEND <component> TO: lt_components,
lt_key_components.
APPEND VALUE #( name = <component>-name
descending = abap_false
astext = abap_true
) TO lt_keys.
ENDIF.
ENDLOOP.
ENDAT. " FIRST
" Get the group by field
ASSIGN COMPONENT i_group_by OF STRUCTURE <data> TO FIELD-SYMBOL(<group_field>).
IF sy-subrc NE 0.
RETURN. " Would be nice to tell the calling program about this error
ENDIF.
" Gather all the values in the group by field
DATA(l_new_group) = group_fld_name( <group_field> ).
READ TABLE lt_components WITH KEY name = l_new_group TRANSPORTING NO FIELDS.
IF sy-subrc NE 0.
ls_component-name = l_new_group.
ls_component-type ?= cl_abap_datadescr=>describe_by_data( <aggregate_field> ).
APPEND ls_component TO lt_components.
ENDIF.
ENDLOOP. " IT_DATA
" LT_COMPONENTS is now filled with all the fields to show in the ALV
" Create the transpose table and fill its
DATA(lr_trans_table_type) = cl_abap_tabledescr=>create( cl_abap_structdescr=>create( lt_components ) ).
CREATE DATA lr_trans_table TYPE HANDLE lr_trans_table_type.
ASSIGN lr_trans_table->* TO <trans_table>.
" Data needs to be sorted to generate the rows in the transposed table
SORT it_data BY (lt_keys).
" Create structures to keep track of the key values
lr_keys_type ?= cl_abap_structdescr=>create( lt_key_components ).
CREATE DATA ls_keys TYPE HANDLE lr_keys_type.
CREATE DATA ls_keys_prev TYPE HANDLE lr_keys_type.
ASSIGN ls_keys->* TO FIELD-SYMBOL(<keys>).
ASSIGN ls_keys_prev->* TO FIELD-SYMBOL(<keys_prev>).
" Transpose the data
LOOP AT it_data ASSIGNING <data>.
MOVE-CORRESPONDING <data> TO <keys>.
IF <keys> NE <keys_prev>.
" Found a new key combination, add a row to the transposed table
APPEND INITIAL LINE TO <trans_table> ASSIGNING FIELD-SYMBOL(<trans_data>).
MOVE-CORRESPONDING <data> TO <trans_data>. " Filling the key fields
ENDIF.
" Agragate the value into the right group
ASSIGN COMPONENT i_aggregate_from OF STRUCTURE <data> TO FIELD-SYMBOL(<value>).
ASSIGN COMPONENT i_group_by OF STRUCTURE <data> TO FIELD-SYMBOL(<group>).
ASSIGN COMPONENT group_fld_name( <group> ) OF STRUCTURE <trans_data> TO FIELD-SYMBOL(<trans_value>).
ADD <value> TO <trans_value>.
" Remember keys to compare with the next row
<keys_prev> = <keys>.
ENDLOOP. " IT_DATA
" Display transposed data in ALV
TRY.
cl_salv_table=>factory(
* EXPORTING
* list_display = IF_SALV_C_BOOL_SAP=>FALSE " ALV Displayed in List Mode
* r_container = " Abstract Container for GUI Controls
* container_name =
IMPORTING
r_salv_table = lr_salv " Basis Class Simple ALV Tables
CHANGING
t_table = <trans_table>
).
CATCH cx_salv_msg. "
" Some error handling would be nice
ENDTRY.
" Will need to do something about the column headers
lr_salv->display( ).
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
APPEND VALUE #( field1 = '64000' group = 'KAGR1' val = 10 ) TO gt_data.
APPEND VALUE #( field1 = '64000' group = 'KAGR1' val = 15 ) TO gt_data.
APPEND VALUE #( field1 = '64010' group = 'KAGR1' val = 20 ) TO gt_data.
APPEND VALUE #( field1 = '64010' group = 'KAGR2' val = 15 ) TO gt_data.
APPEND VALUE #( field1 = '64020' group = 'KAGR2' val = 10 ) TO gt_data.
APPEND VALUE #( field1 = '64020' group = 'KAGR2' val = 20 ) TO gt_data.
lcl_alv_grouped=>show_table_grouped_by(
EXPORTING
it_data = gt_data
i_group_by = 'GROUP'
i_aggregate_from = 'VAL'
).
在 ITAB 中我有 3 个字段:ACCOUNT-OBJECT_AMOUNT 示例是:
64000 KAGR1 10
64000 KAGR1 15
64010 KAGR1 20
64010 KAGR2 15
64020 KAGR2 10
64020 KAGR2 10
我希望显示如下所示:
KAGR1 KAGR2
64000 25
64010 20 15
64020 30
有谁知道如何在ALV中显示吗?
谢谢
这是一个通用的解决方案。请注意,方法 show_table_grouped_by
不知道 table 的类型,因此它可以与任何 table 一起使用,尽管我打赌有一些字段类型会破坏动态代码.要显示的数据可以有多个字段用作键(您的示例只有一个)和一个用于列的字段 (i_group_by
) 和一个用于聚合的字段 (i_aggregate_from
).这个程序的大部分想法来自 this blog,但是下面的解决方案更加动态。完整的程序处理问题中提供的数据,并更正最后一行中的值以得出示例中的结果。
如果您知道按字段分组的值将被限制为一定数量的值,您可以制定一个不太动态的解决方案,但可能会更有效。
REPORT zso_group_alv.
TYPES: BEGIN OF ts_data,
field1 TYPE char10,
group TYPE char10,
val TYPE i,
END OF ts_data,
tt_data TYPE STANDARD TABLE OF ts_data.
DATA: gt_data TYPE tt_data.
CLASS lcl_alv_grouped DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
show_table_grouped_by IMPORTING VALUE(it_data) TYPE ANY TABLE
i_group_by TYPE fieldname
i_aggregate_from TYPE fieldname,
group_fld_name IMPORTING i_value TYPE any
RETURNING VALUE(fld_name) TYPE fieldname.
ENDCLASS.
CLASS lcl_alv_grouped IMPLEMENTATION.
METHOD group_fld_name.
" Returns the field name for the group fields
" This is to make sure there are no reserved names used or
" reuse of already existing fields
fld_name = 'fld_' && i_value.
ENDMETHOD.
METHOD show_table_grouped_by.
" Shows the data in table IT_DATA in an ALV
" The data is transposed
" The data from field I_AGGREGATE_FROM is summed into groups
" from the values in the field I_GROUP_BY
" All the other fields in the table are treated as the key
" fields for the transposed table
DATA: ls_component TYPE cl_abap_structdescr=>component,
lt_components TYPE cl_abap_structdescr=>component_table,
lr_struct TYPE REF TO cl_abap_structdescr,
lt_keys TYPE abap_sortorder_tab,
lt_key_components TYPE cl_abap_structdescr=>component_table,
"ls_keys TYPE REF TO data,
lr_trans_table TYPE REF TO data,
lr_trans_wa TYPE REF TO data,
lr_keys_type TYPE REF TO cl_abap_structdescr,
ls_keys TYPE REF TO data,
ls_keys_prev TYPE REF TO data,
lr_salv TYPE REF TO cl_salv_table.
FIELD-SYMBOLS: <trans_table> TYPE STANDARD TABLE.
" Determine the fields in the transposed table
LOOP AT it_data ASSIGNING FIELD-SYMBOL(<data>).
AT FIRST.
" Get field to aggregate
ASSIGN COMPONENT i_aggregate_from OF STRUCTURE <data> TO FIELD-SYMBOL(<aggregate_field>).
IF sy-subrc NE 0.
RETURN. " Would be nice to tell the calling program about this error
ENDIF.
" Gather all the other fields from the data table, these are treated as keys
lr_struct ?= cl_abap_datadescr=>describe_by_data( <data> ).
LOOP AT lr_struct->get_components( ) ASSIGNING FIELD-SYMBOL(<component>).
IF <component>-name NE i_aggregate_from AND
<component>-name NE i_group_by.
APPEND <component> TO: lt_components,
lt_key_components.
APPEND VALUE #( name = <component>-name
descending = abap_false
astext = abap_true
) TO lt_keys.
ENDIF.
ENDLOOP.
ENDAT. " FIRST
" Get the group by field
ASSIGN COMPONENT i_group_by OF STRUCTURE <data> TO FIELD-SYMBOL(<group_field>).
IF sy-subrc NE 0.
RETURN. " Would be nice to tell the calling program about this error
ENDIF.
" Gather all the values in the group by field
DATA(l_new_group) = group_fld_name( <group_field> ).
READ TABLE lt_components WITH KEY name = l_new_group TRANSPORTING NO FIELDS.
IF sy-subrc NE 0.
ls_component-name = l_new_group.
ls_component-type ?= cl_abap_datadescr=>describe_by_data( <aggregate_field> ).
APPEND ls_component TO lt_components.
ENDIF.
ENDLOOP. " IT_DATA
" LT_COMPONENTS is now filled with all the fields to show in the ALV
" Create the transpose table and fill its
DATA(lr_trans_table_type) = cl_abap_tabledescr=>create( cl_abap_structdescr=>create( lt_components ) ).
CREATE DATA lr_trans_table TYPE HANDLE lr_trans_table_type.
ASSIGN lr_trans_table->* TO <trans_table>.
" Data needs to be sorted to generate the rows in the transposed table
SORT it_data BY (lt_keys).
" Create structures to keep track of the key values
lr_keys_type ?= cl_abap_structdescr=>create( lt_key_components ).
CREATE DATA ls_keys TYPE HANDLE lr_keys_type.
CREATE DATA ls_keys_prev TYPE HANDLE lr_keys_type.
ASSIGN ls_keys->* TO FIELD-SYMBOL(<keys>).
ASSIGN ls_keys_prev->* TO FIELD-SYMBOL(<keys_prev>).
" Transpose the data
LOOP AT it_data ASSIGNING <data>.
MOVE-CORRESPONDING <data> TO <keys>.
IF <keys> NE <keys_prev>.
" Found a new key combination, add a row to the transposed table
APPEND INITIAL LINE TO <trans_table> ASSIGNING FIELD-SYMBOL(<trans_data>).
MOVE-CORRESPONDING <data> TO <trans_data>. " Filling the key fields
ENDIF.
" Agragate the value into the right group
ASSIGN COMPONENT i_aggregate_from OF STRUCTURE <data> TO FIELD-SYMBOL(<value>).
ASSIGN COMPONENT i_group_by OF STRUCTURE <data> TO FIELD-SYMBOL(<group>).
ASSIGN COMPONENT group_fld_name( <group> ) OF STRUCTURE <trans_data> TO FIELD-SYMBOL(<trans_value>).
ADD <value> TO <trans_value>.
" Remember keys to compare with the next row
<keys_prev> = <keys>.
ENDLOOP. " IT_DATA
" Display transposed data in ALV
TRY.
cl_salv_table=>factory(
* EXPORTING
* list_display = IF_SALV_C_BOOL_SAP=>FALSE " ALV Displayed in List Mode
* r_container = " Abstract Container for GUI Controls
* container_name =
IMPORTING
r_salv_table = lr_salv " Basis Class Simple ALV Tables
CHANGING
t_table = <trans_table>
).
CATCH cx_salv_msg. "
" Some error handling would be nice
ENDTRY.
" Will need to do something about the column headers
lr_salv->display( ).
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
APPEND VALUE #( field1 = '64000' group = 'KAGR1' val = 10 ) TO gt_data.
APPEND VALUE #( field1 = '64000' group = 'KAGR1' val = 15 ) TO gt_data.
APPEND VALUE #( field1 = '64010' group = 'KAGR1' val = 20 ) TO gt_data.
APPEND VALUE #( field1 = '64010' group = 'KAGR2' val = 15 ) TO gt_data.
APPEND VALUE #( field1 = '64020' group = 'KAGR2' val = 10 ) TO gt_data.
APPEND VALUE #( field1 = '64020' group = 'KAGR2' val = 20 ) TO gt_data.
lcl_alv_grouped=>show_table_grouped_by(
EXPORTING
it_data = gt_data
i_group_by = 'GROUP'
i_aggregate_from = 'VAL'
).