在群里看大家交流技术问题,曾记下了一条笔记:
用BAPI生成/修改PO/SO,然后紧接着使用BAPI_OUTB_DELIVERY_CREATE_STO/BAPI_OUTB_DELIVERY_CREATE_SLS来生成交货单,就会出现很多莫名其妙的错误。原因是没有清空函数的全局变量,暂时的解决方案可以用DESTINATION 'NONE'.【不要两个都使用】。但这会触发隐式提交哦。
或者
ASSIGN ('(SAPLME03)GET_EKET_DOC[]') TO <FS>.
IF SY-SUBRC = 0. CLEAR <FS>. ENDIF.
之前没有遇到相关的业务需求,也就只是记了条笔记丢在笔记库里了。
然而今天遇到了相应的业务场景,出现的问题却不止一个……
这边的需求是先对采购订单收货,然后去创建交货单。
我先调用了BAPI_GOODSMVT_CREATE收货,然后调用BAPI_OUTB_DELIVERY_CREATE_SLS创建交货单。
结果对于全新的物料,创建交货单的时候有个警告消息,说没有物料在相关工厂相关库存地点的数据。
可是这时候通过MMBE去查物料库存,明明是有数据的。
于是猜到这应该是SAP有些内表的缓存没有被清理的原因。
之后调整代码,调用交货单BAPI时,加上了DESTINATION 'NONE'。
再次执行,第二个问题出现了,BAPI提示交货单创建成功,警告消息没了,但执行完COMMIT之后,数据库里并没有这一行交货单的数据。
接下来,给大家分享我是如何去分析和解决问题的。
我的问题里,BAPI提示成功,但数据库没有数据。问题可能出现在两个地方:
1、BAPI的消息出错了;
2、COMMIT WORK没有执行。
我也稍稍怀疑了一下第一条,但立刻否定了自己的怀疑,BAPI返回的消息如果经常出错,网上肯定很多反映和讨论这个问题的。
那就只能是第二条,COMMIT WORK没有执行。
我看了一下代码,里面明确写着CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'呀,并且传递了wait = 'X'的参数。
再等几秒看看?
于是等了一会,数据库里还是没有。
MMP,SAP不讲武德啊!
纠结了一小下,还是让自己镇定下来思考最根本的问题:BAPI是如何提交数据到数据库的?
想一下BAPI的结构,BAPI里的代码可以分为这样两部分:
1、一部分是数据校核,检查传入的数据是否满足创建相关业务对象的条件,并且把错误消息反馈出来;
2、另一部分是更新数据库,即UPDATE/INSERT/DELETE dbtab这样的操作。
而第二部分的代码,一般是写在一个form里或者一个function里。
而且这些form或者function一般是这样被调用的:
perform save_data on commit.
call function 'SAVE_DATA' in update task.
回头再看一下程序,我写了COMMIT WORK的呀。
哦,难道是因为我在调用交货单BAPI时,加了DESTINATION,但是调用BAPI_TRANSACTION_COMMIT时并没有加DESTINATION!
是不是这个原因呢?
立刻改掉代码再试一次,果然成功了。
所以在调用BAPI是如果加了DESTINATION,也需要在调用BAPI_TRANSACTION_COMMIT时加上DESTINATION。
其实今天的这个小解决方案,大家可能并不会太用到。但我觉得我解决这个问题的过程和思路,或许可以给一些朋友提供一些参考和借鉴。
即:
1、你要尽量储备一些基础知识;
2、你要有好奇心去深入深入再深入的研究你经常使用的东西
3、你要镇定下来像破案一样去排除所有不可能的因素,最后的结果就是:真相只有一个!