SAP CK91N / CK94 物料混合成本估算 的代碼總結 通過 BAPI + BDC 的方式實現

前言

用戶需要批量地使用 CK91N 創建 備選採購,然後通過 CK94 來設定混合比率,因此需要開發一個 批導模板。但是在網絡上查找相關的BAPI均未果,BDC的録屏也有些問題,問題無法解決,苦惱數日,今日完成,特來記録一下。
表 CKMLMV001 存儲 CK91N 中的記録
表 CKMLMV003 存儲 CK94 中的記録

方案說明

1、通過BDC録屏的方式來執行 CK91N 部分
2、關於 CK94 部分,録屏時要輸入 ① 處的三個字段,選中 ② 這一列,或者點擊 ③ 處,通過 ④ 來篩選出唯一一條待修改的數據(因為可能有會有很多條數據,而對於不同的用戶,其前臺顯示的行數可能不同,因此通過 ‘評估類型’來將需要更改的行定位到第一行),如果BDC可以實現 選中-篩選,那BDC無疑是比較容易的解決方案,但實際情況很不幸,無論是 ② 還是 ③,都無法選中。
因此選擇使用BAPI的方式來完成 CK94,但是在實際操作中,BAPI 只能處理修改(CKMLMV003 已經存在 該物料的數據時),爾不能處理 CKMLMV003 還沒有存入數據的情況。
我的解決方案是,先使用BDC輸入第一行的數據,保存。然後使用BAPI來更改。
在这里插入图片描述

代碼

CK91N 的BDC録屏
DATA: lv_msg TYPE string.
  DATA: lv_succ TYPE string VALUE '备选采购执行成功'.

  DATA: ls_01 TYPE ckmlmv001.


  UNASSIGN <fs_data>.
  LOOP AT gt_data ASSIGNING <fs_data> WHERE icon = icon_led_green AND msg IS INITIAL AND zbox = 'X'.
    CLEAR:gt_bdcdata.

    IF <fs_data>-ck91n_flag = 'X'.
      <fs_data>-icon = icon_led_green.
      <fs_data>-msg = '数据已执行过备选采购'.
      CONTINUE.
    ENDIF.


    SELECT SINGLE *
    INTO @DATA(l_matnr_n)
          FROM ckmlmv001
          WHERE matnr = @<fs_data>-matnr
          AND werks = @<fs_data>-werks.

    PERFORM bdc_dynpro      USING 'SAPLCKMLMVSURF'     '0100'.
    PERFORM bdc_field       USING 'BDC_CURSOR'         'CKMLMV_SURF-BWTAR'.
    PERFORM bdc_field       USING 'BDC_OKCODE'         '/00'.
    PERFORM bdc_field       USING 'CKMLMV_SURF-MATNR'  <fs_data>-matnr.
    PERFORM bdc_field       USING 'CKMLMV_SURF-WERKS'  <fs_data>-werks.
    PERFORM bdc_field       USING 'CKMLMV_SURF-BWTAR'  <fs_data>-bwtar.

    PERFORM bdc_dynpro      USING 'SAPLCKMLMVSURF'     '0100'.
    PERFORM bdc_field       USING 'BDC_CURSOR'         'CKMLMV_SURF-MATNR'.
    PERFORM bdc_field       USING 'BDC_OKCODE'         '/00'.
    PERFORM bdc_field       USING 'CKMLMV_SURF-MATNR'  <fs_data>-matnr.
    PERFORM bdc_field       USING 'CKMLMV_SURF-WERKS'  <fs_data>-werks.
    PERFORM bdc_field       USING 'CKMLMV_SURF-BWTAR'  <fs_data>-bwtar.

    PERFORM bdc_dynpro      USING 'SAPLCKMLMVSURF'     '0100'.
    PERFORM bdc_field       USING 'BDC_CURSOR'         'CKMLMV_SURF-MATNR'.
    PERFORM bdc_field       USING 'BDC_OKCODE'         '/00'.
    PERFORM bdc_field       USING 'CKMLMV_SURF-MATNR'  <fs_data>-matnr.
    PERFORM bdc_field       USING 'CKMLMV_SURF-WERKS'  <fs_data>-werks.
    PERFORM bdc_field       USING 'CKMLMV_SURF-BWTAR'  <fs_data>-bwtar.

    PERFORM bdc_dynpro      USING 'SAPLCKMLMVSURF'     '0100'.
    PERFORM bdc_field       USING 'BDC_CURSOR'         'CKMLMV_SURF-MATNR'.
    PERFORM bdc_field       USING 'BDC_OKCODE'         '=CREATE'.
    PERFORM bdc_field       USING 'CKMLMV_SURF-MATNR'  <fs_data>-matnr.
    PERFORM bdc_field       USING 'CKMLMV_SURF-WERKS'  <fs_data>-werks.
    PERFORM bdc_field       USING 'CKMLMV_SURF-BWTAR'  <fs_data>-bwtar.

    PERFORM bdc_dynpro      USING 'SAPLCKMLMVSURF'      '0100'.
    PERFORM bdc_field       USING 'BDC_OKCODE'          '=BTYP'.
    PERFORM bdc_field       USING 'BDC_CURSOR'          'CKMLMVTOOL_540-BTYP'.
    PERFORM bdc_field       USING 'CKMLMVTOOL_540-BTYP' <fs_data>-btyp.

    IF l_matnr_n IS INITIAL.
      PERFORM bdc_dynpro    USING 'SAPLSPO5'   '0110'.
      PERFORM bdc_field     USING 'BDC_OKCODE' '=OK'.
      PERFORM bdc_field     USING 'BDC_CURSOR' 'SPOPLI-SELFLAG(02)'.
    ENDIF.

    PERFORM bdc_dynpro      USING 'SAPLCKMLMVSURF'           '0100'.
    PERFORM bdc_field       USING 'BDC_OKCODE'               '=ENTZ'.
    PERFORM bdc_field       USING 'BDC_CURSOR'               'CKMLMVTOOL_540-VERID_ND'.
    PERFORM bdc_field       USING 'CKMLMVTOOL_540-VERID_ND'  <fs_data>-verid_nd.
    PERFORM bdc_field       USING 'CKMLMVTOOL_540-LOSGR_PC'  <fs_data>-losgr_pc.

    "新加
