[英]Table pivoting via ABAP with dynamic number of columns?
I have the following source sample data (which will be populated from a dictionary table but I am supplying the values manually for demo purpose):我有以下源示例数据(将从字典表中填充,但我出于演示目的手动提供值):
What I am trying to get is the pivot-version of sums-per-week assuming I do not know how many weeks I will have in source and what their (6-digit numeric) values will be at the time of pivot creation:我想要得到的是每周总和的枢轴版本,假设我不知道我将在源中拥有多少周以及在创建枢轴时它们的(6 位数字)值是多少:
Here is the code to reproduce the results from the sample data:以下是从示例数据中重现结果的代码:
************************************** Declare Data types: ******************************************
TYPES: BEGIN OF strct_week,
wk_header(8) TYPE c, wk_number TYPE i, amt_per_wk TYPE i,
END OF strct_week,
BEGIN OF strct_week_pivot,
sum_per_wk1 TYPE i, sum_per_wk2 TYPE i, sum_per_wk3 TYPE i,
END OF strct_week_pivot,
"table definition:
tb_week TYPE STANDARD TABLE OF strct_week WITH DEFAULT KEY,
tb_week_pivot TYPE STANDARD TABLE OF strct_week_pivot WITH DEFAULT KEY.
DATA: ls_week TYPE strct_week,
ls_week_pivot TYPE strct_week_pivot,
gt_weeks TYPE tb_week,
gt_weeks_pivot TYPE tb_week_pivot,
fc_tmp_data TYPE lvc_s_fcat,
fc_acc_data TYPE lvc_t_fcat,
fc_tmp_pivot TYPE lvc_s_fcat,
fc_acc_pivot TYPE lvc_t_fcat.
************************************** Fill gt_weeks with sample data: ********************************
ls_week-wk_header = '202201'.
ls_week-wk_number = 01.
ls_week-amt_per_wk = 11111.
APPEND ls_week TO gt_weeks.
ls_week-wk_header = '202201'.
ls_week-wk_number = 01.
ls_week-amt_per_wk = 111111.
APPEND ls_week TO gt_weeks.
ls_week-wk_header = '202202'.
ls_week-wk_number = 02.
ls_week-amt_per_wk = 22222.
APPEND ls_week TO gt_weeks.
ls_week-wk_header = '202202'.
ls_week-wk_number = 02.
ls_week-amt_per_wk = 222222.
APPEND ls_week TO gt_weeks.
ls_week-wk_header = '202203'.
ls_week-wk_number = 03.
ls_week-amt_per_wk = 33333.
APPEND ls_week TO gt_weeks.
ls_week-wk_header = '202203'.
ls_week-wk_number = 03.
ls_week-amt_per_wk = 333333.
APPEND ls_week TO gt_weeks.
************************************** Fill gt_weeks_pivot with pivot of sample data: **********************
ls_week_pivot-sum_per_wk1 = 11111 + 111111.
ls_week_pivot-sum_per_wk2 = 22222 + 222222.
ls_week_pivot-sum_per_wk3 = 33333 + 333333.
APPEND ls_week_pivot TO gt_weeks_pivot.
************************************ Display regular (source) data in ALV: *******************************
DATA: lo_alv TYPE REF TO cl_salv_table,
lo_columns TYPE REF TO cl_salv_columns_table,
lo_column TYPE REF TO cl_salv_column_list.
CALL METHOD cl_salv_table=>factory
IMPORTING
r_salv_table = lo_alv
CHANGING
t_table = gt_weeks.
lo_columns = lo_alv->get_columns( ).
TRY.
lo_column ?= lo_columns->get_column( 'WK_HEADER' ).
lo_column->set_short_text( 'WeekName' ).
lo_column ?= lo_columns->get_column( 'WK_NUMBER' ).
lo_column->set_short_text( 'WeekNr' ).
lo_column ?= lo_columns->get_column( 'AMT_PER_WK' ).
lo_column->set_short_text( 'AmntPerWk' ).
CATCH cx_salv_not_found.
ENDTRY.
************************************ Display pivot of source data in ALV: *******************************
lo_alv->get_functions( )->set_all( abap_true ).
CALL METHOD lo_alv->display.
CALL METHOD cl_salv_table=>factory
IMPORTING
r_salv_table = lo_alv
CHANGING
t_table = gt_weeks_pivot.
lo_columns = lo_alv->get_columns( ).
TRY.
lo_column ?= lo_columns->get_column( 'SUM_PER_WK1' ).
lo_column->set_short_text( 'SumPerWk1' ).
lo_column ?= lo_columns->get_column( 'SUM_PER_WK2' ).
lo_column->set_short_text( 'SumPerWk2' ).
lo_column ?= lo_columns->get_column( 'SUM_PER_WK3' ).
lo_column->set_short_text( 'SumPerWk3' ).
CATCH cx_salv_not_found.
ENDTRY.
lo_alv->get_functions( )->set_all( abap_true ).
CALL METHOD lo_alv->display.
What I've tried so far was to create Field-catalog that matches the pivot-structure:到目前为止,我尝试的是创建与枢轴结构匹配的字段目录:
DATA: fc_tmp_pvt TYPE lvc_s_fcat,
fc_acc_pvt TYPE lvc_t_fcat.
CLEAR: fc_tmp_pvt.
DATA: counter_i TYPE i,
counter_s TYPE string,
wk_number TYPE string.
counter_i = 1.
counter_s = counter_i.
CONCATENATE 'wk_number' counter_s INTO wk_number.
****************** Create pivoted Field-Catalog by looping through SumsPerWeek Table: ******************
FIELD-SYMBOLS: <fs_week> TYPE strct_week.
LOOP AT gt_weeks ASSIGNING <fs_week>.
fc_tmp_pvt-fieldname = wk_number.
fc_tmp_pvt-col_pos = counter_i.
fc_tmp_pvt-coltext = <fs_week>-wk_header.
fc_tmp_pvt-key = 'X'.
fc_tmp_pvt-seltext = <fs_week>-wk_header.
APPEND fc_tmp_pvt TO fc_acc_pvt.
counter_i = counter_i + 1.
counter_s = counter_i.
CONCATENATE 'wk_number' counter_s INTO wk_number.
ENDLOOP.
Then I tried to create a dynamic table matching the pivoted Field-Catalog:然后我尝试创建一个与旋转字段目录匹配的动态表:
****************** Create Dynamic Table matching pivoted Field-Catalog: ******************
DATA: r_dyn_table TYPE REF TO DATA.
FIELD-SYMBOLS: <t_dyn_table> TYPE STANDARD TABLE.
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
it_fieldcatalog = fc_acc_pvt
IMPORTING
ep_table = r_dyn_table
EXCEPTIONS
generate_subpool_dir_full = 1
OTHERS = 2.
ASSIGN r_dyn_table->* TO <t_dyn_table>.
FIELD-SYMBOLS: <wa_dyn_table> TYPE any,
<w_field> TYPE any.
APPEND INITIAL LINE TO <t_dyn_table> ASSIGNING <wa_dyn_table>.
FIELD-SYMBOLS: <fs_data> type strct_week.
DATA: lv_index type sy-tabix.
counter_i = 1.
counter_s = counter_i.
CONCATENATE 'wk_number' counter_s INTO wk_number.
DATA: sum_per_wk TYPE i.
LOOP AT gt_weeks ASSIGNING <fs_data>.
ASSIGN COMPONENT wk_number OF STRUCTURE <wa_dyn_table> TO <w_field>.
<w_field> = <fs_data>-amt_per_wk.
sum_per_wk = <w_field>.
counter_i = counter_i + 1.
counter_s = counter_i.
CONCATENATE 'wk_number' counter_s INTO wk_number.
* read table gt_weeks assigning <fs_check> index lv_index. " Check so the position will never be processed later
* <fs_check>-check = 'X'.
ENDLOOP.
DATA: gs_layout TYPE slis_layout_alv,
g_repid TYPE sy-repid.
g_repid = sy-repid.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = g_repid
is_layout = gs_layout
it_fieldcat = fc_acc_pvt
TABLES
t_outtab = <t_dyn_table>
EXCEPTIONS program_error = 1
others = 2 .
IF sy-subrc <> 0.
message id sy-msgid type sy-msgty number sy-msgno with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
The idea being to display the pivot as shown here: Pivoted sums per week using dynamically created table passed to alv.想法是显示如下所示的枢轴:使用传递给 alv 的动态创建的表每周透视总和。 This is failing right now on line: CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
with exception:现在在线失败: CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
例外:
When calling function module "REUSE_ALV_GRID_DISPLAY", an attempt was made to pass internal table "FC_ACC_PVT" to formal parameter "IT_FIELDCAT".调用功能模块“REUSE_ALV_GRID_DISPLAY”时,尝试将内部表“FC_ACC_PVT”传递给形式参数“IT_FIELDCAT”。 This resulted in a conflict between the formal and actual parameters.这导致了形式参数和实际参数之间的冲突。 The following conditions have not been met: "2, 3" (2) The row types of both tables are not compatible.未满足以下条件: "2, 3" (2) 两个表的行类型不兼容。 (3) The table keys of both tables do not match. (3) 两个表的表键不匹配。
Turns out there is a much simpler solution than converting field catalog object to TYPE slis_t_fieldcat_alv
by calling LVC_TRANSFER_TO_SLIS
and then using REUSE_ALV_GRID_DISPLAY
;事实证明,有一个比通过调用LVC_TRANSFER_TO_SLIS
然后使用REUSE_ALV_GRID_DISPLAY
将字段目录对象转换为 TYPE slis_t_fieldcat_alv
更简单的解决方案; Instead all I had to do was this:相反,我所要做的就是:
FIELD-SYMBOLS: <fs_tab> TYPE STANDARD TABLE.
ASSIGN r_dyn_table->* TO <fs_tab>.
CALL METHOD grid->set_table_for_first_display
CHANGING
it_fieldcatalog = fc_acc_pvt
it_outtab = <fs_tab>.
改用 REUSE_ALV_GRID_DISPLAY_LVC
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.