简体   繁体   English

表通过 ABAP 与动态列数旋转?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM