ABAP——多表头ALV(单元格合并)

发布时间 2023-06-09 16:32:26作者: 鲸与海

参考:https://tricktresor.de/blog/zellen-verbinden

效果:

按照参考链接建立类ZCL_GUI_ALV_GRID:

类方法

ZCL_GUI_ALV_GRID~Z_SET_MERGE_HORIZ

METHOD Z_SET_MERGE_HORIZ.

* ROW - Zeile deren Spalten zusammengef�hrt werden sollen
* tab_col_merge - Spalten, die zusammengef�hrt werden sollen
   FIELD-SYMBOLS <fs_cols> TYPE lvc_s_co01.
   FIELD-SYMBOLS <fs_data> TYPE lvc_s_data.
   DATA outputlen TYPE i.

   SORT tab_col_merge.
* Die Spalten, die zusammengef�hrt werden sollen
   LOOP AT tab_col_merge ASSIGNING <fs_cols>.
* ein paar Pr�fungen
     if <fs_cols>-col_id    le 0.                continue. endif.
     if <fs_cols>-outputlen le <fs_cols>-col_id. continue. endif.
     outputlen = <fs_cols>-outputlen - <fs_cols>-col_id.
     LOOP AT mt_data ASSIGNING <fs_data>
          WHERE row_pos = row  AND
                ( col_pos between <fs_cols>-col_id AND
                                  <fs_cols>-outputlen ).
* Setze wie weit soll gemerged werden Von Spalte in L�nge
* und zwar wird bei der 1 Spalte angefangen
       IF <fs_data>-col_pos = <fs_cols>-col_id.
         <fs_data>-mergehoriz = outputlen.
         <fs_data>-value = value.
* bei allen anderen, die zusammangeh�ren
* muss der Wert raus, da er aus der 1. Spalte kommt
* und das mergekennzeichen muss auch weg !
       ELSE.
         CLEAR <fs_data>-mergehoriz.
         CLEAR <fs_data>-value.
       ENDIF.
     ENDLOOP.

   ENDLOOP.

ENDMETHOD.

ZCL_GUI_ALV_GRID~Z_SET_MERGE_VERT

METHOD Z_SET_MERGE_VERT.

* ROW - Zeile deren Spalten zusammengef�hrt werden sollen
* tab_col_merge - Spalten, die zusammengef�hrt werden sollen
   FIELD-SYMBOLS <fs_cols> TYPE lvc_s_co01.
   FIELD-SYMBOLS <fs_data> TYPE lvc_s_data.
   DATA outputlen TYPE i.

   SORT tab_col_merge.
* Die Spalten, die zusammengef�hrt werden sollen
   LOOP AT tab_col_merge ASSIGNING <fs_cols>.
* ein paar Pr�fungen
     if <fs_cols>-col_id    le 0.                continue. endif.
     if <fs_cols>-outputlen le <fs_cols>-col_id. continue. endif.
     outputlen = <fs_cols>-outputlen - <fs_cols>-col_id.
     LOOP AT mt_data ASSIGNING <fs_data>
          WHERE row_pos = row  AND
                ( col_pos between <fs_cols>-col_id AND
                                  <fs_cols>-outputlen ).
* Setze wie weit soll gemerged werden Von Spalte in L�nge
* und zwar wird bei der 1 Spalte angefangen
       IF <fs_data>-col_pos = <fs_cols>-col_id.
         <fs_data>-mergevert = outputlen.
         <fs_data>-value = value.
* bei allen anderen, die zusammangeh�ren
* muss der Wert raus, da er aus der 1. Spalte kommt
* und das mergekennzeichen muss auch weg !
       ELSE.
         CLEAR <fs_data>-mergevert.
         CLEAR <fs_data>-value.
       ENDIF.
     ENDLOOP.

   ENDLOOP.


ENDMETHOD.

ZCL_GUI_ALV_GRID~Z_DISPLAY

METHOD Z_DISPLAY.

  DATA lv_stable TYPE lvc_s_stbl.
  DATA lv_soft   TYPE C.

**** Prepare refresh
*  lv_stable-row = 'X'.
*  lv_stable-col = 'X'.
*  lv_soft       = 'X'.
*
**** Refresh table because Z_SET_CELL_STYLE adds style-values
**** Refresh initializes mt_data
*  CALL METHOD refresh_table_display
*    EXPORTING
*      is_stable      = lv_stable
*      i_soft_refresh = lv_soft
*    EXCEPTIONS
*      OTHERS         = 1.

