更新 MARA table 的最佳解决方案是什么?
What is the best solution to update the MARA table?
我今天遇到一个问题:如何使用自定义和非自定义字段更新 MARA table?
我找到了一些解决方案,但我想知道最好的解决方案是什么。
我来自HCM模块。在这个模块上,我们有更新日志。因此,如果可能的话,我想用日志更改来更新 MARA table。
上下文:
- Select table 中的一个 MARA 条目(确定)
- 编辑字段(确定)
- 检查每个字段,如果新值已经在可用值上
- 更新table
逻辑:
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 的信息,没有相关 tables 的数据。
解决方案 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 的功能,修改将通过 tcode 执行(即:MM01/02/03)。
但是,我不知道每一行的初始 tcode 是什么,并且我有功能问题(即:文章类别不正确,...),具体取决于所使用的 tcode。
你知道我怎样才能跳过这些检查吗?或者知道初始 tcode?
解决方案 2 - BAPI_MATERIAL_SAVEDATA
使用功能模块BAPI_MATERIAL_SAVEDATA
。
此 FM 允许使用标准字段 + 自定义更新 MARA table(通过 EXTENSION(X))
有关信息,我的 BAPI_TE_MARA
& BAPI_TE_MARAX
看起来像:
- MATERIAL(MATNR,字符,18)
- .APPEND (ZBAPI_TE_MARAX)
- NOCHANGE (BAPIUPDATE, char, 1)
我想在使用这个 FM 之前我必须在上面添加每个 Z* 字段?
此外,我没有找到更新 table 字段的解决方案。如果我正在检查 FM,我有一些对象,但列名不一样。
我如何才能找到此 FM 上的字段与 MARA table 上的字段之间的映射?
解决方案 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.
我对所有推荐、教程或建议感兴趣 :)
使用解决方案 1,但是 这些自定义字段应该事先分配给组!这应该在自定义路径中完成:
Logistic General->MaterialMaster->Field Selection->Assign fields to field selection group
如果还没有群组,您应该创建新群组。该组确定字段何时为 enabled/disabled/active/inactive 等。
代码应如下所示:
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. 期间。有关详细信息,请参阅@chrisian 和@dirk-trilsbeek 的精彩评论。
关于您关于字段映射的后续问题。对用户更友好的名称非常适合在 SAP 外部使用 BAPI 的人,但它们确实很难映射到我们在 SAP 内部知道的字段。幸运的是,SAP 在这些情况下大部分时间都使用相同的数据元素,因此这是匹配它们的一种方式。另外,不同的BAPI往往有转换功能模块,将BAPI字段转换成数据库字段。对于您提到的 material BAPI,您可以检查子例程
_UEBERGEBEN(转换为 _TRANSFER),其中 是 MARA、MARC 等。请注意,例如 MARA_UEBERGEBEN 例程调用 FM MAP2I_BAPI_MARA_TO_MARA_UEB 并且此 FM 具有从 BAPI 结构到 MARA 的转换,例如NET_WEIGHT 映射到 NTGEW。
方案一和方案二都不错。在使用其中一个 FM 更改标准字段后,您可以直接填写自定义字段,就像您在解决方案 3 中所做的那样。
最后选择的解决方案是这样的。我们使用 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
解决方案 #3 在 SAP 系统中不是一个有效的选项。
我今天遇到一个问题:如何使用自定义和非自定义字段更新 MARA table?
我找到了一些解决方案,但我想知道最好的解决方案是什么。
我来自HCM模块。在这个模块上,我们有更新日志。因此,如果可能的话,我想用日志更改来更新 MARA table。
上下文:
- Select table 中的一个 MARA 条目(确定)
- 编辑字段(确定)
- 检查每个字段,如果新值已经在可用值上
- 更新table
逻辑:
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 的信息,没有相关 tables 的数据。
解决方案 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 的功能,修改将通过 tcode 执行(即:MM01/02/03)。 但是,我不知道每一行的初始 tcode 是什么,并且我有功能问题(即:文章类别不正确,...),具体取决于所使用的 tcode。
你知道我怎样才能跳过这些检查吗?或者知道初始 tcode?
解决方案 2 - BAPI_MATERIAL_SAVEDATA
使用功能模块BAPI_MATERIAL_SAVEDATA
。
此 FM 允许使用标准字段 + 自定义更新 MARA table(通过 EXTENSION(X))
有关信息,我的 BAPI_TE_MARA
& BAPI_TE_MARAX
看起来像:
- MATERIAL(MATNR,字符,18)
- .APPEND (ZBAPI_TE_MARAX)
- NOCHANGE (BAPIUPDATE, char, 1)
我想在使用这个 FM 之前我必须在上面添加每个 Z* 字段? 此外,我没有找到更新 table 字段的解决方案。如果我正在检查 FM,我有一些对象,但列名不一样。 我如何才能找到此 FM 上的字段与 MARA table 上的字段之间的映射?
解决方案 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.
我对所有推荐、教程或建议感兴趣 :)
使用解决方案 1,但是 这些自定义字段应该事先分配给组!这应该在自定义路径中完成:
Logistic General->MaterialMaster->Field Selection->Assign fields to field selection group
如果还没有群组,您应该创建新群组。该组确定字段何时为 enabled/disabled/active/inactive 等。 代码应如下所示:
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. 期间。有关详细信息,请参阅@chrisian 和@dirk-trilsbeek 的精彩评论。
关于您关于字段映射的后续问题。对用户更友好的名称非常适合在 SAP 外部使用 BAPI 的人,但它们确实很难映射到我们在 SAP 内部知道的字段。幸运的是,SAP 在这些情况下大部分时间都使用相同的数据元素,因此这是匹配它们的一种方式。另外,不同的BAPI往往有转换功能模块,将BAPI字段转换成数据库字段。对于您提到的 material BAPI,您可以检查子例程