ABAP Deep Structure纵深结构内表ALV展示

目录

1.代码实现部分:

2.程序测试部分:

SAP中关于ALV展示的函数都不支持深层内表的展示,之前在做接口日志的时候,由于很多接口需要将字段设计成深层结构,看到过一些公司前辈编写的日志框架,关于接口参数的展示,或使用ALV TREE,或使用ALV,但都有一个问题,不支持深层结构字段的显示,但往往接口参数中,经常会有参数类型是深层结构的,所以一直想解决这个问题,我们国内做项目绝大部分关于报表展示都用的是REUSE_ALV_GRID_DISPLAY_LVC,所以我改造了一个基于该函数展示为前提的DEEP ALV框架,实现过程参考了Github上一位大佬的思路,不过他使用的是cl_salv_table这个类去实现的,且需要借助额外的协助程序来完善功能,在实际使用上还有一些其他问题,于是我重新写了一份新的框架,最终效果如下:

 测试程序ALV展示使用的内表对应的行类型如下,其中包括一个表类型字段_ITEMS,和一个深层结构字段_INFO。

实现思路:

 

1.以下是代码实现部分:

SE24创建自开发类:

属性部分如下:

 方法列表如下:

DISPLAY_DEEP_STRUCTURE:展示ALV公用方法

  METHOD display_deep_structure.
    FIELD-SYMBOLS:
      <fs_new_data> TYPE STANDARD TABLE.

    DATA:
      lt_fieldcat TYPE lvc_t_fcat.

*   将展示数据使用堆栈管理
    _update_display_stack( table     = i_table
                           operation = mc_stack_go ).

*   绑定全局变量
    IF i_callback_pf_status_set IS NOT INITIAL.
      mv_callback_pf_status_set = i_callback_pf_status_set.
    ENDIF.

    IF i_callback_user_command IS NOT INITIAL.
      mv_callback_user_command = i_callback_user_command.
    ENDIF.

    IF i_custom_fcat IS NOT INITIAL.
      mt_custom_fcat = i_custom_fcat.
    ENDIF.

    CLEAR mt_components.
    mt_components = _get_line_component( table = i_table ).

*   判断是否包含表类型或者结构类型字段
    LOOP AT mt_components TRANSPORTING NO FIELDS
      WHERE type->type_kind = cl_abap_elemdescr=>typekind_table
         OR type->type_kind = cl_abap_elemdescr=>typekind_struct2.
      EXIT.
    ENDLOOP.

*   如果存在表类型字段
    IF sy-subrc = 0.
      DATA(lo_new_data_ref) = _get_type_handle( i_table ).

      ASSIGN lo_new_data_ref->* TO <fs_new_data>.

      _fill_condensed_data( EXPORTING table          = i_table
                            CHANGING  condensed_data = <fs_new_data> ).
    ELSE.
      ASSIGN i_table TO <fs_new_data>.
    ENDIF.

*   构建fieldcat内表
    lt_fieldcat = _build_fieldcat( table = i_table ).

*   展示ALV
    me->_display_condensed_alv(
      EXPORTING
        condensed_data      = <fs_new_data>
        pf_status_set       = mv_callback_pf_status_set
        user_command        = mv_callback_user_command
        custom_fieldcat_lvc = mt_custom_fcat
      CHANGING
        fieldcat_lvc        = lt_fieldcat
        layout_lvc          = i_custom_layo
    ).
  ENDMETHOD.

_UPDATE_DISPLAY_STACK:更新管理堆栈

  METHOD _update_display_stack.
    DATA:
      lo_curr_disp TYPE REF TO data.

    FIELD-SYMBOLS: <table> TYPE ANY TABLE.

    CASE operation.
      WHEN mc_stack_back.
        DELETE mo_display_stack INDEX 1.
      WHEN mc_stack_go.
        IF table IS NOT SUPPLIED.
          RAISE no_data.
        ELSE.
*         获取类型对象
          DATA(lo_handle) = CAST cl_abap_tabledescr( cl_abap_tabledescr=>describe_by_data( table ) ).

*         基于类型对象创建数据
          CREATE DATA lo_curr_disp TYPE HANDLE lo_handle.

*         指针分配
          ASSIGN lo_curr_disp->* TO <table>.

          LOOP AT table ASSIGNING FIELD-SYMBOL(<line>).
            INSERT INITIAL LINE INTO TABLE <table> ASSIGNING FIELD-SYMBOL(<new_line>).
            <new_line> = CORRESPONDING #( <line> ).
          ENDLOOP.

*         将数据保存至堆栈最上层
          INSERT lo_curr_disp INTO mo_display_stack INDEX 1.
        ENDIF.
    ENDCASE.
  ENDMETHOD.

 _GET_LINE_COMPONENT:获取行类型组件

  METHOD _get_line_component.
    component_table = CAST cl_abap_structdescr(
                            CAST cl_abap_tabledescr(
                              cl_abap_tabledescr=>describe_by_data( table )
                            )->get_table_line_type( )
                      )->get_components( ).
  ENDMETHOD.

_GET_TYPE_HANDLE:构建新扁平类型初始内表

  METHOD _get_type_handle.
*   创建新的扁平类型对象,将表类型或者深层结构字段替换为CHAR类型
    DATA(lo_new_tab) = cl_abap_tabledescr=>create(
      p_line_type = cl_abap_structdescr=>create(
                      VALUE #( FOR wa IN mt_components
                        ( SWITCH #(
                            wa-type->type_kind
*                             表类型
                              WHEN cl_abap_elemdescr=>typekind_table
                                THEN VALUE #( name = wa-name type = cl_abap_elemdescr=>get_c( p_length = 70 ) )
*                             深层结构
                              WHEN cl_abap_elemdescr=>typekind_struct2
                                THEN VALUE #( name = wa-name type = cl_abap_elemdescr=>get_c( p_length = 70 ) )
                              ELSE VALUE #( name = wa-name type = wa-type ) )
                        )
                      )
                    )
      p_table_kind = cl_abap_tabledescr=>tablekind_std
      p_unique     = abap_false
    ).

    CREATE DATA new_table TYPE HANDLE lo_new_tab.
  ENDMETHOD.

