SAP ABAP 中的增强

494 阅读8分钟

在 SAP 中,为了在 R/3 系统中执行任何类型的任务,使用了事务代码。SAP 提供了一套标准的事务代码供使用,但有时,我们需要创建一个特定于客户的定制需求。因为在标准 SAP 中可能不支持该任务,因此我们需要根据他们的要求增强某些屏幕。

图片.png

什么是增强?

Enhancement,是SAP提供的编码块,这是一种特殊类型的编程,我们在其中编写用于增强自定义 SAP 屏幕的代码。简而言之,在 SAP ABAP 中,我们可以根据我们的要求增强特定的屏幕和事务代码,用于根据业务需求或用户需求定制标准报表或标准事务代码。

它允许我们在不修改原始应用程序的情况下修改/添加 SAP 标准业务应用程序。

SAP 中的增强类型:

  • User Exit.
  • Customer Exit.
  • BADI.
  • Enhancement Framework.

USER-EXITS :

主要用于 SD 模块的用户退出。它们由 SAP 作为子程序实施。因此,在标准 SAP 代码中,您会找到语句 PERFORM USEREXIT_XXX… 例如,在第 652 行的包含程序 MV45AF0B_BELEG_SICHERN 中,您会找到语句 PERFORM USEREXIT_SAVE_DOCUMENT_PREPARE.. 但在包含程序 MV45AFZZ 中定义的相应 FORM 是空的。

因此,根据您的客户要求,您必须将代码添加到此表单中。但是,由于您是将代码添加到 SAP 标准包含程序中,因此这将被视为修改而非增强,因为这里我们正在更改标准事务代码的现有代码。

所有用户退出都以单词 FORM USEREXIT 开头(用户出口名称)

FORM USEREXIT_PRICING_PREPARE_TKOMP.

ENDFORM.

要查找用户出口,只需使用 SE93 查找该特定事务代码的第一个程序即可。然后转到该程序的层次结构,然后在此处单击子例程,您将发现所有用户退出。这是查找所有用户退出列表的最简单方法。

CUSTOMER-EXITS:

客户出口是为特定程序或特定目的,特定屏幕和标准应用程序的特定菜单创建的。客户存在以功能模块的形式创建。在客户出口中,我们将更新屏幕,菜单和字段。

基于 OOPS 的 SAP 增强技术。可以在 SAP 标准功能之间插入自定义代码,以满足用户特定的要求。

Customer Exitsfunction Exits,这里我们使用 Call customer-function 语句。我们将在函数模块中添加我们的自定义代码,我们称之为函数 Exits。在这些功能模块中,我们有 Z 包含文件,或者我们将创建 Z 包含文件以进行定制。

3 种类型的函数:

  1. Menu Exists: – Menu Exists 保留用于 SAP GUI 界面。
  2. Screen Exists:- Screen Exists 允许用户将字段添加到 SAP 程序的屏幕。
  3. Field Exists:- Field Exists 用于对输入字段进行验证。

这些退出由 SAP 作为函数模块调用提供。因此,在标准 SAP 代码中,您会发现诸如 CALL CUSTOMER-FUNCTION '003' 之类的语句……例如,在第 21 行的 Include LCATSF0Y 中,您会发现 CALL CUSTOMER-FUNCTION '003' 语句,但是相应的功能模块 EXIT_SAPLCATS_003 有一个包含 ZXCATU03,它确实不存在。因此,根据您的客户要求,您需要将代码添加到此包含中以增强标准 SAP 程序的行为。

请注意,由于此处您实际上并未更改任何 SAP 标准代码,因此这不被视为修改,并且在未来升级期间不会出现任何问题。

BADI:

业务插件是实现 SAP 增强功能的面向对象的方式。自定义出口的局限性在于它只能包含一个 include 实现。然而,一个 BADI 可以有多个实现(作为类实现,而不是像客户退出的情况那样包含程序),您可以根据过滤器值选择应该调用哪个实现。BADI 是特定于模块的,相关的 BADI 可以通过该模块的 IMG 配置节点找到。从技术上讲,SAP 标准代码使用类 CL_EXITHANDLER 来识别和调用相关的 BADI 类。BADI 允许不同级别的系统环境(SAP 标准、合作伙伴系统、客户解决方案以及国家/地区版本、行业解决方案等)

Enhancement Framework.

这是新的增强概念,通过提供使用他们想要添加的自定义代码增强标准代码库的选项来帮助用户、客户和第三方。

