ABAP开发中的增强
ABAP开发中的增强
日期:2008-10-12开始整理
版权声明:大部分资料来源于网络,部分文字、格式及排版出自本人,部分截图由本人亲自完成,如有侵权,请告知本人,欢迎来信讨论SAP或ERP相关的话题。
免责声明:本资料仅供研究、学习、学术讨论之用,不得用于生产环境。对于使用本文档产生的损失,本人不承担任何责任!
★一般说明
使用SAP的增强建议系统学习一下SAP 标准教材BC425 和BC427。
ABAP开发中的增强至少经历了4代,下面详细说明。
★第一代:基于源代码的增强
源代码增强以子程序形式发布,在SAP 的发行版本中,使用PERFORM 调用这些子程序,它们在发布时都是空的,sap提供一个空代码的子过程,在这个子过程中用户可以添加自己的代码,控制自己的需求。这类增强需要修改sap的标准代码。
示例:USEREXIT ... in SAPMV45A。主要集中在一些文件名倒数第二个字符为Z 的包含程序中。用户增强时,应首先到service marketplace 申请对象键,然后才能修改这些子程序,这些子程序可以使用程序中所有的全局数据。
对于第一代增强,可以用以下方法查找增强:
打开欲增强的程序,点击工具栏上的“Display Object List”按钮,选择Subroutines,查找以“UserExit”开头的子程序,根据子程序前面的注释文档来查找用户出口,如下图,事务码:SE38
下面这些以USEEXIT_...开头的都是空的子程序,可以添加自己的代码。
屏幕增强以客户屏幕形式发布,它们包含在标准程序中,没有什么特别规律。
这种源代码增强和屏幕增强的说明可以从事务码spro 后台配置中相关模块的路径里面找到。
同时使用的针对数据表的增强是append structure,可以在事务码se11 中打开透明表,点击应用工具栏最右边的那个append structure 按钮就能为数据表追加新的字段。
这种更改标准程序的方法现在很少使用,因为系统升级有可能不能工作。如果在代码中改变了全局变量,还可能会破坏系统原有的逻辑。
★第二代:基于函数模块的增强
源代码增强以函数模块形式发布,在SAP 的发行版本中,使用CALL CUSTOMER-FUNCTION 调用这些函数模块,它们在发布时只有一句代码INCLUDE xxxxxxx。用户增强时,无需申请对象键,直接双击这个包含,然后回车,就可以创建相关的包含文件,编写相应的代码了。这些函数模块中只能使用接口中传递的参数,不能使用调用程序的全局变量。
首先来讲解一下什么是出口,顾名思义,就是一段程序执行到最后必经的一段程序。在Sap中出口就是标准程序最后要调用的一个函数或者功能模块,这个函数或功能模块的输入已经由Sap定义好。
为什么会有出口呢?因为正常的业务系统不能满足实际需求,这时可以在出口中增加一些功能,来达到要求,这也就是为什么它还叫增强。
自己写的SAP出口程序在系统升级的时候会被保留,而如果更改标准程序在SAP系统升级的时候会被覆盖。
下面介绍一下什么时候需要使用出口以及出口的种类:
1、在业务检查时,比如在某个工厂发货,可以设定在某个库位的出货只能使用某种移动类型。
2、在需要界面增强时,比如用户对某个字段要求大写,但是最终用户不按规范操作,这也可以在出口中自动转换,有
些模块甚至能自定义数据库字段,并且可以在出口中增加字段输入。还有的模块能对输入数据检查,甚至实现自动替代等功能。
3、有不规则业务时,比如按某种条件定价,可以设定从自己定义的表中按某种条件取值。
4、搜索帮助的出口,可以对Sap标准的搜索帮助做权限控制,等等。
SAP有四种基本用户出口的类型:
1、菜单出口-Menu Exits,定义自己的菜单;
2、屏幕出口-Screen Exits,定义自己的屏幕;
3、功能模块出口-Function Module Exits,在SAP应用程序中添加功能;
4、关键字出口-Keyword Exits,在ABAP/4字典中的关键字数据元素添加文档。结果是你在使用这些数据元素的字段
处按F1后会出现你自定义的说明文档。
因为出口都是被Sap预先定义好的,那么怎么寻找自己需要的出口呢?
1:可以通过配置文档的帮助和SAP library 寻找业务系统的出口,sap library 在‘implementation guide’中寻找出口,在配置功能执行按钮左边一般都有一个说明文档,描述相关的出口。
2:为了方便我们把所有的出口名称及其描述列在文章的后面。
下面具体介绍怎样写出口程序:
为了对出口程序的修改进行管理,sap提供了专门用来管理出口程序的事务,事务代码是CMOD。
这些出口函数有标准处理程序传入的参数和输出参数,用户可根据系统输入参数作为条件编写适合本企业流程的逻辑,然后通过输出参数传回给SAP。
屏幕增强也包含在函数模块所属的函数组中。
针对数据表的增强是CI_ 结构,这些结构以.INCLUDE 结构的形式包含在SAP 发布的数据表中,用户可以通过向这些结构中添加字段而对数据表进行增强。
上述这类增强通过事务码SMOD 进行维护,CMOD 进行实现。SMOD 中的一个增强可以包含上述的源代码、屏幕和表结构增强,按照较容易理解的逻辑结构来管理这些增强,使用相对更加便利。
对于第二代增强,可以用以下方法查找增强
用户增强通常包括下面3类,顾名思义,就是增强SAP的可能没有提供的功能(通过后台配置也不能实现).
1.E Enhancement exits :就是常说User_exit (用户出口)
使用SE37搜索EXIT*的函数大都是做exit用的,通常里面预包含了一个Z开头
的程序. SE16查询TFDIR(函数表)输入EXIT*也可.
2.C GUI codes( GUI接口增强)
3. S Subscreens (屏幕增强)
Enhancement在表MODSAP可看到,而TFDIR字段MAND(值为C表示此出口函数被激活).使用SMOD(CMOD)当然可激活exit function,有时候一时难以查询到相关Enhancement时可使用下面程序将出口函数激活.
REPORT Zactexitfun .
data ztfdir like tfdir .
* select single * from tfdir into ztfdir
* where FUNCNAME =
* 'EXIT_SAPMM06E_013'.
* ztfdir-MAND = 'C' .
* update tfdir from ztfdir.
* 将EXIT_SAPMM06E_013换成实际所需exit函数名
update tfdir set MAND = 'C'.
where FUNcname = 'EXIT_SAPMM06E_013'.
***当然也可SE16:MODSAP表enhancement输入EXIT_SAPMM06E_013然后得到enhancement name MM06E005后使用SMOD测试激活exit函数.
增强相关函数和表格
Function:
[1].DYNP_V ALUES_READ
[2]. MODX_ALL_ACTIVE_MENUENTRIES(菜单增强)
[3].MODX_FUNCTION_ACTIVE_CHECK(出口函数增强)
由于读者可能接触user exit最多,除了附录光盘有个查找ZFINDEXIT的程序外(有些exit使用它并不能找到),另一个直接有效的方法就是使用这个函数,SE37设好断点后执行tcode如其有exit就会调用此函数.
[4].MODX_MENUENTRY_ACTIVE_CHECK(菜单增强)
[5].MODX_SUBSCREEN_ACTIVE_CHECK(屏幕增强)
Table:
[1]. TFDIR->function module table
[2]. MODSAP->sap enhancement table
[3]. TSDIR->Dynpro Areas CALL CUSTOMER SUBSCREEN(屏幕增强)
[4]. CUA TEXTS-> GUI Interface: Menu Texts Changed(GUI 菜单文本增强)
***注意,为了确保一个出口被真正应用,必须同时激活相关程序(SE38)和出口函数(SMOD|CMOD,反正就是要保证tfdir-mandt=’C’,用程序也可.)
the third generation enhancement will be discussed in the next post.
1、关于增强的简单介绍
1.1 SMOD包含具体的增强,而CMOD是包含一组SMOD编写的增强.
1.2 User exits (Function module exits)是sap提供出口,它的命名规则如下:
EXIT_
示例:
sd的V A01事务,对应的程序是SAPMV45A ,你会在程序里查到(用CALL CUSTOMER-FUNCTION字符串)如下代码:
CALL CUSTOMER-FUNCTION '003'
exporting
xvbak = vbak
xvbuk = vbuk
xkomk = tkomk
importing
lvf_subrc = lvf_subrc
tables
xvbfa = xvbfa
xvbap = xvbap
xvbup = xvbup.
则exit calls function module的名称就是:EXIT_SAPMV45A_003
2、先试用SMOD建立一个SAP增强
2.1、选择一个增强,如:SDVFX001 ,点击修改,进入sap增强维护屏幕;
2.2、点击"组件"按钮,进入组件维护屏;
2.3、将光标移到"功能模块名",输入模块名,如:EXIT_SAPLV60B_001;
2.4、选择"代码修改"按钮进入函数模块;
2.5、双击函数模块的包含单元,进入包含单元加入自定义代码并激活保存;
3、使用CMOD建立增强项目
3.1、输入自定义的项目名,点击"创建";
3.2、进入增强项目,选择"配置增强",进入增强配置屏幕;
3.3、输入增强名如:SDVFX001
3.4、保存,并退出;
4、使用CMOD将增强项目激活,便大工告成。
如何查找
*判断是否存在相应增强的定义(SMOD)
select single name from modsapa into mod0-name
where name = 'PPCO0002'.
if sy-subrc = 0.
endif.
select single * from tadir into ps_tadir_db
where pgmid = 'R3TR'
and object = 'SMOD'
and obj_name = 'PPCO0002'.
*判断是否存在相应增强项目的定义(CMOD)
SELECT SINGLE name FROM MODA TTR into mod0-name
WHERE NAME = 'PPCO0002'..
*提取增强的定义的组件(可以用此反查增强定义)
select * from modsap
where name = 'PPCO0002'.
*判断该增强是否移植到BADI实现
*Enhancement & has already been migrated in Business Add-In definition
select single migrated badi_def into (migrated, exit_name)
from modsapa where name = modname.
if sy-subrc = 0 and migrated = seex_true.
message s621 with modname exit_name.
check mode ne 'CHAM'.
endif.
MODTYP 类型:
E : 功能退出
S : 屏幕
T : 表
C : GUI代码
sap增强存在MODSAP表内
*获取增强组件的参见函数MOD_SAP_MEMBER_TEXT
*获得退出功能模块的信息
select single * from tftit
where "SPRAS" = '1' AND "FUNCNAME" = 'EXIT_SAPLCORE_001'
if sy-subrc = 0.
endif.
*值得学习的函数
MOD_KUN_ACTIVA TE(会操作相关报表)
小技巧透视ERP增强
(一)什么是增强(Enhancement)?
简单地说,增强就是ERP系统中标准程序的出口,在该出口中由用户根据企业实际需求编写客户化逻辑代码。增强是ERP系统设计时考虑到企业实际的流程有可能和系统默认标准流程不同,在标准流程框架下专门留的接口,每个接口对应一个客户化函数,这些出口函数有标准处理程序传入的参数和输出参数,用户可根据系统输入参数做条件编写适合本企业流程的逻辑,然后通过输出参数传输回。
(二)用户增强分类
SAP的用户增强通常包括下面3类。
1.E类:Enhancement exits,即通常所谓的用户出口(User_exit )
用户出口也叫功能出口(Function Exit)。
使用Tcode:SE37搜索EXIT*,找到的函数大都是做系统预留的出口函数,前面说过,用户出口是标准程序留给用户的接口,标准程序通常不允许用户任意修改,如果修改需要申请Access Key,而且修改标准程序可能导致的错误erp公司通常是不负责的。在SAP中,自定义的程序通常以保留字Y或Z开头,因此,出口函数中都预包含了一个Z开头的程序。
2.C类:GUI接口(GUI codes)
3.S类:屏幕增强(Screen Exit)
比如,在建立采购订单,工单和固定资产主数据时,系统都预留屏幕增强,也就是说允许用户自定义用户输入界面并编写相应的输入输出处理程序。
在各类增强中,可能还用户自己定义结构或表格,系统对应类型T类。比如增强MM06E005
允许用户建立两个结构CI_EKKODB和CI_EKPODB。
接下来将重点介绍功能出口的应用。
(三)组织用户增强
相关增强表格:
MODSAP:增强表格
TFDIR:包括出口函数在内的所有函数表(E类)
CUATEXTS:修改GVI 界面,界面: 菜单文本被客户(C类)
TSDIR:动态程序区CALL CUSTOMER SUBSCREEN(S类)
* 对于以EXIT开头的出口函数,TFDIR-MAND值为C表示此出口函数被激活。
相关增强检查函数:
MODX_FUNCTION_ACTIVE_CHECK:检查E类用户出口是否被激活。
MODX_MENUENTRY_ACTIVE_CHECK:检查C类增强激活状况
MODX_SUBSCREEN_ACTIVE_CHECK: 检查S类增强激活状况
你可能会发现,SAP的各模块的任何一个事务码(Tcode)对应的标准程序都留下了大量的用户出口,正是SAP灵活的配置功能和强大的用户出口才使其产品轻松应对各种复杂需求成为可能,系统还为能快速找到和激活这些增强进行了有效组织,各类增强被记录在table中并且提供了相关检查函数,从而更方便企业用户。
熟悉ABAP开发的朋友通常都收集了一个可以输入事务码快速找到系统留下的所有出口的程序,下表就是一个检测系统增强被激活的简单参考程序。
* 该程序可以检测出系统所有被激活的用户增强.
* By Stone Fu. on 2006/11/07 .
* Used to find out all the activated user-exit of SAP .
report zfindactexit .
tables: modsap,tfdir.
data : begin of itab_exit occurs 0,
funcname like tfdir-funcname,
mand like tfdir-mand,
name like modsap-name,
end of itab_exit .
data : field1(30).
_select a~funcname a~mand b~name
into table itab_exit
from tfdir as a
inner join modsap as b
on a~funcname = b~member
where a~mand = 'C'
and a~funcname = b~member .
format color col_heading intensified on.
write:/1 sy-vline,
2 'Enhancement Name',
21 sy-vline ,
22 'Activated Exit Function',
95 sy-vline.
write:/(95) sy-uline.
loop at itab_exit.
format color col_normal intensified off.
write:/1 sy-vline,
2 itab_exit-name hotspot on,
21 sy-vline ,
22 itab_exit-funcname,
95 sy-vline.
endloop.
at line-selection.
get cursor field field1.
set parameter id 'MON' field sy-lisel+1(10).
call transaction 'SMOD' and skip first screen.
有一种直接有效的查找用户出口增强的方法,就是使用函数MODX_FUNCTION_ACTIVE_CHECK,如图1。
图1中的判断语句If tfdir-mand = aktiv_flag(常数C)则出口函数active标志=’X’,表示该用户出口被激活,处理逻辑将从标准程序转入出口函数,在该语句设置断点然后运行任一个事务码,都会调用该函数判断是否存在用户出口。
(四)增强应用实例
业务背景:如果采购订单已经做了发票校验后,则不再允许用户修改价格。
相关程序:MM06EFPO_POT_FUELLEN| MM06EF0C_CUSTSCR1_ITEM_SET_DAT
相关Tcode:SMOD|CMOD
如果没有启动采购审批功能,SAP标准功能是允许用户随时修改采购价格的,不同的企业有对采购价格控制有不同的
策略,甲企业规模较小为了省事可能为以后数月的采购开了一个大采购单,如果中途材料价格变动则直接修改价格就行,乙集团则严格控制采购价格,采购价格由总部集中维护,各企业采购员只需要维护采购数量等信息等,真因如此,ERP系统显然不会去禁止用户修改价格,如果企业确实需要如此,则可通过增强实现。
前面已经介绍过如何通过在函数MODX_FUNCTION_ACTIVE_CHECK设置断点跟踪系统每个事务预留的用户出口,你很快将发现增强MM06E005的EXIT_SAPMM06E_017用户出口非常适合此业务背景。
首先来看看增强的EXIT_SAPMM06E_017用户出口(以下称017出口)处理流程,Include程序MM06EFPO_POT_FUELLEN被专门用来处理增强出口,调用了子程序CUSTSCR1_ITEM_SET_DATA_
PAI(对应下一级Include程序MM06EF0C_CUSTSCR1_ITEM_SET_DAT),分析Include程序MM06EF0C_CUSTSCR1_ITEM_SET_DAT的代码,如下表,这个程序是从系统原本Copy出来的,注意本人所加的附注粗体部分:
*-----------------------------------------------------------------------
* User-Exit für Positionsfelder versorgen (PAI)
FORM custscr1_item_set_data_pai USING im_no_screen LIKE fc_call.
"770427
DA TA: l_ucomm LIKE sy-ucomm,
l_enj_call TYPE c.
STA TICS: first_call(1) TYPE c VALUE 'X',
active LIKE sy-calld.
ENHANCEMENT-POINT CUSTSCR1_ITEM_SET_DATA_PAI_02 SPOTS ES_MM06EF0C_CUSTSCR1_I_SET_DAT INCLUDE BOUND .
*$*$-Start: CUSTSCR1_ITEM_SET_DA TA_PAI_02-------------------------------------------------------$*$*
ENHANCEMENT 1 OI0_COMMON_MM06EF0C_ITEM_S_DA T. "active version
* C5030897 I.Twardowski Implementation of BADI for OGSD
PERFORM OI0_BADISCR1_ITEM_SET_DATA_PAI.
ENDENHANCEMENT.
*$*$-End: CUSTSCR1_ITEM_SET_DATA_PAI_02-------------------------------------------------------$*$*
IF NOT first_call IS INITIAL.
CLEAR first_call.
*注释: MODX_FUNCTION_ACTIVE_CHECK用来检查017出口是否被激活,如果激活则执行之.
CALL FUNCTION 'MODX_FUNCTION_ACTIVE_CHECK'
EXPORTING
cprogname = 'SAPMM06E'
funcnumber = '017'
IMPORTING
active = active
EXCEPTIONS
not_found = 1
OTHERS = 2.
IF NOT sy-subrc IS INITIAL.
CLEAR active.
ENDIF.
ENDIF.
CHECK NOT active IS INITIAL.
IF fc_vorga EQ cva_en.
l_enj_call = 'X'.
ELSE.
l_enj_call = space.
ENDIF.
*-Define Data:
DA TA: lt_usr_tekpo LIKE bekpo OCCURS 0,
lt_usr_teket LIKE beket OCCURS 0,
lt_usr_tekkn LIKE ekknu OCCURS 0,
lt_usr_tkomv LIKE tkomv OCCURS 0.
*-Copy Tables:
lt_usr_tekpo[] = pot[].
lt_usr_teket[] = ett[].
lt_usr_tekkn[] = knt[].
lt_usr_tkomv[] = tkomv[].
l_ucomm = ok-code.
*注释:调用出口的一般步骤是先定义数据(Define Data),多为内表或工作区,再将参数赋予这些内表(Copy Tables),相当于*建立了原始参数的一个镜象.
*-User Exit:
*如果017出口增强被激活则执行它.
CALL FUNCTION 'EXIT_SAPMM06E_017'
EXPORTING
i_ekpo = ekpo
i_ekpo_old = *ekpo
i_ekko = ekko
i_aktyp = aktyp
i_bstyp = ekko-bstyp
i_no_screen = im_no_screen "770427
i_lfa1 = lfa1
i_lfm1 = lfm1
i_rekpo = rekpo
i_kekpo = kekpo
i_aekpo = aekpo
i_reban = reban
i_mt06e = mt06e
i_eina = *eina
i_eine = *eine
i_komp = komp
i_ucomm = l_ucomm
i_enj_call = l_enj_call
TABLES
tekpo = lt_usr_tekpo
teket = lt_usr_teket
tekkn = lt_usr_tekkn
tkomv = lt_usr_tkomv
EXCEPTIONS
OTHERS = 0.
ENDFORM. "CUSTSCR1_ITEM_SET_DATA_PAI
上面的程序代码非常简单,相信聪明的读者看了对ERP增强的设计思路会开始有一定了解。
现在你可以通俗理解,增强就是ERP设计者在合适的地点设置了一些合适的游戏规则并提供了一些有意义的游戏给用户自己玩耍!独乐乐,与人乐乐,孰乐?好玩的东西应该留点给用户自己乐呵乐呵。
接下来开始编写增强程序,可以使用Tcode:SMOD直接激活增强或CMOD建立一个项目包含一个或多个增强,如图2,输入增强MM06E005并激活它,然后在EXIT_SAPMM06E_017出口函数中编写代码。
在图2中,我们发现增强MM06E005包括用户出口和屏幕增强(Screen Exit),屏幕增强允许用户在采购订单自定义用户界面,从而使采购订单包含更多企业客户化的信息,这种屏幕增强在固定资产模块中更始发挥到极致。
EXIT_SAPMM06E_017包含程序ZXM06U42,程序ZXM06U42示例代码如下表,这段客户化代码逻辑十分简单,为了方便说明,本人注释出该出口函数的输入参数,该出口没有输出参数,也就是说,你只能根据输入参数进行判断而不能更改任何数据:
*增强ZXM06U42的示例代码
*By Stone.Fu 2007/01/02
*"*"Lokale Schnittstelle:
*IMPORTING/TABLES是输入的单个参数和输入的内表参数
*" IMPORTING
*" V ALUE(I_EKPO) LIKE EKPO STRUCTURE EKPO
*" V ALUE(I_AKTYP)
*" V ALUE(I_BSTYP) LIKE EKKO-BSTYP
*" V ALUE(I_NO_SCREEN)
*" V ALUE(I_LFA1) LIKE LFA1 STRUCTURE LFA1
*" V ALUE(I_LFM1) LIKE LFM1 STRUCTURE LFM1
*" V ALUE(I_EKKO) LIKE EKKO STRUCTURE EKKO
*" V ALUE(I_REKPO) LIKE EKPO STRUCTURE EKPO OPTIONAL
*" V ALUE(I_KEKPO) LIKE EKPO STRUCTURE EKPO OPTIONAL
*" V ALUE(I_AEKPO) LIKE EKPO STRUCTURE EKPO OPTIONAL
*" V ALUE(I_REBAN) LIKE EBAN STRUCTURE EBAN OPTIONAL
*" V ALUE(I_MT06E) LIKE MT06E STRUCTURE MT06E OPTIONAL
*" V ALUE(I_EINA) LIKE EINA STRUCTURE EINA OPTIONAL
*" V ALUE(I_EINE) LIKE EINE STRUCTURE EINE OPTIONAL
*" V ALUE(I_EKPO_OLD) LIKE EKPO STRUCTURE EKPO OPTIONAL
*" V ALUE(I_KOMP) LIKE KOMP STRUCTURE KOMP OPTIONAL
*" V ALUE(I_UCOMM) LIKE SY-UCOMM OPTIONAL
*" V ALUE(I_ENJ_CALL) OPTIONAL
*" TABLES
*" TEKPO STRUCTURE BEKPO OPTIONAL
*" TEKET STRUCTURE BEKET OPTIONAL
*" TEKKN STRUCTURE EKKNU OPTIONAL
*" TKOMV STRUCTURE KOMV OPTIONAL
*"----------------------------------------------------------------------
*判断程序代码如下:
DA TA ZWATEKPO like BEKPO.
TABLES EKBE .
* 输入的内表参数TEKPO记录该采购单所有的原始旧数据.
* 输入的I_EKPO 参数表示当前处理的PO行项目,其包含的是采购行项目的最新更新数据.
READ TABLE TEKPO INTO ZWA TEKPO WITH KEY EBELP = I_EKPO-EBELP .
***只对ME21N/22/23才生效.
check SY-TCODE = 'ME22N ' or SY-TCODE = 'ME22N' or SY-TCODE = 'ME23N' .
***EKBE是PO history 表,如有Q,R表示有发票校验历史,不允许更改价##
SELECT SINGLE_ * FROM EKBE
WHERE EBELN = I_EKPO-EBELN
AND EBELP = I_EKPO-EBELP
AND ( BEWTP = 'Q' OR BEWTP = 'R' ) .
*如果SY-SUBRC =0表示发票已经校验,不允许更改价格。
CHECK SY-SUBRC = 0 .
*判断数据更改后新采购行项目的单价是否和从数据库读出的原始行项目单价一致
IF I_EKPO-NETPR <> ZW ATEKPO-NETPR .
MESSAGE E001(00) with '采购订单行项目已经进行发票校验,不再允许修改价格
ENDIF.
如果你熟悉增强,你会发现一些用户出口都会传入旧数据和更新后的新数据以方便两者比较,和财务模块的替代(Substitution)不同,ERP系统一般对增强保留严谨态度,通常只允许在出口中做检查工作,这一点类似财务模块的检查(Validation)。
(五)再次浅析增强
企业实施ERP的目的之一就是实现各部门信息共享,避免数据孤岛,以一个简单的采购收货为实例,仓库人员只要在收货时输入采购订号,收货日期,物料收货数量和仓位,系统将自动产生各模块数据,对财务数据,系统根据输入的采购订单号找到采购订单主数据中的工厂,通过在组织结构中设置的工厂和公司代码的对应关系找到相应公司代码;通过收货物料的Valuation class和收货的移动类型找到对应科目,通过收货数量*采购单价得到本次该料库存金额,通过物料主数据获得业务范围和利润中心,这样财务凭证数据自动收集完毕;如果物料采用标准价格出现采购差异并将差异科目的模认成本对象对应到获利分析段,则将数据写入利润分析模块等等;我要说的是,在这些复杂的逻辑背后,任何一个模块收集过程中存在校验,任何校验失败ERP系统都将停止业务交易,比如说校验收货日期不在物料期间或会计期间允许范围,校验失败向用户提示错误,比如预算模块找不到对应基金中心提示错误中止交易等,当所有的校验完毕,系统将数据Commit到数据库,这些校验是系统标准的,而增强则是系统预留给用户的,和系统的校验一样,在任何模块的增强中只要是出现错误都将停止本次业务交易。在图3中出现的检查/替代/增强/字段移动/推导等关键词,实际上这些东东都可看成系统增强,即使用客户化代码增强标准功能。
有趣的是,SAP的各种增强的代码编写都是极其简单的,象检查/替代/字段移动/推导/派生用户甚至只要简单将对应的源字段和目标字段拖拖拽拽关联关联就行,代码是自动生成的,即使涉及Coding也是非常简单的。神奇的是,作为SAP 顾问你甚至可以对编程和数据库毫不了解,实际上很都SAP顾问的确如此,你只要专注于业务蓝图实现就行,这一点值得国内管理软件设计同行学习,在管理软件设计过程中,同样是细节决定成败。
新一代增强BADI (Tcode:SE17|SE18)
BADI(Business Add-In)是一种新的功能增强概念,它使用类、接口及方法等面向对象的概念,采用一种使用面向对象的方法来进行SAP 增强。
如何查找事务代码所在程序的用户出口(user-exit):
1。执行tcode --> system --> status,找出程序名称。
2。SE80;输入第一步中找到的程序名称。用菜单:GOTO --> Attributes,找出Package 名称。(注:也可以用SE93,查这个
程式所在的Package)
3。SE80 --> Repository Information System --> Enhancements --> Customer Exits --> Enhancements -->将第二步中
找到的Package 名称输入,执行,就可以找到tcode的所有用户出口。
*****************************************************************************************************
TABLES : tstc, "SAP Transaction Codes(SAP 事务代码)
tadir, "Directory of Repository Objects(资源库对象的目录)
modsapt, "SAP Enhancements - Short Texts(SAP增强-短文件)
modact, "Modifications(修正)
trdir, "System table TRDIR(系统表TRDIR)
tfdir, "Function Module(功能模块)
enlfdir, "Additional Attributes for Function Modules(功能模块的附加属性) tstct. "Transaction Code Texts(事务代码文本)
DA TA : jtab LIKE tadir OCCURS 0 WITH HEADER LINE.
DA TA : field1(30).
DA TA : v_devclass LIKE tadir-devclass.
SELECTION-SCREEN BEGIN OF BLOCK a01 WITH FRAME TITLE text-001. SELECTION-SCREEN SKIP.
PARAMETERS : p_tcode LIKE tstc-tcode OBLIGATORY.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN END OF BLOCK a01.
START-OF-SELECTION.
SELECT SINGLE * FROM tstc WHERE tcode EQ p_tcode.
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 = enlfdir-area.
MOVE : tadir-devclass TO v_devclass.
ENDIF.
ENDIF.
SELECT * FROM tadir
INTO TABLE jtab
WHERE pgmid = 'R3TR'
AND object = 'SMOD'
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:/(12) '事务代码- ',
13(20) p_tcode,
34(10) '功能- ' ,
45(50) tstct-ttext.
SKIP.
IF NOT jtab[] IS INITIAL.
WRITE:/(95) sy-uline.
FORMAT COLOR COL_HEADING INTENSIFIED ON. WRITE:/1 sy-vline,
2 'Exit Name',
21 sy-vline ,
22 'Description',
95 sy-vline.
WRITE:/(95) sy-uline.
LOOP AT jtab.
SELECT SINGLE * FROM modsapt
WHERE sprsl = sy-langu AND
name = jtab-obj_name.
FORMAT COLOR COL_NORMAL INTENSIFIED OFF. WRITE:/1 sy-vline,
2 jtab-obj_name HOTSPOT ON,
21 sy-vline ,
22 modsapt-modtext,
95 sy-vline.
ENDLOOP.
WRITE:/(95) sy-uline.
DESCRIBE TABLE jtab.
SKIP.
FORMAT COLOR COL_TOTAL INTENSIFIED ON. WRITE:/ '用户出口数量:' , sy-tfill.
ELSE.
FORMAT COLOR COL_NEGATIVE INTENSIFIED ON. WRITE:/(95) '此TCode没有用户出口!'.
ENDIF.
ELSE.
FORMAT COLOR COL_NEGATIVE INTENSIFIED ON. WRITE:/(95) '事务代码不存在!'.
ENDIF.
AT LINE-SELECTION.
GET CURSOR FIELD field1.
CHECK field1(4) EQ 'JTAB'.
SET PARAMETER ID 'MON' FIELD sy-lisel+1(10).
CALL TRANSACTION 'SMOD' AND SKIP FIRST SCREEN. SAP 中如何寻找增强
方法一、利用TCODE寻找增强(第二代的增强)
执行一个程序(源代码后附),在选择屏幕处输入你所需要增强的程序TCODE,执行後,就会出现一个列表,那里就有关于如何增强这个的绝大部分SMOD增强。
点击进去,自己手动寻找需要的增强。
这是第二代增强
方法二、利用系统函数寻找
MODX_FUNCTION_ACTIVE_CHECK
在这个FUNCTION的代码最后添加一个断点。执行需要增强的TCODE,如果有增强,就会自动跳入DEBUG界面。在DEBUG界面,查看f_tab字段,这里面所显示的Smod就是关于这个TCODE所有的增强项目的列表。这些增强都是属于EXIT_XXXXXX_XXX这种形式。
至于如何查看这个增强是属于哪个SMOD,可以自己查阅MODSAP这个表(SAP Enhancements).
这是第二代增强。
还有一些FUNCTION供参考:
[1].DYNP_V ALUES_READ
[2]. MODX_ALL_ACTIVE_MENUENTRIES(菜单增强)
[3].MODX_FUNCTION_ACTIVE_CHECK(出口函数增强)
[4].MODX_MENUENTRY_ACTIVE_CHECK(菜单增强)
[5].MODX_SUBSCREEN_ACTIVE_CHECK(屏幕增强)
这些的使用方法和上述的一样,可以针对各种情况寻找增强。
方法三、从程序代码中找
在需要增强的事务里面,打开SYSTEM——》status,双击进入PROGRAM,查看所有的subroutines,重点观察所有形似userexit_******* 这种,由描述来确定合适的需要增强的FORM。这里是第一代的增强。
方法四、针对BADI的增强
转摘自网上
1、badi对象的信息存储在SXS_INTER, SXC_EXIT, SXC_CLASS 和SXC_ATTR 这四个表中。
2、sap程序都会调用cl_exithandler=>get_instance来判断对象是否存在,并返回实例;其实get_instance就是对上述几个表和他们的视图(V_EXT_IMP 和V_EXT_ACT)进行查询和搜索。
3、基于这个机理,我查用ST05来监控一个TCODE来跟踪,然后选择查找有关上述几个表和视图的操作,就可获得相关BADI。
4、se18 查找接口,se19 实现接口就可以实现用户增强。
****************************************************************************************************** ******************************
首先来讲解一下什么是出口,顾名思义,就是一段程序执行到最后必经的一段程序。
为什么会有出口呢?因为正常的业务系统不能满足实际需求,这时可以在出口中增加一些功能,来达到要求,这也就是为什么它还叫增强。我感觉它跟给操作系统打补丁差不多。
在Sap中出口就是标准程序最后要调用的一个函数或者功能模块,这个函数或功能模块的输入已经由Sap定义好。
自己写的SAP出口程序在系统升级的时候会被保留,而如果更改标准程序在SAP系统升级的时候会被覆盖。
下面介绍一下什么时候需要使用出口以及出口的种类:
1:在业务检查时,比如在某个工厂发货,可以设定在某个库位的出货只能使用某种移动类型。
2:在需要界面增强时,比如用户对某个字段要求大写,但是最终用户不按规范操作,这也可以在出口中自动转换,有些模块甚至能自定义数据库字段,并且可以在出口中增加字段输入。还有的模块能对输入数据检查,甚至实现自动替代等功能。
3:有不规则业务时,比如按某种条件定价,可以设定从自己定义的表中按某种条件取值
4:搜索帮助的出口,可以对Sap标准的搜索帮助做权限控制。
等等。
SAP有四种基本用户出口的类型:
1.菜单出口-Menu Exits
定义自己的菜单
2.屏幕出口-Screen Exits
定义自己的屏幕
3.功能模块出口-Function Module Exits
在SAP应用程序中添加功能
4.关键字出口-Keyword Exits
在ABAP/4字典中的关键字数据元素添加文档。结果是你在使用这些数据元素的字段处按F1后会出现你自定义的说明文档
因为出口都是被Sap预先定义好的,那么怎么寻找自己需要的出口呢?
1:可以通过配置文档的帮助和SAP library 寻找业务系统的出口,sap library 在‘implementation guide’中寻找出口,
在配置功能执行按钮左边一般都有一个说明文档,描述相关的出口。
2:为了方便我们把所有的出口名称及其描述列在文章的后面。
下面具体介绍怎样写出口程序:
为了对出口程序的修改进行管理,sap提供了专门用来管理出口程序的事务,事务代码是CMOD。
****************************************************************************************************** ******************************
sap的用户出口总共有三代:
1、第一代
sap提供一个空代码的子过程,在这个子过程中用户可以添加自己的代码,控制自己的需求。这类增强都需要修改sap 的标准代码。
示例:USEREXIT.. in SAPMV45A
2、第二代
sap提供的是CUSTOMER-FUNCTION,它是通过SMOD和CMOD完成实现。
3、第三代
sap提供的第三代的用户出口就是BADI,他的调用方式是CALL METHOD (instance),(相关的TCODE是SE18和SE19),可以通过EXIT_HANDLER这个单词查找BADI。
对于第一代增强,可以用以下方法查找增强:
打开欲增强的程序,点击工具栏上的“Display Object List”按钮,选择Subroutines,查找以“UserExit”开头的子程序,根据子程序前面的注释文档来查找用户出口
对于第二代增强,可以用以下方法查找增强
用户增强通常包括下面3类,顾名思义,就是增强SAP的可能没有提供的功能(通过后台配置也不能实现).
1.E Enhancement exits :就是常说User_exit (用户出口)
使用SE37搜索EXIT*的函数大都是做exit用的,通常里面预包含了一个Z开头
的程序. SE16查询TFDIR(函数表)输入EXIT*也可.
2.C GUI codes( GUI接口增强)
3. S Subscreens (屏幕增强)
Enhancement在表MODSAP可看到,而TFDIR字段MAND(值为C表示此出口函数被激活).使用SMOD(CMOD)当然可激活exit function,有时候一时难以查询到相关Enhancement时可使用下面程序将出口函数激活.
REPORT Zactexitfun .
data ztfdir like tfdir .
* select single * from tfdir into ztfdir
* where FUNCNAME =
* 'EXIT_SAPMM06E_013'.
* ztfdir-MAND = 'C' .
* update tfdir from ztfdir.
* 将EXIT_SAPMM06E_013换成实际所需exit函数名
update tfdir set MAND = 'C'.
where FUNcname = 'EXIT_SAPMM06E_013'.
***当然也可SE16:MODSAP表enhancement输入EXIT_SAPMM06E_013然后得到enhancement name MM06E005后使
用SMOD测试激活exit函数.
增强相关函数和表格
Function:
[1].DYNP_V ALUES_READ
[2]. MODX_ALL_ACTIVE_MENUENTRIES(菜单增强)
[3].MODX_FUNCTION_ACTIVE_CHECK(出口函数增强)
由于读者可能接触user exit最多,除了附录光盘有个查找ZFINDEXIT的程序外(有些exit使用它并不能找到),另一个直接有效的方法就是使用这个函数,SE37设好断点后执行tcode如其有exit就会调用此函数.
[4].MODX_MENUENTRY_ACTIVE_CHECK(菜单增强)
[5].MODX_SUBSCREEN_ACTIVE_CHECK(屏幕增强)
Table:
[1]. TFDIR->function module table
[2]. MODSAP->sap enhancement table
[3]. TSDIR->Dynpro Areas CALL CUSTOMER SUBSCREEN(屏幕增强)
[4]. CUA TEXTS-> GUI Interface: Menu Texts Changed(GUI 菜单文本增强)
***注意,为了确保一个出口被真正应用,必须同时激活相关程序(SE38)和出口函数(SMOD|CMOD,反正就是要保证tfdir-mandt=’C’,用程序也可.
****************************************************************************************************** *******
1.1 SMOD包含具体的增强,而CMOD是包含一组SMOD编写的增强.
1.2 User exits (Function module exits)是sap提供出口,它的命名规则如下:
EXIT_
示例:
sd的V A01事务,对应的程序是SAPMV45A ,你会在程序里查到(用CALL CUSTOMER-FUNCTION字符串)如下代码:
CALL CUSTOMER-FUNCTION '003'
exporting
xvbak = vbak
xvbuk = vbuk
xkomk = tkomk
importing
lvf_subrc = lvf_subrc
tables
xvbfa = xvbfa
xvbap = xvbap
xvbup = xvbup.
则exit calls function module的名称就是:EXIT_SAPMV45A_003
2、先试用SMOD建立一个SAP增强
2.1、选择一个增强,如:SDVFX001 ,点击修改,进入sap增强维护屏幕;
2.2、点击“组件”按钮,进入组件维护屏;
2.3、将光标移到“功能模块名”,输入模块名,如:EXIT_SAPLV60B_001;
2.4、选择“代码修改”按钮进入函数模块;
2.5、双击函数模块的包含单元,进入包含单元加入自定义代码并激活保存;
3、使用CMOD建立增强项目
3.1、输入自定义的项目名,点击“创建”;
3.2、进入增强项目,选择“配置增强”,进入增强配置屏幕;
3.3、输入增强名如:SDVFX001
3.4、保存,并退出;
4、使用CMOD将增强项目激活,便大工告成。
如何查找
*判断是否存在相应增强的定义(SMOD)
select single name
from modsapa
into mod0-name
where name = 'PPCO0002'.
if sy-subrc = 0.
endif.
select single *
from tadir
into ps_tadir_db
where pgmid = 'R3TR'
and object = 'SMOD'
and obj_name = 'PPCO0002'.
*判断是否存在相应增强项目的定义(CMOD)
SELECT SINGLE name FROM MODA TTR into mod0-name
WHERE NAME = 'PPCO0002'..
*提取增强的定义的组件(可以用此反查增强定义)
select * from modsap
where name = 'PPCO0002'.
*判断该增强是否移植到BADI实现
*Enhancement & has already been migrated in Business Add-In definition
select single migrated badi_def into (migrated, exit_name)
from modsapa where name = modname.
if sy-subrc = 0 and migrated = seex_true.
message s621 with modname exit_name.
check mode ne 'CHAM'.
endif.
MODTYP 类型:
E : 功能退出
S : 屏幕
T : 表
C : GUI代码
sap增强存在MODSAP表内
*获取增强组件的参见函数MOD_SAP_MEMBER_TEXT
*获得退出功能模块的信息
select single * from tftit
where "SPRAS" = '1' AND "FUNCNAME" = 'EXIT_SAPLCORE_001'
if sy-subrc = 0.
endif.
*值得学习的函数
MOD_KUN_ACTIV ATE(会操作相关报表)
【引用】SAP增强
2011-06-20 02:05:29| 分类:SAP ABAP |字号订阅
本文引用自jawenker《SAP增强》
一介绍
用户增强: 所有的Enhancement在表MODSAP,用户增强大概有三类
MODSAP是Enhancement表, 而TFDIR是看是否此enhancement被激活,就看字段MAND是否是”C”而已
1. E Enhancement exits :就是常说的写User_exit ,经常使用
2. C GUI codes 没用过
3. S Subscreens 屏幕增强
什么叫用户出口呢?打个比方说吧,SAP软件就象一根晾衣服的绳子,上面有数不清的衣架,多数衣架上已经挂上了衣服,就些衣服就SAP的标准程序,还有些衣架是空着的,这些就是“用户出口”,你可以把自己做的衣服(比如程序代码)挂到这些衣架上去--如果你觉得SAP给你准备的衣服不够穿或者不合身的话。
使用用户出口可以:
-不影响标准SAP源代码
-不影响软件升级
SAP有四种基本用户出口的类型:
1.菜单出口-Menu Exits
定义自己的菜单
2.屏幕出口-Screen Exits
定义自己的屏幕
3.功能模块出口-Function Module Exits
在SAP应用程序中添加功能