SAP增强大全(SAP標準を拡張する手段)

1、在se37中为MODX_FUNCTION_ACTIVE_CHECK设置断点
运行事务得到如EXIT_SAPLKBER_002这样的接口
2、在se37中查看EXIT_SAPLKBER_002的包含程序并创建ZXK01U02
3、在ZXK01U02中写入自己的处理代码
4、在se16中找表MODSAP,查到增强名如COCCA002
5、在cmod中创建自己的增强、增强分配中添加COCCA002,激活。

网络
 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_VALUES_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_VALUES_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]. CUATEXTS-> 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_<program name><3 digit suffix> 
示例:
sd的VA01事务,对应的程序是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 MODATTR 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_ACTIVATE(会操作相关报表)



sap寻找用户出口方法
sap的用户出口总共有三代:
一、User EXIT
    这种出口据说是第一代的用户出口,它们include在SAP标准程序的源代码里,可以说他们是源代码的一部分,你改了这种出口就相当于改了SAP标准程序,是需要申请access key才能更改的,不需要建立PROJECT。很多标准程序里的ZZ或者Z结尾的包括程序里都有以user_exit_开始的子程序.
二、Customer exit
   可以把这种出口看成第二代的的出口,好像增强(ehancement)就是指这类,不知道我有没有理解正确,这种出口又包括了六种不同的类型.
   1)function exit,
   2)menu exit,
  3)table exit,
  4)field exit,
  5)screen exit,
  6)keyword exit,
就是function exit.这种出口是以FM的形式存在的,其开发的方式是找到相关的增强后,建立PROJECT,然后在componemt里有FM,在FM里有以Z开始INCLUDE程序,双击这个INCLUDE程序进入后就可以根据FM里IMPORT/EXPORT/CHANGING/TABLE等来开发你们的需求。这些增强是不需要申请ACCESS KEY的,因为他们不属于SAP标准程序里的一部分。这种增强FM的命名方式是EXIT_programname_NNN,NNN是3个数字的序号,实际上在SAP的标准程序里,会用到下面的方式调用该增强的逻辑:call customer-function 'NNN',从而来达到用户的需求。
三、BADI
   这是基于面向对像的第三代增强。自己也只做过1次,特别是自己对SAP的面向对像还搞不清楚,寒~~`一时之间说不出个所以。前面介绍的两种出口增强,都是SAP提供固定的点给用户进行开发,而BADI这种增强,则让顾问们很自由地定义需要增强的地方,据说SAP很多的行业方案就是用这种形式来扩展的。
   如果你需要找某一个出口/增强,还是回去看SPRO,每一个模块里都基本有system modificatio或者BADI的说明,这样能更快找到相关的东西。

1、关于增强的简单介绍
1.1 SMOD包含具体的增强,而CMOD是包含一组SMOD编写的增强. 
1.2 User exits (Function module exits)是sap提供出口,它的命名规则如下:
EXIT_<program name><3 digit suffix> 
示例:
sd的VA01事务,对应的程序是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将增强项目激活,便大工告成。
以下给出一个实例作为参考:

REPORT ZTEST_USER_EXIT  .
TABLES : TSTC,     "SAP Transaction Codes
         TADIR,    "Directory of Repository Objects
         MODSAPT,  "SAP Enhancements - Short Texts
         MODACT,   "Modifications
         TRDIR,    "System table TRDIR
         TFDIR,    "Function Module
         ENLFDIR,  "Additional Attributes for Function Modules
         TSTCT.    "Transaction Code Texts
DATA : JTAB LIKE TADIR OCCURS 0 WITH HEADER LINE.
DATA : FIELD1(30).
DATA : V_DEVCLASS LIKE TADIR-DEVCLASS.
PARAMETERS : P_TCODE LIKE TSTC-TCODE OBLIGATORY.
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 EQ 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:/(19) 'Transaction Code - ',
  20(20) P_TCODE,
  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:/ 'No of Exits:' , SY-TFILL.
  ELSE.
    FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.
    WRITE:/(95) 'No User Exit exists'.
  ENDIF.
ELSE.
  FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.
  WRITE:/(95) 'Transaction Code Does Not Exist'.
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.