*    PERFORM bdc_dynpro      USING 'SAPLCKMLMVSURF'           '0100'.
*    PERFORM bdc_field       USING 'BDC_OKCODE'               '=ENTE'.
*    PERFORM bdc_field       USING 'BDC_CURSOR'               'CKMLMVTOOL_540-VERID_ND'.

    IF l_matnr_n IS NOT INITIAL.
      PERFORM bdc_dynpro    USING 'SAPLSPO1'    '0100'.
      PERFORM bdc_field     USING 'BDC_OKCODE'  '=YES'.
    ENDIF.

    PERFORM bdc_dynpro      USING 'SAPLCKMLMVSURF'          '0100'.
    PERFORM bdc_field       USING 'BDC_CURSOR'              'CKMLMV_SURF-MATNR'.
    PERFORM bdc_field       USING 'BDC_OKCODE'              '=SAVE'.
    PERFORM bdc_field       USING 'CKMLMV_SURF-MATNR'       <fs_data>-matnr.
    PERFORM bdc_field       USING 'CKMLMV_SURF-WERKS'       <fs_data>-werks.
    PERFORM bdc_field       USING 'CKMLMV_SURF-BWTAR'       <fs_data>-bwtar.
    PERFORM bdc_field       USING 'CKMLMVTOOL_530-LOSGR_PC' <fs_data>-losgr_pc.

    PERFORM bdc_dynpro      USING 'SAPLCKMLMVSURF'          '0100'.
    PERFORM bdc_field       USING 'BDC_CURSOR'              'CKMLMV_SURF-MATNR'.
    PERFORM bdc_field       USING 'BDC_OKCODE'              '=SAVE'.
    PERFORM bdc_field       USING 'CKMLMV_SURF-MATNR'       <fs_data>-matnr.
    PERFORM bdc_field       USING 'CKMLMV_SURF-WERKS'       <fs_data>-werks.
    PERFORM bdc_field       USING 'CKMLMV_SURF-BWTAR'       <fs_data>-bwtar.
    PERFORM bdc_field       USING 'CKMLMVTOOL_530-LOSGR_PC' <fs_data>-losgr_pc.

    IF l_matnr_n IS NOT INITIAL.
      PERFORM bdc_dynpro      USING 'SAPLSPO1'   '0100'.
      PERFORM bdc_field       USING 'BDC_OKCODE' '=YES'.
    ENDIF.

    PERFORM bdc_dynpro      USING 'SAPLCKMLMVSURF' '0100'.
    PERFORM bdc_field       USING 'BDC_OKCODE'     '/EBACK'.
    PERFORM bdc_field       USING 'BDC_CURSOR'     'CKMLMV_SURF-MATNR'.

    CLEAR: gt_msgtab.
    CALL TRANSACTION 'CK91N' USING gt_bdcdata
          MODE p_mode
          MESSAGES INTO gt_msgtab
          UPDATE 'S'.
          
    CLEAR: ls_01.
    SELECT SINGLE *
      FROM ckmlmv001
      INTO ls_01
      WHERE matnr = <fs_data>-matnr
        AND werks = <fs_data>-werks
        AND bwtar = <fs_data>-bwtar.
    IF sy-subrc = 0.
      <fs_data>-msg        = lv_succ.
      <fs_data>-ck91n_flag = 'X'.
    ELSE.
      <fs_data>-msg = '备选采购执行失败:' &&  <fs_data>-msg.
      <fs_data>-msg  = shift_right( val =  <fs_data>-msg   sub = ':').
      <fs_data>-icon = icon_led_red.
    ENDIF.

  ENDLOOP.