_FILL_CONDENSED_DATA:mapping填充新的扁平类型内表

  METHOD _fill_condensed_data.
    FIELD-SYMBOLS:
      <fs_table> TYPE ANY TABLE.

    LOOP AT table ASSIGNING FIELD-SYMBOL(<fs_line>).
      INSERT INITIAL LINE INTO TABLE condensed_data ASSIGNING FIELD-SYMBOL(<fs_new_line>).

      LOOP AT mt_components ASSIGNING FIELD-SYMBOL(<fs_component>).
        CASE <fs_component>-type->type_kind.
*         表类型
          WHEN cl_abap_elemdescr=>typekind_table.
            ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_line> TO <fs_table>.
            IF <fs_table> IS ASSIGNED.
              ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_new_line> TO FIELD-SYMBOL(<fs_tab_desc>).
              IF <fs_tab_desc> IS ASSIGNED.
                <fs_tab_desc> = |{ icon_list }Items[ { lines( <fs_table> ) } ]|.
                UNASSIGN:
                  <fs_tab_desc>,
                  <fs_table>.
              ENDIF.
            ENDIF.
*         结构类型
          WHEN cl_abap_elemdescr=>typekind_struct2.
            ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_line> TO FIELD-SYMBOL(<fs_struc>).
            IF <fs_struc> IS ASSIGNED.
              ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_new_line> TO <fs_tab_desc>.
              IF <fs_tab_desc> IS ASSIGNED.
                <fs_tab_desc> = icon_structure.
                UNASSIGN:
                  <fs_tab_desc>,
                  <fs_struc>.
              ENDIF.
            ENDIF.
*         其他类型
          WHEN OTHERS.
            ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_line> TO  FIELD-SYMBOL(<fs_value>).
            IF <fs_value> IS ASSIGNED.
              ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_new_line> TO  FIELD-SYMBOL(<fs_value_new>).
              IF <fs_value_new> IS ASSIGNED.
                <fs_value_new> = <fs_value>.

                UNASSIGN:
                  <fs_value>,
                  <fs_value_new>.
              ENDIF.
            ENDIF.
        ENDCASE.
      ENDLOOP.
    ENDLOOP.
  ENDMETHOD.

_BUILD_FIELDCAT:自动构建fieldcat(没有使用函数自动获取是因为函数的返回并不满足我的需求)

  METHOD _build_fieldcat.
    DATA:
      lv_struc_name TYPE tabname,
      ls_fieldcat   TYPE lvc_s_fcat.

*   获取行类型结构名
    DATA(lv_structure) = CAST cl_abap_tabledescr( cl_abap_tabledescr=>describe_by_data( table ) )->get_table_line_type( )->get_relative_name( ).

    lv_struc_name = lv_structure.

*   获取fieldcat信息
    SELECT a~tabname,
           a~fieldname,
           a~position,
           a~rollname,
           a~inttype,
           a~datatype,
           a~leng,
           a~domname,
           a~comptype,
           b~reftable,
           b~reffield,
           b~reptext,
           b~scrtext_s,
           b~scrtext_m,
           b~scrtext_l,
           c~lowercase,
           c~convexit,
           d~ddtext AS d_ddtext,
           e~ddtext AS t_ddtext,
           f~ddtext AS s_ddtext
      FROM dd03l AS a
      LEFT OUTER JOIN dd03vt AS b
        ON a~tabname    = b~tabname
       AND a~fieldname  = b~fieldname
       AND a~position   = b~position
       AND a~comptype   = b~comptype
       AND b~ddlanguage = @sy-langu
      LEFT OUTER JOIN dd04l AS c
        ON a~rollname   = c~rollname
       AND a~as4local   = c~as4local
      LEFT OUTER JOIN dd03t AS d
        ON a~tabname    = d~tabname
       AND a~as4local   = d~as4local
       AND a~fieldname  = d~fieldname
       AND d~ddlanguage = @sy-langu
      LEFT OUTER JOIN dd40t AS e
        ON a~rollname   = e~typename
       AND e~ddlanguage = @sy-langu
      LEFT OUTER JOIN dd02t AS f
        ON a~rollname = f~tabname
       AND f~ddlanguage = @sy-langu
     WHERE a~tabname    = @lv_struc_name
       AND a~as4local   = 'A'
       AND a~depth      = ''
      INTO TABLE @DATA(lt_fieldinfo).

    SORT lt_fieldinfo BY position ASCENDING.

    LOOP AT lt_fieldinfo INTO DATA(ls_fieldinfo).
      ls_fieldcat-col_pos   = ls_fieldinfo-position.
      ls_fieldcat-fieldname = ls_fieldinfo-fieldname.

      CASE ls_fieldinfo-datatype.
*       数量类型
        WHEN 'QUAN'.
          ls_fieldcat-qfieldname = ls_fieldinfo-reffield.
*       金额类型
        WHEN 'CURR'.
          ls_fieldcat-cfieldname = ls_fieldinfo-reffield.
        WHEN OTHERS.
      ENDCASE.

      ls_fieldcat-convexit  = ls_fieldinfo-convexit.
      ls_fieldcat-datatype  = ls_fieldinfo-datatype.
      ls_fieldcat-inttype   = ls_fieldinfo-inttype.
      ls_fieldcat-intlen    = ls_fieldinfo-leng.
      ls_fieldcat-lowercase = ls_fieldinfo-lowercase.
      ls_fieldcat-reptext   = ls_fieldinfo-reptext.

      CASE ls_fieldinfo-comptype.
*       内置类型
        WHEN ''.
          ls_fieldcat-reptext = ls_fieldinfo-d_ddtext.
*       表类型
        WHEN 'L'.
          ls_fieldcat-hotspot = 'X'.
          ls_fieldcat-reptext = ls_fieldinfo-t_ddtext.
          ls_fieldcat-just    = 'L'.
*       结构
        WHEN 'S'.
          ls_fieldcat-hotspot = 'X'.
          ls_fieldcat-reptext = ls_fieldinfo-s_ddtext.
          ls_fieldcat-just    = 'L'.
        WHEN OTHERS.
      ENDCASE.

      ls_fieldcat-domname   = ls_fieldinfo-domname.
      ls_fieldcat-ref_table = lv_struc_name.
      ls_fieldcat-dd_outlen = ls_fieldinfo-leng.
      ls_fieldcat-scrtext_s = ls_fieldinfo-scrtext_s.
      ls_fieldcat-scrtext_m = ls_fieldinfo-scrtext_m.
      ls_fieldcat-scrtext_l = ls_fieldinfo-scrtext_l.
      APPEND ls_fieldcat TO fieldcat.
      CLEAR ls_fieldcat.
    ENDLOOP.
  ENDMETHOD.

