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

Abap 更新MARA表的最佳解决方案是什么?,abap,sap-data-dictionary,Abap,Sap Data Dictionary,今天我面临一个问题:如何使用自定义和非自定义字段更新MARA表 我找到了一些解决方案,但我想知道什么是最好的解决方案 CONCATENATE sy-mandt lv_matnr INTO lv_mara_key. " Lock object CALL FUNCTION 'ENQUEUE_E_TABLE' EXPORTING MODE_RSTABLE = 'E' tabname = 'MARA' varkey

今天我面临一个问题:如何使用自定义和非自定义字段更新MARA表

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

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.
我来自HCM模块。在这个模块上,我们有变更日志。因此,如果可能的话,我想用日志更改来更新MARA表

上下文:

  • 从表中选择一个MARA条目(确定)
  • 编辑字段(确定)
  • 如果新值已在可用值上,请检查每个字段
  • 更新表
  • 逻辑:

    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-
    材料\u维护\u黑暗
    使用功能模块
    材料维护\u黑暗

    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'.
    
    (我使用了这种代码逻辑)

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

    你知道我怎么跳过这些支票吗?或者知道初始tcode

    解决方案2-
    BAPI\u物料\u保存数据
    使用功能模块
    BAPI\u MATERIAL\u SAVEDATA
    。 此FM允许使用标准字段+自定义(通过扩展名(X))更新MARA表

    有关信息,我的
    BAPI_TE_MARA
    BAPI_TE_MARAX
    如下所示:

    • 材料(材料编号、半焦、18)
    • .APPEND(ZBAPI_TE_MARAX)
    • 无更改(BAPIUPDATE,char,1)
    我想我必须在它上面加上每个Z*字段,然后才能使用这个FM? 此外,我没有找到更新表字段的解决方案。如果我检查FM,我有一些对象,但列名称不相同。 如何找到此FM上的字段与MARA表上的字段之间的映射

    解决方案3 如果我检查了代码的完整性,我想我可以使用一个简单的插入/更新(修改)? 这应该是最简单的解决方案

    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.
    

    我对所有建议、教程或建议感兴趣:)

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

    物流常规->物料主数据->字段选择->将字段分配给字段选择组

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

    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.
    
    调用函数'MATERIAL\u mainter\u DARK'
    出口
    sperrmodus=“”
    kz_prf='W'
    最大错误=“”
    p_kz_no_warn='X'
    kz_verw='X'
    kz_aend='X'
    kz_dispo='X'
    kz_检验=“”
    旗帜_muss_pruefen=''
    调用模式='ACT'
    进口
    最后一次材料=最后一次材料
    数字\u错误\u事务=w\u nb\u错误
    桌子
    amara_ueb=t_amara_ueb
    amarm_ueb=t_amarm_ueb
    例外情况
    kstatus_empty=1
    tkstatus_empty=2
    t130m_误差=3
    内部错误=4
    错误太多=5
    更新错误=6
    其他=7。
    如果sy subrc为0。
    消息ID SY-MSGID类型SY-MSGTY编号SY-MSGNO。
    其他的
    投入工作。
    恩迪夫。
    
    解决方案2。时期有关详细信息,请参阅@chrisian和@dirk trilsbeek的精彩评论


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

    解决方案1和2都很好。在使用一个FMs更改标准字段后,您可以像在解决方案3中那样直接填充客户字段。

    最后,这是选择的解决方案。我们使用了带有扩展名的
    BAPI\u MATERIAL\u SAVEDATA
    。 我对代码进行了注释,以帮助您使用它:)


    解决方案#3在SAP系统中根本不是一个有效的选项。

    我会选择解决方案2。除非您知道不应该更新其他相关表,否则不建议使用解决方案3。您好。谢谢事实上,不会涉及其他表格。除了MARA表,我没有其他信息。方法:大量上传mara数据。另一方面,将使用另一个程序或手动过程。我没有找到任何关于Sol 2的好文档。你有一个吗?解决方案2是三个方案中最好的。BAPI是SAP的官方接口,因此您有一个可靠的连接,在更新或升级后可能不会改变,而内部功能模块可能会改变。BAPI中的字段名是不同的,但是如果您查看函数模块声明,就会发现它们使用相同的数据类型。大多数情况下,这已经足以将内部字段名映射到BAPI字段名。BAPI通常使用标准英文字段名,而表格通常使用5或6个字符长的字段名,通常使用德语。您可以使用
    描述字段类型数据(lv_类型)组件数据(lv_字段的lv_编号),而不是硬编码更新标志结构中的字段数(本例中为41个).
    然后
    执行lv\u字段数\u次。
    。这样,您的代码可以提高重用性,并避免将来可能发生的转储