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

2023-10-13 17:21:49 浏览数 (2)

代码语言:javascript复制
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.

0 人点赞