BOM 多层查询

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.

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值