ABAP 增强介绍

增强介绍

对于SAP系统标准代码的改动都可以称之为增强。

当标准业务流程不满足企业需求时,SAP顾问可以通过实施增强来满足企业相对于标准流程的定制化业务需求。

以下按时间递进依次介绍目前的四代增强:

  1. 一代增强:源代码的增强
  2. 二代增强:基于函数的增强
  3. 三代增强:基于类的增强
  4. 四代增强:显示和隐式增强

一代增强:基于源代码的增强

一代增强体现为标准事务程序中的以USEREXIT开头的FORM

一代增强的好处是可以使用全局变量,缺点是系统升级需要手动迁移增强代码。

以下为三种查找一代增强的方法:

  1. 通过事务码的程序查找
  2. 通过SPRO查找
  3. 通过SAT查找

查找一代增强的方法

通过事务码的程序查找

image-20241118204415193

image-20241118204807229

image-20241118204828146

通过SPRO查找

image-20241118205206095

image-20241119191322530

通过SAT查找

image-20241118211724550

输入事务码,点击执行,之后在弹出的业务界面进行操作最后点击保存或者退出,在SAT分析出来的报表中筛选USEREXITFORM

image-20241118211949289

实施方式

找到对应的FORM直接编辑源码。

image-20241118213039924

二代增强:基于函数的增强

二代增强是基于函数的增强。

SAP在部分标准程序代码中预留了CUSTOMER-FUNCTION的函数调用,开发者所需增强的逻辑在对应的CUSTOMER-FUNCTION中实现即可,二代增强的函数名为EXIT_<程序名>_<3位数字>(程序名为调用该增强函数的程序)。除此之外,GUI增强、屏幕增强以及Include方式的表结构增强也属于二代增强。

二代增强相比一代增强,二代增强在系统升级过程中无需手动迁移,且二代增强的实现无需再申请访问KEY。

以下为四种二代增强:

  1. E类:函数增强
  2. C类:GUI增强
  3. S类:屏幕增强
  4. T类:表结构增强

image-20241124144908912

二代增强相关的记录表:

  1. MODSAP:记录增强点与对应的相关增强出口
  2. TFDIR:记录包括出口函数在内的所有函数的信息(MAND值为C则代表该出口函数已被激活)
  3. CUATEXTS:记录SAP系统GUI界面信息
  4. TSDIR:记录SAP系统子程序信息

以下为三种查找二代增强的方法:

  1. 通过自开发程序查找
  2. 通过MODX_FUNCTION_ACTIVE_CHECK函数查找
  3. 通过调试断点CALL CUSTOMER-FUNCTION查找

二代增强相关的函数:

  1. E类:MODX_FUNCTION_ACTIVE_CHECK(检查功能出口类用户出口是否被激活)
  2. C类:MODX_MENUENTRY_ACTIVE_CHECK(检查菜单关键字类增强激活状况)
  3. S类:MODX_SUBSCREEN_ACTIVE_CHECK(检查屏幕类增强激活状况)

查找二代增强的方法

通过自开发程序查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
REPORT Z_FIND_ENHANCEMENT
NO STANDARD PAGE HEADING
MESSAGE-ID zhuxy
LINE-COUNT 65
LINE-SIZE 120.

*** Global Date declear
TABLES:tstc,tadir,modsapt,modact,trdir,tfdir,enlfdir,sxs_attrt,tstct.
DATA : jtab LIKE tadir OCCURS 0 WITH HEADER LINE.
DATA : field1(30).
DATA : v_devclass LIKE tadir-devclass.
DATA : wa_tadir TYPE tadir.
PARAMETERS : p_tcode LIKE tstc-tcode,
p_pgmna LIKE tstc-pgmna .

*======================================================================*
* Selection Screen Events
*======================================================================*
*** maintain selection screen output
AT SELECTION-SCREEN OUTPUT.
*** F4 value help
*AT SELECTION-SCREEN ON VALUE-REQUEST for <para/sel-opt>.
*** check input data
AT SELECTION-SCREEN.
*AT SELECTION-SCREEN ON <f>.
*AT SELECTION-SCREEN ON BLOCK <>.
****CHECK ON SELECT SCREEN INPUT

*======================================================================*
* Report Events
*======================================================================*
*** initial data
INITIALIZATION.

*** prepare report data
START-OF-SELECTION.
*########
PERFORM get_data.
**#ò######
* PERFORM write_data.
*** output report

END-OF-SELECTION.

*======================================================================*
* List Events
*======================================================================*
*** page header
TOP-OF-PAGE.

*** page header after first list
TOP-OF-PAGE DURING LINE-SELECTION.

*** page footer
END-OF-PAGE.

*** when double click
AT LINE-SELECTION.
PERFORM line_sel.

*** when click some icon (function code)
*at user-command.