增强框架提供了一种增强源代码单元而不修改它们的技术。基本机制是在开发对象中提供所谓的增强选项。这些增强选项的功能类似于“挂钩”,您可以在其中附加增强功能。增强选项是可以增强的开发对象的一部分。当您将增强分配给增强选项时,在运行时控制流到达选项时会处理增强。在运行时,增强的行为就好像它属于它增强的开发对象,而作为传输对象的增强不属于增强的对象。

各种类型的增强

  • 显式增强– SAP 在代码的不同位置类似地提供了显式增强。它们提供有增强点和增强部分。我们将在接下来的文章中了解更多关于它们的信息,但基本的是增强点是代码的空占位符,而增强部分是带有默认代码的占位符。

  • 隐式增强——隐式增强不由 SAP 在代码中提供,但 SAP 提供了在不同位置实施它们的灵活性

    • 子例程/方法/FM/包含 等文件的开头
    • 子例程/Method/FM/Include 等文件的末尾
    • 类增强 - Pre/Post/Overwrite 方法
    • FM 增强 - 附加参数

隐式增强

隐式增强用于将我们自己的代码写入编码块,我们可以将我们自己的代码写入标准程序或任何功能模块或任何包含程序。

我们有针对不同目的的标准包含程序。

  • MV45* 与订单相关。

  • MV50* 与交付相关。

  • RV60* 与计费相关。

显示增强

SAP 在代码的不同部分提供的显式增强。当我们在不干扰原始源代码的情况下在自定义程序中使用增强时,我们将其称为显式增强,此处程序不是 SAP 标准程序。

增强示例:

FORM USEREXIT_PRICING_PREPARE_TKOMP.


ENHANCEMENT 2  ZSD_INV_CKECK.


DATA : V_TAXM1 TYPE MLAN-TAXM1 ,
       TX_ID(2) TYPE N .

IF VBRK-FKART <> 'ZF2'  .
    SELECT SINGLE TAXM5 FROM MLAN INTO V_TAXM1
      WHERE MATNR eq VBAP-MATNR
        AND ALAND eq 'IN'.

   IF sy-subrc eq 0 .

     TKOMP-KONDM = V_TAXM1 .
   ENDIF .

   SELECT SINGLE BRAND_ID FROM MARA INTO TKOMP-ZZBRAND_ID
      WHERE MATNR eq VBAP-MATNR .

ENDIF .



    SELECT SINGLE uname FROM  ZCHECK_UNAME INTO @DATA(lv_flag) WHERE uname = @sy-uname.
    IF lv_flag IS  INITIAL.
      IF SY-TCODE = 'VF01' OR SY-TCODE = 'VF02' OR SY-TCODE = 'VF03'.

        DATA(IT_XVBRP) = XVBRP[].
