SAP中使用BAPI_PO_CREATE1或BAPI_PO_CHANGE更新EAN11字段或其他不存在于BAPI中字段

最近在项目上遇到一个需求,需要在BAPI中更新PO明细上的EAN11字段,由于标准BAPI中并不支持更新该字段,所以考虑在标准预留增强结构(CI_EKPODB)中加入该字段,通过BAPI的EXTENSIONIN传入后,在BADI(ME_PROCESS_PO_CUST)的IF_EX_ME_PROCESS_PO_CUST~PROCESS_ITEM方法中通过SET_DATA方法进行更新,但经过实际尝试,发现依然无法更新该字段,于是开始查阅各种资料,经过调查,官方note中给的建议是前台去更改这个字段:

但是还是想再找找有没有别的解决方案,调试完标准代码,发现是如下逻辑决定了无法更新该字段:

首先在标准BAPI(创建和更新BAPI中结构mapping逻辑相同)中该子例程是将传入参数mapping到标准结构,其中包括增强字段的mapping

在做完数据mapping后,开始实例化后续BADI中用到的OO对象

在此例程中,lt_item和lt_itemx为mapping之后包含EKPO中所有字段的内表,会在此form中通过set_data,set_datax的方式将数据写入OO对象,关键点在于这两个方法中的处理逻辑决定了哪些字段会被传入OO对象

在这段循环中,是具体实现将BAPI传入字段传入到最终更改对象列表中的逻辑,而具体匹配的方法在下面这两个方法中

在merge方法中,将传入参数传递到最终更改使用结构中

我们通过实际数据来debug看一下具体是怎么运行的:

以这条数据为例:

然后在BAPI中将对应的值改为新值,在进入到断点时可以看到如下参数

然而标准逻辑中使用的更新结构MEPOITEM_DATA中并不包括EAN11字段,所以执行后无法将传入的EAN11的值更新至目标结构中,所以在后面set_data的时候,使用的ls_item_new中并不会包含EAN11的最新值,依然是原有的值

而在标准BADI的IF_EX_ME_PROCESS_PO_CUST~PROCESS_ITEM使用的SET_DATA方法中也是同样的处理逻辑,

所以解决思路就是在set_data以及set_datax时将ls_item_new中的值更新为BAPI传入的值,完整解决方式如下:

1.在标准BAPI预留的扩张中添加要更新的字段

Tips:这里需要注意的是,增强字段最好加在CI_EKPODB以及CI_EKPODBX中,这样在BAPI_TE_MEPOITEMBAPI_TE_MEPOITEMX中会默认包含进去,而且会有标准form去处理映射,在BAPI中的标准form move_data_in 中会看到具体的映射方法,里面写死了check的结构名是CI_EKPODB以及其他等标准结构,如果是增强在CI_EKPODB以及CI_EKPODBX中,下面这段增强可以跳过,本例由于增强字段是通过CLOUD平台添加的,所以增强字段不在CI_EKPODB中,那么需要额外做一个增强才可以将字段正确映射,否则无法更新增强字段,增强实现如下:

1.实施BADI ME_BAPI_PO_CUST

2.创建实施类ZCL_ME_BAPI_PO_CUST

3.实施方法IF_EX_ME_BAPI_PO_CREATE_02~EXTENSIONIN

这里参照标准逻辑,创建一个私有方法MOVE_CONTAINER_IN来将BAPIPAREX中的VALUE部分解析到对应的结构中

IF_EX_ME_BAPI_PO_CREATE_02~EXTENSIONIN中完整代码如下:

METHOD IF_EX_ME_BAPI_PO_CREATE_02~EXTENSIONIN.
*    BREAK SHIN063.

*   将VBAK/VBAP增强字段转入POHEADER,POHEADERX,POITEM,POITEMX
    CHECK EXTENSIONIN IS NOT INITIAL.

    DATA:
      WA_BAPI_TE_MEPOHEADER   TYPE BAPI_TE_MEPOHEADER,
      WA_BAPI_TE_MEPOHEADERX  TYPE BAPI_TE_MEPOHEADERX,
      WA_BAPI_TE_MEPOITEM     TYPE BAPI_TE_MEPOITEM,
      WA_BAPI_TE_MEPOITEMX    TYPE BAPI_TE_MEPOITEMX,
      WA_BAPI_TE_MEPOACCOUNT  TYPE BAPI_TE_MEPOACCOUNTING,
      WA_BAPI_TE_MEPOACCOUNTX TYPE BAPI_TE_MEPOACCOUNTINGX,
      L_CONTAINER             TYPE ME_MAX_CONTAINER,
      LR_PAREX                TYPE REF TO CL_NLS_STRUC_CONTAINER.

    LR_PAREX = CL_MMPUR_BAPI_PO=>GET_CODEPAGE_HANDLER( ).

    LOOP AT EXTENSIONIN INTO DATA(LS_EXTENSIONIN).
      L_CONTAINER = LS_EXTENSIONIN+30.
      CASE LS_EXTENSIONIN-STRUCTURE.
        WHEN 'BAPI_TE_MEPOHEADER'.
*         将增强字段转换为可读结构
          CALL METHOD ME->MOVE_CONTAINER_IN
            EXPORTING
              I_CONTAINER = L_CONTAINER
              I_NLS       = LR_PAREX
            CHANGING
              E_STRUC     = WA_BAPI_TE_MEPOHEADER.
          MOVE-CORRESPONDING WA_BAPI_TE_MEPOHEADER TO POHEADER.
        WHEN 'BAPI_TE_MEPOHEADERX'.
