共计 1567 个字符,预计需要花费 4 分钟才能阅读完成。
背景痛点:为什么我们需要增强点
在 SAP 项目实施中,物料主数据保存后的增强需求非常普遍。比如我们经常遇到这些场景:

- 物料创建后自动触发审批工作流
- 需要将关键字段同步到自建表中
- 根据特定条件自动生成关联数据(如批次主数据)
很多新手开发者会直接修改标准程序,比如在 MM01 事务的 include 程序中插入代码。这种做法极其危险,因为:
- 升级时会被覆盖
- 可能导致系统不稳定
- 无法通过传输管理系统
增强机制横向对比
SAP 提供了三种标准的增强方式:
1. USEREXIT(用户出口)
- 位置:在程序中使用
CALL CUSTOMER-FUNCTION 'XXX'调用 - 优点:实现简单,直接可用
- 缺点:功能单一,无法灵活扩展
- 配置路径:SPRO→物料管理→基本设置→用户出口
2. BAdI(业务插件)
- 创建:SE18定义接口,SE19实现
- 优点:面向对象,支持多重实现
- 缺点:需要一定开发量
- 适合场景:复杂业务逻辑,需要多解决方案并存时
3. Enhancement Spot(增强点)
- 事务码:SE80中通过增强模式编辑
- 优点:支持源代码和函数组增强
- 缺点:需要精确找到增强点
- 典型应用:字段增强、屏幕增强
核心实现:USEREXIT_SAVE_DOCUMENT 实战
这是最常用的物料保存后出口,位于函数组 MGA1 中。完整实现示例:
FUNCTION Z_MM_MATERIAL_SAVE_EXIT.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" VALUE(I_MARA) LIKE MARA STRUCTURE MARA
*" VALUE(I_MARC) LIKE MARC STRUCTURE MARC
*" VALUE(I_MARD) LIKE MARD STRUCTURE MARD
*" VALUE(I_MBEW) LIKE MBEW STRUCTURE MBEW
*"----------------------------------------------------------------------
DATA: lv_matnr TYPE matnr.
" 获取物料编号
CALL METHOD cl_material_maintain=>save
IMPORTING
e_matnr = lv_matnr.
" 写入自定义表
INSERT zmat_cust_data FROM @(
VALUE #(
mandt = sy-mandt
matnr = lv_matnr
erdat = sy-datum
ernam = sy-uname
)
).
" 触发审批流程
IF i_mara-mtart = 'FERT'.
CALL FUNCTION 'Z_TRIGGER_APPROVAL'
EXPORTING
matnr = lv_matnr.
ENDIF.
ENDFUNCTION.
性能与安全注意事项
锁表风险处理
- 使用 SM12 监控锁
- 避免在增强中执行长时间操作
- 关键检查必须在
COMMIT WORK前完成
必做检查清单
- 检查
SY-SUBRC和SY-DBCNT - 验证客户端的正确性(
CLIENT SPECIFIED问题) - 处理空值情况
三大常见错误及解决方案
- 错误:忽略 MRP 视图
- 现象:增强逻辑未考虑 MRP 相关字段
-
解决:检查
MARC结构所有必填字段 -
错误:客户端依赖问题
- 现象:跨客户端数据污染
-
解决:所有 SQL 语句显式指定
MANDT字段 -
错误:性能瓶颈
- 现象:大批量导入时超时
- 解决:使用 ST05 跟踪 SQL,优化查询
延伸思考
随着系统迭代升级,增强点的版本兼容性变得尤为重要。比如:
- 当标准字段发生变化时,如何保证既有增强不失效?
- 如何设计增强点才能使不同版本的 SAP 系统都能支持?
- 对于需要停用的增强逻辑,如何实现平滑迁移?
这些问题值得我们在架构设计阶段就提前考虑。欢迎大家在评论区分享你的实践经验。
正文完