* Jetzt noch  �bertragen der ge�nderten Daten
  CALL METHOD me->set_data_table
  CHANGING
    data_table = mt_data[].

  CALL METHOD set_auto_redraw
  EXPORTING
    enable = 1.

ENDMETHOD.

ZCL_GUI_ALV_GRID~Z_SET_CELL_STYLE

METHOD Z_SET_CELL_STYLE.

  FIELD-SYMBOLS <fs_data> TYPE lvc_s_data.
  IF row IS INITIAL.
    IF col IS INITIAL.
* Beides leer -> nichts zu tun.
      EXIT.
    ELSE.
* Nur Spalte setze komplette Spalte
      LOOP AT mt_data ASSIGNING <fs_data>
      WHERE col_pos = col.
        <fs_data>-style  = <fs_data>-style + style.
        <fs_data>-style2 = <fs_data>-style2 + style2.
      ENDLOOP.
    ENDIF.
  ELSE.
    IF col IS INITIAL.
* Nur Zeile eingegeben -> komplette Zeile setzen
      LOOP AT mt_data ASSIGNING <fs_data>
      WHERE row_pos = row.
        <fs_data>-style  = <fs_data>-style + style.
        <fs_data>-style2 = <fs_data>-style2 + style2.
      ENDLOOP.
    ELSE.
      READ TABLE mt_data ASSIGNING <fs_data>
      WITH KEY row_pos = row
      col_pos = col.
      IF sy-subrc EQ 0.
        <fs_data>-style  = <fs_data>-style + style.
        <fs_data>-style2 = <fs_data>-style2 + style2.
      ELSE.
        EXIT.
      ENDIF.
    ENDIF.
  ENDIF.

ENDMETHOD.

ZCL_GUI_ALV_GRID~Z_SET_FIXED_COL_ROW

METHOD Z_SET_FIXED_COL_ROW.

  me->set_fixed_cols( col ).
  me->set_fixed_rows( row ).

ENDMETHOD.

ZCL_GUI_ALV_GRID~Z_INIT_CELL_STYLES

METHOD Z_INIT_CELL_STYLES.
  FIELD-SYMBOLS <fs_data> TYPE lvc_s_data.
* Nur Spalte setze komplette Spalte
  LOOP AT mt_data ASSIGNING <fs_data>.
    <fs_data>-style = 0.
  ENDLOOP.
ENDMETHOD.

代码:

************************************************************************
* 程 序 名:xxx
* 程序描述:商城、SAP、支付宝对账
* 事务代码:xxx
************************************************************************
* 修改日志
************************************************************************
* 日期     版本 修改人       描述
* -------- ---- ------------ -------------------------------------------
* 20230609 1.0  Amell        创建程序
*
************************************************************************
REPORT zsdrtest MESSAGE-ID 00.

INCLUDE <cl_alv_control>.
INCLUDE <icon>.

************************************************************************
* Type Pools Definitions          定义类型池
************************************************************************
TYPE-POOLS slis.

************************************************************************
* Tables Definitions
************************************************************************
TABLES: mkpf.
************************************************************************
* Data Definitions                定义数据
************************************************************************
TYPES: BEGIN OF ty_account,
         field01 TYPE string,
         field02 TYPE string,
         field03 TYPE string,
         field04 TYPE string,
         field05 TYPE string,
         field06 TYPE char4,
         field07 TYPE string,
         field08 TYPE string,
         field09 TYPE string,
         field10 TYPE char4,
         field11 TYPE string,
         field12 TYPE string,
         field13 TYPE string,
         field14 TYPE string,
         field15 TYPE string,
         field16 TYPE string,
       END OF ty_account.

DATA: gt_account         TYPE TABLE OF ty_account.

DATA: ok_code             TYPE sy-ucomm,
      gv_container        TYPE scrfname VALUE 'ACCOUNT',
      go_custom_container TYPE REF TO cl_gui_custom_container,
      go_alv_grid         TYPE REF TO zcl_gui_alv_grid,
      gv_save             TYPE c,
      gs_variant          TYPE disvariant.

DATA: gs_layout    TYPE lvc_s_layo, "布局
      gs_style     TYPE lvc_s_styl, "样式
      gt_fieldcat  TYPE lvc_t_fcat, "字段
      gt_col_merge TYPE lvc_t_co01, "列布局
      gs_col_merge TYPE lvc_s_co01. "列布局

CLASS cl_gui_cfw DEFINITION LOAD.

************************************************************************
* Includes Module                 包含模块
************************************************************************

************************************************************************
* Selection Screen                选择屏幕
************************************************************************
SELECT-OPTIONS: s_erdat FOR mkpf-budat.

