SAP中多层扩展有效地bom

来源:互联网 发布:java 方法签名 throw 编辑:程序博客网 时间:2024/05/01 12:45

 功能: 根据指定的Mbom 以及 序列号 和有效期来查找有效的Mbom

(假设 Mbom的 变更 包括 按有效期 和 按序列号)

 

函数组:ZPLM_BOM_FG

1  function module:

 

 (1)  读取单层的有效Mbom

    ZPLM_GET_USED_BOM

import:

P_SERNR    like  AEEF-SERNR_LO   序列号

P_DATUV   like  AENR-DATUV   开始生效日期

P_MATNR   like  MAST-MATNR  物料号

P_WERKS   like  MAST-WERKS   工厂

P_STLAN   like  MAST-STLAN   BOM用途

P_STLAL   like  MAST-STLAL   可选的BOM

 

tables:

TAB_BOM   like  ZPLM_BOM_USE    查找使用的bom用到的结构

 

source code:

 

  FUNCTION zplm_get_used_bom.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(P_SERNR) LIKE  AEEF-SERNR_LO
*"     VALUE(P_DATUV) LIKE  AENR-DATUV OPTIONAL
*"     VALUE(P_MATNR) LIKE  MAST-MATNR
*"     VALUE(P_WERKS) LIKE  MAST-WERKS OPTIONAL
*"     VALUE(P_STLAN) LIKE  MAST-STLAN
*"     VALUE(P_STLAL) LIKE  MAST-STLAL OPTIONAL
*"  TABLES
*"      TAB_BOM STRUCTURE  ZPLM_BOM_USE
*"----------------------------------------------------------------------


  CHECK     p_matnr IS NOT INITIAL
        AND p_werks IS NOT INITIAL
        AND p_stlan IS NOT INITIAL.



  DATA:  v_datuv TYPE capp_itm-datuv,
         v_stlty  TYPE stko-stlty,
         v_stlal  TYPE stko-stlal,
         v_stlnr  TYPE stko-stlnr,
         v_werks  TYPE mkal-werks,
         v_BMENG  type stko-BMENG.

  DATA:  v_objkt TYPE aeoi-objkt,
         v_usobj TYPE aeoi-usobj.


  DATA: lt_exp_bom_item TYPE STANDARD TABLE OF capp_itm WITH HEADER LINE.




  v_stlty = 'M'.
  v_werks = p_werks.
  IF p_stlal IS INITIAL .
    v_stlal = '1'.
  ELSE.
    v_stlal = p_stlal.
  ENDIF.

  IF p_datuv IS INITIAL.
    v_datuv = sy-datum.
  ELSE.
    v_datuv = p_datuv.
  ENDIF.


* 得到bom单号 and 可选bom
  SELECT SINGLE  m~stlnr m~stlal n~BMENG INTO (v_stlnr,v_stlal,v_BMENG)
     FROM mast   AS m INNER JOIN stko AS n ON m~stlnr = n~stlnr AND m~stlal = n~stlal
        WHERE m~matnr = p_matnr AND n~stlty = v_stlty
          AND m~stlal = v_stlal AND m~werks = p_werks
          AND m~stlan = p_stlan.
  IF sy-subrc = 0.

* 读取有效期内的bom
    CALL FUNCTION 'CABM_READ_BOM_ITEM'
      EXPORTING
        i_stlty      = v_stlty
        i_stlnr      = v_stlnr
        i_stlal      = v_stlal
        i_date_from  = v_datuv
        i_werks      = v_werks
      TABLES
        exp_bom_item = lt_exp_bom_item.

* 如果有序列号参数,则处理序列号变更的组件
    IF p_sernr IS NOT INITIAL.

      DATA: lt_pos TYPE TABLE OF ty_pos,
            ls_pos TYPE ty_pos.

      DATA: lt_aeoi TYPE TABLE OF ty_aeoi,
            ls_aeoi TYPE ty_aeoi.

      DATA: lt_aeef TYPE TABLE OF ty_aeef,
            ls_aeef TYPE ty_aeef.

      DATA: lt_makt TYPE TABLE OF ty_makt,
            ls_makt TYPE ty_makt.

      DATA: lt_marc TYPE TABLE OF ty_marc,
            ls_marc TYPE ty_marc.


      CONCATENATE v_stlty v_stlnr INTO v_objkt.


