第一次接触SAP计划订单屏幕增强时,我也被那些专业术语绕得头晕。但实际做下来发现,只要掌握几个关键点,就能像搭积木一样扩展标准事务码的功能。MD11(创建计划订单)、MD12(修改计划订单)和MD13(显示计划订单)这三个事务码在制造业中使用频率极高,经常需要根据企业特殊需求添加字段。
举个例子,某汽车配件厂需要在计划订单中增加"模具编号"字段,用来关联生产所需的专用模具。标准SAP根本没有这个字段,但通过屏幕增强技术,我们可以在不修改SAP标准代码的前提下,优雅地实现这个需求。整个过程就像给手机安装APP——不需要改动手机系统,却能扩展新功能。
SAP早就料到客户会有自定义需求,所以在MD系列事务中预留了"后门"——子屏幕框架SAPLCFD_SAP_GUI 1000。这就像乐高底板上的标准插槽,我们可以直接在上面添加自定义模块。关键是要找到两个核心组件:
我曾在项目中犯过错误,试图直接修改标准屏幕。结果SAP升级后所有修改都被覆盖,不得不通宵重做。后来学会用隐式增强,再也不用担心升级兼容性问题。
设计字段时要考虑三个维度:
建议先用Excel列出字段矩阵,比如:
| 字段名 | 数据类型 | 长度 | 可编辑 | 搜索帮助 | 校验规则 |
|---|---|---|---|---|---|
| ZZDAUAT | CHAR | 4 | MD11/MD12可写 | 工厂相关类型 | 需校验工厂匹配 |
| YMDC | CHAR | 10 | 只读 | 无 | 自动带出 |
首先在CI_PLAFDB结构中添加字段。这里有个坑:只需要添加需要持久化的字段。像那些临时显示的计算字段,完全可以通过内存变量处理。
abap复制" 在CI_PLAFDB末尾添加
ZZDAUAT TYPE AUFART, " 订单类型
YMDC TYPE ZE_YMDC, " 绑定关系号
ZZREMARK TYPE CHAR50 " 备注
曾经有同事把所有字段都加到结构里,导致数据库表莫名变大。其实只有会被保存的字段才需要在这里声明。
在CL_CFD_SAP_GUI_CONTROLLER的SET_SUBSCREEN_ASSIGNMENT方法中添加增强:
abap复制ENHANCEMENT 1 ZEHM_PP028_001. "active version
DATA: ls_position type i.
IF SY-TCODE = 'MD11' OR SY-TCODE = 'MD12' OR SY-TCODE = 'MD13'.
IF MT_CONTEXT_FIELDS IS INITIAL.
" 订单类型字段配置
DATA(LS_FIELD_METADATA) = VALUE TY_GS_FIELD_METADATA(
POSITION = 1
FIELD_NAME = 'ZZDAUAT'
FIELD_TYPE = 'ASC_TO_STD'
LABEL = '自定义订单类型'
SCREEN_LENGTH = 4
VALUE_HELP_CODE_VIEW_NAME = 'ATPC_CDS_PLAF'
).
APPEND LS_FIELD_METADATA TO MT_CONTEXT_FIELDS.
ENDIF.
ENDIF.
ENDENHANCEMENT.
注意POSITION的值决定了字段在屏幕上的显示顺序。有次我把顺序搞反了,导致重要字段被挤到第二屏,用户差点投诉。
在PBO_SUBSCREEN方法中添加字段状态控制:
abap复制ENHANCEMENT 1 ZEHM_PP028_002. "active version
IF LR_CONTEXT_FIELD->FIELD_NAME = 'YMDC'.
" MD13时所有字段只读
IF SY-TCODE = 'MD13'.
MODIFY_SUBSCREEN_FIELDS(
IV_IS_READ_ONLY = ABAP_TRUE
).
ENDIF.
ENDIF.
ENDENHANCEMENT.
这里有个实用技巧:用SY-TCODE判断当前事务码,可以针对不同操作设置不同的字段状态。
给订单类型字段添加带工厂过滤的搜索帮助:
abap复制ENHANCEMENT 1 ZEHM_PP028_004. "active version
IF LR_CONTEXT_FIELDS->FIELD_NAME = 'ZZDAUAT'.
ASSIGN ('(SAPLM61O)PLAF-PWWRK') TO FIELD-SYMBOL(<Lv_WERKS>).
CALL FUNCTION 'CO_F4_AUART'
EXPORTING
WERKS = <Lv_WERKS>
IMPORTING
AUART_EXP = AUART_TMP.
ENDIF.
ENDENHANCEMENT.
这个功能需要处理一个常见问题:搜索帮助触发后可能会dump。解决方法是在VALIDATE_CODE_VALUE方法中提前退出:
abap复制ENHANCEMENT 1 ZEHM_PP028_006. "active version
IF sy-tcode = 'MD11' OR SY-TCODE = 'MD12' OR SY-TCODE = 'MD13'.
RETURN.
ENDIF.
ENDENHANCEMENT.
在Include LM61OF8I中添加校验逻辑:
abap复制ENHANCEMENT 1 ZEHM_PP028_007. "active version
IF PLAF-ZZDAUAT IS NOT INITIAL.
SELECT SINGLE * FROM T399X
WHERE WERKS = PLAF-PWWRK
AND AUART = PLAF-ZZDAUAT.
IF SY-SUBRC NE 0.
MESSAGE '工厂与订单类型不匹配' TYPE 'E'.
ENDIF.
ENDIF.
ENDENHANCEMENT.
这种校验要特别注意性能问题。有次我忘了加索引字段条件,导致全表扫描把系统拖慢了。
在实际项目中踩过不少坑,这里分享三个最常见的:
字段闪烁问题:当屏幕中有多个增强字段时,可能会出现值被清空的情况。解决方法是在SET_UI_FIELD增强中确保值传递完整
权限控制遗漏:记得在权限对象中加入新字段,否则用户可能看到字段却无法操作
多语言支持:字段标签要从数据元素获取,不要硬编码。有次德国用户看到全是中文标签,场面一度尴尬
abap复制" 正确做法:动态获取标签
SELECT SINGLE DDTEXT INTO @LV_LABEL
FROM DD04T
WHERE ROLLNAME = 'AUFART'
AND DDLANGUAGE = @SY-LANGU.
建议开发完成后,用不同语言账号测试一遍。这些小细节往往决定了用户体验的好坏。