_DISPLAY_CONDENSED_ALV:最终展示处理

  METHOD _display_condensed_alv.
    DATA:
      lv_tabix TYPE i,
      lv_index TYPE i.

    DATA:
      lt_event_exit TYPE slis_t_event_exit,
      ls_event_exit TYPE slis_event_exit.

    FIELD-SYMBOLS <fs_alv> TYPE STANDARD TABLE.

*   设置默认布局控制
    IF layout_lvc IS INITIAL.
      layout_lvc-zebra      = 'X'.                "颜色间隔
      layout_lvc-sel_mode   = 'D'.                "选择模式
      layout_lvc-cwidth_opt = 'A'.                "列宽自适应
    ENDIF.

*   如果存在自定义字段设置,将其与标准获取的字段设置合并
    IF custom_fieldcat_lvc IS NOT INITIAL.
      LOOP AT custom_fieldcat_lvc INTO DATA(ls_cus_fcat).
        READ TABLE fieldcat_lvc ASSIGNING FIELD-SYMBOL(<fs_fieldcat>)
          WITH KEY fieldname = ls_cus_fcat-fieldname
                   ref_table = ls_cus_fcat-ref_table.
        IF sy-subrc = 0.
          DO.
            ADD 1 TO lv_index.
            ASSIGN COMPONENT lv_index OF STRUCTURE ls_cus_fcat TO FIELD-SYMBOL(<fs_cus_fcat>).
            IF <fs_cus_fcat> IS ASSIGNED.
              ASSIGN COMPONENT lv_index OF STRUCTURE <fs_fieldcat> TO FIELD-SYMBOL(<fs_fcat>).
              IF <fs_cus_fcat> <> <fs_fcat> AND <fs_cus_fcat> IS NOT INITIAL.
                <fs_fcat> = <fs_cus_fcat>.
              ENDIF.
            ELSE.
              EXIT.
            ENDIF.

            UNASSIGN:
              <fs_cus_fcat>,
              <fs_fcat>.
          ENDDO.
          CLEAR lv_index.
        ENDIF.
      ENDLOOP.
    ENDIF.

    ASSIGN condensed_data TO <fs_alv>.

*   使标准按钮->"返回",可以触发用户自定义USER_COMMAND回调函数
    ls_event_exit-ucomm = '&F03'.
    ls_event_exit-after = 'X'.
    APPEND ls_event_exit TO lt_event_exit.

*   展示ALV
    CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
      EXPORTING
        i_callback_program       = sy-cprog
        i_callback_pf_status_set = pf_status_set
        i_callback_user_command  = user_command
        is_layout_lvc            = layout_lvc
        it_fieldcat_lvc          = fieldcat_lvc
        i_save                   = 'A'
        it_event_exit            = lt_event_exit
      TABLES
        t_outtab                 = <fs_alv>
      EXCEPTIONS
        program_error            = 1
        OTHERS                   = 2.
  ENDMETHOD.

HOTSPOT_CLICK:处理热点双击事件

  METHOD hotspot_click.
    FIELD-SYMBOLS:
      <fs_current_display> TYPE INDEX TABLE,
      <fs_table>           TYPE STANDARD TABLE,
      <fs_struc>           TYPE any.

    DATA:
      lo_current_display TYPE REF TO data,
      lv_obj_type        TYPE char1,
      lo_data            TYPE REF TO data.

*   获取当前界面展示扁平内表对应的原始内表(深层内表)
    READ TABLE mo_display_stack INTO lo_current_display INDEX 1.
    ASSIGN lo_current_display->* TO <fs_current_display>.

    READ TABLE <fs_current_display> INDEX i_selfield-tabindex ASSIGNING FIELD-SYMBOL(<fs_current_row>).
    IF <fs_current_row> IS ASSIGNED.
*     获取点击单元格数据内容
      ASSIGN COMPONENT i_selfield-fieldname OF STRUCTURE <fs_current_row> TO FIELD-SYMBOL(<fs_deep_field>).

*     获取点击单元格数据类型
      lv_obj_type = cl_abap_tabledescr=>describe_by_data( <fs_deep_field> )->type_kind.

      CASE lv_obj_type.
*       表类型
        WHEN cl_abap_elemdescr=>typekind_table.
          ASSIGN <fs_deep_field> TO <fs_table>.
*       深层结构
        WHEN cl_abap_elemdescr=>typekind_struct2.
          CREATE DATA lo_data LIKE TABLE OF <fs_deep_field>.
          ASSIGN lo_data->* TO <fs_table>.
          APPEND <fs_deep_field> TO <fs_table>.
        WHEN OTHERS.
      ENDCASE.

      IF <fs_table> IS ASSIGNED.
        IF <fs_table> IS NOT INITIAL.
          display_deep_structure( i_table                 = <fs_table>
                                  i_callback_user_command = mv_callback_user_command  ).
        ELSE.
          MESSAGE 'No Data!' TYPE 'S'.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDMETHOD.

BACK_CLICK:捕获标准返回按钮事件

  METHOD back_click.
    _update_display_stack( operation = mc_stack_back ).
  ENDMETHOD.

至此,框架代码完成。 

2.编写程序进行测试:

主程序部分:

*&---------------------------------------------------------------------*
*& Report ZDEEP_ALV_13065
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zdeep_alv_13065.
TABLES:vbak.
TYPES:
  ty_tab_alv  TYPE ztdeep_head,
  ty_alv      TYPE zsdeep_head,
  ty_tab_item TYPE ztdeep_item,
  ty_item     TYPE zsdeep_item.

DATA:
  gt_alv      TYPE ty_tab_alv,
  go_deep_alv TYPE REF TO zdeep_alv.

SELECT-OPTIONS:s_vbeln FOR vbak-vbeln.

START-OF-SELECTION.

  PERFORM frm_get_data.

  PERFORM frm_show_deep_alv.

