无常笔记ABAP Cheat Sheets中文导读全站搜索

英文原文:SAP-samples · 上游版本 d43eb13c4c7c · 原始 Markdown

Enhancements Using BAdIs

This ABAP cheat sheet provides a high-level overview of enhancements using BAdIs (Business Add-Ins), focusing on the relevant ABAP syntax. The cheat sheet aims to illustrate the BAdI-related ABAP syntax with simple, self-created demo BAdIs, whose creation is outlined in tutorial-style descriptions. The descriptions are intended to get an idea about the involved repository objects. The repository objects serve as the basis for the ABAP example code snippets in the executable example.

About BAdIs

[!NOTE] The steps and syntax outlined in this document focus on the kernel-based BAdI concept, which integrates BAdIs in ABAP for use with related ABAP syntax. Legacy classic BAdIs found in classic ABAP are not covered here. In classic ABAP, the BAdI builder, an ABAP Workbench tool, allows you to create and maintain BAdIs. The relevant transaction codes are SE18 for defining and SE19 for implementing BAdIs.

⬆️ back to top

Excursion: Demo BAdIs

This section provides high-level walkthrough examples to illustrate simplified BAdIs, which serve as examples for demonstrating the ABAP syntax below. The step-by-step procedure includes the creation of the following elements:

[!NOTE]

⬆️ back to top

Demo BAdI 1

[!NOTE]

  1. BAdI enhancement spot

    • In your ADT package, create a new object by right-clicking the package, selecting New, then Other ABAP Repository Object, and filtering for BAdI Enhancement Spot.
    • Name the enhancement spot ZES_DEMO_ABAP_CALCULATOR and provide a description.
    • Follow the wizard prompts. Once created, the BAdI Enhancement Spot screen will display.
  2. BAdI / BAdI definition

    • With the BAdI enhancement spot repository object open from the previous step, you are on the BAdI Enhancement Spot screen.
    • Choose the Add BAdI button.
    • In the New BAdI Definition pop-up, enter the name ZBADI_DEMO_ABAP_CALCULATOR and confirm.
    • The new BAdI will appear in the BAdI Definitions list on the left. A message will prompt you to add an interface to the BAdI.
    • Set the following options:
      • Deselect the Multiple Use checkbox, as the BAdI is intended for single use.
      • Select the Use Fallback checkbox.
      • Leave other settings unchanged (the Interface and Fallback Class fields will be covered later).
    • Choose the Add Filter button.
      • In the New Filter pop-up, enter the name OPERATOR and choose Add.
      • The filter will appear below the ZBADI_DEMO_ABAP_CALCULATOR node on the left.
      • In the Filter Details on the right, select Character as the Type. Additional settings, like value checks, are not included in this example.
      • Return to the detail view for ZBADI_DEMO_ABAP_CALCULATOR by selecting the ZBADI_DEMO_ABAP_CALCULATOR node on the left.
  3. BAdI interface

    • The BAdI enhancement spot repository object is opened.

    • Choose the Interface link in the Configuration section.

    • Follow the New ABAP Interface wizard:

      • Enter the name ZIF_DEMO_ABAP_CALCULATOR and provide a description.
      • Ensure that the interface IF_BADI_INTERFACE is included in the Interfaces list.
    • Add the following code and activate the interface. Note that the returning parameter in this simplified example is intentionally typed as string, and an appropriate error handling is not covered.

      INTERFACE zif_demo_abap_calculator
        PUBLIC .
      
        INTERFACES if_badi_interface .
      
        METHODS calculate IMPORTING num1          TYPE i
                                    num2          TYPE i
                          RETURNING VALUE(result) TYPE string.
      ENDINTERFACE.
      
  4. Fallback class

    • The BAdI enhancement spot repository object is opened.

    • Choose the Fallback Class link in the Configuration section.

    • Walk through the New ABAP Class wizard:

      • Enter the name ZCL_DEMO_ABAP_CALCULATOR_FB and add a description.
      • Ensure the interface ZIF_DEMO_ABAP_CALCULATOR is included in the Interfaces list.
    • Add the following code and activate the class.

      CLASS zcl_demo_abap_calculator_fb DEFINITION
        PUBLIC
        FINAL
        CREATE PUBLIC .
      
        PUBLIC SECTION.
      
          INTERFACES if_badi_interface .
          INTERFACES zif_demo_abap_calculator .
        PROTECTED SECTION.
        PRIVATE SECTION.
      ENDCLASS.
      
      
      
      CLASS zcl_demo_abap_calculator_fb IMPLEMENTATION.
        METHOD zif_demo_abap_calculator~calculate.
          result = |{ num1 + num2 }|.
        ENDMETHOD.
      ENDCLASS.
      
  5. BAdI implementation (1)

    • Ensure you activate the BAdI if you have not done already.

    • In your package in ADT, find the enhancement spot ZES_DEMO_ABAP_CALCULATOR. Right-click it and select New BAdI Enhancement Implementation.

    • Follow the New BAdI Enhancement Implementation wizard:

      • Add a suitable target package.
      • Enter the name ZEI_DEMO_ABAP_CALCULATOR and a description.
      • Ensure the enhancement spot ZES_DEMO_ABAP_CALCULATOR is included in the Enhancement Spot input field.
    • After creation, the BAdI Enhancement Implementation screen will appear.

    • Click the Add BAdI Implementation button.

    • In the Add BAdI Implementation pop-up, enter the following:

      • BAdI Definition: ZBADI_DEMO_ABAP_CALCULATOR
      • BAdI Implementation Name: ZBADI_IMPL_DEMO_ABAP_CALC_SUB
    • In the BAdI Implementation Details section on the right, choose the Implementing Class link.

    • Follow the New ABAP Class wizard:

      • Enter the name ZCL_DEMO_ABAP_CALCULATOR_SUBTR and a description.
      • Ensure the interface ZIF_DEMO_ABAP_CALCULATOR is added to the Interfaces list.
    • Add the following code and activate the class:

      CLASS zcl_demo_abap_calculator_subtr DEFINITION
        PUBLIC
        FINAL
        CREATE PUBLIC .
      
        PUBLIC SECTION.
      
          INTERFACES if_badi_interface .
          INTERFACES zif_demo_abap_calculator .
        PROTECTED SECTION.
        PRIVATE SECTION.
      ENDCLASS.
      
      
      
      CLASS zcl_demo_abap_calculator_subtr IMPLEMENTATION.
        METHOD zif_demo_abap_calculator~calculate.
          result = |{ num1 - num2 }|.
        ENDMETHOD.
      ENDCLASS.
      
    • Set filter conditions

      • Back on the BAdI Enhancement Implementation screen, choose the Add Filter Combination button.
      • A Filter Values node should be added below the ZBADI_IMPL_DEMO_ABAP_CALC_SUB node.
      • In the Filter Details section on the right, insert - (minus character) in the Value field.
  6. BAdI implementation (2)

