• 【SAP Abap】SAP增强开发总结


    1、概述

    1.1、增强的概念

    • 增强(enhancement)的概念其实很广,SAP标准系统之上的所有二次开发,都可以理解为增强。
    • 做增强的目的,就是标准的sap正常的业务系统不能满足实际需求,需要增加不同的功能来达到不同企业的要求。
    • ABAP开发的增强主要指的是标准系统事先预留好的接口,根据不同业务需求,进行开发,这种开发称为增强,又叫出口,如果增强满足不了,就只能修正。
      在这里插入图片描述

    1.2、增强的类型

    • 菜单增强
    • 屏幕增强
    • 功能模块增强
    • 表/结构增强

    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 等类似关键字
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    (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菜单文本增强)

    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 .
    *** check input data
    AT SELECTION-SCREEN.
    *AT SELECTION-SCREEN ON .
    *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
    
    • 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

    运行程序,界面如下,输入需要查找增强的对应功能TCODE,如:物料显示-MM03
    在这里插入图片描述
    在这里插入图片描述
    二代增强行上单击,可以进入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页查看已经实现的自定义增强。

  • 相关阅读:
    JavaIO流: IO流原理即流的分类
    mysql性能分析
    行人属性识别二:添加新网络训练和自定义数据集训练
    【从入门到精通系列】-- MySQL(持续更新中……)
    【QT小记】QT线程同步--QWaitCondition
    编写一个函数,输入一个十进制数,输出对应 的十六进制数。(不能用printf的%x格式说明符)
    opencv中的图像操作
    数据结构—B树、B+树
    口感鲜美的健康饮品,随时补充营养恢复活力,厘盏蛋白银耳燕窝体验
    基于GenericAPIView以及五个视图扩展类写接口
  • 原文地址:https://blog.csdn.net/XLevon/article/details/127632234