*&---------------------------------------------------------------------*
*& Form get_data
*&---------------------------------------------------------------------*
* ########
*----------------------------------------------------------------------*
FORM get_data .
IF NOT p_tcode IS INITIAL.
SELECT SINGLE * FROM tstc WHERE tcode EQ p_tcode.
ELSEIF NOT p_pgmna IS INITIAL.
tstc-pgmna = p_pgmna.
ENDIF.
IF sy-subrc EQ 0.
SELECT SINGLE * FROM tadir
WHERE pgmid = 'R3TR'
AND object = 'PROG'
AND obj_name = tstc-pgmna.
MOVE : tadir-devclass TO v_devclass.
IF sy-subrc NE 0.
SELECT SINGLE * FROM trdir
WHERE name = tstc-pgmna.
IF trdir-subc EQ 'F'.
SELECT SINGLE * FROM tfdir
WHERE pname = tstc-pgmna.
SELECT SINGLE * FROM enlfdir
WHERE funcname = tfdir-funcname.
SELECT SINGLE * FROM tadir
WHERE pgmid = 'R3TR'
AND object = 'FUGR'
AND obj_name EQ enlfdir-area.
MOVE : tadir-devclass TO v_devclass.
ENDIF.
ENDIF.
SELECT * FROM tadir INTO TABLE jtab WHERE pgmid = 'R3TR' AND
object IN ('SMOD', 'SXSD') AND
devclass = v_devclass.
SELECT SINGLE * FROM tstct WHERE sprsl EQ sy-langu AND
tcode EQ p_tcode.
FORMAT COLOR COL_POSITIVE INTENSIFIED OFF.
WRITE:/(19) 'Transaction Code - ',
20(20) p_tcode,
45(50) tstct-ttext.
SKIP.
IF NOT jtab[] IS INITIAL.
WRITE:/(105) sy-uline.
FORMAT COLOR COL_HEADING INTENSIFIED ON.
SORT jtab BY object.
DATA : wf_txt(60) TYPE c,
wf_smod TYPE i ,
wf_badi TYPE i ,
wf_object2(30) TYPE c.
CLEAR : wf_smod, wf_badi , wf_object2.
LOOP AT jtab INTO wa_tadir.
AT FIRST.
FORMAT COLOR COL_HEADING INTENSIFIED ON.
WRITE:/1 sy-vline,
2 'Enhancement/ Business Add-in',
41 sy-vline ,
42 'Description',
105 sy-vline.
WRITE:/(105) sy-uline.
ENDAT.
CLEAR wf_txt.
AT NEW object.
IF wa_tadir-object = 'SMOD'.
wf_object2 = 'Enhancement' .
ELSEIF wa_tadir-object = 'SXSD'.
wf_object2 = ' Business Add-in'.
ENDIF.
FORMAT COLOR COL_GROUP INTENSIFIED ON.
WRITE:/1 sy-vline,
2 wf_object2,
105 sy-vline.
ENDAT.
CASE wa_tadir-object.
WHEN 'SMOD'.
wf_smod = wf_smod + 1.
SELECT SINGLE modtext INTO wf_txt
FROM modsapt
WHERE sprsl = sy-langu
AND name = wa_tadir-obj_name.
FORMAT COLOR COL_NORMAL INTENSIFIED OFF.
WHEN 'SXSD'.
* * for badis
wf_badi = wf_badi + 1 .
SELECT SINGLE text INTO wf_txt
FROM sxs_attrt
WHERE sprsl = sy-langu
AND exit_name = wa_tadir-obj_name.
FORMAT COLOR COL_NORMAL INTENSIFIED ON.
ENDCASE.
WRITE:/1 sy-vline,
2 wa_tadir-obj_name HOTSPOT ON,
41 sy-vline ,
42 wf_txt,
105 sy-vline.
AT END OF object.
WRITE : /(105) sy-uline.
ENDAT.
ENDLOOP.
WRITE:/(105) sy-uline.
SKIP.
FORMAT COLOR COL_TOTAL INTENSIFIED ON.
WRITE:/ 'No.of Exits:' , wf_smod.
WRITE:/ 'No.of BADis:' , wf_badi.
ELSE.
FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.
WRITE:/(105) 'No userexits or BADis exist'.
ENDIF.
ELSE.
FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.
WRITE:/(105) 'Transaction does not exist'.
ENDIF.
ENDFORM. " get_data

