SAP BOM 多层展开及组件成本处理

该代码段展示了在SAP环境中如何使用函数`CS_BOM_EXPL_MAT_V2`来展开多层次的物料清单(BOM),处理替代料,并计算组件的成本。程序首先调用官方函数进行BOM展开,然后对展开的结果进行处理,排除某些特定情况,接着根据BOM组件获取价格信息,最后计算总成本,区分不同类型的物料成本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

form sub_get_bom.

  LOOP AT gt_output INTO gs_output.

    REFRESH:lt_stb.



    CALL FUNCTION 'CS_BOM_EXPL_MAT_V2'  "多层BOM展开官方方法
      EXPORTING
        capid                 = 'PP01'
        datuv                 = sy-datum
        emeng                 = 0
        mtnrv                 = gs_output-matnr
        mktls                 = lv_mktls
        mehrs                 = lv_mehrs
        werks                 = gs_output-werks
        stlan                 = gs_output-stlan
        stlal                 = gs_output-stlal
      TABLES
        stb                   = lt_stb
      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
        OTHERS                = 8.
    "多层BOM,如果第一层的BOM 中有替代料,那么这个替代料展开的下层组件都要删除
sort lt_stb by stufe descending.
clear: ls_stb,lv_tim,lv_stufe,lv_vwegx.
read table lt_stb into ls_stb index 1.
  lv_tim = ls_stb-stufe - 1.
lt_stb1 = lt_stb[].
  DO lv_tim times.
    clear: ls_stb,ls_stb1.
    loop at lt_stb into ls_stb.
      lv_stufe = ls_stb-stufe - 1.
      lv_vwegx = ls_stb-vwegx.
      read table lt_stb into ls_stb1 with key stufe = lv_stufe wegxx = lv_vwegx.
        if sy-subrc = 0.
          if ls_stb1-alpos = 'X' and ls_stb1-ewahr <> '100'.
             ls_stb-alpos = 'X'.
          ENDIF.
        ENDIF.
      MODIFY LT_STB FROM LS_STB.
    ENDLOOP.
   ENDDO.
   delete lt_stb where alpos = 'X' and ewahr <> '100'.






CLEAR LS_STB.
    loop at lt_stb into ls_stb."取LT_STB带出来的BOM组件的价格
SELECT
    MBEW~MATNR,
    MBEW~BWKEY,
    MBEW~STPRS,
    MBEW~LFGJA,
    MBEW~LFMON,
    MBEW~PEINH
     FROM MBEW
  APPENDING CORRESPONDING FIELDS OF TABLE @GT_MBEWH
  WHERE MATNR = @ls_stb-IDNRK
  and BWKEY = @ls_stb-WERKS
  and STPRS > '0'.
PERform sub_process_mbew.
ENDLOOP.


CLEAR LS_STB.
clear cost_sum.
clear cost_sumt.
data:substr type string.
    LOOP AT  lt_stb INTO ls_stb.  "在这里计算好成本
      clear substr.
      substr = ls_stb-idnrk.
        if ls_stb-xtlnr <> ''.
          continue.
        ENDIF.
        case substr+0(2).
           when  'R8'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.  
                  cost_sum = cost_sum + rmenge * gt_mbew-stprs / gt_mbew-peinh.
                 clear rmenge.
                  exit.
               endif.
            endloop.

           when  'S2'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sum = cost_sum + rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.

           when  'S3'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sum = cost_sum + rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.
          EXIT.
           ENDCASE.
           case substr+0(5).
           when  'WK101'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sum = cost_sum + rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.


           "以上,芯片成本累加

           when  'WK102'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sumT = cost_sumT +  rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.

          when  'WK103'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sumT = cost_sumT +  rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.

                      when  'WK104'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sumT = cost_sumT +  rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.

                      when  'WK105'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sumT = cost_sumT +  rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.

                      when  'WK106'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sumT = cost_sumT +  rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.

                      when  'WK107'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sumT = cost_sumT +  rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.

                      when  'R1006'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sumT = cost_sumT +  rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.

                      when  'R1014'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                  perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sumT = cost_sumT +  rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.

                      when  'R1017'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sumT = cost_sumT +  rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.

                      when  'R1018'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                 perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sumT = cost_sumT +  rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.

                      when  'R1025'.
             loop at gt_mbewh into gt_mbew.
               if gt_mbew-matnr = ls_stb-idnrk and gt_mbew-bwkey = ls_stb-werks and gt_mbew-peinh <> '0'.
                  perform sub_get_rmenge using ls_stb-idnrk ls_stb-MNGLG.
                  cost_sumT = cost_sumT +  rmenge * gt_mbew-stprs / gt_mbew-peinh.
                  clear rmenge.
                  exit.
               endif.
            endloop.
           exit.
        ENDCASE.


        "以上  计算铜材的成本
