【问题标题】:Table pivoting via ABAP with dynamic number of columns?通过 ABAP 以动态列数旋转表?
【发布时间】:2022-06-24 22:17:27
【问题描述】:

我有以下源示例数据(将从字典表中填充,但我手动提供值用于演示目的):

假设我不知道我将在源中拥有多少周以及它们的(6 位数字)值将在枢轴创建时间:

这里是重现样本数据结果的代码:

************************************** 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.

到目前为止,我尝试的是创建与枢轴结构匹配的字段目录:

    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.

然后我尝试创建一个匹配旋转字段目录的动态表:

        ****************** 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.

显示枢轴的想法如下所示:Pivoted sums per week 使用传递给 alv 的动态创建的表。现在在线失败:CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' 例外:

调用功能模块“REUSE_ALV_GRID_DISPLAY”时,尝试将内部表“FC_ACC_PVT”传递给形式参数“IT_FIELDCAT”。这导致了形式参数和实际参数之间的冲突。未满足以下条件:“2、3” (2) 两个表的行类型不兼容。 (3) 两个表的表键不匹配。

【问题讨论】:

  • 请澄清“当然现在失败了”。实际症状是什么,您期望什么?也澄清问题。您必须在参数it_fieldcat 中传递要显示的列列表。
  • ABAP (NOT sql) dynamic table-pivot 为什么不是 sql? sql pivoting 比 ABAP 更漂亮更简洁
  • @SandraRossi:我的意思是“当然失败了”我收到红屏错误:调用功能模块“REUSE_ALV_GRID_DISPLAY”时,尝试将内部表“FC_ACC_PVT”传递给形式参数“IT_FIELDCAT”。这导致了冲突 (2) 两个表的行类型不兼容。 (3) 两个表的表键不匹配。
  • @Suncatcher - 是的。当您确切地知道列名和需要旋转的列数时,它会很漂亮。正如我在问题中提到的:我不知道这些列名是什么。它们可以是 202201 或 201152 - 代码必须接受源表中可能出现的 weeknr 列中的任何值(只要它们是 6 位数字的字符串)并将这些周数行转换为列。
  • 语法错误是正常的,因为REUSE_ALV_GRID_DISPLAY的参数IT_FIELDCAT的类型是SLIS_T_FIELDCAT_ALV,而不是LVC_T_FCAT

标签: dynamic pivot abap alv internal-tables


【解决方案1】:

原来有一个比通过调用LVC_TRANSFER_TO_SLIS 然后使用REUSE_ALV_GRID_DISPLAY 将字段目录对象转换为TYPE slis_t_fieldcat_alv 更简单的解决方案;相反,我所要做的就是:

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>.

【讨论】:

    【解决方案2】:

    改用 REUSE_ALV_GRID_DISPLAY_LVC

    【讨论】:

      猜你喜欢
      • 2012-10-15
      • 1970-01-01
      • 2020-02-25
      • 1970-01-01
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 2016-07-18
      • 1970-01-01
      相关资源
      最近更新 更多