*&---------------------------------------------------------------------*
*& Form line_sel
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM line_sel .
DATA : wf_object TYPE tadir-object.
CLEAR wf_object.
GET CURSOR FIELD field1.
CHECK field1(8) EQ 'WA_TADIR'.
READ TABLE jtab WITH KEY obj_name = sy-lisel+1(20).
MOVE jtab-object TO wf_object.
CASE wf_object.
WHEN 'SMOD'.
SET PARAMETER ID 'MON' FIELD sy-lisel+1(10).
CALL TRANSACTION 'SMOD' AND SKIP FIRST SCREEN.
WHEN 'SXSD'.
SET PARAMETER ID 'EXN' FIELD sy-lisel+1(20).
CALL TRANSACTION 'SE18' AND SKIP FIRST SCREEN.
ENDCASE.
ENDFORM. " line_sel
*Extracted by Mass Download version 1.4.1 - E.G.Mellodew. 1998-2019. Sap Release 731

运行程序,输入需要查找增强的事务码,运行

image-20241123211144784

image-20241123211244449

通过MODX_FUNCTION_ACTIVE_CHECK函数查找

如果标准事务的运行中存在二代增强的调用,则在事务调用二代增强前,会先进入标准函数MODX_FUNCTION_ACTIVE_CHECK

最后查找到的增强函数可以搭配自开发增强查找程序一起确定是否适用于当前业务要求。

image-20241123212411696

比如运行MM02,修改物料描述并保存

image-20241123212743610

通过调试断点CALL CUSTOMER-FUNCTION查找

以MM02修改物料描述为例

image-20241124134744298

image-20241124134917022

实施方式

二代增强的实施涉及到SMODCMOD两个事务码:

  • SMOD:记录SAP系统预留的二代增强点。
  • CMOD:可以理解为开发自定义的增强项目,将SMOD中开发实现的增强管理起来的一个已实现的增强的组。在CMOD中通过配置SMOD的增强点进行增强管理,通过激活CMOD的增强项目来开启项目中的增强点,如需要删除CMOD增强项目中的个别增强点,则需要先取消激活CMOD增强项目才可以进一步进行删除增强点的操作。

四类二代增强实现案例:

  1. 函数增强的实现方式可以参考ABAP第二代增强-销售订单增强(示例)
  2. 子屏幕增强的实现方式可以参考增强篇4 CO01生产订单屏幕增强
  3. 表结构增强的实现方式可以参考上述子屏幕增强,一般搭配子屏幕增强一起实现

三代增强:基于类的增强

第三代增强为BADI(Business add-in)增强。BADI增强表现为SAP预定义好的接口的实现类,其中包含的各种方法代表了各个业务动作。开发人员通过创建实现类、编写方法逻辑来完成BADI增强的实施。

一个接口可以有多个实现类,因此一个BADI增强可能同时存在多个增强实现类,而具体业务场景需要的增强实现类则通过过滤器来区分。

查找业务场景中的BADI增强可以通过以下三种方式:

  1. 通过CL_EXITHANDLER=>GET_INSTANCE方法查找
  2. 通过调试CALL BADI断点查找
  3. 通过ST05查找

当然也可以通过上述查找二代增强时所用到的程序来查找三代增强,这里不在赘述。

查找三代增强的方式

通过CL_EXITHANDLER=>GET_INSTANCE方法查找

业务流程如果存在BADI增强,则会调用该方法。

image-20241127195752444

image-20241127195850007

通过调试CALL BADI断点查找

BADI增强的调用在标准代码中体现为CALL BADI

image-20241127200043041

通过ST05查找

BADI增强的信息存储在SXS_INTERSXC_EXITSXC_CLASSSXC_ATTR 这四个表中,所以可以通过ST05分析业务场景,筛选存在对应表的语句即可。方式一中的方法实际也是通过查询这些表来判断是否存在BAID增强。

实施方式

BADI增强涉及到两个事务码:

  1. se18:查询BADI增强
  2. se19:创建BADI增强

具体的增强实施参考BADI实例开发-生产订单收货(MB_DOCUMENT_BADI)

关于BADI增强中的多次使用选项:

  • 勾上该选项,则在对应的业务场景中所有的BADI增强实施都会被调用,但这些增强实施的调用顺序是不被保证的。

  • 不勾上多次使用选项,则只能有一个BADI增强实施被激活。

    image-20241130191922342

四代增强:显示增强和隐式增强

四代增强中的显示增强表现为标准代码中的ENHANCEMENT-POINT,增强的实施通过菜单栏中的增强按钮>创建增强来进行,创建出来的增强段依附于它上面的系统预留的增强点。

关于隐式增强,创建出来的增强段则是依附于开发人员定义的增强实施下。

SAP在标准程序的代码中预留了它的位置:

  • 包含的末尾
  • 局部类的末尾
  • 类的实现部分的末尾
  • 接口定义的末尾
  • 结构定义的末尾
  • 过程的开头和结尾

通过菜单栏的显示隐式增强来发现标准代码中可以实施的隐式增强:

image-20241130201910128


ABAP 增强介绍
https://claudechan1228.github.io/2024/11/12/028-ABAP 增强介绍/
作者
Claude Chan
发布于
2024年11月12日
许可协议