共计 1476 个字符,预计需要花费 4 分钟才能阅读完成。
业务背景与技术痛点
在 SAP MM 模块中,物料凭证(Material Document)是记录物料移动的核心单据。标准功能虽然覆盖了大部分业务场景,但实际项目中常遇到需要自动更新行项目数据的定制需求,例如:

- 根据移动类型自动填充成本中心
- 按特定规则计算并更新自定义字段
- 与外部系统实时同步数据
新手开发者常面临的两个主要问题:
1. 对增强点选择迷茫(BAdI/User Exit/Enhancement Spot)
2. 担心数据更新导致事务不一致
技术方案对比
1. BAdI 方案(MB_DOCUMENT_BADI)
优点 :
– 标准 SAP 推荐方式
– 支持多重实现(多个业务逻辑共存)
– 良好的版本兼容性
缺点 :
– 执行时机较晚(凭证已生成)
– 需注意性能影响
2. User Exit(如 EXIT_SAPMM07E_001)
优点 :
– 执行时机更早(保存前)
– 直接访问原始内存结构
缺点 :
– 修改需 Access Key
– 不同 SAP 版本可能变化
适用场景决策树 :
1. 需要修改凭证抬头数据 → User Exit
2. 仅需更新行项目且需多实现 → BAdI
3. 需要事务内实时更新 → Update Module
核心实现(BAdI 示例)
实现步骤
- 通过 SE18 创建 BAdI 实现
CLASS zcl_mm_mb_document_badi IMPLEMENTATION. METHOD if_ex_mb_document_badi~change_at_save. " 获取所有行项目 LOOP AT im_mseg ASSIGNING FIELD-SYMBOL(<fs_mseg>). " 示例:自动填充成本中心 IF <fs_mseg>-kostl IS INITIAL AND <fs_mseg>-bwart = '101'. " 移动类型检查 <fs_mseg>-kostl = '100000'. "默认成本中心" 记录修改日志 MESSAGE s398(00) WITH '自动填充成本中心 100000' INTO DATA(lv_msg). " 注意:实际项目应使用统一日志框架 ENDIF. ENDLOOP. ENDMETHOD. ENDCLASS.
关键注意事项
- 事务一致性 :BAdI 在凭证保存后触发,避免在此处做 COMMIT WORK
- 性能优化 :
- 使用 FIELD-SYMBOL 减少内存拷贝
- 批量场景优先使用 FOR ALL ENTRIES
- 权限检查 :
AUTHORITY-CHECK OBJECT 'M_MATE_WRK' ID 'ACTVT' FIELD '02' ID 'WERKS' FIELD <fs_mseg>-werks. IF sy-subrc <> 0. " 错误处理 ENDIF.
避坑指南
- 批量处理遗漏
- 错误现象:前台操作正常但后台作业失败
-
解决方案:所有循环必须处理内表为空的情况
-
忽略版本差异
- 错误现象:开发机正常但生产环境报错
-
解决方案:使用 CL_ABAP_CHAR_UTILITIES=>CR_LF 等标准常量
-
直接更新数据库
- 危险操作:在 BAdI 中使用 UPDATE 语句
- 正确做法:通过标准 API 或后续 Job 处理
测试建议
单元测试要点
- 模拟不同移动类型组合
- 测试空成本中心的自动填充
- 验证权限错误时的处理流程
集成测试场景
- 通过 MIGO 创建混合类型凭证
- 后台作业批量导入测试
- 并发用户操作测试
总结与思考
实际项目中,技术选型需要考虑:
– 业务逻辑复杂度(简单规则用 User Exit,复杂逻辑用 BAdI)
– 系统负载情况(高频操作避免在 BAdI 中做耗时处理)
– 长期维护成本(BAdI 更易升级)
对于批量场景优化建议:
1. 使用内存表暂存待处理数据
2. 通过 SM36 创建定时作业分批处理
3. 考虑启用并行处理(需评估锁冲突风险)
最终选择没有绝对标准,需要根据具体业务场景和技术环境权衡决策。