*  查询所有序列号变更的
      SELECT a~idnrk a~menge a~posnr a~postp a~meins a~aennr
           INTO CORRESPONDING FIELDS OF TABLE lt_pos
            FROM stpo AS a INNER JOIN stas AS b
               ON a~stlnr = b~stlnr
              AND a~stlty = b~stlty
              AND a~stlkn = b~stlkn
                  INNER JOIN aenr AS c
               ON a~aennr = c~aennr
           WHERE a~stlnr = v_stlnr
             AND b~stlal = v_stlal
             AND a~stlty = v_stlty
             AND a~postp IN ('L','X')
             AND c~clint = 5
             .
* 查询序列号变更区间和日期
      IF sy-subrc = 0.
*    查询序列号变更日期
        SELECT aennr objkt usobj objdt
             INTO TABLE lt_aeoi
               FROM aeoi
                FOR ALL ENTRIES IN lt_pos
             WHERE aennr = lt_pos-aennr
               AND aetyp = '02'
               AND objkt = v_objkt.
*      查询序列号区间
        SELECT aennr sernr_lo sernr_hi
            INTO TABLE lt_aeef
               FROM aeef
                 FOR ALL ENTRIES IN lt_pos
            WHERE aennr = lt_pos-aennr.

        LOOP AT lt_pos INTO ls_pos.
          CLEAR v_usobj.
*      获得usobj
          PERFORM get_usobj USING
                     p_matnr p_werks p_stlan v_usobj.

          READ TABLE lt_aeoi INTO ls_aeoi WITH KEY
                          aennr = ls_pos-aennr
                          objkt = v_objkt
                          usobj = v_usobj.
          IF sy-subrc = 0.
            ls_pos-objdt = ls_aeoi-objdt.
          ENDIF.

          READ TABLE lt_aeef INTO ls_aeef WITH KEY
                          aennr = ls_pos-aennr.
          IF sy-subrc = 0.
            ls_pos-sernr_lo = ls_aeef-sernr_lo.
            ls_pos-sernr_hi = ls_aeef-sernr_hi.
          ENDIF.
          MODIFY lt_pos FROM ls_pos.
        ENDLOOP.
      ENDIF.

      DELETE lt_pos WHERE objdt > v_datuv.   "删除所有变更日期为应用日期之后的
      DELETE lt_pos WHERE sernr_lo > p_sernr
                     OR  sernr_hi < p_sernr.  "删除更改的序列号区间在当前序列号之外的

      CLEAR tab_bom.  REFRESH tab_bom.
      IF lt_pos[] IS NOT INITIAL.
*    删除掉重复的数据
        SORT lt_pos DESCENDING BY idnrk posnr objdt.
        DELETE ADJACENT DUPLICATES FROM lt_pos COMPARING idnrk posnr objdt.
*    用序列号变更的数量更新到bom中
        LOOP AT lt_exp_bom_item.
          READ TABLE  lt_pos INTO ls_pos
            WITH KEY idnrk = lt_exp_bom_item-idnrk
                     posnr = lt_exp_bom_item-posnr.
          IF sy-subrc = 0.
            lt_exp_bom_item-menge = ls_pos-menge.
            MODIFY lt_exp_bom_item.
          ENDIF.
        ENDLOOP.

*   把序列号变更新加的组件加进去
        LOOP AT lt_pos INTO ls_pos.
          READ TABLE  lt_exp_bom_item
            WITH KEY idnrk = ls_pos-idnrk
                     posnr = ls_pos-posnr.
          IF sy-subrc <> 0.
            CLEAR lt_exp_bom_item.
            MOVE-CORRESPONDING ls_pos TO lt_exp_bom_item.
            APPEND lt_exp_bom_item.
          ENDIF.
        ENDLOOP.
      ENDIF.
    ENDIF.
*  把使用的bom放到 tab_bom表中
    IF lt_exp_bom_item[] IS NOT INITIAL.
      LOOP AT lt_exp_bom_item.
        MOVE-CORRESPONDING lt_exp_bom_item TO tab_bom.
        tab_bom-matnr = lt_exp_bom_item-idnrk.
        tab_bom-stlnr = v_stlnr.
        tab_bom-stlal = v_stlal.
        tab_bom-BMENG = v_BMENG.
        APPEND tab_bom.
      ENDLOOP.
    ENDIF.

