• ABAP 动态列表(动态ALV)超简单实际案例,模板


    一、项目背景。

      研发需要有个报表来对账,

    汇总时,alv后面的标题是用RD项目号来做标题,所以这里需要用到动态列表。前两列的数据是固定的,后面可能改。

     然后是明细显示(参考KOB1,但有不同,KOB1是参考凭证,有物料凭证和会计凭证等,主要以成本元素为主,从COVP视图取数。

    实际是需要会计凭证号,所以直接关联ACDOCA和AUFK)

     还有订单和RD号的对应关系,一个RD号可对应多个订单。

    二、解决方案

      1、先在KO03增加了个字段(RD号,ZRDTXT),在结构CI_AUFK中增加ZRDTXT,然后直接在屏幕上画。

    验证

     

       2、开发报表

      动态列表部分可以直接看汇总部分,主要用到cl_alv_table_create=>create_dynamic_table创建动态列表,

    其它都有注释,建议直接看程序,可把AUFK-ZRDTXT替换成其它字段后,直接保存调试。

    ZFICOR055

    *&---------------------------------------------------------------------*
    *& Report ZFICOR055
    *&---------------------------------------------------------------------*
    *&
    *&---------------------------------------------------------------------*
    REPORT zficor055.
    
    INCLUDE zficor055_head.
    INCLUDE zficor055_screen.
    INCLUDE zficor055_form.
    
    START-OF-SELECTION.
      IF r1 EQ 'X'."委外清单明细
        PERFORM frm_check_auth.
        IF lv_auth EQ 'X'.
          MESSAGE lv_msg TYPE 'S' DISPLAY LIKE 'E'.
          RETURN.
        ENDIF.
        PERFORM frm_get_data."获取明细
      ENDIF.
    
      IF r2 EQ 'X'."汇总
        PERFORM frm_check_auth.
        IF lv_auth EQ 'X'.
          MESSAGE lv_msg TYPE 'S' DISPLAY LIKE 'E'.
          RETURN.
        ENDIF.
        PERFORM frm_get_data."获取明细
        PERFORM frm_get_data3."创建<dyn_table>结构
        PERFORM frm_get_data4."获取<dyn_table>数据
      ENDIF.
    
      IF r3 EQ 'X'."委外清单明细
        PERFORM frm_check_auth.
        IF lv_auth EQ 'X'.
          MESSAGE lv_msg TYPE 'S' DISPLAY LIKE 'E'.
          RETURN.
        ENDIF.
        PERFORM frm_get_data2.
      ENDIF.
    
    END-OF-SELECTION.
      PERFORM f_display_data.
    View Code

    包含文件ZFICOR055_HEAD

    *&---------------------------------------------------------------------*
    *& 包含               ZFICOR055_HEAD
    *&---------------------------------------------------------------------*
    TABLES:sscrfields,aufk,acdoca.
    DATA: d_ref      TYPE REF TO data,
          d_ref2     TYPE REF TO data,
          lt_alv_cat TYPE TABLE OF lvc_s_fcat,
          ls_alv_cat LIKE LINE OF lt_alv_cat.
    
    DATA: lt_table LIKE TABLE OF dntab.
    DATA: ls_table TYPE dntab.
    
    DATA: dyn_table TYPE REF TO data.
    DATA: dyn_wa TYPE REF TO data.
    FIELD-SYMBOLS :<dyn_table> TYPE table,
                   <dyn_wa>    TYPE any,
                   <dyn_field> TYPE any,
                   <fs_str>    TYPE any,
                   <fs_strb>   TYPE any.
    
    
    DATA: dyn_table2 TYPE REF TO data.
    DATA: dyn_wa2 TYPE REF TO data.
    
    
    FIELD-SYMBOLS :<dyn_table2> TYPE table,
                   <dyn_wa2>    TYPE any,
                   <dyn_field2> TYPE any,
                   <fs_str2>    TYPE any.
    DATA: go_excel    TYPE ole2_object,
          go_workbook TYPE ole2_object,
          go_sheet    TYPE ole2_object.
    DATA: gs_layout   TYPE lvc_s_layo,
          gt_fieldcat TYPE lvc_t_fcat.
    
    TYPES: BEGIN OF sy_output.
        INCLUDE STRUCTURE zficos055a. "ALV显示
    TYPES:
      zcolor(4),
      message   TYPE char200, "
    *  cellcolor TYPE lvc_t_scol,
      zsel      TYPE c,
      slbox,
      END OF sy_output.
    
    DATA: gt_output  TYPE TABLE OF sy_output,
          gt_output2 TYPE TABLE OF sy_output,
          gs_output  TYPE sy_output.
    
    
    DATA: BEGIN OF gs_vbpa,
            vbeln TYPE vbpa-vbeln,
            posnr TYPE vbpa-posnr,
            parvw TYPE vbpa-parvw,
            kunnr TYPE vbpa-kunnr,
          END OF gs_vbpa.
    DATA: gt_vbpa LIKE TABLE OF gs_vbpa.
    DATA: gt_zficot054_1 LIKE TABLE OF zficot054_1.
    *DATA: gt_zficot054_2 LIKE TABLE OF zficot054_2.
    RANGES: r_fkdat FOR vbrk-fkdat.
    
    TYPES: BEGIN OF sy_output3.
        INCLUDE STRUCTURE zficos055b. "ALV显示
    TYPES:
      zcolor(4),
      message   TYPE char200, "
    *       cellcolor TYPE lvc_t_scol,
      zsel      TYPE c,
      slbox,
      END OF sy_output3.
    
    DATA: gt_output3 TYPE TABLE OF sy_output3,
          gt_output4 TYPE TABLE OF sy_output3,
          gs_output3 TYPE sy_output3.
    
    
    DATA: lv_auth TYPE c,
          lv_msg  TYPE bapi_msg.
    CONSTANTS: c_x TYPE c VALUE 'X'.
    DATA: flag(1).
    
    DATA: p_param TYPE char5.
    
    TYPES: BEGIN OF sy_node,
             mnode TYPE tv_nodekey, "母节点
             znode TYPE tv_nodekey, "自身节点
             zstr1 TYPE skat-txt50, "文本1
             txt50 TYPE skat-txt50, "科目文本
             zstr3 TYPE string, "科目范围
           END OF sy_node.
    DATA: gt_node TYPE TABLE OF sy_node,
          gs_node TYPE sy_node.
    RANGES: gr_racct FOR acdoca-racct."科目
    
    DATA: BEGIN OF gs_zrdtxt,
            zrdtxt TYPE zficos055a-zrdtxt,
            racct  TYPE zficos055a-racct,
    *        txt50  TYPE zficos055a-txt50,
            hsl    TYPE zficos055a-hsl,
          END OF gs_zrdtxt.
    DATA: gt_zrdtxt  LIKE TABLE OF gs_zrdtxt,
          gt_zrdtxt2 LIKE TABLE OF gs_zrdtxt.
    DATA: lv_num       TYPE sy-tabix.
    DATA: lv_fieldname TYPE lvc_s_fcat-fieldname.
    View Code

    包含文件ZFICOR055_SCREEN

    *&---------------------------------------------------------------------*
    *& 包含               ZFICOR055_SCREEN
    *&---------------------------------------------------------------------*
    SELECTION-SCREEN: BEGIN OF BLOCK b01 WITH FRAME TITLE TEXT-001.
    *PARAMETERS: p_name TYPE dd03l-tabname OBLIGATORY.
    *PARAMETERS: p_file1 TYPE string MODIF ID m0."线下(导入)
    *
    *PARAMETERS: p_file2 TYPE string MODIF ID m1."线上(导入)
    *
    *PARAMETERS: p_bukrs TYPE bseg-bukrs MODIF ID m2, "公司代码
    *            p_gjahr TYPE bseg-gjahr MODIF ID m2,
    *            p_monat TYPE bseg-h_monat MODIF ID m2,
    *            p_budat TYPE bseg-h_budat MODIF ID m2,
    *            p_bktxt TYPE bkpf-bktxt MODIF ID m2.
    **            p_werks TYPE bseg-werks MODIF ID m2. "工厂
    **            r1      RADIOBUTTON GROUP g1.
    PARAMETERS: p_bukrs TYPE acdoca-rbukrs MODIF ID m0 DEFAULT '1000'."公司代码
    
    SELECT-OPTIONS: s_gjahr FOR acdoca-gjahr MODIF ID m1 DEFAULT sy-datum+0(4), "年度
                    s_poper FOR acdoca-poper MODIF ID m1, "期间
                    s_racct FOR acdoca-racct MODIF ID m1,"科目
                    s_aufnr FOR aufk-aufnr MODIF ID m0,"订单
                    s_rdtxt FOR aufk-zrdtxt MODIF ID m0,"RD描述
                    s_erdat FOR aufk-erdat MODIF ID m0,"订单创建日期
                    s_ernam FOR aufk-ernam MODIF ID m0."订单创建人
    *                s_budat FOR bseg-h_budat MODIF ID m4."过账日期
    *                s_erdat FOR zficot053-erdat MODIF ID m4,
    *                s_kunnr FOR kna1-kunnr MODIF ID m1,
    *                s_vtweg FOR vbak-vtweg MODIF ID m1.
    
    *SELECTION-SCREEN: FUNCTION KEY 1.
    *SELECTION-SCREEN: FUNCTION KEY 2.
    SELECTION-SCREEN: END OF BLOCK b01.
    
    SELECTION-SCREEN: BEGIN OF BLOCK b02 WITH FRAME TITLE TEXT-002.
    *PARAMETERS: p_name TYPE dd03l-tabname OBLIGATORY.
    *PARAMETERS: p_file2 TYPE string MODIF ID m2.
    PARAMETERS:
    *            r0 RADIOBUTTON GROUP g1 USER-COMMAND u1,
      r1 RADIOBUTTON GROUP g1 USER-COMMAND u1,
      r2 RADIOBUTTON GROUP g1,
      r3 RADIOBUTTON GROUP g1.
    *            r3 RADIOBUTTON GROUP g1,
    *            r4 RADIOBUTTON GROUP g1,
    *            r5 RADIOBUTTON GROUP g1.
    *SELECTION-SCREEN: FUNCTION KEY 1.
    SELECTION-SCREEN: END OF BLOCK b02.
    View Code

    包含文件ZFICOR055_FORM

     实际效果:
    *&---------------------------------------------------------------------*
    *& 包含               ZFICOR055_FORM
    *&---------------------------------------------------------------------*
    *&---------------------------------------------------------------------*
    *& Form FRM_CHECK_AUTH
    *&---------------------------------------------------------------------*
    *& text
    *&---------------------------------------------------------------------*
    *& -->  p1        text
    *& <--  p2        text
    *&---------------------------------------------------------------------*
    FORM frm_check_auth .
    *  IF r1 EQ 'X'.
      SELECT bukrs
        INTO TABLE @DATA(lt_t001)
        FROM t001
       WHERE bukrs EQ @p_bukrs..
      LOOP AT lt_t001 INTO DATA(ls_t001).
        AUTHORITY-CHECK OBJECT 'ZHL_AUTHOR'
            ID 'ZBUKRS' FIELD ls_t001-bukrs.
        IF sy-subrc NE 0.
          lv_msg = |您没有该公司代码{ ls_t001-bukrs }的权限,如有需求,请联系信息部|.
          lv_auth = 'X'.
        ENDIF.
      ENDLOOP.
    *  ENDIF.
    *  IF p_yearm IS INITIAL.
    *    lv_msg = |请填写'年/月'|.
    *    lv_auth = 'X'.
    *  ENDIF.
    ENDFORM.
    *&---------------------------------------------------------------------*
    *& Form FRM_GET_DATA
    *&---------------------------------------------------------------------*
    *& text
    *&---------------------------------------------------------------------*
    *& -->  p1        text
    *& <--  p2        text
    *&---------------------------------------------------------------------*
    FORM frm_get_data.
    
      SELECT a~aufnr,a~ktext,a~zrdtxt,
             b~belnr,b~gjahr,b~rbukrs,b~buzei,b~budat,b~racct,b~hsl,b~msl,b~runit,b~sgtxt
        INTO CORRESPONDING FIELDS OF TABLE @gt_output
        FROM aufk AS a JOIN acdoca AS b ON a~aufnr EQ b~aufnr
       WHERE a~aufnr IN @s_aufnr
         AND a~auart EQ 'Z100'
         AND a~zrdtxt IN @s_rdtxt
         AND a~ernam IN @s_ernam
         AND a~erdat IN @s_erdat
         AND b~rbukrs EQ @p_bukrs
         AND b~gjahr IN @s_gjahr
         AND b~poper IN @s_poper
         AND b~racct IN @s_racct
         AND b~racct not in ('0069999999','0022020900').
    
      IF gt_output[] IS NOT INITIAL.
        SELECT *
          INTO TABLE @DATA(lt_skat)
          FROM skat
           FOR ALL ENTRIES IN @gt_output
         WHERE saknr EQ @gt_output-racct
           AND spras EQ @sy-langu
           AND ktopl EQ 'HL00'.
        SORT lt_skat[] BY saknr.
      ENDIF.
    
      LOOP AT gt_output ASSIGNING FIELD-SYMBOL(<fs_output>).
        READ TABLE lt_skat INTO DATA(ls_skat) WITH KEY saknr = <fs_output>-racct BINARY SEARCH.
        IF sy-subrc EQ 0.
          <fs_output>-txt50 = ls_skat-txt50."总账科目长文本
        ENDIF.
      ENDLOOP.
    
    ENDFORM.
    
    *&---------------------------------------------------------------------*
    *& Form F_DISPLAY_DATA
    *&---------------------------------------------------------------------*
    *& text
    *&---------------------------------------------------------------------*
    *& -->  p1        text
    *& <--  p2        text
    *&---------------------------------------------------------------------*
    FORM f_display_data .
      PERFORM f_set_layout.
      IF r1 EQ 'X'.
        PERFORM f_set_fieldcat USING 'ZFICOS055A'.
        PERFORM f_alv_display TABLES gt_output.
      ELSEIF r2 EQ 'X'.
        DELETE lt_alv_cat WHERE fieldname EQ 'MNODE'.
        DELETE lt_alv_cat WHERE fieldname EQ 'ZNODE'.
        PERFORM f_alv_display TABLES <dyn_table>.
      ELSEIF r3 EQ 'X'.
        PERFORM f_set_fieldcat USING 'ZFICOS055B'.
        PERFORM f_alv_display TABLES gt_output3.
      ENDIF.
    ENDFORM.
    
    FORM f_set_layout.
      CLEAR: gs_layout.
    *  IF r0 EQ 'X'.
      IF r2 EQ ''.
        gs_layout-box_fname = 'SLBOX'.
      ENDIF.
    
    *    gs_layout-ctab_fname = 'CELLCOLOR'.
    *  ENDIF.
      gs_layout-zebra = 'X'.
      gs_layout-cwidth_opt = 'X'.
    
    ENDFORM.
    FORM f_set_fieldcat USING i_tabname TYPE dntab-tabname.
    *取出表结构的字段目录
    
      CALL FUNCTION 'NAMETAB_GET'
        EXPORTING
          langu          = sy-langu
          tabname        = i_tabname
        TABLES
          nametab        = lt_table
        EXCEPTIONS
          no_texts_found = 1.
    *根据取出的字段目录生成参考字段目录
    
      CLEAR lt_alv_cat.
    
    *内表创建
    
    *  CALL METHOD cl_alv_table_create=>create_dynamic_table
    *    EXPORTING
    *      it_fieldcatalog = lt_alv_cat
    *    IMPORTING
    *      ep_table        = d_ref.
    *
    *
    **指定生成的内表到字段符号
    *  ASSIGN d_ref->* TO <dyn_table>.
    *
    **创建动态工作区结构
    *  CREATE DATA dyn_wa LIKE LINE OF <dyn_table>.
    *
    **创建动态工作区
    *  ASSIGN dyn_wa->* TO <dyn_wa>.
    
    * zcolor
    
    
      DATA: ls_fieldcat TYPE lvc_s_fcat.
      DEFINE set_fieldcat.
        CLEAR: ls_fieldcat.
        ls_fieldcat-fieldname = &1.
        ls_fieldcat-ref_field = &2.
        ls_fieldcat-ref_table = &3.
        ls_fieldcat-edit  = &4.
        ls_fieldcat-checkbox    = &5.
        ls_fieldcat-seltext   = &6.
        ls_fieldcat-scrtext_l = &6.
        ls_fieldcat-scrtext_m = &6.
        ls_fieldcat-scrtext_s = &6.
        ls_fieldcat-coltext   = &6.
        APPEND ls_fieldcat TO lt_alv_cat.
      END-OF-DEFINITION.
    *显示内容
    *  set_fieldcat 'ZSEL'      ''      ''     'X' 'X'  '选择'.
    *  set_fieldcat 'ZCOLOR'    ''      ''     '' ''  '更新结果'.
    *  set_fieldcat 'MESSAGE'   ''      ''     '' ''  '更新信息'.
    *  set_fieldcat 'INV'       'VBELN' 'VBRK' '' ''  '发票号'.
    
    
      LOOP AT lt_table INTO ls_table.
    *    IF LS_TABLE-FIELDNAME NE 'MANDT'.
        ls_alv_cat-fieldname = ls_table-fieldname.
        ls_alv_cat-ref_table = i_tabname.
        ls_alv_cat-ref_field = ls_table-fieldname.
        IF ls_table-fieldname EQ 'MEINS' OR ls_table-fieldname EQ 'KMEIN'.
          ls_alv_cat-no_convext = 'X'.
    *      CLEAR: ls_alv_cat-ref_field,ls_alv_cat-ref_table.
        ENDIF.
        ls_alv_cat-seltext   = ls_table-fieldtext.
        ls_alv_cat-scrtext_l = ls_table-fieldtext.
        ls_alv_cat-scrtext_m = ls_table-fieldtext.
        ls_alv_cat-scrtext_s = ls_table-fieldtext.
        APPEND ls_alv_cat TO lt_alv_cat.
    *    ENDIF.
        CLEAR ls_alv_cat.
      ENDLOOP.
      DELETE lt_alv_cat[] WHERE fieldname EQ 'MANDT'.
    *  DELETE lt_alv_cat[] WHERE fieldname EQ 'ZTABIX'.
    *  DELETE lt_alv_cat[] WHERE fieldname EQ 'CHECKBOX'.
    *  DELETE lt_alv_cat[] WHERE fieldname EQ 'STATUS'.
    *  DELETE lt_alv_cat[] WHERE fieldname EQ 'MES_01'.
    *  DELETE lt_alv_cat[] WHERE fieldname EQ 'MES_02'.
    ENDFORM.
    FORM f_alv_display TABLES it_table.
      CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
        EXPORTING
          i_callback_program      = sy-repid
    *     i_callback_pf_status_set = 'F_SET_PF_STATUS'
          i_callback_user_command = 'F_USER_COMMAND'
          is_layout_lvc           = gs_layout
          it_fieldcat_lvc         = lt_alv_cat
          i_save                  = 'U'
        TABLES
          t_outtab                = it_table
        EXCEPTIONS
          program_error           = 1
          OTHERS                  = 2.
      IF sy-subrc <> 0.
      ENDIF.
    ENDFORM.
    *-----------------------------------------------------------------------* *
    *-----------------------------------------------------------------------*
    FORM f_set_pf_status USING rt_extab TYPE slis_t_extab.
    *  SET PF-STATUS 'STD'.
      DATA: itab TYPE TABLE OF sy-ucomm.
    *  IF r0 EQ 'X'.
    **    APPEND 'ZCREAT' TO itab.
    **    APPEND 'ZSEL' TO itab.
    **    APPEND 'ZUNSEL' TO itab.
    **    APPEND 'ZADDBZ' TO itab.
    *    SET PF-STATUS 'STD' EXCLUDING itab."'ZDEL'.
    *  ENDIF.
    *  IF r1 EQ 'X'.
    *    APPEND 'ZCREAT' TO itab.
    *    APPEND 'ZSEL' TO itab.
    *    APPEND 'ZUNSEL' TO itab.
    **    APPEND 'ZADDBZ' TO itab.
    *    SET PF-STATUS 'STD' EXCLUDING itab."'ZDEL'.
    *  ENDIF.
    *  IF r2 EQ 'X'.
    *    APPEND 'ZCREAT' TO itab.
    *    APPEND 'ZSEL' TO itab.
    *    APPEND 'ZUNSEL' TO itab.
    **    APPEND 'ZADDBZ' TO itab.
    *    SET PF-STATUS 'STD' EXCLUDING itab."'ZDEL'.
    *  ENDIF.
    ENDFORM.
    *-----------------------------------------------------------------------* *
    *-----------------------------------------------------------------------*
    FORM f_user_command USING r_ucomm LIKE sy-ucomm
     rs_selfield TYPE slis_selfield.
      PERFORM f_check_change_data.
      CASE r_ucomm.
    *    WHEN 'ZCHANGE'.
    *      PERFORM frm_save_zchange. "保存资产更改数据
        WHEN 'ZCREAT'.
    *      PERFORM frm_zcreag_inv."同一个交货单创建一张发票
        WHEN 'ZSEL'.
    *      PERFORM frm_zsel. "全选
        WHEN 'ZUNSEL'.
    *      PERFORM frm_zunsel. "取消全选
        WHEN '&IC1'."双击事件
          READ TABLE gt_output INTO DATA(gs_output) INDEX rs_selfield-tabindex.
          IF sy-subrc EQ 0.
            CASE rs_selfield-tabname.
              WHEN 'MBLNR'.
    *            CALL FUNCTION 'MIGO_DIALOG'
    *              EXPORTING
    *                i_action            = 'A04'
    *                i_refdoc            = 'R02'
    *                i_mblnr             = gs_output-mblnr
    *                i_mjahr             = gs_output-mjahr
    *              EXCEPTIONS
    *                illegal_combination = 1
    *                OTHERS              = 2.
    *            IF sy-subrc <> 0.
    ** Implement suitable error handling here
    *            ENDIF.
              WHEN 'EBELN'.
    *            SET PARAMETER ID 'BES' FIELD gs_output-ebeln.
    *            CALL TRANSACTION 'ME23N' AND SKIP FIRST SCREEN.
              WHEN OTHERS.
            ENDCASE.
          ENDIF.
      ENDCASE.
      PERFORM f_refresh_alv.
    ENDFORM.
    *-----------------------------------------------------------------------* *
    *-----------------------------------------------------------------------*
    FORM f_check_change_data.
      DATA: lo_grid TYPE REF TO cl_gui_alv_grid.
      CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
        IMPORTING
          e_grid = lo_grid.
      lo_grid->check_changed_data( ).
    ENDFORM.
    *-----------------------------------------------------------------------* *
    *-----------------------------------------------------------------------*
    FORM f_refresh_alv.
      DATA: lo_grid      TYPE REF TO cl_gui_alv_grid,
            ls_is_stable TYPE lvc_s_stbl.
      CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
        IMPORTING
          e_grid = lo_grid.
      ls_is_stable-col = 'X'.
      ls_is_stable-row = 'X'.
      lo_grid->refresh_table_display(
      EXPORTING
      is_stable = ls_is_stable
      EXCEPTIONS
      finished = 1
      OTHERS = 2 ).
      IF sy-subrc <> 0.
      ENDIF.
    ENDFORM.
    *&---------------------------------------------------------------------*
    *& Form FRM_GET_DATA2
    *&---------------------------------------------------------------------*
    *& text
    *&---------------------------------------------------------------------*
    *& -->  p1        text
    *& <--  p2        text
    *&---------------------------------------------------------------------*
    FORM frm_get_data2.
    
      SELECT a~aufnr,a~ktext,a~zrdtxt
    *         b~belnr,b~gjahr,b~rbukrs,b~buzei,b~budat,b~racct,b~hsl,b~msl,b~runit,b~sgtxt
        INTO CORRESPONDING FIELDS OF TABLE @gt_output3
        FROM aufk AS a
    *                   JOIN acdoca AS b ON a~aufnr EQ b~aufnr
       WHERE a~aufnr IN @s_aufnr
         AND a~zrdtxt IN @s_rdtxt
         AND a~ernam IN @s_ernam
         AND a~erdat IN @s_erdat
         AND a~auart EQ 'Z100'.
    *     AND b~rbukrs EQ @p_bukrs
    *     AND b~gjahr IN @s_gjahr
    *     AND b~poper IN @s_poper
    *     AND b~racct IN @s_racct.
    
    ENDFORM.
    *&---------------------------------------------------------------------*
    *& Form FRM_GET_DATA3
    *&---------------------------------------------------------------------*
    *& text
    *&---------------------------------------------------------------------*
    *& -->  p1        text
    *& <--  p2        text
    *&---------------------------------------------------------------------*
    FORM frm_get_data3.
    *  DATA(lo_table_basic) = CAST cl_abap_tabledescr( cl_abap_tabledescr=>describe_by_data( gt_output ) ).
    *  DATA(lo_struct_basic) = CAST cl_abap_structdescr( lo_table_basic->get_table_line_type( ) ).
    *  DATA(lt_component_basic_all) = lo_struct_basic->get_components( ).
    *
    *  DATA(lt_component_include) = lt_component_basic_all.
    *  DATA: lv_fieldname TYPE lvc_s_fcat-fieldname.
    *  BREAK-POINT.
      CLEAR: lt_alv_cat[],gt_zrdtxt.
    
    
      LOOP AT gt_output INTO DATA(ls_output).
        gs_zrdtxt-zrdtxt = ls_output-zrdtxt."RD描述
        gs_zrdtxt-racct = ls_output-racct."科目号
    *    gs_zrdtxt-txt50  = ls_output-txt50."科目长文本
        gs_zrdtxt-hsl    = ls_output-hsl."金额
        COLLECT gs_zrdtxt INTO gt_zrdtxt[].
        CLEAR: gs_zrdtxt,ls_output.
      ENDLOOP.
    
      gt_zrdtxt2 = gt_zrdtxt[].
      SORT gt_zrdtxt2[] BY zrdtxt.
      DELETE ADJACENT DUPLICATES FROM gt_zrdtxt2[] COMPARING zrdtxt.
    
      DATA: ls_fieldcat TYPE lvc_s_fcat.
      DEFINE set_fieldcat.
        CLEAR: ls_fieldcat.
        ls_fieldcat-fieldname = &1.
        ls_fieldcat-ref_field = &2.
        ls_fieldcat-ref_table = &3.
        ls_fieldcat-edit  = &4.
        ls_fieldcat-checkbox    = &5.
        ls_fieldcat-seltext   = &6.
        ls_fieldcat-scrtext_l = &6.
        ls_fieldcat-scrtext_m = &6.
        ls_fieldcat-scrtext_s = &6.
        ls_fieldcat-coltext   = &6.
        APPEND ls_fieldcat TO lt_alv_cat.
      END-OF-DEFINITION.
    
      set_fieldcat 'MNODE'       'NODE_KEY' 'MTREESNODE' '' ''  '母节点'.
      set_fieldcat 'ZNODE'       'NODE_KEY' 'MTREESNODE' '' ''  '自身节点'.
      set_fieldcat 'ZSTR1'       'JSONSTR1' 'ZRFC_LOGS'  '' ''  '内部研究开发投入额'.
      set_fieldcat 'TXT50'       'TXT50'    'SKAT'       '' ''  '科目名称'.
    *  set_fieldcat 'ZSTR3'       'JSONSTR1' 'ZRFC_LOGS'  '' ''  '科目范围'.
    
      LOOP AT gt_zrdtxt2 INTO DATA(ls_zrdtxt2).
        ADD 1 TO lv_num.
    
        lv_fieldname = |NODE{ sy-tabix }|.
        set_fieldcat lv_fieldname  'HSL' 'ACDOCA' '' ''  ls_zrdtxt2-zrdtxt.
      ENDLOOP.
    
    *内表创建
    
      CALL METHOD cl_alv_table_create=>create_dynamic_table
        EXPORTING
          it_fieldcatalog = lt_alv_cat
        IMPORTING
          ep_table        = d_ref.
    
    
    *指定生成的内表到字段符号
      ASSIGN d_ref->* TO <dyn_table>.
    
    *创建动态工作区结构
      CREATE DATA dyn_wa LIKE LINE OF <dyn_table>.
    
    *创建动态工作区
      ASSIGN dyn_wa->* TO <dyn_wa>.
    ENDFORM.
    *&---------------------------------------------------------------------*
    *& Form FRM_GET_DATA4
    *&---------------------------------------------------------------------*
    *& text
    *&---------------------------------------------------------------------*
    *& -->  p1        text
    *& <--  p2        text
    *&---------------------------------------------------------------------*
    FORM frm_get_data4 .
      DATA: ls_node   TYPE sy_node, "记录上一行的节点
            lv_tabix2 TYPE sy-tabix.
      FIELD-SYMBOLS : <fs_hsla> TYPE any,
                      <fs_hslb> TYPE any.
    
      RANGES: r_racct FOR acdoca-racct.
      DATA: lv_str3 TYPE string,
            lv_str1 TYPE string,
            lv_str2 TYPE string.
      DATA: lv_tabix TYPE sy-tabix.
      DATA: lt_str  LIKE TABLE OF lv_str3 WITH HEADER LINE.
    
      CLEAR: gt_node[].
      DEFINE set_node.
        CLEAR: gs_node.
        IF &1 EQ ''.
          gs_node-mnode = ls_node-znode."母节点
        ELSE.
          gs_node-mnode = &1."母节点
        ENDIF.
        IF &2 EQ '' OR &2 EQ 'X'.
          ADD 1 TO lv_tabix.
          gs_node-znode = |{ gs_node-mnode+0(1) }{ lv_tabix }|.
        ELSE.
          gs_node-znode = &2."自身节点
          IF gs_node-mnode EQ gs_node-znode.
            CLEAR: lv_tabix.
          ENDIF.
        ENDIF.
    
        IF &2 EQ 'X' OR &2 NE ''.
          ls_node-mnode = &1.
          ls_node-znode = gs_node-znode."
        ENDIF.
        gs_node-zstr1 = &3."文本1
        gs_node-txt50 = &4."科目文本
        gs_node-zstr3 = &5."科目范围。格式, A~B;C;D;E,用;分隔,范围用~连接
        APPEND gs_node TO gt_node[].
      END-OF-DEFINITION.
    
      "合计的不填科目范围,额外写个嵌套循环,获取下阶节点金额,方便后续增减节点
      "自身节点将作为新的母节点时,打个'X'
      "最后额外循环一次,计算总计,累加'母节点'和'自身节点'相等的数值。
      set_node 'A' 'A' '1、人员人工'                 '合计'                   ''.
      set_node 'A' ''  ''                            '间接人员薪资-自有'      '0066010000'.
      set_node 'A' '' ''                             '间接人员奖金-年终奖'    '0066010045'.
      set_node 'A' '' ''                             '间接人员奖金-其他'      '0066010050'.
      set_node 'A' '' ''                             '补偿金'                 '0066010052'.
      set_node 'A' '' ''                             '间接人员奖金-提成奖'    '0066010072'.
      set_node 'A' '' ''                             '加班费'                 '0066010049'.
      set_node 'A' 'X' '     五险一金'               '合计'                   ''.
      set_node ''  '' ''                             '住房公积金'             '0066010051'.
      set_node ''  '' ''                             '社会基本养老保险'       '0066010065'.
      set_node ''  '' ''                             '基本医疗保险'           '0066010066'.
      set_node ''  '' ''                             '失业保险'               '0066010067'.
      set_node ''  '' ''                             '工伤保险'               '0066010068'.
      set_node ''  '' ''                             '生育保险'               '0066010069'.
      set_node 'B' 'B' '2、直接投入'                 '合计'                   ''.
      set_node 'B'  '' '其中:材料'                  '物料消耗'               '0066010004'.
      set_node 'B'  'X' '     产品试制模具费'        '合计'                   ''.
      set_node ''  '' ''                             '修模费'                 '0066010034'.
      set_node ''  '' ''                             '开模费'                 '0066010038'.
      set_node ''  '' '   样品、样机测试购置'        '样品费'                 '0066010037'.
      set_node ''  '' '     测试、检测费用'          '检测费'                 '0066010060'.
      set_node ''  '' '     低值易耗品'              '低值易耗品'             '0066010031'.
      set_node ''  '' '     水费'                    '水费'                   '0066010008'.
      set_node ''  '' '     电费'                    '电费'                   '0066010014'.
      set_node ''  '' '     房租'                    '房屋租赁'               '0066010003'.
      set_node ''  '' '     设备安装调试费'          ''                       ''.
      set_node 'C' 'C' '3、折旧费用与长期费用摊销'   '合计'                   ''.
      set_node 'C' '' ''                             '折旧费-其它'            '0066010007'.
      set_node 'C' '' ''                             '折旧费-机器'            '0066010011'.
      set_node 'C' '' ''                             '折旧费-模具'            '0066010042'.
      set_node 'D' 'D' '4、其他费用'                 '合计'                   ''.
      set_node 'D'  '' ''                            '职工福利-福利费'        '0066010001'.
      set_node 'D'  '' ''                            '伙食费'                 '0066010002'.
      set_node 'D'  '' ''                            '运输费-外部车辆'        '0066010005'.
      set_node 'D'  '' ''                            '维修保养'               '0066010006'.
      set_node 'D'  '' ''                            '办公费'                 '0066010010'.
      set_node 'D'  '' ''                            '其他费用'               '0066010012'.
      set_node 'D'  '' ''                            '差旅费'                 '0066010016'.
      set_node 'D'  '' ''                            '通讯费'                 '0066010017'.
      set_node 'D'  '' ''                            '业务招待费'             '0066010018'.
      set_node 'D'  '' ''                            '培训及企业文化费'       '0066010026'.
      set_node 'D'  '' ''                            '运输费-公司车辆'        '0066010028'.
      set_node 'D'  '' ''                            '商标注册与认证费'       '0066010033'.
      set_node 'D'  '' ''                            '费用摊销'               '0066010035'.
      set_node 'D'  '' ''                            '消耗品'                 '0066010039'.
      set_node 'D'  '' ''                            '装修费'                 '0066010041'.
      set_node 'D'  '' ''                            '劳务费'                 '0066010053'.
      set_node 'D'  '' ''                            '包装费'                 '0066010057'.
      set_node 'D'  '' ''                            '夹治具耗材'             '0066010061'.
      set_node 'D'  '' ''                            '设备租赁'               '0066010063'.
      set_node 'D'  '' ''                            '长摊费用摊销'           '0066010070'.
      set_node 'D'  '' ''                            'APP服务费'              '0066010073'.
      set_node 'D'  '' ''                            '快递费'                 '0066010074'.
      set_node 'Z' 'Z' '总计'                        '总计'                   ''.
    
      DEFINE set_dyn_wa.
        IF &1 NE ''.
          ASSIGN COMPONENT &1 OF STRUCTURE <dyn_wa> TO <fs_str>.
          IF sy-subrc EQ 0.
             <fs_str> = &2.
          ENDIF.
        ENDIF.
        IF &3 NE ''.
          ASSIGN COMPONENT &3 OF STRUCTURE <dyn_wa> TO <fs_str>.
          IF sy-subrc EQ 0.
            <fs_str> = &4.
          ENDIF.
        ENDIF.
      END-OF-DEFINITION.
    
      DEFINE set_dyn_wa_node.
    *    CLEAR: <dyn_wa>.
        IF &1 NE ''.
          ASSIGN COMPONENT &1 OF STRUCTURE <dyn_wa> TO <fs_str>.
          IF sy-subrc EQ 0.
             <fs_str> = <fs_str> + &2.
          ENDIF.
        ENDIF.
      END-OF-DEFINITION.
    
      CLEAR gs_node.
      DATA: lv_racct1 TYPE acdoca-racct,
            lv_racct2 TYPE acdoca-racct.
      LOOP AT gt_node INTO gs_node.
        CLEAR: <dyn_wa>.
        set_dyn_wa 'MNODE' gs_node-mnode 'ZNODE' gs_node-znode.
        set_dyn_wa 'ZSTR1' gs_node-zstr1 'TXT50' gs_node-txt50.
        "处理并获取 科目号
        CLEAR: lt_str,r_racct[].
        SPLIT gs_node-zstr3 AT ';' INTO TABLE lt_str.
        LOOP AT lt_str INTO DATA(ls_str)."table_line
          CLEAR: lv_str1,lv_str2,r_racct.
          IF ls_str NE ''.
            SPLIT ls_str AT '~' INTO lv_str1 lv_str2.
            IF lv_str2 NE ''.
              r_racct = 'IBT'.
              r_racct-low = lv_str1.
              r_racct-high = lv_str2.
            ELSE.
              r_racct = 'IEQ'.
              r_racct-low = lv_str1.
            ENDIF.
            APPEND r_racct.
          ENDIF.
        ENDLOOP.
    
        IF r_racct[] IS NOT INITIAL.
          LOOP AT gt_zrdtxt INTO gs_zrdtxt WHERE racct IN r_racct."根据RD描述匹配字段
            READ TABLE gt_zrdtxt2 WITH KEY zrdtxt = gs_zrdtxt TRANSPORTING NO FIELDS BINARY SEARCH.
            IF sy-subrc EQ 0.
              lv_tabix2 = sy-tabix.
              lv_fieldname = |NODE{ lv_tabix2 }|.
              set_dyn_wa_node lv_fieldname gs_zrdtxt-hsl.
            ENDIF.
          ENDLOOP.
        ENDIF.
        APPEND <dyn_wa> TO <dyn_table>[].
      ENDLOOP.
    
      LOOP AT <dyn_table> ASSIGNING <dyn_wa>.
    *    lv_tabix2 = sy-tabix.
        ASSIGN COMPONENT 'ZNODE' OF STRUCTURE <dyn_wa> TO <fs_str>.
        IF sy-subrc EQ 0.
    *      ASSIGN COMPONENT 'ZNODE' OF STRUCTURE <dyn_wa> TO <fs_str>.
          PERFORM frm_get_hj USING <fs_str> ."计算合计金额
        ENDIF.
    *    READ TABLE
      ENDLOOP.
    *  BREAK-POINT.
      "计算最后一行的 总计
    
      DATA(lv_lines) = lines( <dyn_table> ).
      READ TABLE <dyn_table> ASSIGNING <dyn_wa> INDEX lv_lines.
      IF sy-subrc EQ 0.
        LOOP AT <dyn_table> ASSIGNING FIELD-SYMBOL(<fs_tablec>).
          CLEAR lv_tabix2.
          ASSIGN COMPONENT 'ZNODE' OF STRUCTURE <fs_tablec> TO <fs_str>.
          IF sy-subrc EQ 0.
            CASE <fs_str>.
              WHEN 'A' OR 'B' OR 'C' OR 'D' OR 'E' OR 'F' OR 'G'.
                CLEAR lv_tabix2.
                DO lv_num TIMES.
                  ADD 1 TO lv_tabix2.
                  lv_fieldname = |NODE{ lv_tabix2 }|.
                  ASSIGN COMPONENT lv_fieldname OF STRUCTURE <dyn_wa> TO <fs_hsla>.
                  IF sy-subrc EQ 0.
                    ASSIGN COMPONENT lv_fieldname OF STRUCTURE <fs_tablec> TO <fs_hslb>.
                    IF sy-subrc EQ 0.
                      <fs_hsla> = <fs_hsla> + <fs_hslb>.
                    ENDIF.
                  ENDIF.
                ENDDO.
    *            WHEN .
              WHEN OTHERS.
            ENDCASE.
          ENDIF.
        ENDLOOP.
      ENDIF.
    ENDFORM.
    *&---------------------------------------------------------------------*
    *& Form FRM_GET_HJ
    *&---------------------------------------------------------------------*
    *& text
    *&---------------------------------------------------------------------*
    *& -->  p1        text
    *& <--  p2        text
    *&---------------------------------------------------------------------*
    FORM frm_get_hj USING lv_znode TYPE tv_nodekey.
      DATA: lv_tabix  TYPE sy-tabix,
            lv_tabix2 TYPE sy-tabix.
      DATA: lv_znode2 TYPE tv_nodekey.
      FIELD-SYMBOLS : <fs_hsla> TYPE any,
                      <fs_hslb> TYPE any.
      LOOP AT gt_node INTO gs_node WHERE mnode = lv_znode.
        lv_tabix = sy-tabix.
        IF gs_node-znode NE gs_node-mnode ."不计算自身
          READ TABLE gt_node WITH KEY mnode = gs_node-znode TRANSPORTING NO FIELDS.
          IF sy-subrc NE 0.
            "自身没有下阶节点时
            READ TABLE <dyn_table> ASSIGNING FIELD-SYMBOL(<fs_table>) INDEX lv_tabix.
            IF sy-subrc EQ 0.
              CLEAR lv_tabix2.
              DO lv_num TIMES.
                ADD 1 TO lv_tabix2.
                lv_fieldname = |NODE{ lv_tabix2 }|.
                ASSIGN COMPONENT lv_fieldname OF STRUCTURE <dyn_wa> TO <fs_hsla>.
                IF sy-subrc EQ 0.
                  ASSIGN COMPONENT lv_fieldname OF STRUCTURE <fs_table> TO <fs_hslb>.
                  IF sy-subrc EQ 0.
                    <fs_hsla> = <fs_hsla> + <fs_hslb>.
                  ENDIF.
                ENDIF.
              ENDDO.
            ENDIF.
          ELSE.
            "自身也为合计时,或者还有下阶节点时
            lv_znode2 = gs_node-znode.
            PERFORM frm_get_hj USING lv_znode2.
          ENDIF.
        ENDIF.
      ENDLOOP.
    
    ENDFORM.
    View Code

     

  • 相关阅读:
    【车】平安车险费用
    【光环国际】掌握项目经理12个工作流程
    【光环国际】500强公司7个项目管理工具
    数据仓库和商业智能演进五个阶段
    【技术与商业案例解读笔记】095:Google大数据三驾马车笔记
    15道最常考的SpringBoot面试题,你都遇到过哪些?
    用户画像4:标签数据开发
    plsql 传参
    shell专题(二):Shell解析器
    shell专题(三):Shell脚本入门
  • 原文地址:https://www.cnblogs.com/chaguoguo/p/16354243.html
Copyright © 2020-2023  润新知