CK94
 CASE r_ucomm.
    WHEN 'CK94'.
    "說明,gt_data 的結構為  matnr 、werks 、bwtar,同一批執行的數據 是相同的matnr和相同的werks,bwtar(评估类型) 來區分不同的數據
      LOOP AT gt_data ASSIGNING <fs_data> WHERE icon = icon_led_green AND zbox = 'X'.
        AT NEW  werks.
          "執行 BDC 只為將數據保存值表 CKMLMV003 中
          SELECT SINGLE * FROM ckmlmv003 INTO @DATA(ls_ckml03) WHERE matnr = @<fs_data>-matnr  AND werks = @<fs_data>-werks.
          IF sy-subrc <> 0.
            READ TABLE gt_head INTO gs_head  WITH KEY matnr = <fs_data>-matnr werks = <fs_data>-werks   BINARY SEARCH.
            IF sy-subrc = 0 AND ls_ckml03 IS INITIAL.
              PERFORM frm_bdc_ck94 USING gs_head. "先通過BDC在CK94中保存數據
            ENDIF.
          ENDIF.
        ENDAT.

        IF <fs_data>-ck91n_flag = ''.
          <fs_data>-msg = '备选采购未执行,请先执行该步骤'.
          <fs_data>-icon = icon_led_red.
          CONTINUE.
        ENDIF.

        APPEND <fs_data> TO gt_item.
        
        AT END OF werks.
          PERFORM  frm_bapi_ck94 USING <fs_data>.
          CLEAR: gt_item.
        ENDAT.
      ENDLOOP.
  ENDCASE.

####### CK94 的 BDC

