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."创建结构 PERFORM frm_get_data4."获取数据 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.
包含文件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 :TYPE table, TYPE any, TYPE any, TYPE any, TYPE any. DATA: dyn_table2 TYPE REF TO data. DATA: dyn_wa2 TYPE REF TO data. FIELD-SYMBOLS : TYPE table, TYPE any, TYPE any, 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.
包含文件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.
包含文件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(). READ TABLE lt_skat INTO DATA(ls_skat) WITH KEY saknr = -racct BINARY SEARCH. IF sy-subrc EQ 0. -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 . 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 . * **创建动态工作区结构 * CREATE DATA dyn_wa LIKE LINE OF. * **创建动态工作区 * ASSIGN dyn_wa->* TO. * 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. *创建动态工作区结构 CREATE DATA dyn_wa LIKE LINE OF . *创建动态工作区 ASSIGN dyn_wa->* TO . 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 : TYPE any, 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 TO . IF sy-subrc EQ 0. = &2. ENDIF. ENDIF. IF &3 NE ''. ASSIGN COMPONENT &3 OF STRUCTURE TO . IF sy-subrc EQ 0. = &4. ENDIF. ENDIF. END-OF-DEFINITION. DEFINE set_dyn_wa_node. * CLEAR: . IF &1 NE ''. ASSIGN COMPONENT &1 OF STRUCTURETO . IF sy-subrc EQ 0. = + &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: . 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 TO []. ENDLOOP. LOOP AT ASSIGNING . * lv_tabix2 = sy-tabix. ASSIGN COMPONENT 'ZNODE' OF STRUCTURE TO . IF sy-subrc EQ 0. * ASSIGN COMPONENT 'ZNODE' OF STRUCTURE TO PERFORM frm_get_hj USING. ."计算合计金额 ENDIF. * READ TABLE ENDLOOP. * BREAK-POINT. "计算最后一行的 总计 DATA(lv_lines) = lines( ). READ TABLE ASSIGNING INDEX lv_lines. IF sy-subrc EQ 0. LOOP AT ASSIGNING FIELD-SYMBOL( ). CLEAR lv_tabix2. ASSIGN COMPONENT 'ZNODE' OF STRUCTURE TO . IF sy-subrc EQ 0. CASE . 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 TO . IF sy-subrc EQ 0. ASSIGN COMPONENT lv_fieldname OF STRUCTURE TO . IF sy-subrc EQ 0. = + . 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 : TYPE any, 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 ASSIGNING FIELD-SYMBOL( ) 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 TO . IF sy-subrc EQ 0. ASSIGN COMPONENT lv_fieldname OF STRUCTURE TO . IF sy-subrc EQ 0. = + . ENDIF. ENDIF. ENDDO. ENDIF. ELSE. "自身也为合计时,或者还有下阶节点时 lv_znode2 = gs_node-znode. PERFORM frm_get_hj USING lv_znode2. ENDIF. ENDIF. ENDLOOP. ENDFORM.