Demo BAdI 2

[!NOTE]

  1. BAdI enhancement spot

    • Create an enhancement spot with the name ZES_DEMO_ABAP_CONVERTER.
  2. BAdI

    • Create a BAdI definition with the name ZBADI_DEMO_ABAP_CONVERTER.
    • Set the following options:
      • Select the Multiple use checkbox since the BAdI is intended for multiple use.
      • Leave the other settings unchanged (only the Interface field is relevant).
  3. BAdI interface

    • Create a BAdI interface with the name ZIF_DEMO_ABAP_CONVERTER.

    • Note that only importing and changing parameters are possible here. For display purposes, the method definition includes an importing parameter having a reference to the classrun output. In the executable example class, the calling class implements the classrun and supplies a bound interface reference variable when calling the BAdI method.

      INTERFACE zif_demo_abap_converter
        PUBLIC .
      
        INTERFACES if_badi_interface .
        METHODS convert IMPORTING content TYPE any
                                  out     TYPE REF TO if_oo_adt_classrun_out.
      ENDINTERFACE.
      
  4. BAdI enhancement implementation

    • Name: ZEI_DEMO_ABAP_CONVERTER
    • BAdI implementations (using the ZBADI_DEMO_ABAP_CONVERTER BAdI definition)
      • ZBADI_IMPL_DEMO_ABAP_CONV_XML
        • Implementing class: ZCL_DEMO_ABAP_CONVERTER_XML
      • ZBADI_IMPL_DEMO_ABAP_CONV_JSON
        • Implementing class: ZCL_DEMO_ABAP_CONVERTER_JSON
    • Add the following code to the classes activate them:
      • ZCL_DEMO_ABAP_CONVERTER_XML

        CLASS zcl_demo_abap_converter_xml DEFINITION
          PUBLIC
          FINAL
          CREATE PUBLIC .
        
          PUBLIC SECTION.
        
            INTERFACES if_badi_interface .
            INTERFACES zif_demo_abap_converter .
          PROTECTED SECTION.
          PRIVATE SECTION.
        ENDCLASS.
        
        
        
        CLASS zcl_demo_abap_converter_xml IMPLEMENTATION.
          METHOD zif_demo_abap_converter~convert.
            IF out IS NOT BOUND.
              RETURN.
            ENDIF.
        
            DATA xml TYPE xstring.
        
            DATA(tdo) = cl_abap_typedescr=>describe_by_data( content ).
            CASE TYPE OF tdo.
              WHEN TYPE cl_abap_elemdescr.
                CALL TRANSFORMATION id
                  SOURCE var = content
                  RESULT XML xml.
              WHEN TYPE cl_abap_structdescr.
                CALL TRANSFORMATION id
                  SOURCE structure = content
                  RESULT XML xml.
              WHEN TYPE cl_abap_tabledescr.
                CALL TRANSFORMATION id
                  SOURCE table = content
                  RESULT XML xml.
              WHEN OTHERS.
                RETURN.
            ENDCASE.
        
            DATA(xml_str) = cl_abap_conv_codepage=>create_in( )->convert( xml ).
        
            out->write( xml_str ).
            out->write( |\n| ).
          ENDMETHOD.
        ENDCLASS.
        
      • ZCL_DEMO_ABAP_CONVERTER_JSON

        CLASS zcl_demo_abap_converter_json DEFINITION
          PUBLIC
          FINAL
          CREATE PUBLIC .
        
          PUBLIC SECTION.
        
            INTERFACES if_badi_interface .
            INTERFACES zif_demo_abap_converter .
          PROTECTED SECTION.
          PRIVATE SECTION.
        ENDCLASS.
        
        
        
        CLASS zcl_demo_abap_converter_json IMPLEMENTATION.
          METHOD zif_demo_abap_converter~convert.
            IF out IS NOT BOUND.
              RETURN.
            ENDIF.
        
            DATA(json) = /ui2/cl_json=>serialize( data = content
                                                  format_output = abap_true ).
        
            out->write( json ).
            out->write( |\n| ).    
          ENDMETHOD.
        ENDCLASS.
        