FORM frm_bdc_ck94 USING ps_data TYPE ty_data.

  CLEAR: gt_bdcdata.

  "CK94 初始屏幕
  PERFORM bdc_dynpro      USING 'SAPLCKBASCR1'            '0200'.
  PERFORM bdc_field       USING 'BDC_CURSOR'              'CKI94A-MATNR'.
  PERFORM bdc_field       USING 'BDC_OKCODE'              '=ENTR'.
  PERFORM bdc_field       USING 'CKI94A-MATNR'            ps_data-matnr  .
  PERFORM bdc_field       USING 'CKI94A-WERKS'            ps_data-werks  .
  PERFORM bdc_field       USING 'CKI94A-MGTYP'            'Z9000'  .

  "第一次进入时,有弹框
  PERFORM bdc_dynpro      USING 'SAPLSPO2'               '0300'.
  PERFORM bdc_field       USING 'BDC_OKCODE'              '=OPT1'.


  "输入相关数据
  PERFORM bdc_dynpro      USING 'SAPLCKBASCR1'            '0202'.
  PERFORM bdc_field       USING 'BDC_CURSOR'              'CKI94B-MISCH_VERH(01)'.
  PERFORM bdc_field       USING 'BDC_OKCODE'              '=ENTR'.
  PERFORM bdc_field       USING 'CKI94B-ALDAT_PC(01)'     ps_data-aldat_pc."成本核算数量结构日期
  PERFORM bdc_field       USING 'CKI94B-MIXCOST_PC(01)'   ps_data-mixcost_pc."是否混合相关比率
  PERFORM bdc_field       USING 'CKI94B-MISCH_VERH(01)'   ps_data-misch_verh. "混合比例

  "保存
  PERFORM bdc_dynpro      USING 'SAPLCKBASCR1'            '0202'.
  PERFORM bdc_field       USING 'BDC_CURSOR'              'CKI94B-MISCH_VERH(01)'.
  PERFORM bdc_field       USING 'BDC_OKCODE'              '=STOR'.


  CLEAR: gt_msgtab.
  CALL TRANSACTION 'CK94' USING gt_bdcdata
        MODE p_mode
        MESSAGES INTO gt_msgtab
        UPDATE 'S'.

ENDFORM.

####### CK94 的 BAPI

FORM frm_bapi_ck94 USING ps_data TYPE ty_data. .
  DATA: ls_03 TYPE ckmlmv003.

"CK94 相關結構及變量
TYPES:
* Tabelle für Materialbewertunsgarten mit Mischungsverhältnisse
  BEGIN OF ckmv1_mat_cratio_str,
    kalnr_mb   LIKE ckmlmv001-kalnr,       "Material (MBEW-Ebene)
    kalnr_mk   LIKE ckmlmv001-kalnr,       "Material (BwKreis-Ebene)
    bwkey      LIKE ckmlmv001-bwkey,       "BewertKreis(Kalnr_Mb)
    matnr      LIKE ckmlmv001-matnr,       "Material(Kalnr_Mb)
    bwtar      LIKE ckmlmv001-bwtar,       "Bewqertungsart(Kalnr_Mb)
    misch_verh LIKE ckmlmv003-misch_verh,  "Mischungsverhältnis
  END OF ckmv1_mat_cratio_str,

  BEGIN OF ckmv1_alt_cratio_str,
    kalnr_pr   LIKE ckmlmv001-kalnr,       "Prozeß
    kalnr_ba   LIKE ckmlmv001-kalnr,       "Alternative
    kalnr_mb   LIKE ckmlmv001-kalnr,       "Material (MBEW-Ebene)
    werks      LIKE ckmlmv001-werks,       "Werk (Alternative)
    bwkey      LIKE ckmlmv001-bwkey,       "BewertKreis(Kalnr_Mb)
    matnr      LIKE ckmlmv001-matnr,       "Material(Kalnr_Mb)
    bwtar      LIKE ckmlmv001-bwtar,       "Bewqertungsart(Kalnr_Mb)
    btyp       LIKE ckmlmv001-btyp,        "Beschaffungstyp
    misch_verh LIKE ckmlmv003-misch_verh,  "Mischungsverh
*   Zusatzdaten für die Mischkalkulation
    mixcost_pc TYPE ck_mixcost.            "Kz:Relevant f.Mischkal
    INCLUDE TYPE   ckmv1_mix001_data.          "Aus Stammsatz
    INCLUDE TYPE   ckmv1_mix003_data.          "Aus Mischverhältnis
TYPES:
*   Namen/Bezeichnungen der Beschaffungsalternative
  name          TYPE ckmv1_ename,           "Editierter Name (Altern)
  balt_name_str TYPE ckmv1_name_str,        "Merkmale (Alternative)
  END OF ckmv1_alt_cratio_str.

DATA:li_mmratio_tbl TYPE STANDARD TABLE OF ckmv1_mat_cratio_str,
     li_amratio_tbl TYPE STANDARD TABLE OF  ckmv1_alt_cratio_str,
     ls_amratio     TYPE ckmv1_alt_cratio_str,
     ls_cki94c      TYPE cki94c,
     ls_cki94a      TYPE cki94a.