*  读取物料描述
    IF tab_bom[] IS NOT INITIAL.
      SELECT matnr maktx FROM makt
         INTO TABLE lt_makt
          FOR ALL ENTRIES IN tab_bom
          WHERE matnr = tab_bom-matnr
          AND   spras = sy-langu.

      SELECT matnr werks beskz sobsl FROM marc
         INTO TABLE lt_marc
          FOR ALL ENTRIES IN tab_bom
          WHERE matnr = tab_bom-matnr
          AND   werks = P_WERKS.


      LOOP AT tab_bom.
        READ TABLE lt_makt INTO ls_makt
          WITH KEY matnr = tab_bom-matnr.
        IF sy-subrc = 0.
          tab_bom-maktx = ls_makt-maktx.
          MODIFY tab_bom.
        ENDIF.

        READ TABLE lt_marc INTO ls_marc
          WITH KEY matnr = tab_bom-matnr
                   werks = P_WERKS
                   .
        IF sy-subrc = 0.
          tab_bom-beskz = ls_marc-beskz.
          tab_bom-sobsl = ls_marc-sobsl.
          MODIFY tab_bom.
        ENDIF.
      ENDLOOP.
    ENDIF.
  ENDIF.
ENDFUNCTION.

 

  (2)  读取多层层的有效Mbom

    ZPLM_GET_USED_BOM_EXP

import:

P_SERNR    like  AEEF-SERNR_LO   序列号

P_DATUV   like  AENR-DATUV   开始生效日期

P_MATNR   like  MAST-MATNR  物料号

P_WERKS   like  MAST-WERKS   工厂

P_STLAN   like  MAST-STLAN   BOM用途

P_STLAL   like  MAST-STLAL   可选的BOM

 

tables:

TAB_BOM   like  ZPLM_BOM_USE    查找使用的bom用到的结构

 

source code:

 

  FUNCTION ZPLM_GET_USED_BOM_EXP.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(P_SERNR) LIKE  AEEF-SERNR_LO
*"     VALUE(P_DATUV) LIKE  AENR-DATUV OPTIONAL
*"     VALUE(P_MATNR) LIKE  MAST-MATNR
*"     VALUE(P_WERKS) LIKE  MAST-WERKS OPTIONAL
*"     VALUE(P_STLAN) LIKE  MAST-STLAN
*"     VALUE(P_STLAL) LIKE  MAST-STLAL OPTIONAL
*"  TABLES
*"      TAB_BOM STRUCTURE  ZPLM_BOM_USE
*"----------------------------------------------------------------------


CHECK       p_matnr IS NOT INITIAL
        AND p_werks IS NOT INITIAL
        AND p_stlan IS NOT INITIAL.

  data: cindex2 type text10.
  data: ilevel type i.
  data: clevel type text20.

  data: irate type KMPMG.

  oindex = 0.
  cindex = oindex.
  oindex = 1.
  cindex2 = oindex.


  ilevel = 0.
  clevel = '0'.

  irate = 1.





  refresh it_bom.  clear it_bom.

  it_bom-matnr = p_matnr.
  it_bom-myid = cindex2.
  it_bom-ilevel = clevel.
  it_bom-pid = cindex .
  it_bom-irate = irate .
  append it_bom.


  cindex = oindex.
  cindex2 = cindex .
  perform get_exp_bom using
           p_sernr
           p_datuv
           p_matnr
           p_werks
           p_stlan
           p_stlal
           cindex2
           ilevel
           irate.
  if it_bom is not initial.
     append lines of it_bom to tab_bom.
  endif.

ENDFUNCTION.

 

2  definetions:

 

  FUNCTION-POOL zplm_bom_fg.                  "MESSAGE-ID ..


TYPESBEGIN OF ty_pos,
     idnrk LIKE stpo-idnrk ,           "组件
     menge LIKE stpo-menge ,
     posnr LIKE stpo-posnr ,           "项目
     postp LIKE stpo-postp ,
     meins LIKE stpo-meins ,
     objdt TYPE aeoi-objdt ,
     aennr LIKE stpo-aennr ,
     sernr_lo TYPE aeef-sernr_lo,
     sernr_hi TYPE aeef-sernr_hi,
  END OF ty_pos.

TYPESBEGIN OF ty_aeoi,
   aennr LIKE aeoi-aennr ,
   objkt LIKE aeoi-objkt ,
   usobj LIKE aeoi-usobj ,
   objdt TYPE aeoi-objdt ,
END OF ty_aeoi.