取数部分

*&---------------------------------------------------------------------*
*& Form FRM_GET_DATA
*&---------------------------------------------------------------------*
*& 获取数据
*&---------------------------------------------------------------------*
FORM frm_get_data .
  DATA:
    ls_item      TYPE ty_item,
    lt_item      TYPE ty_tab_item,
    ls_head      TYPE ty_alv,
    ls_head_info TYPE zsdeep_head_info,
    ls_return    TYPE bapiret2.

  SELECT a~vbeln,
         a~ernam,
         a~audat,
         a~auart,
         a~waerk,
         a~vkorg,
         a~vtweg,
         b~posnr,
         b~matnr,
         b~charg,
         b~matkl,
         b~zmeng,
         b~zieme,
         b~netwr,
         b~waerk AS item_waerk,
         a~kunnr
    INTO TABLE @DATA(lt_salesorder)
    FROM vbak AS a
   INNER JOIN vbap AS b
      ON a~vbeln = b~vbeln
   WHERE a~vbeln IN @s_vbeln
     AND a~auart = 'ZOR1'.

  SORT lt_salesorder BY vbeln ASCENDING
                        posnr ASCENDING.

  LOOP AT lt_salesorder INTO DATA(ls_salesorder)
    GROUP BY ( vbeln = ls_salesorder-vbeln ) ASCENDING
    REFERENCE INTO DATA(lo_salesorder).

    LOOP AT GROUP lo_salesorder ASSIGNING FIELD-SYMBOL(<fs_salesorder>).
      ls_item-posnr = <fs_salesorder>-posnr.
      ls_item-matnr = <fs_salesorder>-matnr.
      ls_item-charg = <fs_salesorder>-charg.
      ls_item-matkl = <fs_salesorder>-matkl.
      ls_item-zmeng = <fs_salesorder>-zmeng.
      ls_item-zieme = <fs_salesorder>-zieme.
      ls_item-netwr = <fs_salesorder>-netwr.
      ls_item-waerk = <fs_salesorder>-item_waerk.
      ls_item-ztest = 'Test..'.
      APPEND ls_item TO lt_item.
      CLEAR ls_item.
    ENDLOOP.
    ls_head-_items = lt_item.

    ls_head-vbeln = <fs_salesorder>-vbeln.
    ls_head-ernam = <fs_salesorder>-ernam.
    ls_head-audat = <fs_salesorder>-audat.
    ls_head-auart = <fs_salesorder>-auart.
    ls_head-waerk = <fs_salesorder>-waerk.
    ls_head-vkorg = <fs_salesorder>-vkorg.
    ls_head-vtweg = <fs_salesorder>-vtweg.

    ls_head_info-uname = sy-uname.
    ls_head_info-utext = sy-datum.
    ls_return-type    = 'S'.
    ls_return-message = 'this is a test message'.
    APPEND ls_return TO ls_head_info-_message.

    ls_head-_info = ls_head_info.
    ls_head-kunnr = <fs_salesorder>-kunnr.

    APPEND ls_head TO gt_alv.
    CLEAR:
      ls_head,
      lt_item,
      ls_item,
      ls_head_info.
  ENDLOOP.
ENDFORM.

调用框架进行ALV展示

*&---------------------------------------------------------------------*
*& Form FRM_SHOW_DEEP_ALV
*&---------------------------------------------------------------------*
*& 展示ALV
*&---------------------------------------------------------------------*
FORM frm_show_deep_alv .
  DATA:
    ls_layout     TYPE lvc_s_layo,
    lv_struc_name TYPE tabname,
    lt_fieldcat   TYPE lvc_t_fcat,
    ls_fieldcat   TYPE lvc_s_fcat.

  ls_fieldcat-fieldname = 'VBELN'.                "字段名
  ls_fieldcat-ref_table = 'ZSDEEP_HEAD'.          "参考表类型
  ls_fieldcat-reptext   = 'My订单'.
  ls_fieldcat-scrtext_s = 'My订单'.
  ls_fieldcat-scrtext_m = 'My订单'.
  ls_fieldcat-scrtext_l = 'My订单'.
  APPEND ls_fieldcat TO lt_fieldcat.

  ls_fieldcat-fieldname = '_MESSAGE'.             "字段名
  ls_fieldcat-ref_table = 'ZSDEEP_HEAD_INFO'.     "参考表类型
  ls_fieldcat-reptext   = 'My消息'.
  ls_fieldcat-scrtext_s = 'My消息'.
  ls_fieldcat-scrtext_m = 'My消息'.
  ls_fieldcat-scrtext_l = 'My消息'.
  APPEND ls_fieldcat TO lt_fieldcat.

  CREATE OBJECT go_deep_alv.

*  SELECT * INTO TABLE @DATA(lt_t001) FROM t001.

  go_deep_alv->display_deep_structure(
    i_table                  = gt_alv
*    i_table                  = lt_t001
    i_callback_pf_status_set = 'FRM_STATUS_SET'
    i_callback_user_command  = 'FRM_USER_COMMAND'
*    i_custom_fcat            = lt_fieldcat
  ).
ENDFORM.

i_table:必传参数,可以是深层结构内表,也可以是普通扁平类型内表。

i_callback_pf_status_set:选填参数,不传则使用默认标准状态栏。

i_callback_user_command:选填参数,当传入内表为纵深结构时,则需要传入参数指定处理子例程,需要调用框架方法释放堆栈内存;当传入内表为普通扁平结构时,如果没有自定义按钮逻辑,则不需要传入。

i_custom_fcat:选填参数,不传则在框架内默认,传了则在框架内会自动与标准生成的fieldcat信息合并覆盖。

i_custom_layo:选填参数,同fieldcat。

回调函数部分

*&---------------------------------------------------------------------*
*& Form FRM_STATUS_SET
*&---------------------------------------------------------------------*
*& GUI状态栏设置
*&---------------------------------------------------------------------*
*&      --> RT_EXTAB      排除按钮
*&---------------------------------------------------------------------*
FORM frm_status_set USING rt_extab TYPE slis_t_extab.
  SET PF-STATUS 'STANDARD'." EXCLUDING RT_EXTAB.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_USER_COMMAND