DATA: e_percent TYPE ckmlmv003-misch_verh,
      rc        LIKE sy-subrc,
      i_percent TYPE ckmlmv003-misch_verh.

CLEAR: ls_cki94a.
  ls_cki94a-matnr = ps_data-matnr.
  ls_cki94a-werks = ps_data-werks.
  ls_cki94a-mgtyp = 'Z9000'.                "数量结构类型


  CALL FUNCTION 'CKBA_MIXRATIO_PREPARE_VALUES'
    IMPORTING
      e_cki94c      = ls_cki94c
      e_mmratio_tbl = li_mmratio_tbl
      e_amratio_tbl = li_amratio_tbl
    CHANGING
      c_cki94a      = ls_cki94a.

  READ TABLE li_amratio_tbl INTO ls_amratio INDEX 1.
  IF sy-subrc EQ 0.
    CALL FUNCTION 'CKBA_MIXRATIO_CHECK'
      EXPORTING
        i_percent_check = space
        i_mixratio      = li_amratio_tbl[]
      IMPORTING
        e_returncode    = rc
        e_percent       = e_percent.
    IF rc EQ 0.
      LOOP AT li_amratio_tbl ASSIGNING FIELD-SYMBOL(<fs_amratio>).
        READ TABLE gt_item INTO gs_item  WITH KEY bwtar = <fs_amratio>-bwtar .
        IF sy-subrc = 0.
          <fs_amratio>-aldat_pc    = gs_item-aldat_pc.   "数量结构日期
          <fs_amratio>-mixcost_pc  = gs_item-mixcost_pc. "是否混合相关比率
          <fs_amratio>-misch_verh  = gs_item-misch_verh. "混合比率
        ENDIF.
      ENDLOOP.

      CALL FUNCTION 'CKML_MGV_CROSS_RATIO_UPDATE'
        EXPORTING
          iv_mgtyp      = ls_cki94a-mgtyp
          iv_gjahr      = '0000'
          iv_perio      = '000'
          it_alt_cratio = li_amratio_tbl[].

    ENDIF.
  ENDIF.

*2.Update Mixing ratio
*for updatign mixing ratio, we can use the below function module.

  DATA: lw_bdatj    TYPE cki94a-bdatj,         "Posting date YYYY
        lw_mgtyp    TYPE cki94a-mgtyp VALUE 'Z9000',         "Quantity Structure Type

        lt_mixratio TYPE ckmv1_alt_cratio_tbl.

  CONSTANTS:  c_per_000      TYPE ckmlmv003-perio VALUE '000'.         ":Period 000

  MOVE-CORRESPONDING li_amratio_tbl TO lt_mixratio.

* Update Mix Ratio
  CALL FUNCTION 'MIXRATIO_MAINTAIN'
    EXPORTING
      i_mgtyp                = lw_mgtyp
      i_fyear                = lw_bdatj
      i_perio                = c_per_000
      i_mixratio_procalt     = lt_mixratio[]
    EXCEPTIONS
      mixratio_already_exist = 1
      db_error               = 2
      mgtyp_error            = 3
      no_mixratio            = 4
      percent_error          = 5
      OTHERS                 = 6.

  IF sy-subrc EQ 0.
    COMMIT WORK.
  ENDIF.

  LOOP AT gt_item INTO gs_item ."LOOP gt_item 是因為 gt_item 存儲的是同物料號下能執行的被選中的數據
    CLEAR: ls_03.
    READ TABLE gt_data ASSIGNING <fs_data1>  WITH KEY matnr = gs_item-matnr  werks = gs_item-werks  bwtar = gs_item-bwtar.
    IF sy-subrc = 0.

      SELECT SINGLE * FROM ckmlmv003 INTO ls_03
       WHERE matnr      = <fs_data1>-matnr
         AND werks      = <fs_data1>-werks
         AND aldat_pc   = <fs_data1>-aldat_pc
         AND misch_verh = <fs_data1>-misch_verh
  .
    ENDIF.
    IF ls_03 IS NOT INITIAL.
      <fs_data1>-msg = <fs_data1>-msg && ';估算比率执行成功'.
      <fs_data1>-icon = icon_led_green.
    ELSE.
      <fs_data1>-msg = <fs_data1>-msg && ';估算比率执行失败'.
      <fs_data1>-icon = icon_led_red.
    ENDIF.

    <fs_data1>-msg  = shift_left( val = <fs_data1>-msg sub = ';').

  ENDLOOP.

