代码:
*&---------------------------------------------------------------------* *& Report ZPPRTEST *&---------------------------------------------------------------------* *& *&---------------------------------------------------------------------* REPORT ZPPRTEST. DATA: lt_mkal TYPE TABLE OF mkal, lt_stpox TYPE TABLE OF stpox, ls_mkal TYPE mkal, ls_stko TYPE stko. *-->找到生产版本(也可以直接找BOM单头资料) SELECT * INTO TABLE lt_mkal FROM mkal WHERE werks = '2000' AND matnr = 'ATBQ0333-11'. SORT lt_mkal BY verid. READ TABLE lt_mkal INTO ls_mkal INDEX 1. IF sy-subrc = 0. CALL FUNCTION 'CS_BOM_EXPL_MAT_V2' EXPORTING capid = 'PP01' "生产BOM datuv = sy-datum emeng = 1 "用量 * mdmps = 'X' " 展开虚拟件 mehrs = 'X' " 多阶 mmory = '0' mtnrv = ls_mkal-matnr stlal = ls_mkal-stlal stlan = ls_mkal-stlan werks = ls_mkal-werks TABLES stb = lt_stpox EXCEPTIONS alt_not_found = 1 call_invalid = 2 material_not_found = 3 missing_authorization = 4 no_bom_found = 5 no_plant_data = 6 no_suitable_bom_found = 7 conversion_error = 8 OTHERS = 9. * STUFE为阶层, MNGLG为根据展BOM的用量计算出各个下阶的用量 cl_demo_output=>write( ls_mkal ). cl_demo_output=>write( lt_stpox ). cl_demo_output=>display( ). ENDIF.
注意:
1、IMPORT的DATUV(生效日期)参数,最好放当天,ECN变更的资料失效的元件还在资料库中,不然会把失效元件带出来。
2、IMPORT的MDMPS(展虚拟件)和MEHRS(展多阶)参数,要让物料多阶BOM的时候直接MEHRS = 'X'即可;
如果一同使用MDMPS = 'X',则物料只会单阶展,若单阶下有虚拟件,会继续展开虚拟件下阶,其它自制件或委外件不会展下阶。
拓展:找到最底阶层非原材料的零件
*&---------------------------------------------------------------------* *& Report ZPPRTEST *&---------------------------------------------------------------------* *& *&---------------------------------------------------------------------* REPORT ZPPRTEST. TABLES: marc. TYPES: BEGIN OF ty_data, matnr TYPE matnr, stufe TYPE histu, idnrk TYPE idnrk, text TYPE c LENGTH 20, END OF ty_data, BEGIN OF ty_marc, matnr TYPE matnr, beskz TYPE beskz, sobsl TYPE sobsl, END OF ty_marc, BEGIN OF ty_stko, matnr TYPE matnr, stlan TYPE stlan, stlal TYPE stlal, bmeng TYPE basmn, END OF ty_stko, BEGIN OF ty_bom_mat, matnr TYPE matnr, stufe TYPE histu, END OF ty_bom_mat. DATA: gt_data TYPE TABLE OF ty_data, gt_stko TYPE TABLE OF ty_stko. TYPE-POOLS slis. DATA: gs_layout TYPE slis_layout_alv, gt_fieldcat TYPE slis_t_fieldcat_alv. PARAMETERS: p_werks LIKE marc-werks DEFAULT '2000' OBLIGATORY. SELECT-OPTIONS: s_matnr FOR marc-matnr. PERFORM get_data. PERFORM display_data. *&---------------------------------------------------------------------* *& Form GET_DATA *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* *& --> p1 text *& <-- p2 text *&---------------------------------------------------------------------* FORM get_data . DATA: lt_mat TYPE TABLE OF ty_marc, lt_marc TYPE TABLE OF ty_marc, lt_bom_mat TYPE TABLE OF ty_bom_mat, lt_stpox TYPE TABLE OF stpox, ls_data TYPE ty_data, ls_mat TYPE ty_marc, ls_marc TYPE ty_marc, ls_bom_mat TYPE ty_bom_mat, ls_stpox TYPE stpox. DATA: l_lev TYPE histu VALUE 0. *-->工厂数据 SELECT matnr beskz sobsl INTO TABLE lt_marc FROM marc WHERE werks = p_werks AND lvorm = ''. *-->展BOM料号 SELECT matnr beskz sobsl INTO TABLE lt_mat FROM marc WHERE werks = p_werks AND lvorm = '' AND matnr IN s_matnr. *-->展BOM料号的BOM单头 SELECT mast~matnr mast~stlan mast~stlal stko~bmeng INTO TABLE gt_stko FROM mast INNER JOIN stko ON mast~stlnr = stko~stlnr AND mast~stlal = stko~stlal WHERE mast~werks = p_werks AND mast~stlan = '1' AND stko~loekz = '' AND stko~lkenz = ''. SORT: lt_marc BY matnr, gt_stko BY matnr. LOOP AT lt_mat INTO ls_mat. READ TABLE lt_marc INTO ls_marc WITH KEY matnr = ls_mat-matnr BINARY SEARCH. IF sy-subrc = 0. *-->一般委外件(分包)和自制件展开下阶BOM IF ls_marc-beskz = 'E' OR ( ls_marc-beskz = 'F' AND ls_marc-sobsl = '30' ). CLEAR: lt_bom_mat. ls_bom_mat-matnr = ls_mat-matnr. ls_bom_mat-stufe = 0. APPEND ls_bom_mat TO lt_bom_mat.CLEAR ls_bom_mat. LOOP AT lt_bom_mat INTO ls_bom_mat. l_lev = ls_bom_mat-stufe. CLEAR lt_stpox. PERFORM get_bom TABLES lt_stpox USING ls_bom_mat-matnr. "剔除原材料和废料 DELETE lt_stpox WHERE idnrk+(2) = 'MT'. IF lt_stpox IS INITIAL. "如果无BOM或者BOM下只有原材料或废料,则为最低阶非原材料零件 ls_data-matnr = ls_mat-matnr. ls_data-idnrk = ls_bom_mat-matnr. ls_data-stufe = ls_bom_mat-stufe. APPEND ls_data TO gt_data.CLEAR ls_data. ELSE. l_lev = ls_bom_mat-stufe + 1. LOOP AT lt_stpox INTO ls_stpox. CLEAR ls_marc. "删除替代料 IF ls_stpox-alpgr NE '' AND ls_stpox-ewahr IS INITIAL. CONTINUE. ENDIF. READ TABLE lt_marc INTO ls_marc WITH KEY matnr = ls_stpox-idnrk BINARY SEARCH. IF ls_marc-beskz = 'E' OR ( ls_marc-beskz = 'F' AND ls_marc-sobsl = '30' ). "如果是一般委外件(分包)和自制件展开下阶BOM,则加入展BOM清单继续往下展开 ls_bom_mat-matnr = ls_stpox-idnrk. ls_bom_mat-stufe = l_lev. APPEND ls_bom_mat TO lt_bom_mat.CLEAR ls_bom_mat. ELSE. "如果是直接外购件,则为最低阶非原材料零件 ls_data-matnr = ls_mat-matnr. ls_data-idnrk = ls_stpox-idnrk. ls_data-stufe = l_lev. APPEND ls_data TO gt_data.CLEAR ls_data. ENDIF. ENDLOOP. ENDIF. ENDLOOP. ELSE. ls_data-matnr = ls_data-idnrk = ls_mat-matnr. ls_data-stufe = 0. APPEND ls_data TO gt_data.CLEAR ls_data. ENDIF. ELSE. ls_data-matnr = ls_data-idnrk = ls_mat-matnr. ls_data-stufe = 0. APPEND ls_data TO gt_data.CLEAR ls_data. ENDIF. ENDLOOP. ENDFORM. *&---------------------------------------------------------------------* *& Form GET_BOM *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* *& --> LT_STPOX *&---------------------------------------------------------------------* FORM get_bom TABLES lt_stpox STRUCTURE stpox USING in_matnr. DATA: ls_stko TYPE ty_stko. READ TABLE gt_stko INTO ls_stko WITH KEY matnr = in_matnr BINARY SEARCH. IF sy-subrc = 0. CALL FUNCTION 'CS_BOM_EXPL_MAT_V2' EXPORTING capid = 'PP01' "生产BOM datuv = sy-datum emeng = ls_stko-bmeng "用量 * mdmps = 'X' " 展开虚拟件 * mehrs = 'X' " 多阶 mmory = '0' mtnrv = ls_stko-matnr stlal = ls_stko-stlal stlan = ls_stko-stlan werks = p_werks TABLES stb = lt_stpox EXCEPTIONS alt_not_found = 1 call_invalid = 2 material_not_found = 3 missing_authorization = 4 no_bom_found = 5 no_plant_data = 6 no_suitable_bom_found = 7 conversion_error = 8 OTHERS = 9. ENDIF. * STUFE为阶层, MNGLG为根据展BOM的用量计算出各个下阶的用量 ENDFORM. *&---------------------------------------------------------------------* *& Form DISPLAY_DATA *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* *& --> p1 text *& <-- p2 text *&---------------------------------------------------------------------* FORM display_data . DATA: l_repid TYPE sy-repid, l_inclname TYPE trdir-name, l_idx LIKE sy-tabix. CLEAR: gt_fieldcat[]. l_repid = l_inclname = sy-cprog. gs_layout-colwidth_optimize = 'X'. PERFORM create_field. CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' EXPORTING i_callback_program = sy-repid is_layout = gs_layout it_fieldcat = gt_fieldcat[] i_save = 'A' TABLES t_outtab = gt_data EXCEPTIONS program_error = 1 OTHERS = 2. ENDFORM. *&---------------------------------------------------------------------* *& Form CREATE_FIELD *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* *& --> p1 text *& <-- p2 text *&---------------------------------------------------------------------* FORM create_field . DATA: ls_fieldcat TYPE slis_fieldcat_alv. DATA: l_count TYPE i. ADD 1 TO l_count. ls_fieldcat-col_pos = l_count. ls_fieldcat-fieldname = 'MATNR'. ls_fieldcat-ref_fieldname = 'MATNR'. ls_fieldcat-ref_tabname = 'MARA'. ls_fieldcat-seltext_m = ls_fieldcat-seltext_l = ls_fieldcat-seltext_s = '物料'. ls_fieldcat-ddictxt = 'L'. APPEND ls_fieldcat TO gt_fieldcat. CLEAR ls_fieldcat. ADD 1 TO l_count. ls_fieldcat-col_pos = l_count. ls_fieldcat-fieldname = 'STUFE'. ls_fieldcat-seltext_m = ls_fieldcat-seltext_l = ls_fieldcat-seltext_s = '阶层'. ls_fieldcat-ddictxt = 'L'. APPEND ls_fieldcat TO gt_fieldcat. CLEAR ls_fieldcat. ADD 1 TO l_count. ls_fieldcat-col_pos = l_count. ls_fieldcat-fieldname = 'IDNRK'. ls_fieldcat-ref_fieldname = 'MATNR'. ls_fieldcat-ref_tabname = 'MARA'. ls_fieldcat-seltext_m = ls_fieldcat-seltext_l = ls_fieldcat-seltext_s = '元件'. ls_fieldcat-ddictxt = 'L'. APPEND ls_fieldcat TO gt_fieldcat. CLEAR ls_fieldcat. ADD 1 TO l_count. ls_fieldcat-col_pos = l_count. ls_fieldcat-fieldname = 'TEXT'. ls_fieldcat-seltext_m = ls_fieldcat-seltext_l = ls_fieldcat-seltext_s = '备注'. ls_fieldcat-ddictxt = 'L'. APPEND ls_fieldcat TO gt_fieldcat. CLEAR ls_fieldcat. ENDFORM.