REPORT zpprp0003.
TABLES:mast,stko,stpo,tc04.
TYPE-POOLS: slis. "引用类型池
DATA: go_grid TYPE REF TO cl_gui_alv_grid.
"定义ALV使用的内表、结构
DATA: it_fieldcat TYPE lvc_t_fcat,
wa_fieldcat TYPE lvc_s_fcat.
CONSTANTS:co_success LIKE icon-id VALUE '@08@',
co_warning LIKE icon-id VALUE '@09@',
co_error LIKE icon-id VALUE '@0A@'.
DEFINE hout. "定义宏
wa_fieldcat-fieldname = &1. "字段名
wa_fieldcat-scrtext_l = &2. "显示的列名
* wa_fieldcat-no_zero = 'X'.
wa_fieldcat-ref_field = &3.
wa_fieldcat-ref_table = &4.
wa_fieldcat-outputlen = &5.
* IF wa_fieldcat-fieldname = 'ZMSG'.
* wa_fieldcat-outputlen = '50'.
* wa_fieldcat-edit = 'X'.
* ENDIF.
APPEND wa_fieldcat TO it_fieldcat.
CLEAR: wa_fieldcat.
end-of-definition.
DATA:BEGIN OF gt_out OCCURS 0,
werks LIKE mast-werks, "工厂
matnr LIKE mast-matnr, "顶层父项物料编码
maktx LIKE makt-maktx, "顶层父项物料描述
emeng LIKE stko-bmeng, "父项需求数量
stufex(20) TYPE c, "级别编号
matnr1 LIKE mast-matnr, "上层父项物料编码
maktx1 LIKE makt-maktx, "上层父项物料描述
posnr LIKE stpox-posnr, "项目编号
postp LIKE stpox-postp, "项目类别
idnrk LIKE stpox-idnrk, "组件物料编码
maktx2 LIKE makt-maktx, "组件物料描述
menge LIKE stpox-menge, "组件数量
meins LIKE stpox-meins, "组件计量单位
stufe LIKE stpox-stufe, "层级
mtart LIKE stpox-mtart, "物料类型
mmsta LIKE stpox-mmsta, "工厂特定的物料状态
mmstd LIKE stpox-mmstd, "工厂特定物料状态有效的起始日期
mstae LIKE stpox-mstae, "跨工厂物料状态
mstde LIKE stpox-mstde, "从跨工厂物料状态有效起的日期
sbdkz LIKE stpox-sbdkz, "独立/集中
dismm LIKE stpox-dismm, "物料需求计划类型
ausch LIKE stpox-ausch, "组件报废(组件物料)
matkl LIKE stpox-matkl, "物料组
lgort LIKE stpox-lgort, "生产存储地点
verid LIKE stpox-verid, "生产版本
schgt LIKE stpox-schgt, "散装物料(组件物料)
aennr LIKE stpox-aennr, "变更编号
dumps LIKE stpox-dumps, "虚拟标识
datuv LIKE stpox-datuv, "有效期自
datub LIKE stpox-datub, "有效截止日期
sanka LIKE stpox-sanka, "标识:与成本核算相关的项目
sanfe LIKE stpox-sanfe, "标识:与生产相关项目
dispo LIKE marc-dispo, "顶层MRP控制者
dispo1 LIKE marc-dispo, "顶层MRP控制者
dispo2 LIKE marc-dispo, "顶层MRP控制者
revlv LIKE aeoi-revlv, "版次
field_style TYPE lvc_t_styl, " 为内表添加设置编辑状态所需的字段
END OF gt_out.
DATA:gv_count TYPE i.
*----------------------------------------------------------------------*
* SELECTION-SCREEN ,
*----------------------------------------------------------------------*
SELECTION-SCREEN : BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-t01.
SELECT-OPTIONS:s_matnr FOR mast-matnr OBLIGATORY. "父项物料编码
PARAMETERS:p_werks LIKE mast-werks OBLIGATORY, "工厂
p_stlan LIKE mast-stlan DEFAULT '1', "BOM用途
p_stlal LIKE mast-stlal DEFAULT '1', "可选BOM
p_capid LIKE tc04-capid DEFAULT 'PP01' OBLIGATORY, "BOM应用
p_datuv LIKE stko-datuv DEFAULT sy-datum OBLIGATORY, "有效期至
p_emeng LIKE stko-bmeng DEFAULT '1' OBLIGATORY. "需求数量
PARAMETERS:p_chk AS CHECKBOX DEFAULT 'X'.
SELECTION-SCREEN : END OF BLOCK b1 .
*----------------------------------------------------------------------*
* INITIALIZATION *
*----------------------------------------------------------------------*
INITIALIZATION.
PERFORM frm_init.
*----------------------------------------------------------------------*
* AT SELECTION-SCREEN OUTPUT
*----------------------------------------------------------------------*
AT SELECTION-SCREEN OUTPUT.
PERFORM frm_mod_screen.
*----------------------------------------------------------------------*
* AT SELECTION-SCREEN *
*----------------------------------------------------------------------*
AT SELECTION-SCREEN.
*----------------------------------------------------------------------*
* START-OF-SELECTION *
*----------------------------------------------------------------------*
START-OF-SELECTION.
PERFORM frm_get_data.
PERFORM frm_show_alv.
*----------------------------------------------------------------------*
* END-OF-SELECTION *
*----------------------------------------------------------------------*
end-of-selection.
*&---------------------------------------------------------------------*
*& Form FRM_INIT
*&---------------------------------------------------------------------*
FORM frm_init.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_MOD_SCREEN
*&---------------------------------------------------------------------*
FORM frm_mod_screen .
ENDFORM.
*----------------------------------------------------------------------*
* SUBROUTINES *
*----------------------------------------------------------------------*
FORM frm_get_data.
*函数BOM内表
DATA:lt_stpox LIKE TABLE OF stpox WITH HEADER LINE.
DATA:lt_stpoxs LIKE TABLE OF stpox WITH HEADER LINE.
*根据工厂输入物料获取内表作为循环
DATA:BEGIN OF lt_marc OCCURS 0,
matnr LIKE marc-matnr,
werks LIKE marc-werks,
dispo LIKE marc-dispo,
END OF lt_marc.
DATA:lt_marc_all LIKE TABLE OF lt_marc WITH HEADER LINE.
*获取所有物料
DATA:BEGIN OF lt_mara OCCURS 0,
matnr LIKE mara-matnr,
END OF lt_mara.
*获取所有物料描述
DATA:BEGIN OF lt_makt OCCURS 0,
matnr LIKE mara-matnr,
maktx LIKE makt-maktx,
END OF lt_makt.
*待更改对象
DATA:BEGIN OF lt_objkt OCCURS 0,
objkt LIKE aeoi-objkt,
END OF lt_objkt.
*获取版次
DATA:BEGIN OF lt_aeoi OCCURS 0,
aennr LIKE aeoi-aennr,
objkt LIKE aeoi-objkt,
revlv LIKE aeoi-revlv,
datuv LIKE aenr-datuv,
END OF lt_aeoi.
DATA:lv_stufe LIKE stpox-stufe,
lv_objkt LIKE aeoi-objkt.
DATA:lv_mehrs TYPE csdata-xfeld.
CLEAR:lv_mehrs.
IF p_chk IS NOT INITIAL.
lv_mehrs = 'X'.
ENDIF.
*根据输入条件获取物料工厂数据
SELECT matnr werks INTO TABLE lt_marc FROM marc
WHERE matnr IN s_matnr
AND werks = p_werks.
*根据获取的工厂物料数据获取对应的BOM并做相应处理。
LOOP AT lt_marc.
*获取所有物料
lt_mara-matnr = lt_marc-matnr.
COLLECT lt_mara.
CLEAR:lt_mara.
*获取BOM
CLEAR:lt_stpox,lt_stpox[],lt_stpoxs,lt_stpoxs[].
CALL FUNCTION 'CS_BOM_EXPL_MAT_V2'
EXPORTING
capid = p_capid
datuv = p_datuv
emeng = p_emeng
mehrs = lv_mehrs "X多层 空单层
mtnrv = lt_marc-matnr
stlal = p_stlal
stlan = p_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.
IF sy-subrc <> 0.
* Implement suitable error handling here
ELSE.
lt_stpoxs[] = lt_stpox[].
SORT lt_stpoxs BY stufe wegxx.
ENDIF.
*找上层父项物料编码逻辑:根据该BOM函数返回内表当前条目VWEGX的值和STUFE的值减去1后,
*然后按STUFE = STUFE-1,WEGXX = VWEGX的值获取对应的IDNRK就是该记录的上层父项物料编码
LOOP AT lt_stpox.
*获取所有物料
lt_mara-matnr = lt_stpox-idnrk.
COLLECT lt_mara.
CLEAR:lt_mara.
*待更改对象内表
lt_objkt-objkt = lt_stpox-idnrk.
COLLECT lt_objkt.
CLEAR:lt_objkt.
gt_out-werks = lt_marc-werks. "工厂
gt_out-matnr = lt_marc-matnr. "顶层父项物料编码
gt_out-emeng = p_emeng. "父项需求数量
IF lt_stpox-vwegx = 0. "上层父项物料编码 = 顶层父项物料编码
gt_out-matnr1 = lt_marc-matnr. "上层父项物料编码
ELSE.
CLEAR:lv_stufe.
lv_stufe = lt_stpox-stufe - 1.
READ TABLE lt_stpoxs WITH KEY stufe = lv_stufe
wegxx = lt_stpox-vwegx BINARY SEARCH.
IF sy-subrc = 0.
gt_out-matnr1 = lt_stpoxs-idnrk. "上层父项物料编码
ENDIF.
ENDIF.
gt_out-posnr = lt_stpox-posnr. "项目编号
gt_out-postp = lt_stpox-postp. "项目类别
gt_out-idnrk = lt_stpox-idnrk. "组件物料编码
gt_out-menge = lt_stpox-menge * gt_out-emeng. "组件数量
gt_out-meins = lt_stpox-meins. "组件计量单位
gt_out-stufe = lt_stpox-stufe. "层级
gt_out-mtart = lt_stpox-mtart. "物料类型
gt_out-mmsta = lt_stpox-mmsta. "工厂特定的物料状态
gt_out-mmstd = lt_stpox-mmstd. "工厂特定物料状态有效的起始日期
gt_out-mstae = lt_stpox-mstae. "跨工厂物料状态
gt_out-mstde = lt_stpox-mstde. "从跨工厂物料状态有效起的日期
gt_out-sbdkz = lt_stpox-sbdkz. "独立/集中
gt_out-dismm = lt_stpox-dismm. "物料需求计划类型
gt_out-ausch = lt_stpox-ausch. "组件报废(组件物料)
gt_out-matkl = lt_stpox-matkl. "物料组
gt_out-lgort = lt_stpox-lgort. "生产存储地点
gt_out-verid = lt_stpox-verid. "生产版本
gt_out-schgt = lt_stpox-schgt. "散装物料(组件物料)
gt_out-aennr = lt_stpox-aennr. "变更编号
gt_out-dumps = lt_stpox-dumps. "虚拟标识
gt_out-datuv = lt_stpox-datuv. "有效期自
gt_out-datub = lt_stpox-datub. "有效截止日期
gt_out-sanka = lt_stpox-sanka. "标识:与成本核算相关的项目
gt_out-sanfe = lt_stpox-sanfe. "标识:与生产相关项目
APPEND gt_out.
CLEAR:lt_stpox,gt_out.
ENDLOOP.
CLEAR:lt_marc.
ENDLOOP.
IF lt_mara[] IS NOT INITIAL.
*根据工厂输入物料获取内表作为循环
SELECT matnr werks dispo INTO TABLE lt_marc_all FROM marc
FOR ALL ENTRIES IN lt_mara
WHERE matnr = lt_mara-matnr
AND werks = p_werks.
SORT lt_marc_all BY matnr werks.
*获取所有物料描述
SELECT matnr maktx INTO TABLE lt_makt FROM makt
FOR ALL ENTRIES IN lt_mara
WHERE matnr = lt_mara-matnr
AND spras = sy-langu.
SORT lt_makt BY matnr.
ENDIF.
IF lt_objkt[] IS NOT INITIAL.
*获取版次:物料号 IDNRK关联表 AEOI-OBJKT取到变更编号AENNR(只保留对象类别 AEOI-AETYP=41 的值,其它值过滤掉。
*然后根据变更编号AENNR关联表AENR-AENNR取到有效期自DATUV,对有效期自DATUV进行排序后取最大的日期对应REVLV的值
SELECT a~aennr a~objkt a~revlv b~datuv INTO TABLE lt_aeoi
FROM aeoi AS a INNER JOIN aenr AS b ON a~aennr = b~aennr
FOR ALL ENTRIES IN lt_objkt
WHERE a~objkt = lt_objkt-objkt
AND a~aetyp = '41'.
SORT lt_aeoi BY objkt datuv DESCENDING.
ENDIF.
LOOP AT gt_out.
*获取对应的物料描述
READ TABLE lt_makt WITH KEY matnr = gt_out-matnr BINARY SEARCH.
IF sy-subrc = 0.
gt_out-maktx = lt_makt-maktx.
ENDIF.
READ TABLE lt_makt WITH KEY matnr = gt_out-matnr1 BINARY SEARCH.
IF sy-subrc = 0.
gt_out-maktx1 = lt_makt-maktx.
ENDIF.
READ TABLE lt_makt WITH KEY matnr = gt_out-idnrk BINARY SEARCH.
IF sy-subrc = 0.
gt_out-maktx2 = lt_makt-maktx.
ENDIF.
*获取MRP控制者
READ TABLE lt_marc_all WITH KEY matnr = gt_out-matnr
werks = gt_out-werks BINARY SEARCH.
IF sy-subrc = 0.
gt_out-dispo = lt_marc_all-dispo.
ENDIF.
READ TABLE lt_marc_all WITH KEY matnr = gt_out-matnr1
werks = gt_out-werks BINARY SEARCH.
IF sy-subrc = 0.
gt_out-dispo1 = lt_marc_all-dispo. "上层物料MRP控制者
ENDIF.
READ TABLE lt_marc_all WITH KEY matnr = gt_out-idnrk
werks = gt_out-werks BINARY SEARCH.
IF sy-subrc = 0.
gt_out-dispo2 = lt_marc_all-dispo. "组件MRP控制者
ENDIF.
*获取版次
CLEAR:lv_objkt.
lv_objkt = gt_out-idnrk.
READ TABLE lt_aeoi WITH KEY objkt = lv_objkt BINARY SEARCH.
IF sy-subrc = 0.
LOOP AT lt_aeoi FROM sy-tabix WHERE objkt = lv_objkt.
IF lt_aeoi-datuv <= sy-datum.
gt_out-revlv = lt_aeoi-revlv.
EXIT.
ENDIF.
ENDLOOP.
ENDIF.
*级别编号
DO gt_out-stufe TIMES.
gt_out-stufex = '.' && gt_out-stufex.
ENDDO.
gt_out-stufex = gt_out-stufex && gt_out-stufe.
MODIFY gt_out.
CLEAR:gt_out.
ENDLOOP.
DESCRIBE TABLE gt_out LINES gv_count.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SHOW_ALV
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM frm_show_alv .
DATA:layout TYPE lvc_s_layo.
DATA:ls_variant TYPE disvariant.
DATA:lt_events TYPE STANDARD TABLE OF slis_alv_event,
lw_events TYPE slis_alv_event.
hout 'WERKS' '工厂' '' '' '4'.
hout 'MATNR' '顶层父项物料编码' '' '' '40'.
hout 'MAKTX' '顶层父项物料描述' '' '' '40'.
hout 'EMENG' '父项需求数量' '' '' '13'.
hout 'STUFEX' '级别编号' '' '' '20'.
hout 'MATNR1' '上层父项物料编码' '' '' '40'.
hout 'MAKTX1' '上层父项物料描述' '' '' '40'.
hout 'POSNR' '项目编号' '' '' '4'.
hout 'POSTP' '项目类别' '' '' '1'.
hout 'IDNRK' '组件物料编码' '' '' '40'.
hout 'MAKTX2' '组件物料描述' '' '' '40'.
hout 'MENGE' '组件数量' '' '' '13'.
hout 'MEINS' '组件计量单位' '' '' '3'.
hout 'STUFE' '层级' '' '' '2'.
hout 'MTART' '物料类型' '' '' '4'.
hout 'MMSTA' '工厂特定的物料状态' '' '' '2'.
hout 'MMSTD' '工厂特定物料状态有效的起始日期' '' '' '10'.
hout 'MSTAE' '跨工厂物料状态' '' '' '2'.
hout 'MSTDE' '从跨工厂物料状态有效起的日期' '' '' '10'.
hout 'SBDKZ' '独立/集中' '' '' '1'.
hout 'DISMM' '物料需求计划类型' '' '' '2'.
hout 'DISPO' '顶层MRP控制者' '' '' '3'.
hout 'DISPO1' '上层物料MRP控制者' '' '' '3'.
hout 'DISPO2' '组件MRP控制者' '' '' '3'.
hout 'AUSCH' '组件报废(组件物料)' '' '' '1'.
hout 'MATKL' '物料组' '' '' '9'.
hout 'LGORT' '生产存储地点' '' '' '4'.
hout 'REVLV' '版次' '' '' '2'.
hout 'VERID' '生产版本' '' '' '4'''.
hout 'SCHGT' '散装物料(组件物料)' '' '' '1'.
hout 'AENNR' '变更编号' '' '' '12'.
hout 'DUMPS' '虚拟标识' '' '' '1'.
hout 'DATUV' '有效期自' '' '' '10'.
hout 'DATUB' '有效截止日期' '' '' '10'.
hout 'SANKA' '标识:与成本核算相关的项目' '' '' '1'.
hout 'SANFE' '标识:与生产相关项目' '' '' '1'.
"set the layout format of output "
layout-cwidth_opt = 'X'.
layout-zebra = 'X'.
* layout-box_fname = 'SEL'.
* layout-stylefname = 'FIELD_STYLE'.
* v_repid = sy-repid.
ls_variant-report = sy-repid.
* lw_events-name = 'CALLER_EXIT'. "'DATA_CHANGED'.
* lw_events-form = 'FRM_CALLER_EXIT'. "'FRM_DATA_CHANGED'.
* APPEND lw_events TO lt_events.
* CLEAR lw_events.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
it_fieldcat_lvc = it_fieldcat[]
is_layout_lvc = layout
is_variant = ls_variant
i_save = 'A'
i_callback_program = sy-repid
i_callback_pf_status_set = 'FRM_STATUS_SET'
i_callback_user_command = 'FRM_USER_COMMAND'
i_callback_html_top_of_page = 'FRM_TOP_OF_PAGE'
* it_events = lt_events
TABLES
t_outtab = gt_out.
ENDFORM. " FRM_SHOW_ALV
FORM frm_status_set USING pt_extab TYPE slis_t_extab.
APPEND 'SAVE' TO pt_extab.
SET PF-STATUS 'ALV' EXCLUDING pt_extab.
ENDFORM. " FRM_ALV_STATUS_SET
FORM frm_user_command USING pa_ucomm TYPE sy-ucomm
ps_selfield TYPE slis_selfield.
ps_selfield-refresh = 'X'.
IF go_grid IS INITIAL .
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = go_grid.
ENDIF.
* CASE pa_ucomm.
* WHEN 'SAVE'.
* CALL METHOD go_grid->check_changed_data.
* ENDCASE.
ps_selfield-refresh = 'X'.
ps_selfield-col_stable = 'X'. "防止列跑位
ps_selfield-row_stable = 'X'. "防止行跑位
ENDFORM. " FRM_ALV_USER_COMMAND
*添加头标题
FORM frm_top_of_page USING p_cl_dd TYPE REF TO cl_dd_document.
DATA:lv_p TYPE i,
lv_buffer TYPE string.
DATA:lv_title(10) TYPE c.
lv_buffer = '<HTML><CENTER><H3>BOM清单</H3></CENTER></HTML>'.
lv_buffer = lv_buffer && '<P ALIGN = LEFT>报表总条目数: ' && gv_count && '条'.
lv_buffer = lv_buffer && '<P ALIGN = LEFT>当前日期: ' && sy-datum.
CALL METHOD p_cl_dd->html_insert
EXPORTING
contents = lv_buffer
CHANGING
position = lv_p.
ENDFORM.
BOM 多层查询
于 2024-02-19 16:34:20 首次发布