IF IT_XVBRP IS NOT INITIAL.
        SELECT * FROM zsd_param INTO TABLE @DATA(it_tax_12) WHERE ZPROGRAM = 'RV60AFZZ'
              AND FIELD1    = 'BILLTAX_12'
              AND FIELD2   = 'STEUC'
              AND VAL3    = 'X'.
        SELECT * FROM zsd_param INTO TABLE @DATA(it_tax_5) WHERE ZPROGRAM = 'RV60AFZZ'
              AND FIELD1    = 'BILLTAX_5'
              AND FIELD2   = 'STEUC'
              AND VAL3    = 'X'.
            SELECT * FROM zsd_param INTO TABLE @DATA(it_tax_COND_TYPE) WHERE ZPROGRAM = 'RV60AFZZ'
              AND FIELD1    = 'BILLTAX'
              AND FIELD2   = 'COND_TYPE'
              AND VAL3    = 'X'.

        LOOP  AT XKOMV ASSIGNING FIELD-SYMBOL(<FS_KOMV>) WHERE KPOSN  NE ''." XVBRP-POSNR "VBRP-POSNR
          READ TABLE IT_TAX_COND_TYPE INTO DATA(WA_COND_TYPE) WITH KEY  VAL1 = <FS_KOMV>-KSCHL.
        IF SY-SUBRC IS INITIAL.
          "boc arpita 11/2/22.
          READ TABLE IT_XVBRP INTO DATA(WA_XVBRP) WITH KEY  POSNR = <FS_KOMV>-KPOSN.
          IF SY-SUBRC IS INITIAL.
            SELECT SINGLE steuc FROM marc
            INTO @DATA(lv_steuc)
                  WHERE matnr = @WA_Xvbrp-matnr
                  AND werks = @WA_Xvbrp-werks.
            READ TABLE it_tax_12  INTO DATA(WA_TAX_12) WITH KEY  VAL1 = LV_STEUC+0(4).
            IF SY-SUBRC IS INITIAL.
              CASE <FS_KOMV>-KSCHL.
              WHEN 'JOIG'.
                IF ( <FS_KOMV>-KAWRT / WA_XVBRP-FKIMG ) LE 1000.
                  <FS_KOMV>-KBETR = '120.00'.
                  <FS_KOMV>-KWERT = ( <FS_KOMV>-KAWRT * 12 ) / 100.
                ENDIF.
              WHEN 'JOCG'.
                IF ( <FS_KOMV>-KAWRT / WA_XVBRP-FKIMG ) LE 1000.
                  <FS_KOMV>-KBETR = '60.00'.
                  <FS_KOMV>-KWERT = ( <FS_KOMV>-KAWRT * 60 ) / 1000.
                ENDIF.
              WHEN 'JOUG'.
                IF <FS_KOMV>-KBETR IS NOT INITIAL.
                  IF ( <FS_KOMV>-KAWRT / WA_XVBRP-FKIMG ) LE 1000.
                    <FS_KOMV>-KBETR = '60.00'.
                    <FS_KOMV>-KWERT = ( <FS_KOMV>-KAWRT * 60 ) / 1000.
                  ENDIF.
                ENDIF.
              WHEN 'JOSG'.
                IF ( <FS_KOMV>-KAWRT / WA_XVBRP-FKIMG ) LE 1000.
                  <FS_KOMV>-KBETR = '60.00'.
                  <FS_KOMV>-KWERT = ( <FS_KOMV>-KAWRT * 60 ) / 1000.
                ENDIF.
              ENDCASE.
            ENDIF.

            READ TABLE it_tax_5  INTO DATA(WA_TAX_5) WITH KEY  VAL1 = LV_STEUC+0(2).
            IF SY-SUBRC IS NOT INITIAL .
              READ TABLE it_tax_5  INTO WA_TAX_5 WITH KEY  VAL1 = LV_STEUC+0(4).
            ENDIF.
            IF SY-SUBRC IS INITIAL.
              CASE <FS_KOMV>-KSCHL.
              WHEN 'JOIG'.
                IF ( <FS_KOMV>-KAWRT / WA_XVBRP-FKIMG ) LE 1000.
                  <FS_KOMV>-KBETR = '50.00'.
                  <FS_KOMV>-KWERT = ( <FS_KOMV>-KAWRT * 5 ) / 100.
                ENDIF.
              WHEN 'JOCG'.
                IF ( <FS_KOMV>-KAWRT / WA_XVBRP-FKIMG ) LE 1000.
                  <FS_KOMV>-KBETR = '25.00'.
                  <FS_KOMV>-KWERT = ( <FS_KOMV>-KAWRT * 25 ) / 1000.
                ENDIF.
              WHEN 'JOUG'.
                IF <FS_KOMV>-KBETR IS NOT INITIAL.
                  IF ( <FS_KOMV>-KAWRT / WA_XVBRP-FKIMG ) LE 1000.
                    <FS_KOMV>-KBETR = '25.00'.
                    <FS_KOMV>-KWERT = ( <FS_KOMV>-KAWRT * 25 ) / 1000.
                  ENDIF.
                ENDIF.
              WHEN 'JOSG'.
                IF ( <FS_KOMV>-KAWRT / WA_XVBRP-FKIMG ) LE 1000.
                  <FS_KOMV>-KBETR = '25.00'.
                  <FS_KOMV>-KWERT = ( <FS_KOMV>-KAWRT * 25 ) / 1000.
                ENDIF.
              ENDCASE.
            ENDIF. 
          ENDIF.
          ENDIF.
        ENDLOOP.

   ENDIF.
      ENDIF.
    ENDIF.


ENDENHANCEMENT.
ENDFORM.

增强相对于修改的优势

与修改相比,增强功能在升级过程中的工作量要少得多。增强本身就是传输对象,可以存储在它们自己的包中,而修改是它们修改的对象的一部分。由于在升级期间所有 SAP 对象都被这些对象的新版本替换,因此升级后所有修改都将消失。这导致客户不得不调整所有修改,无论底层对象是否已更改。

相比之下,作为传输对象的客户增强在升级过程中永远不会被覆盖,因为它们存储在客户名称空间中的客户包中。可能会发生开发对象的新版本不再与增强兼容的情况,例如,如果增强对象被删除或增强中使用的数据类型不再存在。在这些情况下,增强框架的相关工具会提供必须调整哪些增强功能的信息,并为此提供工具支持。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 21 天,点击查看活动详情