首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用BAPI_GOODSMVT_CREATE编程创建纪录片批次?

用BAPI_GOODSMVT_CREATE编程创建纪录片批次?
EN

Stack Overflow用户
提问于 2019-10-30 13:13:58
回答 1查看 1.3K关注 0票数 4

问题摘要

通过自定义ABAP代码自动处理文件批次

我的雇主希望对来自外部供应商的一些产品执行自动文件批次处理,我正在设法通过自定义和ABAP来设置这个过程。

在我看来,纪录片的批次只能通过MIGO来使用--无论如何,我无法找到适当的解决方案来编程分配它们,而且我可以想出的任何被黑客攻击的解决方案,似乎都是不够的和不稳定的。

我有什么办法来解决这个问题呢?

增强BAPI_GOODSMVT_CREATE?

我可以通过BAPI_GOODSMVT_CREATE这样的方法来做吗?

加强PPPI信息目的地?

我还特别需要它来通过PPPI进行消费消息传递,并且我想构建在标准消息目的地PI04 ( FM COCI_CONFIRM_MATERIAL_CONS )之上。

此FM创建一个重要文档,但不通过BAPI_GOODSMVT_CREATE FM。

不过,它确实使用了MB_CREATE_GOODS_MOVEMENT

我已经尝试过的

基于MIGO快照的单用黑客解决方案

我为一个区域制定了黑客解决方案,在那里我观察了哪些表更新了MIGO,使用了哪些数据(通过FM的VB_INSERT_BATCHVB_BATCH_WHERE_USED_LIST),然后手动填写了这些结构。

但是,提供所有所需的信息对于其他实现领域是不可行的,因为它们没有所有可用的必要值,而且它也不包括可能需要其他参数的意外情况。

读取BAPI_GOODSMVT_CREATE代码

我尝试过监视BAPI_GOODSMVT_CREATE是否执行相同的FM,但只发现它访问了VB_BATCH_WHERE_USED_LIST

通过控制内存ID Documentary Batch #1Documentary Batch #2Documentary Batch #3Documentary Batch #5 (请参阅FM VBDBDM_DATA_POST_IM)来激活此功能似乎是可能的,但这需要填充大量数据,包括名为DOCUBATCH_SCREEN_FIELDS的结构,这再次使人觉得这可能不是正确的方法。

无论如何,这仍然不允许我通过表MCHA和MCH1来维护批处理。

基于MIGO快照的混合解决方案

这是我被黑的解决方案的样子。同样,这并不是解决这一问题的可行办法,因为其他执行领域没有立即获得所产生的材料文件:

代码语言:javascript
复制
    FUNCTION zproxy_mdr_goodsreceipt.
    *"----------------------------------------------------------------------
    *"*"Local Interface:
    *"  IMPORTING
    *"     VALUE(IS_GOODSRECEIPT_HEAD) TYPE  ZPROXY_GOODSREC_HEAD
    *"     VALUE(IT_GOODSRECEIPT_ITEM) TYPE  ZPROXY_GOODSREC_ITEM_T
    *"     REFERENCE(I_CREATE_TO_FROM_REQUIREMENTS) TYPE  FLAG DEFAULT '-'
    *"  EXPORTING
    *"     REFERENCE(E_GOODSMVT_MSG_IDNO) TYPE  CHAR23
    *"     REFERENCE(E_MBLNR) TYPE  MBLNR
    *"     REFERENCE(E_TO_CREATION_SUBRC) TYPE  SY-SUBRC
    *"     REFERENCE(E_LGNUM_ERROR) TYPE  LGNUM
    *"     REFERENCE(E_TBNUM_ERROR) TYPE  TBNUM
    *"     REFERENCE(E_DOCBATCH_SUBRC) TYPE  SY-SUBRC
    *"     REFERENCE(E_DOCBATCH_MSG_IDNO) TYPE  CHAR23
    *"     REFERENCE(E_CLASSNUM) TYPE  BAPI1003_KEY-CLASSNUM
    *"     REFERENCE(E_OBJKEY) TYPE  BAPI1003_KEY-OBJECT
    *"  EXCEPTIONS
    *"      GOODSMVT_FAILED
    *"      NO_TRANSFER_REQUIREMENTS
    *"      TRANSFER_ORDER_CREATION_ERROR
    *"----------------------------------------------------------------------

      FIELD-SYMBOLS: <return>         TYPE bapiret2,
                     <goods_rec_item> TYPE zproxy_goodsrec_item,
                     <mseg>           TYPE mseg,
                     <char_char>      TYPE bapi1003_alloc_values_char,
                     <ltap_creat>     TYPE LTAP_CREAT.

      DATA: ls_header   TYPE bapi2017_gm_head_01,
            ls_code     TYPE bapi2017_gm_code,
            ls_item     TYPE bapi2017_gm_item_create,
            lt_item     TYPE STANDARD TABLE OF bapi2017_gm_item_create,
            lt_return   TYPE STANDARD TABLE OF bapiret2,
            ls_headret  TYPE bapi2017_gm_head_ret,
            l_mblnr     LIKE bapi2017_gm_head_ret-mat_doc,
            l_docubatch TYPE charg_d,
            l_subrc     TYPE sy-subrc,
            lt_mseg     TYPE STANDARD TABLE OF mseg.

      CLEAR l_subrc.


    *     ############################## Create goods movement ##############################
    *     Build structures
      MOVE-CORRESPONDING is_goodsreceipt_head TO ls_header.
      ls_code-gm_code = '01'.

      LOOP AT it_goodsreceipt_item ASSIGNING <goods_rec_item>.
        MOVE-CORRESPONDING <goods_rec_item> TO ls_item.
        APPEND ls_item TO lt_item.
      ENDLOOP.

    *     BAPI call
      CALL FUNCTION 'BAPI_GOODSMVT_CREATE'
        EXPORTING
          goodsmvt_header  = ls_header
          goodsmvt_code    = ls_code
        IMPORTING
          goodsmvt_headret = ls_headret
          materialdocument = l_mblnr
        TABLES
          goodsmvt_item    = lt_item
          return           = lt_return.
    *     Check errors
      READ TABLE lt_return ASSIGNING <return> WITH KEY type = 'E'.
      IF sy-subrc = 0.
        e_goodsmvt_msg_idno = <return>-id && <return>-number.
        ROLLBACK WORK.
        RAISE goodsmvt_failed.
      ELSE.
        e_mblnr = l_mblnr.
        COMMIT WORK AND WAIT. "Wait for TO requirements to be created
      ENDIF.

    *     Only proceede if Material Document has been successfully posted
      CHECK l_subrc = 0 AND l_mblnr IS NOT INITIAL.

    *     ############################## Update with Documentary Batch ###################################

      DATA: lt_chvw      TYPE STANDARD TABLE OF chvw,
            ls_chvw      TYPE chvw,
            lt_mch1      TYPE STANDARD TABLE OF mch1,
            ls_mch1      TYPE mch1,
            lt_mcha      TYPE STANDARD TABLE OF mcha,
            ls_mcha      TYPE mcha,
            lt_mchb      TYPE STANDARD TABLE OF mchb,
            lt_mska      TYPE STANDARD TABLE OF mska,
            lt_mspr      TYPE STANDARD TABLE OF mspr,
            lt_char_num  TYPE STANDARD TABLE OF bapi1003_alloc_values_num,
            lt_char_char TYPE STANDARD TABLE OF bapi1003_alloc_values_char,
            lt_char_curr TYPE STANDARD TABLE OF bapi1003_alloc_values_curr,
            l_objkey     TYPE bapi1003_key-object,
            l_classnum   TYPE bapi1003_key-classnum,
            l_atnam      TYPE atnam.

      REFRESH lt_chvw.

    *     Get material document items
      SELECT *
          FROM mseg
          INTO TABLE lt_mseg
          WHERE mblnr = l_mblnr.

    *     Perpare docubatch registration data
      LOOP AT it_goodsreceipt_item ASSIGNING <goods_rec_item>.
    *       Generate class num and atnam from plant
        CONCATENATE 'PI_' <goods_rec_item>-plant INTO l_classnum.
        CONCATENATE 'Z_DOC_BATCH_' <goods_rec_item>-plant INTO l_atnam.

    *       Get material docubatch usage characteristic
        REFRESH: lt_return,
                 lt_char_num,
                 lt_char_char,
                 lt_char_curr.

        l_objkey(18) = <goods_rec_item>-material.
        CALL FUNCTION 'BAPI_OBJCL_GETDETAIL'
          EXPORTING
            objectkey       = l_objkey
            objecttable     = 'MARA'
            classnum        = l_classnum
            classtype       = '001'
          TABLES
            allocvaluesnum  = lt_char_num
            allocvalueschar = lt_char_char
            allocvaluescurr = lt_char_curr
            return          = lt_return.
        LOOP AT lt_return ASSIGNING <return> WHERE type = 'E'. "Check for errors
    *         Couldn't read characteristic, assume no docubatch handling
          e_docbatch_subrc = '1'.
          e_docbatch_msg_idno = <return>-id && <return>-number.
          e_classnum = l_classnum.
          e_objkey = l_objkey.
          CONTINUE.
        ENDLOOP.

        READ TABLE lt_char_char ASSIGNING <char_char> WITH KEY charact = l_atnam.
        IF sy-subrc <> 0 OR <char_char>-value_neutral = 0.
    *         No docubatch value
          CONTINUE.
        ENDIF.



    *       Get associated material document item
        READ TABLE lt_mseg ASSIGNING <mseg>
              WITH KEY mblnr = ls_headret-mat_doc
                       mjahr = ls_headret-doc_year
                       bwart = <goods_rec_item>-move_type
                       matnr = <goods_rec_item>-material
                       werks = <goods_rec_item>-plant
                       menge = <goods_rec_item>-entry_qnt
                       meins = <goods_rec_item>-entry_uom
                       hsdat = <goods_rec_item>-prod_date
                       kzbew = <goods_rec_item>-mvt_ind
                       lgort = <goods_rec_item>-stge_loc.
        IF sy-subrc <> 0.
    *         No associated material document item
          CONTINUE.
        ENDIF.

    *       Check docubatch type
        IF <char_char>-value_neutral <> 0.
    *         Perform basic docubatch actions (MCHA and MCH1)
    *         Verify that docubatch nr is assigned
          IF <goods_rec_item>-vendrbatch IS INITIAL.
    *            !!!!!!!!!!!!! Venderbatch not filled even though material is docubatch managed, what to do? !!!!!!!!!!!!!!!
            CONTINUE.
          ENDIF.

    *         Prepare data for docubatch registration
          CLEAR: ls_mch1,
                 ls_mcha.

          ls_mch1-matnr = <goods_rec_item>-material.
          ls_mch1-charg = <goods_rec_item>-vendrbatch.
          ls_mch1-ersda = sy-datum.
          ls_mch1-ernam = sy-uname.
          ls_mch1-ersda_tmstp = sy-datum && sy-uzeit.
          ls_mch1-ersda_tz_sys = sy-tzone.
          ls_mch1-ersda_tz_usr = sy-zonlo.

          MOVE-CORRESPONDING ls_mch1 TO ls_mcha. "Same fields from MCH1 are included in MCHA
          ls_mcha-werks = <goods_rec_item>-plant.

          APPEND: ls_mch1 TO lt_mch1,
                  ls_mcha TO lt_mcha.
        ENDIF.

        IF <char_char>-value_neutral = 2. "Also include batch where-used
    *         Perpare data for batch where-used registration
          CLEAR ls_chvw.
          ls_chvw-matnr = <goods_rec_item>-material.
          ls_chvw-werks = <goods_rec_item>-plant.
          ls_chvw-charg = <goods_rec_item>-vendrbatch.
          ls_chvw-ebeln = <goods_rec_item>-po_number.
          ls_chvw-ebelp = <goods_rec_item>-po_item.
          ls_chvw-mblnr = ls_headret-mat_doc.
          ls_chvw-mjahr = ls_headret-doc_year.
          ls_chvw-zeile = <mseg>-zeile.
          ls_chvw-budat = is_goodsreceipt_head-pstng_date.
          ls_chvw-shkzg = 'S'. "??? VALUE ???
          ls_chvw-bwart = <goods_rec_item>-move_type.
          ls_chvw-kzbew = <goods_rec_item>-mvt_ind. "Goods Movement for Purchase Order
          ls_chvw-menge = <goods_rec_item>-entry_qnt.
          ls_chvw-meins = <goods_rec_item>-entry_uom.
          APPEND ls_chvw TO lt_chvw.
        ENDIF.
      ENDLOOP.

    *     Perform batch registration
      CALL FUNCTION 'VB_INSERT_BATCH'
        TABLES
          zmch1         = lt_mch1
          zmcha         = lt_mcha
          zmchb         = lt_mchb
          zmska         = lt_mska
          zmspr         = lt_mspr
                .

    *     Perform batch where-used registration
      CALL FUNCTION 'VB_BATCH_WHERE_USED_LIST'
        TABLES
          xchvw = lt_chvw.

