更新MARA表的最佳解决方案是什么?

时间:2016-10-31 01:18:58

标签: abap

我今天遇到了一个问题:如何使用custo和非custo字段更新mara表?

我找到了一些解决方案,但我想知道什么是最佳解决方案?

我来自HCM模块。在这个模块中,我们有更改日志。所以如果可能的话,我想用日志更改来更新mara表。

上下文

  1. 从表格中选择一个mara条目(确定)
  2. 编辑字段(确定)
  3. 检查每个字段,如果新值已经在可用值
  4. 更新表格
  5. 逻辑:

    DATA:
      lt_mara TYPE TABLE OF mara,
      ls_mara TYPE mara.
    
    lv_matnr = '000000000024856';
    
    * Seelct data
    "" matnr from CONVERSION_EXIT_MATN1_INPUT
    SELECT SINGLE * INTO ls_mara FROM mara WHERE matnr = lv_matnr.
    
    * Modification
    ls_mara-vlumn = '999.9'. 
    "ls_mara-z* = '...'.   
    
    * Checks : volumn is numeric, ...
    " [...]
    
    * Update
    " [...]
    

    有关信息,我只有关于mara的信息。没有关于相关表格的数据。

    解决方案1 ​​ - MATERIAL_MAINTAIN_DARK

    使用功能模块MATERIAL_MAINTAIN_DARK

    CALL FUNCTION 'MATERIAL_MAINTAIN_DARK'
        EXPORTING
            kz_activ_cad = blank
            flag_muss_pruefen = fest_x
            sperrmodus = fest_e
            max_errors = 0
            p_kz_no_warn = fest_x " 'N' ?
            kz_prf = blank " 's' ?
            kz_verw = fest_x
            kz_aend = fest_x
            kz_dispo = fest_x
            kz_test = blank
            kz_mdip = blank
            kz_mprp = blank
            kz_ale = blank
            kz_actv = blank
        TABLES
            AMARA_UEB = TMARA_UEB
            AMERRDAT = lt_amerrdat
        EXCEPTIONS
            OTHERS = 7.
    
    " Loop lt_amerrdat.
    "   CALL FUNCTION 'RPY_MESSAGE_COMPOSE' [...]
    "     WRITE:/ lv_errmsg.
    
    " ROLLBACK WORK.
    " or
    " CALL FUNCTION 'DB_COMMIT'.
    

    (我使用了代码逻辑https://archive.sap.com/discussions/thread/169786

    问题:我成功执行了代码...但现在我发现了一些功能错误。如果我正确理解了这个FM的功能,修改将通过T_CODE(即:MM01 / 02/03)执行。 但是,我不知道每行的初始T_CODE是什么,我有功能问题(即:文章类别不正确,......)取决于使用的T_CODE。

    你知道我怎么能跳过这些检查吗?或者知道最初的T_CODE?

    解决方案2 - BAPI_MATERIAL_SAVEDATA

    使用功能模块BAPI_MATERIAL_SAVEDATA。 此FM允许使用标准字段+ custo(通过EXTENSION(X))

    更新MARA表

    有关信息,我的BAPI_TE_MARA& BAPI_TE_MARAX看起来像:

    • MATERIAL(MATNR,char,18)
    • .APPEND(ZBAPI_TE_MARAX)
    • NOCHANGE(BAPIUPDATE,char,1)

    我想在使用此FM之前,我必须在其上添加每个Z *字段? 而且,我没有找到更新表格字段的解决方案。如果我正在检查FM,我有一些对象,但列名称不一样。 如何找到此FM上的字段与MARA表中字段之间的映射?

    解决方案3

    我是否在代码上检查完整性,我想我可以使用简单的INSERT / UPDATE(MODIFY)? 这应该是最简单的解决方案。

    CONCATENATE sy-mandt lv_matnr INTO lv_mara_key.
    
    " Lock object
    CALL FUNCTION 'ENQUEUE_E_TABLE'
        EXPORTING
            MODE_RSTABLE   = 'E'
            tabname        = 'MARA'
            varkey         = lv_mara_key
        EXCEPTIONS
            foreign_lock   = 1      system_failure = 2      OTHERS = 3.
    
    ls_mara-ernam = sy-uname.
    " ...
    " std & custo
    
    MODIFY mara FROM ls_mara.
    
    " Unlock object
    CALL FUNCTION 'DEQUEUE_E_TABLE'
        EXPORTING
            MODE_RSTABLE   = 'E'
            tabname        = 'MARA'
            varkey         = lv_mara_key
        EXCEPTIONS
            foreign_lock   = 1      system_failure = 2      OTHERS = 3.
    

    如果对所有建议,教程或建议感兴趣:)

5 个答案:

答案 0 :(得分:4)

解决方案2.期间。有关详细信息,请参阅@chrisian和@ dirk-trilsbeek的精彩评论。