GS_OUTPUT-COST_XF = COST_SUM.
GS_OUTPUT-COST_TF = COST_SUMT.
MODIFY GT_OUTPUT FROM GS_OUTPUT.


*      MOVE-CORRESPONDING gs_output TO gs_alv.  "这个也是不用了  ,这是zpp009 的目标结构,这里换成我自己的
*
*      MOVE-CORRESPONDING ls_stb  TO gs_alv.
*
*
*      APPEND gs_alv TO gt_alv.
    ENDLOOP.
  ENDLOOP.


endform.

form sub_get_rmenge using idnrk menge. "考虑损耗 rmenge  加上损耗后的实际数量
  clear: smenge,rmenge.
  sort lt_stb by stufe descending.
clear: lv_tim,lv_stufe,lv_vwegx.
  if ls_stb-ausch <> '0' .
    smenge = ls_stb-mnglg * ls_stb-ausch / 100.  "自己当前级的损耗  
  endif.
  lv_tim = ls_stb-stufe - 1.
lt_stb1 = lt_stb[].
  DO lv_tim times.   "找父阶料
    clear: ls_stb1.
      lv_stufe = ls_stb-stufe - 1.
      lv_vwegx = ls_stb-vwegx.
      read table lt_stb into ls_stb1 with key stufe = lv_stufe wegxx = lv_vwegx."取父级的组件
     " ls_stb1-idnrk = ls_stb1-idnrk. "调试时看了下  可以没有
        if sy-subrc = 0.
          if ls_stb1-ausch <> '0'."父一级也有损耗,
             smenge =  smenge + ls_stb-mnglg * ls_stb1-ausch / 100  .  "MNGLG已经做了换算了,自己当前的耗用量
          ENDIF.
        ENDIF.
      "MODIFY LT_STB FROM LS_STB.
   ENDDO.
   rmenge = menge + smenge.
endform.



FORM SUB_SELECT_MBEW ." 取成品料的当前成本
  clear gs_output.
  loop at gt_output into gs_output.
SELECT
    MBEW~MATNR,
    MBEW~BWKEY,
    MBEW~STPRS,
    MBEW~LFGJA,
    MBEW~LFMON,
    MBEW~PEINH
     FROM MBEW
  APPENDING CORRESPONDING FIELDS OF TABLE @GT_MBEWH
  WHERE MATNR = @gS_output-MATNR
  and BWKEY = @GS_OUTPUT-WERKS
  and STPRS > '0'.
ENDLOOP.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form SUB_SELECT_MBEWH
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM SUB_SELECT_MBEWH ."取成品料的历史成本

    clear gs_output.
  loop at gt_output into gs_output.
 SELECT
        MBEWH~MATNR,
    MBEWH~BWKEY,
    MBEWH~STPRS,
    MBEWH~LFGJA,
    MBEWH~LFMON,
    MBEWH~PEINH
     FROM MBEWH
   APPENDING CORRESPONDING FIELDS OF TABLE @GT_MBEWH

   WHERE MATNR = @gS_output-MATNR
   and BWKEY = @GS_OUTPUT-WERKS
   and STPRS > '0'.
ENDLOOP.
ENDFORM.

form sub_process_mbew."根据年份和期间拼接后排序,取最新的价格
  data: lfgja_a like GT_MBEW-LFGJA.
  data: lfmon_a like GT_MBEW-LFmon.
  LOOP AT GT_MBEWH INTO GT_MBEW.
    clear lfgja_a.
    clear lfmon_a.
    lfgja_a = GT_MBEW-LFGJA.
    lfmon_a = GT_MBEW-LFMON.
     GT_MBEW-SORTID = |{ lfgja_a+0(4) }{ lfmon_a+0(2) }| .
     MODIFY GT_MBEWH FROM GT_MBEW.
   ENDLOOP.
   SORT GT_MBEWH BY BWKEY MATNR sortid DESCENDING.
   delete adjacent duplicates from gt_mbewh comparing BWKEY MATNR.
endform.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值