Statement Notes

GET BADI

  • Creates a new BAdI object and assigns the BAdI reference to a BAdI reference variable.
  • If the BAdI includes filters, the addition FILTERS must be specified, followed by assignments. The arguments for the filters must by type-compliant. Note that filters can also be defined to use only constants. In this case, only literals and constants can be specified. If a BAdI does not define filters, the FILTERS addition cannot be specified.
  • After instantiation, the system searches for BAdI implementation classes. Only active classes that match the filter criteria are included in the search. If no matching implementations are found, the system will look for standard implementations. If none are found, it will use the fallback class, if available. For more information, refer to the ABAP Keyword Documentation.
  • In addition to a static variant, a dynamic variant is also available:
    • The dynamic variant uses the addition TYPE and requires the name of a BAdI as a character-like data object in parentheses.
    • The static type of the reference variable must be CL_BADI_BASE, the superclass of all BAdI classes.
    • The FILTERS addition can also be applied in the dynamic variant. Alternatively, the FILTER-TABLE addition can be used, requiring a table of type badi_filter_bindings. Its components are name (type c, length 30; the filter name should be in uppercase) and value (type REF TO data; it expects a pointer to a matching data object).
  • For context-dependent BAdIs, the CONTEXT addition is available. Find more details in the ABAP Keyword Documentation.

CALL BADI

  • Calls a BAdI method using the BAdI reference variable.
  • Expects a list of parameters to assign actual parameters to the method's formal parameters.
  • In addition to a static variant, a dynamic variant is available:
    • The method name comes after the BAdI reference variable, which has the static type of CL_BADI_BASE, and is specified as a character-like data object within parentheses.
    • You can either specify the parameter list as in static statements or use a parameter table with PARAMETER-TABLE, which requires a table of type abap_parmbind_tab (refer to dynamic CALL METHOD statements in the Dynamic Programming cheat sheet).