*         将增强字段转换为可读结构
          CALL METHOD ME->MOVE_CONTAINER_IN
            EXPORTING
              I_CONTAINER = L_CONTAINER
              I_NLS       = LR_PAREX
            CHANGING
              E_STRUC     = WA_BAPI_TE_MEPOHEADERX.
          MOVE-CORRESPONDING WA_BAPI_TE_MEPOHEADER TO POHEADERX.
        WHEN 'BAPI_TE_MEPOITEM'.
*         将增强字段转换为可读结构
          CALL METHOD ME->MOVE_CONTAINER_IN
            EXPORTING
              I_CONTAINER = L_CONTAINER
              I_NLS       = LR_PAREX
            CHANGING
              E_STRUC     = WA_BAPI_TE_MEPOITEM.

          IF WA_BAPI_TE_MEPOITEM-PO_ITEM = POITEM-EBELP.
            ASSIGN POITEM TO FIELD-SYMBOL(<FS_POITEM>).
            MOVE-CORRESPONDING WA_BAPI_TE_MEPOITEM TO <FS_POITEM>.
          ENDIF.
        WHEN 'BAPI_TE_MEPOITEMX'.
*         将增强字段转换为可读结构
          CALL METHOD ME->MOVE_CONTAINER_IN
            EXPORTING
              I_CONTAINER = L_CONTAINER
              I_NLS       = LR_PAREX
            CHANGING
              E_STRUC     = WA_BAPI_TE_MEPOITEMX.

            IF WA_BAPI_TE_MEPOITEMX-PO_ITEM = POITEMX-EBELP_KEY.
              ASSIGN POITEMX TO FIELD-SYMBOL(<FS_POITEMX>).
              MOVE-CORRESPONDING WA_BAPI_TE_MEPOITEMX TO <FS_POITEMX>.
            ENDIF.
        WHEN OTHERS.

      ENDCASE.
    ENDLOOP.
  ENDMETHOD.

MOVE_CONTAINER_IN中完整代码如下:

  METHOD MOVE_CONTAINER_IN.
    TRY.
        ASSIGN E_STRUC TO FIELD-SYMBOL(<FS_STRUC>).
*       convert container data to target structure
        I_NLS->CONT_TO_STRUC( EXPORTING CONT   = I_CONTAINER
                                        LANGU  = SY-LANGU
                              IMPORTING STRUC  = <FS_STRUC> ).
      CATCH CX_ROOT.                             "#EC *
    ENDTRY.
  ENDMETHOD.

第一个增强结束,继续后续操作

2.在include L2012F25的set_object_attributes子例程中进行如下增强,系统预留了标准的增强点

3.在BAPI调用时将EAN11放在EXTENSIONIN中

至此,所有增强完成,可以使用BAPI来进行EAN11的更新,验证一下:

更新前

BAPI赋值测试(项目封装函数,里面调用BAPI_PO_CREATE1/BAPI_PO_CHANGE)

更新后

以上。

2021/07/19日追加,由于这种四代增强在以后升级中会有丢失的风险,考虑到这个影响,所以后来采用实现方式为,将标准BAPI复制一份出来,修改其中子例程,配合EXTENSIONIN实现,具体如下:

将copy出来的标准form替换为自定义form

在自定义form中添加如下逻辑:

将扩张字段更改为ZZEAN11,避免以后升级后系统支持更新EAN11的更新造成冲突 ,在BADI增强中添加如下逻辑进行字段映射

以上。

SAP BAPI_PO_CREATE1是一个SAP系统中的功能模块,用于创建采购订单(Purchase Order)。通过该功能模块,我们可以使用SAP系统来快速创建和维护采购订单的相关数据。 使用BAPI_PO_CREATE1,我们可以通过调用该功能模块来向SAP系统中创建新的采购订单。在调用该功能模块时,我们需要提供一些必要的输入参数,如采购订单的相关信息、采购组织和公司代码等。 这个功能模块可以帮助我们在SAP系统中自动化采购订单的创建流程。它可以根据输入的参数,自动生成采购订单,并将相关的物料、供应商和价格等信息添加到订单中。 通过使用BAPI_PO_CREATE1,我们可以实现以下功能: 1. 创建采购订单:我们可以通过调用该功能模块来创建新的采购订单。在调用时,我们需要提供订单的相关信息,如供应商、物料、数量、交货日期等。系统会根据提供的信息自动创建采购订单。 2. 修改采购订单:除了创建新的采购订单,我们还可以使用BAPI_PO_CREATE1来修改现有的采购订单。在调用时,我们需要提供订单的标识符和要修改的字段及对应的值。系统将根据提供的信息来更新采购订单的数据。 3. 检查采购订单:在调用BAPI_PO_CREATE1之前,我们可以先使用BAPI_PO_EXISTENCE_CHECK来检查采购订单是否存在。这可以帮助我们避免重复创建订单更新存在的订单。 总而言之,SAP BAPI_PO_CREATE1是一个用于创建和维护采购订单的功能模块。它可以帮助我们在SAP系统中实现自动化的采购订单处理,并提高采购过程的效率和准确性。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeveloperMrMeng

觉得有用的佛系投币哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值