*&---------------------------------------------------------------------*
*& 用户按钮事件响应
*&---------------------------------------------------------------------*
*&      --> R_UCOMM      事件码
*&      --> RS_SELFIELD  操作数据字段信息
*&---------------------------------------------------------------------*
FORM frm_user_command USING r_ucomm LIKE sy-ucomm
                            rs_selfield TYPE slis_selfield.
  CASE r_ucomm.
    WHEN '&IC1'.
      go_deep_alv->hotspot_click( i_selfield = rs_selfield ).      
    WHEN '&F03'.
      go_deep_alv->back_click( ).
    WHEN OTHERS.
  ENDCASE.
ENDFORM.

传入深层结构内表时,其中user_command事件中需要对双击事件和返回按钮调用对应的框架方法,来完成界面跳转和堆栈管理,调用完之后,可以进行自定义逻辑的处理。


不使用自定义fieldcat和status效果:

使用自定义status和fieldcat的效果:

普通扁平结构内表的效果: 

 以上。

框架完整代码如下,如果大家有更好的方式也可以评论。

CLASS zdeep_alv DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    METHODS constructor .
    METHODS display_deep_structure
      IMPORTING
        VALUE(i_table)                  TYPE ANY TABLE
        VALUE(i_callback_user_command)  TYPE slis_formname OPTIONAL
        VALUE(i_callback_pf_status_set) TYPE slis_formname OPTIONAL
        VALUE(i_custom_fcat)            TYPE lvc_t_fcat OPTIONAL
        VALUE(i_custom_layo)            TYPE lvc_s_layo OPTIONAL .
    METHODS hotspot_click
      IMPORTING
        VALUE(i_selfield) TYPE slis_selfield .
    METHODS back_click .
  PROTECTED SECTION.
  PRIVATE SECTION.

    DATA mv_callback_pf_status_set TYPE slis_formname .
    DATA mv_callback_user_command TYPE slis_formname .
    DATA:
      mo_display_stack TYPE STANDARD TABLE OF REF TO data .
    CONSTANTS mc_stack_go TYPE char1 VALUE '1' ##NO_TEXT.
    CONSTANTS mc_stack_back TYPE char1 VALUE '2' ##NO_TEXT.
    DATA mt_components TYPE abap_component_tab .
    DATA mt_custom_fcat TYPE lvc_t_fcat .

    METHODS _update_display_stack
      IMPORTING
        !table     TYPE ANY TABLE OPTIONAL
        !operation TYPE char1
      EXCEPTIONS
        no_data .
    METHODS _get_type_handle
      IMPORTING
        !table           TYPE ANY TABLE
      RETURNING
        VALUE(new_table) TYPE REF TO data .
    METHODS _fill_condensed_data
      IMPORTING
        VALUE(table)    TYPE ANY TABLE
      CHANGING
        !condensed_data TYPE ANY TABLE .
    METHODS _display_condensed_alv
      IMPORTING
        VALUE(condensed_data) TYPE ANY TABLE
        !pf_status_set        TYPE slis_formname OPTIONAL
        !user_command         TYPE slis_formname OPTIONAL
        !custom_fieldcat_lvc  TYPE lvc_t_fcat OPTIONAL
      CHANGING
        !fieldcat_lvc         TYPE lvc_t_fcat OPTIONAL
        !layout_lvc           TYPE lvc_s_layo OPTIONAL .
    METHODS _get_line_component
      IMPORTING
        VALUE(table)           TYPE ANY TABLE
      RETURNING
        VALUE(component_table) TYPE abap_component_tab .
    METHODS _build_fieldcat
      IMPORTING
        !table          TYPE ANY TABLE
      RETURNING
        VALUE(fieldcat) TYPE lvc_t_fcat .
ENDCLASS.



CLASS ZDEEP_ALV IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZDEEP_ALV->BACK_CLICK
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD back_click.
    _update_display_stack( operation = mc_stack_back ).
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZDEEP_ALV->CONSTRUCTOR
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD constructor.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZDEEP_ALV->DISPLAY_DEEP_STRUCTURE
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_TABLE                        TYPE        ANY TABLE
* | [--->] I_CALLBACK_USER_COMMAND        TYPE        SLIS_FORMNAME
* | [--->] I_CALLBACK_PF_STATUS_SET       TYPE        SLIS_FORMNAME(optional)
* | [--->] I_CUSTOM_FCAT                  TYPE        LVC_T_FCAT(optional)
* | [--->] I_CUSTOM_LAYO                  TYPE        LVC_S_LAYO(optional)
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD display_deep_structure.
    FIELD-SYMBOLS:
      <fs_new_data> TYPE STANDARD TABLE.

    DATA:
      lt_fieldcat TYPE lvc_t_fcat.

*   将展示数据使用堆栈管理
    _update_display_stack( table     = i_table
                           operation = mc_stack_go ).

*   绑定全局变量
    IF i_callback_pf_status_set IS NOT INITIAL.
      mv_callback_pf_status_set = i_callback_pf_status_set.
    ENDIF.

    IF i_callback_user_command IS NOT INITIAL.
      mv_callback_user_command = i_callback_user_command.
    ENDIF.

    IF i_custom_fcat IS NOT INITIAL.
      mt_custom_fcat = i_custom_fcat.
    ENDIF.

    CLEAR mt_components.
    mt_components = _get_line_component( table = i_table ).

*   判断是否包含表类型或者结构类型字段
    LOOP AT mt_components TRANSPORTING NO FIELDS
      WHERE type->type_kind = cl_abap_elemdescr=>typekind_table
         OR type->type_kind = cl_abap_elemdescr=>typekind_struct2.
      EXIT.
    ENDLOOP.

*   如果存在表类型字段
    IF sy-subrc = 0.
*     构建新的扁平类型的内表
      DATA(lo_new_data_ref) = _get_type_handle( i_table ).

      ASSIGN lo_new_data_ref->* TO <fs_new_data>.

*     填充新的扁平类型的内表
      _fill_condensed_data( EXPORTING table          = i_table
                            CHANGING  condensed_data = <fs_new_data> ).
    ELSE.
      ASSIGN i_table TO <fs_new_data>.
    ENDIF.

*   构建fieldcat内表
    lt_fieldcat = _build_fieldcat( table = i_table ).

