SAP增强开发总结
1、概述
1.1、增强的概念
1.2、增强的类型
1.3、增强的发展
2、第一代增强(Form Exit)
2.1、简介
2.2、查找方法
2.3、实现方式
3、第二代增强(Function Exit)
3.1、简介
3.2、相关的函数和表
3.3、查找方法
3.4、实现方式
4、第三代增强(Classic BADI)
4.1、简介
4.2、查找方法
4.3、实现方式
5、第四代增强(Enhancement Framework)
5.1、基本概念
5.2、New BADI
5.3、实现方式
1、概述
1.1、增强的概念
增强(enhancement)的概念其实很广,SAP标准系统之上的所有二次开发,都可以理解为增强。
做增强的目的,就是标准的sap正常的业务系统不能满足实际需求,需要增加不同的功能来达到不同企业的要求。
ABAP开发的增强主要指的是标准系统事先预留好的接口,根据不同业务需求,进行开发,这种开发称为增强/出口,如果增强满足不了,就只能修正。
1.2、增强的类型
MENU菜单增强
SCREEN屏幕增强
function功能模块增强
table/structure表/结构增强
1.3、增强的发展
第一代,基于源代码的增强(Form Exit)
第二代,基于函数出口的增强(Function Exit)
第三代,基于类的增强(BADI Interface)
第四代,三代增强的加强(Enhancement Framework,包括New BADI和Enhancement-Point)
2、第一代增强(Form Exit)
2.1、简介
SAP提供的一个空的子例程(Form),一般是以 UserExit_ 打头,在这个Form中用户可以添加自己的代码,实现自己的需求。
这些出口集中存储在一些名称倒数第二个字符为Z的Include程序中(如销售凭证主程序SAPMV45A中的MV45ATZZ、MV45AOZZ等Include程序),主程序的全局数据都可以使用。
源代码增强,需要事先到 Service MarketPlace 申请对应Include的对象键(ACCESS KEY),然后才能修改其中的子例程。
屏幕增强以客户屏幕形式发布,初始屏幕元素为空
表/结构的增强是 append structure
这类增强需要修改SAP的标准代码,因为系统升级时会被新版本覆盖后不能使用,且如果在代码中改变了全局变量,还可能会破坏系统原有的逻辑,因而现在很少使用。
2.2、查找方法
(1)后台查找:可以从事务码 SPRO 后台配置中相关模块的路径里面找到增强的说明(进入SPRO,Ctrl+F 搜索增强或 User Exit 等类似关键字)
例如SD模块在:SPRO/销售与分销/系统修正/用户出口路径下:
(2)SE80查找:
通过 TCODE对应的主程序,来查找。
如销售凭证创建,执行事务码 VA01,查看标准程序源代码,点击菜单:系统 → 状态
展开左边程序目录中的包含,查找名称倒数第二位为Z的 Include 程序
或者直接展开子例程,查看 EXIT_ 打头的 Form
可以通过名称判断,打断点验证等方式,来判断出口能否满足业务需求。
2.3、实现方式
申请Access Key后,直接在所需的出口Form中添加代码。
3、第二代增强(Function Exit)
3.1、简介
第二代增强主要有4类:
E. Function exits:函数增强 以函数模块形式发布,在SAP的发布的版本中,使用 CALL CUSTOMER-FUNCTION <3位数字> 调用这些函数模块,所以可以通过在程序中查找 customer-function 来查找此类增强。出口函数名称由三部分组成:EXIT_<程序名>_<3位数字>(注:这里的<程序名>即调用该出口函数的程序名),根据这个规则可以找到对应的出口函数,然后到SE37中查看函数详细信息;通过该出口函数名到MODSAP表里查找对应的出口对象(即增强点)。这些函数在发布时只有一句代码 INCLUDE xxxx,xxxx 名称已预留,但还未创建。进行功能模块增强时,只能使用函数中传递的参数,不能使用调用程序的全局变量(二代增强中最常用的,如:销售订单单VA02中,对PO长度限制在10-15位之间,且不能为中文与其他特殊字符,还有如对PO采购日期不能晚于交货日期的检验等,这些都会用来函数增强)。
C. GUI Codes:GUI增强
S. Screens:屏幕增强 SAP使用 CALL CUSTOMER-SCREEN 调用这些子屏幕,已预留了子屏幕编号,程序已经创建,但子屏幕还未创建。所以可以通过在程序中查找 customer-screen 来查找此类增强。
T. Tables:表结构增强 include structure,SAP已预留了结构名称,以**CI_**打头,但结构字段还未创建。这些结构将以.include的形式包含到相应的数据表中,用户可以通过向这些结构中添加字段从而达到对数据表字段的增加。
3.2、相关的函数和表
Function:
(1)DYNP_VALUES_READ
(2)MODX_ALL_ACTIVE_MENUENTRIES(菜单增强)
(3)MODX_FUNCTION_ACTIVE_CHECK(E类:出口函数增强)
(4)MODX_MENUENTRY_ACTIVE_CHECK(C类:菜单增强)
(5)MODX_SUBSCREEN_ACTIVE_CHECK(S类:屏幕增强)
Table:
(1)TFDIR:function module table,里面记录了所有函数,重要的字段有:funcname函数名,mand功能模块激活状态(c代表激活)
(2)MODSAP:sap enhancement table,里面记录了所有enhancement的增强,重要的字段有:name增强名,type组件类型(E-功能、C-菜单、S-屏幕、T-表),member组件功能模块名
(3)TSDIR:Dynpro Access CALL CUSTOMER SUBSCREEN(屏幕增强)
(4)CUATEXTS:GUI Interface:Menu Texts Changed(GUI菜单文本增强)
举个例子:销售订单VA01/销售合同VA42对应的SAP标准主程序是SAPMV45A, 通过CUSTOMER-FUNCTION搜索到增强出口,然后在MODSAP表里查找对应的出口对象(即增强点),MODSAP-MEMBER=EXIT_SAPMV45A_002可以找到对应的SMOD的出口
MODSAP-MEMBER=EXIT_主程序名_CUSTOMER-FUNCTION对应的''名称/编号
3.3、查找方法
(1)利用代码查找TCODE增强(支持查找二代、三代增强查找)
在 SAP 系统中,创建以下 report 程序,用于查找增强点
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
运行TCODE=VA22
二代增强行上单击,可以进入SMOD界面,可以查看具体的增强说明。
三代增强行上单击,可以进入SE18界面,可以查看具体的增强点定义。
(2)利用SE37函数(MODX_FUNCTION_ACTIVE_CHECK)断点调式跟踪寻找增强
在函数源代码入口打断点,执行所需的功能TCODE,如果有执行到二代功能增强的地方,就会进入该函数,此时可以通过入参来确定出口函数。
说明:以上两种方式可以结合使用,第一种确定TCODE的增强出口,第二种确定出口触发的时机,以确定是否满足业务需求。
3.4、实现方式
二代增强,无需申请对象键,直接创建对象,编写相应代码。
(1)SMOD:查看增强组件说明
(2)CMOD:创建增强项目,添加增强,实现组件逻辑
A. 功能增强:在目标 Function Module 中编写相应代码。
具体实例,参考《记录一次销售交货开票 VF04 增强开发》
B. 屏幕增强:在被调程序中,创建对应屏幕号的屏幕,设置属性为SubScreen,编写相应屏幕逻辑。
主调程序屏幕代码
被调程序,创建相应编号的子屏幕
C. 表/结构增强:双击结构,添加相应字段。
4、第三代增强(Classic BADI)
4.1、简介
第三代增强 BADI(business add-in),基于面向对象概念的增强,源代码发布以接口的方式,通过接口的方法调用来实现。
用户增强实际上是实现一个或多个基于这个接口的实现类,因为接口类实际上是一个抽象类,所以对同一个增强可以实现不同的源代码,这些不同的源代码是通过过滤器(adapter)来区别用于不同的业务场景的。
BADI与EXIT的区别:Exit中一个Enhancement(Form/Function)只能使用一次,BADI中一个接口可以被实现多次(即定义多个实现类)。
BADI对象的信息存储在 SXS_INTER,SXC_EXIT,SXC_CLASS 和 SXC_ATTR 这四个表中(位于SECE包中)。
SAP程序都会调用 cl_exithandler=>get_instance 来判断 BADI 对象是否存在,存在则返回实例; get_instance 其实就是对上述几个表和他们的视图(V_EXT_IMP和V_EXT_ACT)进行查询和搜索。
可以使用ST05来跟踪一个TCODE的执行过程,然后选择查找有关上述几个表和视图的操作,来获得相关BADI信息。
4.2、查找方法
(1)利用代码查找TCODE增强(同上)。
(2)利用 SE24 类方法(CL_EXITHANDLER=>GET_INSTANCE)断点调式跟踪寻找增强
在类方法开头打上断点,执行相应的TCODE,如果有执行到BADI增强的地方,就会进入该方法,此时可以通过程序变量来确定增强点。
说明:两种方式可以结合使用,第一种确定 TCODE 的 BADI ,第二种确定BADI 触发的时机,以确定是否满足业务需求。
4.3、实现方式
这种增强是用 SE18来查看 BADI 定义,SE19 来实现的。
(1)SE18:查看 BADI 定义,以 MM_DELIVERY_ADDR_SAP 为例
SE24,可以查看接口 IF_EX_MM_DELIVERY_ADDR_SAP 和已实现的类 CL_EX_MM_DELIVERY_ADDR_SAP 的信息。
在BADI定义界面,可以查看该BADI已有的实施,通过菜单:实施 → 概览
(2)实现 BADI(以 BADI_MATN1 为例)
在 SE19 中创建BADI实施
也可以在 SE18 的实施菜单中创建,选择:实施 → 创建
输入BADI实施的名称
输入 BADI 实施的描述,
系统自定为 BADI实施 指定一个接口(IF_EX+ BADI名),
同时自动生成了实现这个接口的实施类的名称,也可以按需调整。
保存 BADI实施并激活,自动生成并激活实施类 ZCL_IM_IM_BADI_MATN1。
下一步,可在SE24中查看并编写类方法代码实现业务逻辑。
说明:BADI实施与类实施概念略有不同,一个BADI实施,串起一个接口与实施类的对应关系。一个BADI可以有多个BADI实施,即一个接口可以有多个实施类。
5、第四代增强(Enhancement Framework)
5.1、基本概念
Ehancement Spot:用来组织 Enhancement options,是 Enhancement options 的容器.
Enhancement Implementation:用来组织 Enhancement options 的实现代码。
Enhancement options:是系统预留的,源代码中可以实施增强代码的位置,分隐式和显式,不能做屏幕和菜单增强。
隐式增强:就是系统内置的 Enhancement options,是系统本身就预留的,如在:执行程序、包含程序、函数组、对话模块、结构的结尾处;Form例程、函数模块、方法等的开始和结尾处。
显式增强:就是通过代码加入到程序中的 Enhancement options,有两种显式增强:ENHANCEMENT-POINT 和 ENHANCEMENT-SECTION。也可以自定义显式增强点,但不能自定义增强选项,增强选项一定是系统预留下来的,如果没有增强选项则该处不可做增强。此类增强最大的优势在于方便,可以使用程序中已定义的变量,不像 BADI 和 EXIT 只能使用函数接口传过来的参数。
ENHANCEMENT-POINT:只有一个预留点,没有代码,用来在程序中直接插入新的功能代码。标准程序预留了部分已定义好的增强点可以让ABAP做插入代码来实现这个增强,可以多次实现,类似于AOP。
ENHANCEMENT-SECTION:ENHANCEMENT-SECTION 和 END-ENHANCEMENT-SECTION 之间有代码,只能实现一次,用来替换原有的功能代码,类似于OO中的方法重写/覆盖。
5.2、New BADI
New BADI 就是所谓的 Enhancement Spot 中多 BADI Definition。
Enhancement Spot 的结构是个树形结构。
Enhancement Spot 下面可以定义若干个 BADI definition,SAP官方的说法是,下面的 BADI Definition 的数量是没有限制的,BADI Definition 可以通过 SE18 进行创建、修改、查看。
每个 BADI Definition 里面包含一个 Interface,有且仅有一个Interface,是一一对应的关系。除此之外,还包含若干个filter,这些filter的数量也没有什么限制,filter可以通过 SE18 进行创建、修改、查看。
Enhancement Spot 可以创建无数 Enhancement Implementation,通过 SE19 进行创建修改和删除,因为 Enhancement Spot 下面可以定义无数BADI Definition,因此 Enhancement Implemention下面固然也可以创建无数个相应的BADI Implemention,在创建 BADI Implemention的时候要指定BADI Implemention Class的名字,需要注意的是,每个 BADI Definition 都对应一个interface,那么BADI Implementation就对应一个class,并且该class实现了相应的interface。
5.3、实现方式
不建议使用此种增强,只有在通过 BADI 与 Exit 都无法实现时,才考虑该增强。
(1)标准程序一般增强步骤
DEBUG标准程序找到需要增强的位置,点 编辑 -> 显示 隐式增强选项,查看是否有预留增强选项(标准程序不能自己创建enhancement option,只能使用系统预留的)。
具体增强实施,参考下一部分内容。
(2)自开发程序增强实施演示
参考《SAP第四代增强开发DEMO》
附:SAP提供了一个标准程序SNIF,通过这个程序可以直接查找出系统已经实施的BAdi、BTE、客户出口、字段出口甚至是调用的BAPI。具体操作方法:打开【系统】|【状态】菜单,双击进入程序,点击【对象列表】按钮,然后通过点击【上级对象列表】按钮,找到程序所在的包。SE38运行程序SNIF,输入包名,如果勾上【也选择SAP实施业务加载项】就会把SAP标准的增强实现也显示出。运行后,可以点击各Tab页查看已经实现的自定义增强。
参考链接:https://blog.csdn.net/XLevon/article/details/127632234