TYPESBEGIN OF ty_aeef,
    aennr LIKE aeef-aennr ,
    sernr_lo LIKE aeef-sernr_lo ,
    sernr_hi LIKE aeef-sernr_hi ,
 END OF ty_aeef.

TYPESBEGIN OF ty_makt,
         matnr TYPE makt-matnr,
         maktx TYPE makt-maktx,
       END OF ty_makt.


TYPESBEGIN OF ty_marc,
         matnr TYPE marc-matnr,
         werks TYPE marc-werks,
         beskz type marc-beskz,
         sobsl type marc-sobsl,
       END OF ty_marc.


  data: oindex type i.
  data: cindex type text10.

  DATA: it_bom TYPE STANDARD TABLE OF ZPLM_BOM_USE WITH HEADER LINE.

 

3 subroutins:

 

  *&---------------------------------------------------------------------*
*&      Form  get_usobj
*&---------------------------------------------------------------------*
*       获得更改的对象的 usobj
*----------------------------------------------------------------------*
*      -->P_P_MATNR  物料
*      -->P_P_WERKS  工厂
*      -->P_P_STLAN  类型
*      -->P_V_USOBJ  usobj
*----------------------------------------------------------------------*
FORM get_usobj  USING    p_p_matnr
                         p_p_werks
                         p_p_stlan
                         p_v_usobj.
  DATA matnr(18).
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = p_p_matnr
    IMPORTING
      output = matnr.

  p_v_usobj+0(18) = matnr.
  p_v_usobj+18(4) = p_p_werks.
  p_v_usobj+22(1) = p_p_stlan.
ENDFORM.                    " get_usobj


*&---------------------------------------------------------------------*
*&      Form  get_exp_bom
*&---------------------------------------------------------------------*
*       递归获得子bom
*----------------------------------------------------------------------*
*   -->    p_sernr   序列号
*   -->    p_datuv   有效期
*   -->    p_matnr   物料号
*   -->    p_werks   工厂
*   -->    p_stlan   bom用途
*   -->    p_stlal   可选bom
*   -->    p_index   索引
*   -->    p_level   层次
*   -->    p_rate    比例
*----------------------------------------------------------------------*
form get_exp_bom using
          p_sernr
          p_datuv
          p_matnr
          p_werks
          p_stlan
          p_stlal
          p_index
          p_level
          p_rate
              .

 DATA: it_bom1 TYPE STANDARD TABLE OF ZPLM_BOM_USE WITH HEADER LINE.

  data: cindex2 type text10.

  data: ilevel type i.
  data: clevel type text20.

  data: irate type KMPMG.

  clear it_bom1.  refresh it_bom1.
  CALL FUNCTION 'ZPLM_GET_USED_BOM'
    EXPORTING
      p_sernr       = p_sernr
      P_DATUV       = p_datuv
      p_matnr       = p_matnr
      P_WERKS       = p_werks
      p_stlan       = p_stlan
      P_STLAL       = p_stlal
    tables
      tab_bom       = it_bom1
            .

   ilevel = p_level + 1.
   perform get_level using
             ilevel clevel.
   loop at it_bom1.
     oindex = oindex + 1.
     cindex = oindex.
     irate = p_rate * it_bom1-menge / it_bom1-BMENG.
     move it_bom1 to it_bom.
     it_bom-pid = p_index.
     it_bom-myid = cindex.
     it_bom-ilevel = clevel.
     it_bom-irate = irate.
     append it_bom.
     cindex2 = cindex.
     perform get_exp_bom using
           p_sernr
           p_datuv
           it_bom1-matnr
           p_werks
           p_stlan
           p_stlal
           cindex2
           ilevel
           irate.
   endloop.
endform.                    " get_exp_bom
*&---------------------------------------------------------------------*
*&      Form  get_level
*&---------------------------------------------------------------------*
*       生成level信息串
*----------------------------------------------------------------------*
*  -->  p_level_num       层数
*  <--  p_level_str       层串
*----------------------------------------------------------------------*
form get_level using
        p_level_num
        p_level_str.
   clear p_level_str.
   do p_level_num times.
     concatenate  p_level_str '.' into p_level_str.
   enddo.
   data str type text20.
   str = p_level_num.
   condense str no-gaps.
   concatenate  p_level_str str into p_level_str.
endform.                    " get_level

 

4  sturctures:

 

ZPLM_BOM_USE

 

 

原创粉丝点击