*   展示ALV
    me->_display_condensed_alv(
      EXPORTING
        condensed_data      = <fs_new_data>
        pf_status_set       = mv_callback_pf_status_set
        user_command        = mv_callback_user_command
        custom_fieldcat_lvc = mt_custom_fcat
      CHANGING
        fieldcat_lvc        = lt_fieldcat
        layout_lvc          = i_custom_layo
    ).
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZDEEP_ALV->HOTSPOT_CLICK
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_SELFIELD                     TYPE        SLIS_SELFIELD
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD hotspot_click.
    FIELD-SYMBOLS:
      <fs_current_display> TYPE INDEX TABLE,
      <fs_table>           TYPE STANDARD TABLE,
      <fs_struc>           TYPE any.

    DATA:
      lo_current_display TYPE REF TO data,
      lv_obj_type        TYPE char1,
      lo_data            TYPE REF TO data.

*   获取当前界面展示扁平内表对应的原始内表(深层内表)
    READ TABLE mo_display_stack INTO lo_current_display INDEX 1.
    ASSIGN lo_current_display->* TO <fs_current_display>.

    READ TABLE <fs_current_display> INDEX i_selfield-tabindex ASSIGNING FIELD-SYMBOL(<fs_current_row>).
    IF <fs_current_row> IS ASSIGNED.
*     获取点击单元格数据内容
      ASSIGN COMPONENT i_selfield-fieldname OF STRUCTURE <fs_current_row> TO FIELD-SYMBOL(<fs_deep_field>).

*     获取点击单元格数据类型
      lv_obj_type = cl_abap_tabledescr=>describe_by_data( <fs_deep_field> )->type_kind.

      CASE lv_obj_type.
*       表类型
        WHEN cl_abap_elemdescr=>typekind_table.
          ASSIGN <fs_deep_field> TO <fs_table>.
*       深层结构
        WHEN cl_abap_elemdescr=>typekind_struct2.
          CREATE DATA lo_data LIKE TABLE OF <fs_deep_field>.
          ASSIGN lo_data->* TO <fs_table>.
          APPEND <fs_deep_field> TO <fs_table>.
        WHEN OTHERS.
      ENDCASE.

      IF <fs_table> IS ASSIGNED.
        IF <fs_table> IS NOT INITIAL.
          display_deep_structure( i_table                 = <fs_table>
                                  i_callback_user_command = mv_callback_user_command  ).
        ELSE.
          MESSAGE 'No Data!' TYPE 'S'.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZDEEP_ALV->_BUILD_FIELDCAT
* +-------------------------------------------------------------------------------------------------+
* | [--->] TABLE                          TYPE        ANY TABLE
* | [<-()] FIELDCAT                       TYPE        LVC_T_FCAT
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD _build_fieldcat.
    DATA:
      lv_struc_name TYPE tabname,
      ls_fieldcat   TYPE lvc_s_fcat.

*   获取行类型结构名
    DATA(lv_structure) = CAST cl_abap_tabledescr( cl_abap_tabledescr=>describe_by_data( table ) )->get_table_line_type( )->get_relative_name( ).

    lv_struc_name = lv_structure.

*   获取fieldcat信息
    SELECT a~tabname,
           a~fieldname,
           a~position,
           a~rollname,
           a~inttype,
           a~datatype,
           a~leng,
           a~domname,
           a~comptype,
           b~reftable,
           b~reffield,
           b~reptext,
           b~scrtext_s,
           b~scrtext_m,
           b~scrtext_l,
           c~lowercase,
           c~convexit,
           d~ddtext AS d_ddtext,
           e~ddtext AS t_ddtext,
           f~ddtext AS s_ddtext
      FROM dd03l AS a
      LEFT OUTER JOIN dd03vt AS b
        ON a~tabname    = b~tabname
       AND a~fieldname  = b~fieldname
       AND a~position   = b~position
       AND a~comptype   = b~comptype
       AND b~ddlanguage = @sy-langu
      LEFT OUTER JOIN dd04l AS c
        ON a~rollname   = c~rollname
       AND a~as4local   = c~as4local
      LEFT OUTER JOIN dd03t AS d
        ON a~tabname    = d~tabname
       AND a~as4local   = d~as4local
       AND a~fieldname  = d~fieldname
       AND d~ddlanguage = @sy-langu
      LEFT OUTER JOIN dd40t AS e
        ON a~rollname   = e~typename
       AND e~ddlanguage = @sy-langu
      LEFT OUTER JOIN dd02t AS f
        ON a~rollname = f~tabname
       AND f~ddlanguage = @sy-langu
     WHERE a~tabname    = @lv_struc_name
       AND a~as4local   = 'A'
       AND a~depth      = ''
      INTO TABLE @DATA(lt_fieldinfo).

    SORT lt_fieldinfo BY position ASCENDING.

    LOOP AT lt_fieldinfo INTO DATA(ls_fieldinfo).
      ls_fieldcat-col_pos   = ls_fieldinfo-position.
      ls_fieldcat-fieldname = ls_fieldinfo-fieldname.

      CASE ls_fieldinfo-datatype.
*       数量类型
        WHEN 'QUAN'.
          ls_fieldcat-qfieldname = ls_fieldinfo-reffield.
*       金额类型
        WHEN 'CURR'.
          ls_fieldcat-cfieldname = ls_fieldinfo-reffield.
        WHEN OTHERS.
      ENDCASE.

      ls_fieldcat-convexit  = ls_fieldinfo-convexit.
      ls_fieldcat-datatype  = ls_fieldinfo-datatype.
      ls_fieldcat-inttype   = ls_fieldinfo-inttype.
      ls_fieldcat-intlen    = ls_fieldinfo-leng.
      ls_fieldcat-lowercase = ls_fieldinfo-lowercase.
      ls_fieldcat-reptext   = ls_fieldinfo-reptext.

      CASE ls_fieldinfo-comptype.
*       内置类型
        WHEN ''.
          ls_fieldcat-reptext = ls_fieldinfo-d_ddtext.
*       表类型
        WHEN 'L'.
          ls_fieldcat-hotspot = 'X'.
          ls_fieldcat-reptext = ls_fieldinfo-t_ddtext.
          ls_fieldcat-just    = 'L'.