[!NOTE] Note that various catchable exceptions can be raised when using GET BADI and CALL BADI.

The following snippet uses the demo BAdIs outlined earlier. For more example snippets, see the executable example.

*&---------------------------------------------------------------------*
*& Static variant of the GET BADI and CALL BADI statements
*&---------------------------------------------------------------------*

"Declaring a BAdI reference variable
"The variable references the multiple-use demo BAdI definition.
DATA badi_a TYPE REF TO zbadi_demo_abap_converter.

"Creating a BAdI object
"The demo BAdI does not specify filters.
GET BADI badi_a.

"Calling a BAdI method through the BAdI reference variable
"and providing actual parameters to formal parameters.
CALL BADI badi_a->convert
  EXPORTING
    content = `Hello world`
    out     = out.

"Declaring another BAdI reference variable
"The variable references the single-use demo BAdI.
DATA badi_b TYPE REF TO zbadi_demo_abap_calculator.

"The demo BAdI specifies a filter condition. Therefore, the GET BADI
"statement requires to specify the FILTERS addition.
GET BADI badi_b FILTERS operator = '-'.

"Not that unlike methods of multiple-use BAdIs, methods of single-use
"BAdIs can include output parameters in the signature.
CALL BADI badi_b->calculate
  EXPORTING
    num1   = 10
    num2   = 8
  RECEIVING
    result = DATA(res).

*&---------------------------------------------------------------------*
*& Dynamic variants of the GET BADI and CALL BADI statements
*&---------------------------------------------------------------------*

"Character-like data objects to be used in the dynamic statements
DATA(badi_name) = 'ZBADI_DEMO_ABAP_CALCULATOR'.
DATA(method_name) = 'CALCULATE'.
DATA dyn_result TYPE string.

"Declaring a BAdI reference variable
"The static type of the reference variable must reference CL_BADI_BASE,
"the superclass of all BAdI classes.
DATA badi_dyn TYPE REF TO cl_badi_base.

"Dynamic GET BADI statement specifying the TYPE addition and
"the name of a BAdI (a data object containing it) in parentheses.
GET BADI badi_dyn TYPE (badi_name) FILTERS operator = '-'.

"Dynamic CALL BADI statement specifying the method name
"dyanmically (i.e. a data object containing the name) in
"parentheses following object component selector ->.
CALL BADI badi_dyn->(method_name)
  EXPORTING
    num1   = 10
    num2   = 8
  RECEIVING
    result = dyn_result.

"Using the FILTER-TABLE addition in dynamic GET BADI statements
"After the addition, a filter table of type badi_filter_bindings is
"expected.
DATA(op) = '/'.
DATA(filter_name) = CONV badi_filter_name( 'OPERATOR' ).