ENDFORM.

注意

使用 BDC 録屏時,輸入的數值型的字段要轉換為 Char 型,否則會有警告:長度不一致,致使BDC 被迫結束

TYPES: BEGIN OF ty_data,

         matnr          TYPE  ckmlmv001-matnr       ,   " 物料
         werks          TYPE  ckmlmv001-werks       ,   " 工厂
         bwtar          TYPE  ckmlmv001-bwtar       ,   " 评估类型
         btyp           TYPE  ckmlmv001-btyp        ,   " 处理类型
         verid_nd       TYPE  ckmlmv001-verid_nd    ,   " 生产版本
         losgr_pc(17)   TYPE  c   				    ,   " 成本核算批量
         aldat_pc(8)    TYPE  c                     ,   " 数量结构日期
         mixcost_pc     TYPE  c                     ,   " 是否混合相关比率
         misch_verh(17) TYPE  c                     ,   " 混合比率

         "以上Excel模板字段
         icon(4)        TYPE c,
         zbox,
         msg(100)       TYPE c,
         ck91n_flag,
       END OF ty_data.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用BAPI_GOODSMVT_CREATE跨工厂物料调拨时,需要对以下参数进行赋值: 1. GOODSMVT_HEADER:物料凭证头数据 - PSTNG_DATE:过账日期 - DOC_DATE:凭证日期 - REF_DOC_NO:参考凭证号码 - HEADER_TXT:凭证抬头文本 - GM_CODE:物料移动类型 2. GOODSMVT_CODE:物料移动类型数据 - GM_CODE:物料移动类型代码 3. GOODSMVT_ITEM:物料凭证行项目数据 - MATERIAL:物料号 - PLANT:发货工厂 - STORAGE_LOC:发货库存地点 - MOVE_TYPE:移动类型 - ENTRY_QNT:数量 - ENTRY_UOM:计量单位 - COSTCENTER:成本中心 - VAL_TYPE:价值类型 - MOVE_PLANT:收货工厂 - MOVE_STLOC:收货库存地点 - ITEM_TEXT:项目文本 下面是一个简单的示例代码: ``` DATA: lv_material TYPE bapi2017_gm_item_create-matnr, lv_plant TYPE bapi2017_gm_item_create-werks, lv_stloc TYPE bapi2017_gm_item_create-lgort, lv_move_type TYPE bapi2017_gm_head-mvt_code, lv_entry_qnt TYPE bapi2017_gm_item_create-menge, lv_entry_uom TYPE bapi2017_gm_item_create-meins, lv_costcenter TYPE bapi2017_gm_item_create-kostl, lv_val_type TYPE bapi2017_gm_item_create-bwtar, lv_move_plant TYPE bapi2017_gm_item_create-wempf, lv_move_stloc TYPE bapi2017_gm_item_create-lgort, lt_item_data TYPE TABLE OF bapi2017_gm_item_create, ls_item_data LIKE LINE OF lt_item_data. ls_item_data-matnr = lv_material. ls_item_data-werks = lv_plant. ls_item_data-lgort = lv_stloc. ls_item_data-mvt_ind = lv_move_type. ls_item_data-menge = lv_entry_qnt. ls_item_data-meins = lv_entry_uom. ls_item_data-kostl = lv_costcenter. ls_item_data-bwtar = lv_val_type. ls_item_data-wempf = lv_move_plant. ls_item_data-welme = lv_entry_uom. ls_item_data-lgort_wempf = lv_move_stloc. APPEND ls_item_data TO lt_item_data. CALL FUNCTION 'BAPI_GOODSMVT_CREATE' EXPORTING goodsmvt_header = ls_header_data goodsmvt_code = ls_code_data TABLES goodsmvt_item = lt_item_data EXCEPTIONS error_message = 1 OTHERS = 2. ``` 请根据实际情况进行相应的修改和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值