*       结构
        WHEN 'S'.
          ls_fieldcat-hotspot = 'X'.
          ls_fieldcat-reptext = ls_fieldinfo-s_ddtext.
          ls_fieldcat-just    = 'L'.
        WHEN OTHERS.
      ENDCASE.

      ls_fieldcat-domname   = ls_fieldinfo-domname.
      ls_fieldcat-ref_table = lv_struc_name.
      ls_fieldcat-dd_outlen = ls_fieldinfo-leng.
      ls_fieldcat-scrtext_s = ls_fieldinfo-scrtext_s.
      ls_fieldcat-scrtext_m = ls_fieldinfo-scrtext_m.
      ls_fieldcat-scrtext_l = ls_fieldinfo-scrtext_l.
      APPEND ls_fieldcat TO fieldcat.
      CLEAR ls_fieldcat.
    ENDLOOP.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZDEEP_ALV->_DISPLAY_CONDENSED_ALV
* +-------------------------------------------------------------------------------------------------+
* | [--->] CONDENSED_DATA                 TYPE        ANY TABLE
* | [--->] PF_STATUS_SET                  TYPE        SLIS_FORMNAME(optional)
* | [--->] USER_COMMAND                   TYPE        SLIS_FORMNAME(optional)
* | [--->] CUSTOM_FIELDCAT_LVC            TYPE        LVC_T_FCAT(optional)
* | [<-->] FIELDCAT_LVC                   TYPE        LVC_T_FCAT(optional)
* | [<-->] LAYOUT_LVC                     TYPE        LVC_S_LAYO(optional)
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD _display_condensed_alv.
    DATA:
      lv_tabix TYPE i,
      lv_index TYPE i.

    DATA:
      lt_event_exit TYPE slis_t_event_exit,
      ls_event_exit TYPE slis_event_exit.

    FIELD-SYMBOLS <fs_alv> TYPE STANDARD TABLE.

*   设置默认布局控制
    IF layout_lvc IS INITIAL.
      layout_lvc-zebra      = 'X'.                "颜色间隔
      layout_lvc-sel_mode   = 'D'.                "选择模式
      layout_lvc-cwidth_opt = 'A'.                "列宽自适应
    ENDIF.

*   如果存在自定义字段设置,将其与标准获取的字段设置合并
    IF custom_fieldcat_lvc IS NOT INITIAL.
      LOOP AT custom_fieldcat_lvc INTO DATA(ls_cus_fcat).
        READ TABLE fieldcat_lvc ASSIGNING FIELD-SYMBOL(<fs_fieldcat>)
          WITH KEY fieldname = ls_cus_fcat-fieldname
                   ref_table = ls_cus_fcat-ref_table.
        IF sy-subrc = 0.
          DO.
            ADD 1 TO lv_index.
            ASSIGN COMPONENT lv_index OF STRUCTURE ls_cus_fcat TO FIELD-SYMBOL(<fs_cus_fcat>).
            IF <fs_cus_fcat> IS ASSIGNED.
              ASSIGN COMPONENT lv_index OF STRUCTURE <fs_fieldcat> TO FIELD-SYMBOL(<fs_fcat>).
              IF <fs_cus_fcat> <> <fs_fcat> AND <fs_cus_fcat> IS NOT INITIAL.
                <fs_fcat> = <fs_cus_fcat>.
              ENDIF.
            ELSE.
              EXIT.
            ENDIF.

            UNASSIGN:
              <fs_cus_fcat>,
              <fs_fcat>.
          ENDDO.
          CLEAR lv_index.
        ENDIF.
      ENDLOOP.
    ENDIF.

    ASSIGN condensed_data TO <fs_alv>.

*   使标准按钮->"返回",可以触发用户自定义USER_COMMAND回调函数
    ls_event_exit-ucomm = '&F03'.
    ls_event_exit-after = 'X'.
    APPEND ls_event_exit TO lt_event_exit.

*   展示ALV
    CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
      EXPORTING
        i_callback_program       = sy-cprog
        i_callback_pf_status_set = pf_status_set
        i_callback_user_command  = user_command
        is_layout_lvc            = layout_lvc
        it_fieldcat_lvc          = fieldcat_lvc
        i_save                   = 'A'
        it_event_exit            = lt_event_exit
      TABLES
        t_outtab                 = <fs_alv>
      EXCEPTIONS
        program_error            = 1
        OTHERS                   = 2.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZDEEP_ALV->_FILL_CONDENSED_DATA
* +-------------------------------------------------------------------------------------------------+
* | [--->] TABLE                          TYPE        ANY TABLE
* | [<-->] CONDENSED_DATA                 TYPE        ANY TABLE
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD _fill_condensed_data.
    FIELD-SYMBOLS:
      <fs_table> TYPE ANY TABLE.

    LOOP AT table ASSIGNING FIELD-SYMBOL(<fs_line>).
      INSERT INITIAL LINE INTO TABLE condensed_data ASSIGNING FIELD-SYMBOL(<fs_new_line>).

      LOOP AT mt_components ASSIGNING FIELD-SYMBOL(<fs_component>).
        CASE <fs_component>-type->type_kind.
*         表类型
          WHEN cl_abap_elemdescr=>typekind_table.
            ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_line> TO <fs_table>.
            IF <fs_table> IS ASSIGNED.
              ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_new_line> TO FIELD-SYMBOL(<fs_tab_desc>).
              IF <fs_tab_desc> IS ASSIGNED.
                <fs_tab_desc> = |{ icon_list }Items[ { lines( <fs_table> ) } ]|.
                UNASSIGN:
                  <fs_tab_desc>,
                  <fs_table>.
              ENDIF.
            ENDIF.
*         结构类型
          WHEN cl_abap_elemdescr=>typekind_struct2.
            ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_line> TO FIELD-SYMBOL(<fs_struc>).
            IF <fs_struc> IS ASSIGNED.
              ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_new_line> TO <fs_tab_desc>.
              IF <fs_tab_desc> IS ASSIGNED.
                <fs_tab_desc> = icon_structure.
                UNASSIGN:
                  <fs_tab_desc>,
                  <fs_struc>.
              ENDIF.
            ENDIF.