关于您对字段映射的后续问题。用户友好的名称对于使用SAP外部BAPI的用户来说非常好,但是它们确实难以映射到我们在SAP内部知道的字段。幸运的是,SAP在这些情况下大多数时间使用相同的数据元素,因此这是匹配它们的一种方法。否则,不同的BAPI通常具有转换功能模块以从BAPI字段转换到数据库字段。对于您提到的材料BAPI,您可以检查子程序< TABLE> _UEBERGEBEN(这转换为< TABLE> _TRANSFER),其中< TABLE>是MARA,MARC等。注意,例如MARA_UEBERGEBEN例程调用FM MAP2I_BAPI_MARA_TO_MARA_UEB,并且该FM具有从BAPI结构到MARA的转换,例如, NET_WEIGHT映射到NTGEW。

答案 1 :(得分:1)

使用解决方案1,这些自定义字段应事先分配给组!这应该通过路径定制:

Logistic General->材料大师 - >场选择 - >将字段分配给字段选择组

如果还没有组,您应该创建新组。该组确定何时启用/禁用/激活/非活动等字段。 代码应如下所示:

CALL FUNCTION 'MATERIAL_MAINTAIN_DARK'
 EXPORTING
  sperrmodus = ' '
  kz_prf = 'W'
  max_errors = ' '
  p_kz_no_warn = 'X'
  kz_verw = 'X'
  kz_aend = 'X'
  kz_dispo = 'X'
  kz_test = ' '
  flag_muss_pruefen = ' '
  call_mode = 'ACT'
 IMPORTING
  matnr_last = w_matnr_last
  number_errors_transaction = w_nb_errors
 TABLES
  amara_ueb = t_amara_ueb
  amarm_ueb = t_amarm_ueb
 EXCEPTIONS
  kstatus_empty = 1
  tkstatus_empty = 2
  t130m_error = 3
  internal_error = 4
  too_many_errors = 5
  update_error = 6
 OTHERS = 7.

 IF sy-subrc <> 0.
  MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO.
 ELSE.
  COMMIT WORK.
 ENDIF.

答案 2 :(得分:1)

解决方案#3在SAP系统中只是无效选项

答案 3 :(得分:0)

解决方案1和2都很好。在您使用其中一个FM更改标准字段后,您可以直接填写自定义字段,就像在解决方案3中一样。

答案 4 :(得分:0)

最后这是解决方案选择。我们使用BAPI_MATERIAL_SAVEDATA扩展名。 我评论了代码,如果你想使用它可以帮助你:)

FORM update_mara
  USING
    us_result TYPE mara. "Input entry of mara with masterdata to update in the system

  DATA :  ls_mara           TYPE bapi_te_mara,
          ls_head           TYPE bapimathead,
          lt_extensionin    TYPE TABLE OF bapiparex,
          ls_extensionin    TYPE bapiparex,
          lt_extensioninx   TYPE TABLE OF bapiparexx,
          ls_extensioninx   TYPE bapiparexx,
          ls_return         TYPE bapiret2,
          lv_x              TYPE char41,
          lv_mara           TYPE string. "Container for all data of ls_mara

  " MASTERDATA PART
  MOVE-CORRESPONDING us_result TO ls_mara.
  ls_mara-material = ls_head-material = us_result-matnr.
  "At least the mendatory key field: 'material'

  " DATA PART
  " Use extension BAPI_TE_MARA
  ls_extensionin-structure = 'BAPI_TE_MARA'.
  lv_mara = ls_mara.
  " Fill data into the extension
  ls_extensionin+30(960) = lv_mara.
  APPEND ls_extensionin TO lt_extensionin.

  " FLAG PART
  CLEAR lv_x.
  DO 41 TIMES. "Don't forget to change 'lv_x TYPE char41' if needed
    CONCATENATE lv_x 'X' INTO lv_x.
    "Add an 'X' where you want to activate the update
    "Here, it's for all fields
  ENDDO. " End of the do loop for all fields of the mara

  " Use extension BAPI_TE_MARAX
  ls_extensioninx-structure  = 'BAPI_TE_MARAX'.
  ls_extensioninx-valuepart1(18)  = us_result-matnr.
  ls_extensioninx-valuepart1+19   = lv_x.
  " The first part (18) of the extensioninx is the matnr and the next ones some 'X' flags to activate the update or not.
  APPEND ls_extensioninx TO lt_extensioninx.

  " PROCESS PART
  CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA'
    EXPORTING
      headdata     = ls_head
    IMPORTING
      return       = ls_return
    TABLES
      extensionin  = lt_extensionin
      extensioninx = lt_extensioninx
  .

  IF ls_return-type = 'E'.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
  ELSE.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait = 'X'.
  ENDIF.  " End if of check of BAPI result

ENDFORM.                    " UPDATE_MARA