为什么这还不够好,我需要的是

这作为配置了文档批处理的MIGO的快照执行,但不一定涵盖所有情况。

它只在购买文档的上下文中工作,不包括其他情况,例如订单和销售订单。

此外,我只有必要的日期,因为上面正在创建的材料文档,这不是所有的实现案例都可能的。

我想知道是否有一种从自定义代码执行文件批处理的有意方法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-30 13:47:31

引用文献资料

如果您使用RFID或TRM功能,或者调用IDocs/BAPI,您只能通过事先调用具有RFC功能的功能模块VBDBDM_DATA_MAINTAIN_RFC或将其合并到流程中,在文档批中预订。

也许这个功能模块是关键?然而,似乎你并不是第一个经历这种痛苦的人。对该文件的评论如下:

文件批次有很多限制,它似乎是SAP的半成品,因为缺少了很多真正批次的特性。 准备做很多定制的增强..。

来自社区的增编:以下是这个答案两天后从原海报上拿出的解决方案,移开了他的问题。

解决方案

采购订单、货物收据的呼叫示例

代码语言:javascript
复制
  LOOP AT it_goodsreceipt_item ASSIGNING <goods_rec_item>.

    CALL FUNCTION 'VBDBDM_DATA_MAINTAIN_RFC'
      EXPORTING
        i_matnr            = <goods_rec_item>-material
        i_werks            = <goods_rec_item>-plant
        i_quantity         = <goods_rec_item>-entry_qnt
        i_uom              = <goods_rec_item>-entry_uom
        i_docubatch_charg  = <goods_rec_item>-vendrbatch
*       IT_DOCUBATCHES     =
        i_process_id       = '01' "Goods Receipt for External Procurement
*       I_REPLACE_EXISTING_DATA       =
        i_ebeln            = <goods_rec_item>-po_number
        i_ebelp            = <goods_rec_item>-po_item
*       I_AUFNR            =
*       I_AUFPS            =
*       I_RSNUM            =
*       I_RSPOS            =
*       I_RSART            =
*       I_VBELN            =
*       I_POSNR            =
*       IS_DOCUBATCH_COM   =
*       I_LINE_ID          =
*       I_LGNUM            =
*       I_TANUM            =
*       I_TAPOS            =
      EXCEPTIONS
        parameter_error    = 1
        process_not_active = 2.
  ENDLOOP.

* Follow up by creating Material Document, for example through BAPI_GOODSMVT_CREATE
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58626204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档