展BOM清单——CS_BOM_EXPL_MAT_V2

代码:

*&---------------------------------------------------------------------*
*& 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 V_TC04-CAPID
      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.

************************************************************************
* Type Pools Definitions          定义类型池
************************************************************************
TYPE-POOLS slis.

************************************************************************
* Tables Definitions
************************************************************************
TABLES: marc.
************************************************************************
* Data Definitions                定义数据
************************************************************************
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. "字段

************************************************************************
* Includes Module                 包含模块
************************************************************************

************************************************************************
* Selection Screen                选择屏幕
************************************************************************
PARAMETERS: p_werks LIKE marc-werks DEFAULT '2000' OBLIGATORY.

SELECT-OPTIONS: s_matnr FOR marc-matnr.

************************************************************************
* Initialization                  初始化事件
************************************************************************
INITIALIZATION.

************************************************************************
* At Selection Screen             PAI事件
************************************************************************
AT SELECTION-SCREEN.

************************************************************************
* At Selection Screen Output      PBO事件
************************************************************************
AT SELECTION-SCREEN OUTPUT.

************************************************************************
* Report Format                   报表格式
************************************************************************
TOP-OF-PAGE.

END-OF-PAGE.

************************************************************************
* Main Process                    主要逻辑
************************************************************************
START-OF-SELECTION.

  "获取数据
  PERFORM frm_get_data.
  "显示数据
  PERFORM frm_display_data.

END-OF-SELECTION.
*&---------------------------------------------------------------------*
*& Form FRM_GET_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
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
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
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
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
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
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LT_STPOX
*&      --> LS_BOM_MAT_MATNR
*&---------------------------------------------------------------------*
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.

 

posted @ 2020-03-13 10:16  鲸与海  阅读(3981)  评论(0编辑  收藏  举报