[英]Specific layout in an ALV
In an ITAB I have 3 fields: ACCOUNT-OBJECT_AMOUNT and a sample is:在 ITAB 中,我有 3 个字段:ACCOUNT-OBJECT_AMOUNT,示例是:
64000 KAGR1 10
64000 KAGR1 15
64010 KAGR1 20
64010 KAGR2 15
64020 KAGR2 10
64020 KAGR2 10
And I want the display to be like the below:我希望显示如下所示:
KAGR1 KAGR2
64000 25
64010 20 15
64020 30
Can anyone know how to display it in an ALV?谁能知道如何在 ALV 中显示它?
Thanks谢谢
Here is a generic solution.这是一个通用的解决方案。 Note that the method show_table_grouped_by
has no knowledge of the type of the table, so it can be used with any table, although I bet there are some field types that would break the dynamic code.请注意,方法show_table_grouped_by
不知道表的类型,因此它可以用于任何表,尽管我敢打赌有些字段类型会破坏动态代码。 The data to display can have multiple fields that will be used as keys (your example only has one) and one field that is used for the columns ( i_group_by
) and one field that is used to aggregate from ( i_aggregate_from
).要显示的数据可以有多个将用作键的字段(您的示例只有一个)和一个用于列的字段 ( i_group_by
) 和一个用于从中聚合的字段 ( i_aggregate_from
)。 Most of the idea of this program comes from this blog , however the solution below is more dynamic.这个程序的大部分想法来自这个博客,但是下面的解决方案更加动态。 The complete program processes the data as provided in the question, with the value in the last line corrected to come to the result in the example.完整的程序按照问题中提供的方式处理数据,并更正最后一行中的值以得出示例中的结果。
If you know that the values for your group by field will be limited to a certain number of values you can make a less dynamic solution that will probably be more efficient.如果您知道按字段分组的值将被限制为一定数量的值,您可以制定一个不太动态的解决方案,但可能会更有效。
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'
).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.