************************************************************************
* Initialization                  初始化事件
************************************************************************
INITIALIZATION.

************************************************************************
* At Selection Screen             PAI事件
************************************************************************
AT SELECTION-SCREEN.

************************************************************************
* At Selection Screen Output      PBO事件
************************************************************************
AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.
    IF screen-name = 'S_ERDAT-LOW'.
      screen-required = '1'.
      MODIFY SCREEN.
    ENDIF.

    IF screen-name = 'S_ERDAT-HIGH'.
      screen-required = '1'.
      MODIFY SCREEN.
    ENDIF.
  ENDLOOP.

************************************************************************
* Report Format                   报表格式
************************************************************************
TOP-OF-PAGE.

END-OF-PAGE.

************************************************************************
* Main Process                    主要逻辑
************************************************************************
START-OF-SELECTION.

  "显示容器
  CALL SCREEN 0200.

END-OF-SELECTION.

*&---------------------------------------------------------------------*
*& Module STATUS_0200 OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE status_0200 OUTPUT.
  SET PF-STATUS '0200'.
  SET TITLEBAR '001'.
ENDMODULE.

*&---------------------------------------------------------------------*
*& Module INIT_ALV_0200 OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE init_alv_0200 OUTPUT.

  "初始化对象
  PERFORM frm_init_object.
  "构建ALV的栏位
  PERFORM frm_create_field.
  "构建数据
  PERFORM frm_create_data.
  "显示数据
  PERFORM frm_display_data.
  "合并
  PERFORM frm_merge_data.
  "样式
  PERFORM frm_set_style.
  "显示数据
  go_alv_grid->z_display( ).
ENDMODULE.

*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0200  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_0200 INPUT.

  cl_gui_cfw=>dispatch( ).

  CASE ok_code.
    WHEN 'BACK'.
      SET SCREEN 0. LEAVE SCREEN.
  ENDCASE.
ENDMODULE.

