{2022年10月14日新增内容:我的程序是在S4 1909上执行的,ECC系统也有可能只需要调用一次函数吧,具体问题具体分析}
{2022年5月6日新增内容:可能存在第二次调用函数失败的话,将返回的 lt_return2清空,然后再调用一次。}
这次项目遇到创建/修改采购信息记录,在网上查了一下资料,几乎全是使用BDC来创建或修改的。经过一下午的研究与测试,终于使用函数来创建或修改了采购信息记录,现在分享出来,希望能够对大家有所帮助。
说明:1.因为函数ME_INFORECORD_MAINTAIN不允许同时有净价和条件,所以需要分两次调用来实现创建/修改;
2.因为函数ME_INFORECORD_MAINTAIN报错不明显,返回的报错信息仅当参考,因为需要自己debug去看具体的报错原因,比如:如果单位错了,函数会报一个不相干的错误;
3.以下代码经过业务顾问测试了,稍作修改应该就可以用;
DATA:lv_mode TYPE c.
data:ls_eina type eina.
*-------------------------------------
DATA:i_eina TYPE mewieina,
i_einax TYPE mewieinax,
" i_einax TYPE mewieinax,
i_eine TYPE mewieine,
i_einex TYPE mewieinex.
DATA:lv_test TYPE bapiflag-bapiflag.
DATA:lt_return2 TYPE mewi_t_return,
ls_return2 LIKE LINE OF lt_return2.
DATA:lt_con_vali TYPE TABLE OF mewivalidity,
ls_con_vali TYPE mewivalidity.
DATA:lt_condition TYPE TABLE OF mewicondition,
ls_condition TYPE mewicondition.
DATA:e_eina TYPE mewieina,
e_eine TYPE mewieine.
DATA:ls_mara TYPE mara.
LOOP AT it_tab.
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING
input = it_tab-matnr
IMPORTING
output = it_tab-matnr
EXCEPTIONS
length_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
"补齐供应商的前导零
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = it_tab-lifnr
IMPORTING
output = it_tab-lifnr.
SELECT SINGLE * INTO CORRESPONDING FIELDS OF ls_eina
FROM eina
WHERE matnr = it_tab-matnr
AND lifnr = it_tab-lifnr.
IF sy-subrc <> 0.
lv_mode = 'I'."新增
ELSE.
SELECT SINGLE * INTO CORRESPONDING FIELDS OF ls_eine
FROM eine
WHERE infnr = ls_eina-infnr
AND ekorg = it_tab-ekorg "采购组织
AND esokz = it_tab-esokz "采购信息记录分类
AND werks = it_tab-werks."工厂
if sy-subrc = 0.
lv_mode = 'M'."修改
i_eina-info_rec = ls_eina-infnr."采购信息记录号
i_eine-info_rec = ls_eina-infnr."
i_einex-info_rec = 'X'.
i_einax-vendor = 'X'.
i_einax-material = 'X'.
else.
lv_mode = 'I'."新增
endif.
ENDIF.
i_eina-vendor = it_tab-lifnr."供应商
i_eina-material = it_tab-matnr."物料编码
"
i_eine-purch_org = it_tab-ekorg."采购组织
IF i_eine-purch_org IS NOT INITIAL.
i_einex-purch_org = 'X'.
ENDIF.
i_eine-info_type = it_tab-esokz."信息类别
IF i_eine-info_type IS NOT INITIAL.
i_einex-info_type = 'X'.
ENDIF.
i_eine-plant = it_tab-werks."工厂
IF i_eine-plant IS NOT INITIAL.
i_einex-plant = 'X'.
ENDIF.
i_eine-pur_group = it_tab-ekgrp."采购组
IF i_eine-pur_group IS NOT INITIAL.
i_einex-pur_group = 'X'.
ENDIF.
i_eine-currency = it_tab-waers."货币码
IF i_eine-currency IS NOT INITIAL.
i_einex-currency = 'X'.
ENDIF.
i_eine-tax_code = it_tab-mwskz."税码
IF i_eine-tax_code IS NOT INITIAL.
i_einex-tax_code = 'X'.
ENDIF.
i_eine-plnd_delry = it_tab-aplfz."计划交货时间(天)
IF i_eine-plnd_delry IS NOT INITIAL.
i_einex-plnd_delry = 'X'.
ENDIF.
i_eine-net_price = it_tab-netpr."净价
IF i_eine-net_price IS NOT INITIAL.
i_einex-net_price = 'X'.
ENDIF.
"对采购单位进行一次转换
CALL FUNCTION 'CONVERSION_EXIT_CUNIT_INPUT'
EXPORTING
input = it_tab-bprme
* LANGUAGE = SY-LANGU
IMPORTING
output = it_tab-bprme
EXCEPTIONS
unit_not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
"对单位进行校验
SELECT SINGLE * INTO ls_mara
FROM mara
WHERE matnr = it_tab-matnr.
IF sy-subrc = 0.
IF ls_mara-bstme IS NOT INITIAL.
IF ls_mara-bstme <> it_tab-bprme.
et_tab-zresult = 'E'.
et_tab-message = '采购单位与采购订单计量单位不一致'.
APPEND et_tab.
CLEAR et_tab.
CONTINUE.
ENDIF.
ELSE.
IF ls_mara-meins <> it_tab-bprme.
et_tab-zresult = 'E'.
et_tab-message = '采购单位与基本单位不一致'.
APPEND et_tab.
CLEAR et_tab.
CONTINUE.
ENDIF.
ENDIF.
ENDIF.
i_eine-orderpr_un = it_tab-bprme."采购单位
IF i_eine-orderpr_un IS NOT INITIAL.
i_einex-orderpr_un = 'X'.
ENDIF.
i_eine-price_unit = it_tab-peinh."价格单位
IF i_eine-price_unit IS NOT INITIAL.
i_einex-price_unit = 'X'.
ENDIF.
"i_eine-nrm_po_qty = '1'."标准采购订单数量
"i_einex-nrm_po_qty = 'X'.
ls_con_vali-plant = it_tab-werks."工厂
ls_con_vali-valid_from = it_tab-datab."有效起始日
ls_con_vali-valid_to = it_tab-datbi."有效截止日
APPEND ls_con_vali TO lt_con_vali.
ls_condition-cond_type = 'PB00'."固定值
ls_condition-currency = it_tab-waers."货币码
ls_condition-cond_value = it_tab-netpr."净价
ls_condition-cond_p_unt = it_tab-peinh."条件定价单位
ls_condition-cond_unit = it_tab-bprme."条件单位
APPEND ls_condition TO lt_condition.
lv_test = it_tab-zmark."是否测试,如果为'X',则为测试
CLEAR:lt_return2.
IF lv_mode = 'I'.
CALL FUNCTION 'ME_INFORECORD_MAINTAIN'
EXPORTING
i_eina = i_eina
* I_EINAX =
i_eine = i_eine
i_einex = i_einex
testrun = lv_test
IMPORTING
e_eina = e_eina
e_eine = e_eine
TABLES
* TXT_LINES =
* cond_validity = lt_con_vali
* condition = lt_condition
* COND_SCALE_VALUE =
* COND_SCALE_QUAN =
return = lt_return2.
READ TABLE lt_return2 INTO ls_return2 WITH KEY type = 'E'.
IF sy-subrc <> 0 AND lv_test = ''.
"创建时需要将数据写入到数据库里,不然报错
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
"因为净价和条件不能同时维护,所以分开维护
CLEAR:i_einex-net_price.
CLEAR:lt_return2.
i_eina-info_rec = e_eina-info_rec."采购信息记录号
i_eine-info_rec = e_eina-info_rec."
i_einex-info_rec = 'X'.
CALL FUNCTION 'ME_INFORECORD_MAINTAIN'
EXPORTING
i_eina = i_eina
* I_EINAX =
i_eine = i_eine
i_einex = i_einex
testrun = lv_test
IMPORTING
e_eina = e_eina
e_eine = e_eine
TABLES
* TXT_LINES =
cond_validity = lt_con_vali
condition = lt_condition
* COND_SCALE_VALUE =
* COND_SCALE_QUAN =
return = lt_return2.
ENDIF.
ELSE.
"对数据进行修改
CALL FUNCTION 'ME_INFORECORD_MAINTAIN'
EXPORTING
i_eina = i_eina
i_einax = i_einax
i_eine = i_eine
i_einex = i_einex
testrun = lv_test
IMPORTING
e_eina = e_eina
e_eine = e_eine
TABLES
* TXT_LINES =
* cond_validity = lt_con_vali
* condition = lt_condition
* COND_SCALE_VALUE =
* COND_SCALE_QUAN =
return = lt_return2.
"理论上这里可以不用commit就能更改条件
CLEAR:i_einex-net_price."一定要清空这个变量,不然程序会报错
CALL FUNCTION 'ME_INFORECORD_MAINTAIN'
EXPORTING
i_eina = i_eina
* I_EINAX =
i_eine = i_eine
i_einex = i_einex
testrun = lv_test
IMPORTING
e_eina = e_eina
e_eine = e_eine
TABLES
* TXT_LINES =
cond_validity = lt_con_vali
condition = lt_condition
* COND_SCALE_VALUE =
* COND_SCALE_QUAN =
return = lt_return2.
ENDIF.
IF lv_test IS INITIAL."正式运行
READ TABLE lt_return2 INTO ls_return2 WITH KEY type = 'E'.
IF sy-subrc = 0.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
et_tab-zresult = 'E'.
et_tab-message = '创建失败'.
APPEND et_tab.
CLEAR et_tab.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
et_tab-zkey = it_tab-zkey2."行项目号
et_tab-infnr = e_eina-info_rec."采购信息记录号
et_tab-zresult = 'S'.
et_tab-message = '创建成功'.
APPEND et_tab.
CLEAR et_tab.
ENDIF.
ELSE.
READ TABLE lt_return2 INTO ls_return2 WITH KEY type = 'E'.
IF sy-subrc = 0.
LOOP AT lt_return2 INTO ls_return2.
IF sy-tabix = 1.
et_tab-message = ls_return2-message.
ELSE.
et_tab-message = et_tab-message && ';' && ls_return2-message.
ENDIF.
ENDLOOP.
et_tab-zresult = 'E'.
APPEND et_tab.
CLEAR et_tab.
ELSE.
et_tab-zresult = 'S'.
et_tab-message = '试运行成功'.
APPEND et_tab.
CLEAR:et_tab.
ENDIF.
ENDIF.
CLEAR:i_eina,i_einax,
i_eine,i_einex,
lt_con_vali,lt_condition,
ls_eina.
CLEAR:lt_return2.
ENDLOOP.