*         其他类型
          WHEN OTHERS.
            ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_line> TO  FIELD-SYMBOL(<fs_value>).
            IF <fs_value> IS ASSIGNED.
              ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_new_line> TO  FIELD-SYMBOL(<fs_value_new>).
              IF <fs_value_new> IS ASSIGNED.
                <fs_value_new> = <fs_value>.

                UNASSIGN:
                  <fs_value>,
                  <fs_value_new>.
              ENDIF.
            ENDIF.
        ENDCASE.
      ENDLOOP.
    ENDLOOP.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZDEEP_ALV->_GET_LINE_COMPONENT
* +-------------------------------------------------------------------------------------------------+
* | [--->] TABLE                          TYPE        ANY TABLE
* | [<-()] COMPONENT_TABLE                TYPE        ABAP_COMPONENT_TAB
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD _get_line_component.
    component_table = CAST cl_abap_structdescr(
                            CAST cl_abap_tabledescr(
                              cl_abap_tabledescr=>describe_by_data( table )
                            )->get_table_line_type( )
                      )->get_components( ).
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZDEEP_ALV->_GET_TYPE_HANDLE
* +-------------------------------------------------------------------------------------------------+
* | [--->] TABLE                          TYPE        ANY TABLE
* | [<-()] NEW_TABLE                      TYPE REF TO DATA
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD _get_type_handle.
*   创建新的扁平类型对象,将表类型或者深层结构字段替换为CHAR类型
    DATA(lo_new_tab) = cl_abap_tabledescr=>create(
      p_line_type = cl_abap_structdescr=>create(
                      VALUE #( FOR wa IN mt_components
                        ( SWITCH #(
                            wa-type->type_kind
*                             表类型
                              WHEN cl_abap_elemdescr=>typekind_table
                                THEN VALUE #( name = wa-name type = cl_abap_elemdescr=>get_c( p_length = 70 ) )
*                             深层结构
                              WHEN cl_abap_elemdescr=>typekind_struct2
                                THEN VALUE #( name = wa-name type = cl_abap_elemdescr=>get_c( p_length = 70 ) )
                              ELSE VALUE #( name = wa-name type = wa-type ) )
                        )
                      )
                    )
      p_table_kind = cl_abap_tabledescr=>tablekind_std
      p_unique     = abap_false
    ).

    CREATE DATA new_table TYPE HANDLE lo_new_tab.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZDEEP_ALV->_UPDATE_DISPLAY_STACK
* +-------------------------------------------------------------------------------------------------+
* | [--->] TABLE                          TYPE        ANY TABLE(optional)
* | [--->] OPERATION                      TYPE        CHAR1
* | [EXC!] NO_DATA
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD _update_display_stack.
    DATA:
      lo_curr_disp TYPE REF TO data.

    FIELD-SYMBOLS: <table> TYPE ANY TABLE.

    CASE operation.
      WHEN mc_stack_back.
        DELETE mo_display_stack INDEX 1.
      WHEN mc_stack_go.
        IF table IS NOT SUPPLIED.
          RAISE no_data.
        ELSE.
*         获取类型对象
          DATA(lo_handle) = CAST cl_abap_tabledescr( cl_abap_tabledescr=>describe_by_data( table ) ).

*         基于类型对象创建数据
          CREATE DATA lo_curr_disp TYPE HANDLE lo_handle.

*         指针分配
          ASSIGN lo_curr_disp->* TO <table>.

          LOOP AT table ASSIGNING FIELD-SYMBOL(<line>).
            INSERT INITIAL LINE INTO TABLE <table> ASSIGNING FIELD-SYMBOL(<new_line>).
            <new_line> = CORRESPONDING #( <line> ).
          ENDLOOP.

*         将数据保存至堆栈最上层
          INSERT lo_curr_disp INTO mo_display_stack INDEX 1.
        ENDIF.
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
要将XML文件解析为内表,并在ALV中显示输出,你可以使用以下步骤: 1. 创建ABAP结构:首先,你需要创建一个与XML文件中的数据结构相对应的ABAP结构。确保结构字段与XML元素或属性名称匹配。 2. 定义内表:创建一个内表,使用上一步创建的ABAP结构作为行类型。 3. 使用XML解析器解析XML文件:使用`cl_xml_document`类创建一个XML文档对象,并使用`load`方法加载XML文件。 ```abap DATA: lo_xml_document TYPE REF TO if_ixml_document, lv_file_path TYPE string. lv_file_path = '<XML_FILE_PATH>'. "替换为你的XML文件路径 CREATE OBJECT lo_xml_document. lo_xml_document->load( lv_file_path ). ``` 4. 获取根节点:通过调用`get_root_node`方法获取XML文档的根节点。 ```abap DATA: lo_root_node TYPE REF TO if_ixml_node. lo_root_node = lo_xml_document->get_root_node( ). ``` 5. 遍历XML节点并解析数据:使用循环遍历子节点,并使用`get_attribute_value`方法获取节点属性值,使用`get_text`方法获取节点文本内容。将解析后的数据填充到内表中。 ```abap DATA: lt_data TYPE TABLE OF your_structure, ls_data TYPE your_structure, lo_child_node TYPE REF TO if_ixml_node. lo_child_node = lo_root_node->get_child_nodes( 'NodeName' ). "替换为你的节点名称 WHILE lo_child_node IS BOUND. ls_data-field1 = lo_child_node->get_attribute_value( 'AttributeName' ). "替换为你的属性名称 ls_data-field2 = lo_child_node->get_text( ). APPEND ls_data TO lt_data. lo_child_node = lo_child_node->get_next_sibling( ). ENDWHILE. ``` 6. 显示数据在ALV中:使用ALV控制台类(`cl_salv_table`)创建一个ALV对象,并使用`set_table`方法将内表数据传递给ALV对象。 ```abap DATA: lo_alv_table TYPE REF TO cl_salv_table. CREATE OBJECT lo_alv_table. lo_alv_table->set_table( lt_data ). ``` 7. 显示ALV格:使用`display`方法显示ALV格。 ```abap lo_alv_table->display( ). ``` 这样,你就可以将XML文件解析为内表,并在ALV中显示输出。请根据实际情况修改上述代码,并确保ABAP结构与XML文件的结构匹配。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeveloperMrMeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值