TYPE-POOLS slis.
TABLES: marc.
TYPES: BEGIN OF ty_data,
matnr TYPE matnr, "母件
stufe TYPE histu, "阶层
idnrk TYPE idnrk, "子件
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, "BOM用途
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.
DATA: gs_layout TYPE lvc_s_layo, "布局
gt_fieldcat TYPE lvc_t_fcat. "字段
PARAMETERS: p_werks LIKE marc-werks DEFAULT 'C100' OBLIGATORY.
SELECT-OPTIONS: s_matnr FOR marc-matnr.
INITIALIZATION.
AT SELECTION-SCREEN.
AT SELECTION-SCREEN OUTPUT.
TOP-OF-PAGE.
END-OF-PAGE.
START-OF-SELECTION.
"获取数据
PERFORM frm_get_data.
"显示数据
PERFORM frm_display_data.
END-OF-SELECTION.
FORM frm_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: lv_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.
lv_lev = ls_bom_mat-stufe.
CLEAR lt_stpox.
PERFORM frm_get_bom TABLES lt_stpox USING ls_bom_mat-matnr.
"剔除原材料和废料
DELETE lt_stpox WHERE idnrk+0(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.
lv_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 = lv_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 = lv_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 frm_display_data .
"栏位最适宽度
gs_layout-cwidth_opt = 'X'.
"ALV条纹
gs_layout-zebra = 'X'.
"构建ALV的栏位
PERFORM frm_create_field.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid "当前程序名
is_layout_lvc = gs_layout "Layout
it_fieldcat_lvc = gt_fieldcat "Fieldcat
i_save = 'A'
TABLES
t_outtab = gt_data
EXCEPTIONS
program_error = 1
OTHERS = 2.
ENDFORM.
FORM frm_create_field .
DATA: ls_fieldcat TYPE lvc_s_fcat,
lv_count TYPE i.
DEFINE fieldcat.
ADD 1 TO lv_count.
"栏位显示顺序
ls_fieldcat-col_pos = lv_count.
"内表栏位
ls_fieldcat-fieldname = &1.
"参考栏位
ls_fieldcat-ref_field = &2.
"参考表
ls_fieldcat-ref_table = &3.
"单位
ls_fieldcat-qfieldname = &4.
"栏位标题(长文或中等文或短文)
ls_fieldcat-scrtext_s = ls_fieldcat-scrtext_m =
ls_fieldcat-scrtext_l = &5.
"显示长文或中等文或短文
ls_fieldcat-colddictxt = &6.
APPEND ls_fieldcat TO gt_fieldcat.
CLEAR ls_fieldcat.
END-OF-DEFINITION.
fieldcat 'MATNR' 'MATNR' 'MARC' '' '' ''.
fieldcat 'STUFE' '' '' '' '阶层' 'L'.
fieldcat 'IDNRK' 'IDNRK' 'STPO' '' '' ''.
ENDFORM.
FORM frm_get_bom TABLES et_stpox STRUCTURE stpox
USING iv_matnr.
DATA: ls_stko TYPE ty_stko.
READ TABLE gt_stko INTO ls_stko WITH KEY
matnr = iv_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 = et_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.