共计 2042 个字符,预计需要花费 6 分钟才能阅读完成。
最近在实施一个汽车零部件项目时,客户抱怨 MM02 保存物料主数据时经常遇到问题:

- 采购视图的 ” 最小订单量 ” 字段经常被留空,导致 MRP 跑出异常结果
- 当物料类型为 ZENG(发动机)时,需要联动检查 QM 视图是否维护了检测规范
- 财务部门要求所有物料必须维护利润中心,但标准界面没有强制校验
标准事务码 MM02 就像一辆没有安全带的汽车——虽然能开,但风险随时可能爆发。下面分享三种给这辆 ” 汽车 ” 加装 ” 安全带 ” 的方案。
技术方案选型
方案一:传统 User Exit
事务码 CMOD 中激活出口 MM06E005,实现函数出口 USEREXIT_MATERIAL_SAVE:
FUNCTION userexit_material_save.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(I_HEADER) TYPE MARCU_KEY
*" CHANGING
*" REFERENCE(C_MARA) TYPE MARA
*" REFERENCE(C_MARC) TYPE MARC
*"----------------------------------------------------------------------" 示例:检查发动机物料必须维护检测规范
IF c_mara-mtart = 'ZENG' AND
c_marc-prctr IS INITIAL.
MESSAGE e888(sabapdocu) WITH '发动机物料必须维护利润中心'.
ENDIF.
ENDFUNCTION.
优点 :
– 实施速度快,适合简单校验逻辑
– 不需要注册 BADI 实现
缺点 :
– 修改标准函数组需要传输请求
– 多个项目增强容易冲突
方案二:BADI 实现
使用 BADI_MATERIAL_SAVE 更符合现代 ABAP 开发规范:
CLASS zcl_mm_material_save_badi DEFINITION PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_ex_badi_material_save.
ENDCLASS.
CLASS zcl_mm_material_save_badi IMPLEMENTATION.
METHOD if_ex_badi_material_save~change_at_save.
" 获取物料锁定状态
DATA(lv_locked) = cl_mm_material_maintain=>lock(
iv_matnr = i_mara-matnr
iv_werks = i_marc-werks ).
" 校验逻辑示例
IF i_mara-mtart = 'ZFIL' AND
i_marc-disgr IS INITIAL.
MESSAGE e888(sabapdocu) WITH '过滤器物料必须维护处置组'.
ENDIF.
" 高频操作时建议的提交策略
IF iv_in_update_task = abap_false.
COMMIT WORK AND WAIT.
ENDIF.
ENDMETHOD.
ENDCLASS.
关键点 :
1. 使用 CL_MM_MATERIAL_MAINTAIN=>LOCK 避免并发修改
2. 通过 IV_IN_UPDATE_TASK 区分事务上下文
3. 事务代码 SE19 创建实现后需激活
方案三:隐式增强
在 MM06 标准程序的 SAVE_DATA 方法中找到增强点:
ENHANCEMENT 1 ZMM_MATERIAL_ENHANCE. "SPOT ENHANCEMENT" 这里可以访问程序所有局部变量
IF mara-mtart = 'ZHYB' AND
marc-lgpro IS INITIAL.
MESSAGE e888(sabapdocu) WITH '混合物料必须维护发运仓库'.
ENDIF.
ENDENHANCEMENT.
适用场景 :
– 需要访问程序内部变量时
– 逻辑与特定业务场景强相关
生产环境生存指南
版本控制要点
- 在 SMOD 中修改 User Exit 时,务必创建副本 Z 开头对象
- 使用事务码 SCMN 比较不同系统的增强版本
- 批量传输前用 SE80 检查语法兼容性
权限控制模板
AUTHORITY-CHECK OBJECT 'M_MATE_WRK'
ID 'ACTVT' FIELD '02'
ID 'WERKS' FIELD i_marc-werks.
IF sy-subrc <> 0.
MESSAGE e888(sabapdocu) WITH '无权维护该工厂的物料主数据'.
ENDIF.
内存优化技巧
当处理批量导入时:
- 使用 FREE 语句及时释放内表
- 避免在循环中调用 COMMIT WORK
- 对大文本字段使用 MEMORY ID 释放
思考题延伸
当我们需要在保存物料时调用供应商的 Web Service 验证原材料合规性时:
- 如何设计 RFC 调用的重试机制?
- 事务码 BDC 录屏时怎么处理弹窗警告?
- 能否使用 SAP Cloud Platform 集成服务替代直接 RFC?
这些问题的答案,或许就是下一个项目的技术突破点。
正文完