*&---------------------------------------------------------------------*
*& Form FRM_INIT_OBJECT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_init_object .

  IF go_custom_container IS INITIAL.

    CREATE OBJECT go_custom_container
      EXPORTING
        container_name = gv_container.

    CREATE OBJECT go_alv_grid
      EXPORTING
        i_parent = go_custom_container.
  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_CREATE_FIELD
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_create_field .

  DATA: ls_fieldcat TYPE lvc_s_fcat,
        lv_count(2) TYPE n.

  DO 16 TIMES.

    lv_count = sy-index.

    "栏位显示顺序
    ls_fieldcat-col_pos    = lv_count.

    "内表栏位
    ls_fieldcat-fieldname  = 'FIELD' && lv_count.

    APPEND ls_fieldcat TO gt_fieldcat.
    CLEAR ls_fieldcat.
  ENDDO.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CREATE_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_create_data .


  DATA: ls_account TYPE ty_account,
        lv_num TYPE n LENGTH 5.

  "空行数据,用于客户标题合并
  APPEND ls_account TO gt_account.
  CLEAR ls_account.

  ls_account-field01 = '客户'.
  ls_account-field02 = '订单'.
  ls_account-field03 = '建立时间'.
  ls_account-field04 = '金额'.
  ls_account-field05 = '币别'.
  ls_account-field06 = '匹配'.
  ls_account-field07 = '订单'.
  ls_account-field08 = '出货单'.
  ls_account-field09 = '金额'.
  ls_account-field10 = '币别'.
  ls_account-field11 = '匹配'.
  ls_account-field12 = '交易ID'.
  ls_account-field13 = '交易状态'.
  ls_account-field14 = '交易时间'.
  ls_account-field15 = '金额'.
  ls_account-field16 = '币别'.
  APPEND ls_account TO gt_account.
  CLEAR ls_account.

  DO 10 TIMES.
    ADD 1 TO lv_num.
    ls_account-field01 = '客户A'.
    ls_account-field02 = 'EC' && '00000' && lv_num.
    ls_account-field03 = '2023/06/09'.
    ls_account-field04 = '100'.
    ls_account-field05 = 'CNY'.
    ls_account-field06 = icon_led_green.
    ls_account-field07 = '20000' && lv_num.
    ls_account-field08 = '62000' && lv_num.
    ls_account-field09 = '100'.
    ls_account-field10 = 'CNY'.
    IF lv_num > 8.
      ls_account-field11 = icon_led_red.
    ELSE.
      ls_account-field11 = icon_led_green.
    ENDIF.
    ls_account-field12 = '20230610' && lv_num.
    ls_account-field13 = '已到账'.
    ls_account-field14 = '2023/06/10'.
    IF lv_num > 8.
      ls_account-field15 = '90'.
    ELSE.
      ls_account-field15 = '100'.
    ENDIF.
    ls_account-field16 = 'CNY'.
    APPEND ls_account TO gt_account.
    CLEAR ls_account.
  ENDDO.


ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_DISPLAY_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_display_data .

  "内表字段名称
  gs_layout-stylefname = 'CELL'.

  "隐藏列标题
  gs_layout-no_headers = 'X'.

  "栏位最适宽度
  gs_layout-cwidth_opt = 'X'.

  "隐藏工具栏
  gs_layout-no_toolbar = 'X'.

  "解决多表头ALV行数据有限制的问题
  CALL METHOD go_alv_grid->set_ready_for_input
    EXPORTING
      i_ready_for_input = 1.

  "显示数据
  CALL METHOD go_alv_grid->set_table_for_first_display
    EXPORTING
      is_variant                    = gs_variant
      i_save                        = gv_save
      is_layout                     = gs_layout
    CHANGING
      it_fieldcatalog               = gt_fieldcat
      it_outtab                     = gt_account
    EXCEPTIONS
      invalid_parameter_combination = 1
      program_error                 = 2
      too_many_lines                = 3
      OTHERS                        = 4.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_MERGE_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_merge_data .

  "合并客户标题
  gs_col_merge-col_id    = 1.
  gs_col_merge-outputlen = 2.
  APPEND gs_col_merge TO gt_col_merge.
  CLEAR gs_col_merge.

  CALL METHOD go_alv_grid->z_set_merge_vert
    EXPORTING
      row           = 1
      value         = '客户'
    CHANGING
      tab_col_merge = gt_col_merge.

  CLEAR gt_col_merge.

  "合并商城标题
  gs_col_merge-col_id    = 2.
  gs_col_merge-outputlen = 5.
  APPEND gs_col_merge TO gt_col_merge.
  CLEAR gs_col_merge.

  CALL METHOD go_alv_grid->z_set_merge_horiz
    EXPORTING
      row           = 1
      value         = '商城'
    CHANGING
      tab_col_merge = gt_col_merge.

  CLEAR gt_col_merge.

  "合并SAP标题
  gs_col_merge-col_id    = 7.
  gs_col_merge-outputlen = 10.
  APPEND gs_col_merge TO gt_col_merge.
  CLEAR gs_col_merge.

  CALL METHOD go_alv_grid->z_set_merge_horiz
    EXPORTING
      row           = 1
      value         = 'SAP'
    CHANGING
      tab_col_merge = gt_col_merge.

  CLEAR gt_col_merge.

  "合并支付宝标题
  gs_col_merge-col_id    = 12.
  gs_col_merge-outputlen = 16.
  APPEND gs_col_merge TO gt_col_merge.
  CLEAR gs_col_merge.

  CALL METHOD go_alv_grid->z_set_merge_horiz
    EXPORTING
      row           = 1
      value         = '支付宝'
    CHANGING
      tab_col_merge = gt_col_merge.

  CLEAR gt_col_merge.

  "固定标题
  go_alv_grid->z_set_fixed_col_row( EXPORTING col = 0 row = 2 ).

ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_SET_STYLE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_set_style .

  "客户标题、Magento标题、SAP标题、Braintree标题设置粗体和居中
  gs_style-style = alv_style_font_bold + alv_style_align_center_center.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      row   = 1
      col   = 1
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      row   = 1
      col   = 2
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      row   = 1
      col   = 7
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      row   = 1
      col   = 12
      style = gs_style-style.

  CLEAR gs_style.

  "商城列样式(第2列到第5列)
  gs_style-style = alv_style_color_heading.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 2
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 3
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 4
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 5
      style = gs_style-style.

  CLEAR gs_style.

  "SAP列样式(第7列到第10列)
  gs_style-style = alv_style_color_group.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 7
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 8
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 9
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 10
      style = gs_style-style.

  CLEAR gs_style.

  "支付宝列样式(第12列到第16列)
  gs_style-style = alv_style_color_total.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 12
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 13
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 14
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 15
      style = gs_style-style.

  CALL METHOD go_alv_grid->z_set_cell_style
    EXPORTING
      col   = 16
      style = gs_style-style.

  CLEAR gs_style.
ENDFORM.

屏幕:

PROCESS BEFORE OUTPUT.
  MODULE status_0200.
  MODULE init_alv_0200.

PROCESS AFTER INPUT.
  MODULE user_command_0200.