点击蓝字 关注我们
一
前言
标准事务代码MR22 通过调整金额影响物料的成本价,前台界面中单个凭证中允许输入多行物料, 但是对应的BAPI函数仅支持输入单行物料
BAPI_MATVAL_DEBIT_CREDIT 正常库存
BAPI_SALESORDSTCK_DEBIT_CREDIT 销售订单库存
这种情况
婶可忍叔不可忍 (感谢用户的执着)(不排除SAP有允许输入多行的价格变更BAPI,但没有找到)
本文主要介绍自定义BAPI,允许生成多行物料的价格变更凭证
二
MR22的标准BAPI
BAPI_MATVAL_DEBIT_CREDIT 正常库存
BAPI_SALESORDSTCK_DEBIT_CREDIT 销售订单库存
项目中用到过这两个标准BAPI. 因为物料编码作为独立的传入参数, 因此这两个BAPI注定只能传入单行物料.
三
BAPI VS BDC
BDC使用方式详见连接
无峰,公众号:ABAP 技巧与实战ABAP基础知识 BDC记录创建单据
BDC是基于屏幕记录的处理过程, 如果因为配置或者数据的原因导致实际处理的屏幕过程不同于记录的屏幕过程,就会出现异常报错. 因此不推荐使用BDC记录生成的函数创建事务数据.
BDC录屏过程中,对于多行处理会有一个较复杂逻辑调整: 记录时需要形成一个重复处理过程, 该重复处理过程最好使用标准的定位按钮把要处理的行放到第一行. 翻页键或方向键不是一个精确的定位方式,可能会导致异常. 最后生成的代码基于传入的多行,调整重复处理的逻辑. 有些事务没有提供定位按钮,基本上很难实现多行(不定行)录入
BDC 没有一个准确的成功判定方式, 通过SY-SUBRC 和指定一个成功消息号来判断成功, 但特殊业务系统可能会触发另外一个成功消息号 . 这样会导致程序逻辑的不确定性.
综上所述,除非没有找到事务对应BAPI函数. 否则不要用BDC记录生成函数创建事务.
但凡事都有例外, 系统某些标准BAPI(财务居多),内核就是BDC录屏.这些BDC的标准BAPI考虑了所有屏幕呈现的逻辑,基本上不会有自己录制BDC的问题.
四
标准BAPI的分析
标准BAPI的调用过程比较简单, 程序中也有相应的注释提示
转换物料编码(18位编码->40位编码)
调用FORM matval_debit_credit生成凭证
FORM matval_debit_credit中 调用本地类方法产生凭证
类方法lcl_matval_debit_credit中
处理了下述逻辑
检查授权
读取物料的物料分类账信息
读取物料成本
获取原因信息
填写核心调用方法的参数
最后调用核心方法 execute_price_change 生成凭证
五
BAPI分析的结论
最终传递给方法 execute_price_change 的参数中. 传递的物料信息通过内表LT_MATPR传递. 该内表允许多行物料.
比较困惑为何SAP在底层类方法中允许多行物料, 但是封装的上层BAPI函数仅支持单行物料.
不管怎样. 上述的分析结果形成了一个想法: 创建一个新的, 允许多行物料的BAPI函数
六
改造结果
函数
ZBAPI_MULTI_SALESORDSTCK_DEBIT
允许传入多行物料. 产生多行物料的凭证
改造的过程比较简单, 把标准BAPI准备核心方法execute_price_change的参数准备部分,从单行调整成多行物料. 最终调用即可.
如下截图的红线部分是改变的部分
七
测试验证
最终生成的凭证和前台界面MR22创建的凭证一致.
八
总结
SAP的标准程序的模块划分比较清晰, 让改造标准BAPI函数成为可能. 这次改造行为仔细分析了MR22标准BAPI的处理逻辑. 因此对改造后的函数比较有信心. 实测也验证了该函数可行.
同时也希望SAP后续能给出MR22的多行创建的BAPI函数
改造后, 标准成本及销售订单成本的修改整合到了一起. 基于传输数据是否有销售订单来判断.
改造的关键点都标识出来了. 感兴趣的可以自行尝试.