DATA(filter_tab) = VALUE badi_filter_bindings( ( name  = filter_name
                                                 value = REF #( op ) ) ).

GET BADI badi_dyn TYPE (badi_name) FILTER-TABLE filter_tab.

CALL BADI badi_dyn->(method_name)
  EXPORTING
    num1   = 10
    num2   = 5
  RECEIVING
    result = dyn_result.

"Using the PARAMETER-TABLE addition in dynamic CALL BADI statements
"Similar to dynamic CALL METHOD statements, dynamic CALL BADI statements
"can specify a parameter table of type abap_parmbind_tab.
DATA(ptab) = VALUE abap_parmbind_tab( ( name  = 'NUM1'
                                        kind  = cl_abap_objectdescr=>exporting
                                        value = NEW i( 10 ) )
                                      ( name  = 'NUM2'
                                        kind  = cl_abap_objectdescr=>exporting
                                        value = NEW i( 5 ) )
                                      ( name  = 'RESULT'
                                        kind  = cl_abap_objectdescr=>returning
                                        value = REF #( dyn_result ) ) ).

CALL BADI badi_dyn->(method_name) PARAMETER-TABLE ptab.

⬆️ back to top

More Information

⬆️ back to top

Executable Example

[!NOTE]

CLASS zcl_demo_abap DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.
  PROTECTED SECTION.
  PRIVATE SECTION.
    TYPES c1 TYPE c LENGTH 1.
    DATA: operand1       TYPE i,
          operand2       TYPE i,
          op             TYPE c1,
          example_number TYPE i.
    METHODS set_example_divider IMPORTING out  TYPE REF TO if_oo_adt_classrun_out
                                          text TYPE string.
ENDCLASS.



CLASS zcl_demo_abap IMPLEMENTATION.

  METHOD if_oo_adt_classrun~main.

*&---------------------------------------------------------------------*
*& Multiple-use demo BAdI
*&---------------------------------------------------------------------*

    "The multiple-use demo BAdI does not specify filters. Therefore, the syntax
    "does not allow the use of the FILTERS addition. Two demo BAdI implementations
    "are available in the demo, converting data objects to XML and JSON. When
    "calling the BAdI method, it executes both implementations. Consequently,
    "the output includes data objects converted to both XML and JSON.

    example_number += 1.
    set_example_divider( out  = out
                         text = |{ example_number }) Multiple-use BAdI| ).

    "Creating demo data objects for the example to work with
    DATA str TYPE string VALUE `Hello world`.

    DATA: BEGIN OF struct,
            comp1 TYPE string VALUE `ABAP`,
            comp2 TYPE i VALUE 987,
            comp3 TYPE n LENGTH 5 VALUE '12345',
            comp4 TYPE abap_boolean VALUE abap_true,
          END OF struct.

    DATA itab LIKE TABLE OF struct WITH EMPTY KEY.
    itab = VALUE #( ( struct )
                    ( comp1 = `BAdI` comp2 = 321 comp3 = '67890' comp4 = abap_false ) ).

    "Declaring a BAdI reference variable
    "The variable references the multiple-use demo BAdI definition.
    DATA badi_m TYPE REF TO zbadi_demo_abap_converter.

    "Creating a BAdI object
    GET BADI badi_m.

    out->write( |---------- Converting elementary data objects ----------\n| ).

    CALL BADI badi_m->convert
      EXPORTING
        content = str
        out     = out.

    out->write( |---------- Converting a structure ----------\n| ).

    CALL BADI badi_m->convert
      EXPORTING
        content = struct
        out     = out.

    out->write( |---------- Converting an internal table ----------\n| ).

    CALL BADI badi_m->convert
      EXPORTING
        content = itab
        out     = out.

*&---------------------------------------------------------------------*
*& Single-use demo BAdI
*&---------------------------------------------------------------------*

    "The single-use demo BAdI specifies filters. Therefore, the GET BADI
    "statement requires to specify the FILTERS addition.
    "Additionally, a fallback class is created for the demo BAdI. It
    "means that if an implementation class is not found that matches
    "the filter condition, the BAdI method implemented in the fallback
    "class is called.

    example_number += 1.
    set_example_divider( out  = out
                         text = |{ example_number }) Single-use demo BAdI| ).

    "Declaring a BAdI reference variable
    "The variable references the single-use demo BAdI definition.
    DATA badi_s TYPE REF TO zbadi_demo_abap_calculator.

    "Assigning demo values to data objects used for the BAdI
    "method calls
    operand1 = 10.
    operand2 = 8.
    op = '-'.

    "Creating a BAdI object
    "Note that the demo BAdI requires filters to be specified.
    GET BADI badi_s FILTERS operator = op.

    CALL BADI badi_s->calculate
      EXPORTING
        num1   = operand1
        num2   = operand2
      RECEIVING
        result = DATA(result).

    out->write( |{ operand1 } { op } { operand2 } = { result }| ).
    out->write( |\n| ).

    op = '/'.

    GET BADI badi_s FILTERS operator = op.

    CALL BADI badi_s->calculate
      EXPORTING
        num1   = operand1
        num2   = operand2
      RECEIVING
        result = result.

    out->write( |{ operand1 } { op } { operand2 } = { result }| ).
    out->write( |\n| ).

    operand1 = 5.
    operand2 = 0.

    CALL BADI badi_s->calculate
      EXPORTING
        num1   = operand1
        num2   = operand2
      RECEIVING
        result = result.

    out->write( |{ operand1 } { op } { operand2 } = { result }| ).
    out->write( |\n| ).

    "Using a non-specified filter
    "In this case, the BAdI method in the fallback class is called,
    "reflecting addition.
    op = '?'.

    GET BADI badi_s FILTERS operator = op.

    operand1 = 3.
    operand2 = 2.

    CALL BADI badi_s->calculate
      EXPORTING
        num1   = operand1
        num2   = operand2
      RECEIVING
        result = result.

    out->write( |{ operand1 } { op } { operand2 } = { result }| ).
    out->write( |\n| ).

*&---------------------------------------------------------------------*
*& Dynamic specifications
*&---------------------------------------------------------------------*

    example_number += 1.
    set_example_divider( out  = out
                         text = |{ example_number }) Dynamic specifications| ).

    "Dynamic variant of the GET BADI statement
    "Creating character-like data objects holding the names of a BAdI
    "and BAdI method
    DATA(badi_name) = 'ZBADI_DEMO_ABAP_CALCULATOR'.
    DATA(method_name) = 'CALCULATE'.

    operand1 = 15.
    operand2 = 9.
    op = '-'.

    "The dynamic variant of the GET BADI statement specifies the TYPE addition,
    "followed by the BAdI name (contained in a character-like data object) in
    "parentheses. The BAdI reference variable must have the static type CL_BADI_BASE,
    "the superclass of all BAdI classes.
    DATA badi_dyn TYPE REF TO cl_badi_base.

    GET BADI badi_dyn TYPE (badi_name) FILTERS operator = op.

    "The dynamic variant of the CALL BADI statement specifies the object component
    "selector -> followed by the BAdI method name (contained in a character-like
    "data object) in parentheses. The following statement explicitly specifies the
    "parameters, similar to dynamic CALL METHOD statements.
    CALL BADI badi_dyn->(method_name)
      EXPORTING
        num1   = operand1
        num2   = operand2
      RECEIVING
        result = result.

    out->write( |{ operand1 } { op } { operand2 } = { result }| ).
    out->write( |\n| ).

    "Using the FILTER-TABLE addition in dynamic GET BADI statements
    "After the addition, a filter table of type badi_filter_bindings is
    "expected.
    DATA filter_tab TYPE badi_filter_bindings.
    DATA badi_filter_name TYPE badi_filter_name.

    badi_filter_name = 'OPERATOR'.
    op = '/'.
    operand1 = 30.
    operand2 = 6.

    filter_tab = VALUE #( ( name  = badi_filter_name
                            value = NEW c1( op ) ) ).

    GET BADI badi_dyn TYPE (badi_name) FILTER-TABLE filter_tab.

    CALL BADI badi_dyn->(method_name)
      EXPORTING
        num1   = operand1
        num2   = operand2
      RECEIVING
        result = result.

    out->write( |{ operand1 } { op } { operand2 } = { result }| ).
    out->write( |\n| ).

    "Using the PARAMETER-TABLE addition in dynamic CALL BADI statements
    "Similar to dynamic CALL METHOD statements, dynamic CALL BADI statements
    "can specify a parameter table of type abap_parmbind_tab.
    badi_filter_name = 'OPERATOR'.
    op = '/'.
    operand1 = 1.
    operand2 = 8.

    filter_tab = VALUE #( ( name  = badi_filter_name
                            value = NEW c1( op ) ) ).

    GET BADI badi_dyn TYPE (badi_name) FILTER-TABLE filter_tab.

    DATA(ptab) = VALUE abap_parmbind_tab( ( name  = 'NUM1'
                                            kind  = cl_abap_objectdescr=>exporting
                                            value = REF #( operand1 ) )
                                          ( name  = 'NUM2'
                                            kind  = cl_abap_objectdescr=>exporting
                                            value = REF #( operand2 ) )
                                          ( name  = 'RESULT'
                                            kind  = cl_abap_objectdescr=>returning
                                            value = REF #( result ) ) ).

    CALL BADI badi_dyn->(method_name) PARAMETER-TABLE ptab.

    out->write( |{ operand1 } { op } { operand2 } = { result }| ).
    out->write( |\n| ).

    "Note:
    "The following statement is not possible as the BAdI reference variable
    "is typed with type ref to zbadi_demo_abap_calculator. A reference to
    "the superclass CL_BADI_BASE is expected.
    "GET BADI badi_s TYPE (name) FILTERS operator = '-'.

*&---------------------------------------------------------------------*
*& Exceptions
*&---------------------------------------------------------------------*

    example_number += 1.
    set_example_divider( out  = out
                         text = |{ example_number }) Demonstrating selected exceptions| ).

    DATA error TYPE REF TO cx_root.

    "1) Filter not bound
    CLEAR filter_tab.
    TRY.
        GET BADI badi_dyn TYPE (badi_name) FILTER-TABLE filter_tab.
      CATCH cx_badi_filter_error INTO error.
        out->write( error->get_text( ) ).
    ENDTRY.

    out->write( |\n| ).

    "2) Filter not bound (not specifying filters at all)
    TRY.
        GET BADI badi_dyn TYPE (badi_name).
      CATCH cx_badi_filter_error INTO error.
        out->write( error->get_text( ) ).
    ENDTRY.

    out->write( |\n| ).

    "3) Non-existant BAdI name
    DATA badi_dyn_2 TYPE REF TO cl_badi_base.
    badi_name = 'NOPE'.

    TRY.
        GET BADI badi_dyn_2 TYPE (badi_name).
      CATCH cx_badi_filter_error INTO error.
        out->write( error->get_text( ) ).
    ENDTRY.

    out->write( |\n| ).

    "4) Wrong parameters (you might know the exception class
    "   from regular dynamic method calls)
    badi_name = 'ZBADI_DEMO_ABAP_CONVERTER'.
    method_name = 'CONVERT'.

    GET BADI badi_dyn_2 TYPE (badi_name).

    TRY.
        CALL BADI badi_dyn_2->(method_name)
          EXPORTING
            nope1 = str
            nope2 = out.
      CATCH cx_sy_dyn_call_param_missing INTO error.
        out->write( error->get_text( ) ).
    ENDTRY.

    out->write( |\n| ).

    "5) Wrong method name (you might know the exception class
    "   from regular dynamic method calls)
    TRY.
        CALL BADI badi_dyn_2->('NOPE')
          EXPORTING
            content = str
            out     = out.
      CATCH cx_sy_dyn_call_illegal_method INTO error.
        out->write( error->get_text( ) ).
    ENDTRY.

    out->write( |\n| ).

    "6) Initial BAdI reference variable
    CLEAR badi_dyn_2.

    TRY.
        CALL BADI badi_dyn_2->('CONVERT')
          EXPORTING
            content = str
            out     = out.
      CATCH cx_badi_initial_reference INTO error.
        out->write( error->get_text( ) ).
    ENDTRY.

    out->write( |\n| ).

    "7) No exception raised here, but demonstrating the following:
    "   In case of an initial BAdI reference variable whose static type
    "   refers to a multiple-use BAdI, there is no effect of the statement
    "   and no exception raised. In the console, there should not be any
    "   output displayed between the two dividers.
    GET BADI badi_m.

    CLEAR badi_m.

    out->write( `----------` ).

    CALL BADI badi_m->convert
      EXPORTING
        content = 123
        out     = out.

    out->write( `----------` ).
    out->write( |\n| ).

    "8) BAdI reference variable whose static type refers to a single-use
    "   BAdI: Exception is raised in case of an initial BAdI reference variable.
    op = '-'.
    operand1 = 3.
    operand2 = 2.

    GET BADI badi_s FILTERS operator = op.

    CLEAR badi_s.

    TRY.
        CALL BADI badi_s->calculate
          EXPORTING
            num1   = operand1
            num2   = operand2
          RECEIVING
            result = result.

        out->write( |{ operand1 } { op } { operand2 } = { result }| ).
      CATCH cx_badi_initial_reference INTO error.
        out->write( error->get_text( ) ).
    ENDTRY.

  ENDMETHOD.

  METHOD set_example_divider.
    out->write( |*&{ repeat( val = `-` occ = 70 ) }*| ).
    out->write( |*& { text }| ).
    out->write( |*&{ repeat( val = `-` occ = 70 ) }*| ).
    out->write( |\n| ).
  ENDMETHOD.

ENDCLASS.

⬆️ back to top