ABAP BAdIs & Enhancements: GET BADI, CALL BADI

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

BAdIs (Business Add-Ins) sind der moderne Erweiterungsmechanismus in SAP. Sie ermöglichen die Modifikation von SAP-Standardverhalten ohne Änderung des Originalcodes. Mit Enhancement Spots können eigene Erweiterungspunkte definiert werden.

BAdI-Typen

TypBeschreibung
Klassisches BAdISE18/SE19, veraltet
Neues BAdIEnhancement Spot, GET/CALL BADI
Filter-BAdIKontextabhängige Implementierung
Fallback-BAdIStandard-Implementierung

Neue BAdI-Syntax

" BAdI-Handle holen
GET BADI lo_badi.
" BAdI aufrufen
CALL BADI lo_badi->method_name
EXPORTING param = value
IMPORTING result = lv_result.

Beispiele

1. BAdI implementieren (neues BAdI)

" 1. Enhancement Spot finden (SE18)
" Beispiel: BADI_SD_SALES
" 2. Implementierung anlegen (SE19)
" Enhancement Implementation: ZEI_SD_SALES
" BAdI Implementation: ZBI_SD_SALES
" 3. Implementierungsklasse
CLASS zcl_sd_sales_badi DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES: if_badi_sd_sales.
ENDCLASS.
CLASS zcl_sd_sales_badi IMPLEMENTATION.
METHOD if_badi_sd_sales~check_document.
" Kundenspezifische Prüfung
IF is_header-auart = 'ZOR'.
" Spezialbehandlung für Auftragsart ZOR
IF is_header-vkorg NOT IN gt_allowed_orgs.
ev_error = abap_true.
ev_message = 'Auftragsart ZOR nicht erlaubt für diese VKOrg'.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD if_badi_sd_sales~modify_data.
" Daten modifizieren vor Speicherung
IF cs_header-bstkd IS INITIAL.
cs_header-bstkd = |AUTO-{ sy-datum }|.
ENDIF.
ENDMETHOD.
ENDCLASS.

2. BAdI in eigenem Code aufrufen

" BAdI-Definition finden
DATA: lo_badi TYPE REF TO badi_sd_sales.
" Handle holen
GET BADI lo_badi.
" Methode aufrufen
CALL BADI lo_badi->check_document
EXPORTING
is_header = ls_header
IMPORTING
ev_error = lv_error
ev_message = lv_message.
IF lv_error = abap_true.
MESSAGE lv_message TYPE 'E'.
ENDIF.

3. Eigenes BAdI erstellen

" 1. Enhancement Spot erstellen (SE18)
" Name: ZES_ORDER_PROCESSING
" Kurzbeschreibung: Order Processing Extensions
" 2. BAdI Definition erstellen
" Name: ZBADI_ORDER_CHECK
" Interface: ZIF_ORDER_CHECK
" 3. Interface definieren
INTERFACE zif_order_check PUBLIC.
METHODS: validate_order
IMPORTING
is_order TYPE ty_order
EXPORTING
ev_valid TYPE abap_bool
et_messages TYPE bapiret2_t.
METHODS: enrich_order
CHANGING
cs_order TYPE ty_order.
ENDINTERFACE.
" 4. In eigenem Code verwenden
CLASS zcl_order_processor DEFINITION.
PUBLIC SECTION.
METHODS: process_order
IMPORTING is_order TYPE ty_order
RAISING zcx_order_error.
ENDCLASS.
CLASS zcl_order_processor IMPLEMENTATION.
METHOD process_order.
DATA: lo_badi TYPE REF TO zbadi_order_check,
lv_valid TYPE abap_bool,
lt_messages TYPE bapiret2_t.
" BAdI holen und aufrufen
GET BADI lo_badi.
CALL BADI lo_badi->validate_order
EXPORTING is_order = is_order
IMPORTING ev_valid = lv_valid
et_messages = lt_messages.
IF lv_valid = abap_false.
RAISE EXCEPTION TYPE zcx_order_error
EXPORTING messages = lt_messages.
ENDIF.
" Daten anreichern
DATA(ls_order) = is_order.
CALL BADI lo_badi->enrich_order
CHANGING cs_order = ls_order.
" Weiterverarbeitung...
ENDMETHOD.
ENDCLASS.

4. BAdI mit Filter

" BAdI-Definition mit Filter (SE18):
" Filter: VKORG (Verkaufsorganisation)
" Implementierung für VKOrg 1000
CLASS zcl_badi_vkorg_1000 DEFINITION.
PUBLIC SECTION.
INTERFACES: zif_sales_badi.
ENDCLASS.
CLASS zcl_badi_vkorg_1000 IMPLEMENTATION.
METHOD zif_sales_badi~process.
" Logik nur für VKOrg 1000
cs_data-discount = '10.00'.
ENDMETHOD.
ENDCLASS.
" Implementierung für VKOrg 2000
CLASS zcl_badi_vkorg_2000 DEFINITION.
PUBLIC SECTION.
INTERFACES: zif_sales_badi.
ENDCLASS.
CLASS zcl_badi_vkorg_2000 IMPLEMENTATION.
METHOD zif_sales_badi~process.
" Andere Logik für VKOrg 2000
cs_data-discount = '15.00'.
ENDMETHOD.
ENDCLASS.
" Aufruf mit Filter
DATA: lo_badi TYPE REF TO zbadi_sales.
GET BADI lo_badi
FILTERS
vkorg = lv_vkorg. " Nur passende Implementierung
CALL BADI lo_badi->process
CHANGING cs_data = ls_data.

5. Fallback-Klasse (Default-Implementierung)

" BAdI mit Fallback (SE18):
" Fallback-Klasse: ZCL_DEFAULT_HANDLER
CLASS zcl_default_handler DEFINITION
PUBLIC FINAL.
PUBLIC SECTION.
INTERFACES: zif_custom_badi.
ENDCLASS.
CLASS zcl_default_handler IMPLEMENTATION.
METHOD zif_custom_badi~process.
" Standard-Verhalten wenn keine Implementierung aktiv
rv_result = 'DEFAULT'.
ENDMETHOD.
ENDCLASS.
" Aufruf - Fallback wird verwendet wenn keine Impl. aktiv
DATA: lo_badi TYPE REF TO zbadi_custom.
GET BADI lo_badi.
" Prüfen ob Implementierung existiert
IF lo_badi IS BOUND.
CALL BADI lo_badi->process
IMPORTING rv_result = lv_result.
ENDIF.

6. Mehrfache Implementierungen

" BAdI erlaubt mehrfache Implementierungen (Multiple Use)
" Alle aktiven Implementierungen werden aufgerufen
DATA: lo_badi TYPE REF TO zbadi_validators,
lt_messages TYPE bapiret2_t.
GET BADI lo_badi.
" Alle Implementierungen werden durchlaufen
CALL BADI lo_badi->validate
EXPORTING is_data = ls_data
CHANGING ct_messages = lt_messages.
" lt_messages enthält Nachrichten aller Implementierungen
IF line_exists( lt_messages[ type = 'E' ] ).
" Mindestens eine Implementierung hat Fehler gemeldet
ENDIF.

7. Enhancement Implementations

" Implizite Enhancement Points im Standard-Code
" Können ohne Modifikation erweitert werden
" Im Standard-Code existiert:
" ENHANCEMENT-POINT ep_before_save SPOTS es_order.
" Eigene Implementierung (SE19):
ENHANCEMENT zei_order_enhancement.
" Code wird an diesem Punkt eingefügt
IF ls_order-custom_field IS INITIAL.
ls_order-custom_field = 'DEFAULT'.
ENDIF.
ENDENHANCEMENT.

8. Enhancement Sections

" Im Standard-Code:
" ENHANCEMENT-SECTION es_validation SPOTS es_order.
" " Original-Code
" IF lv_amount < 0.
" lv_error = abap_true.
" ENDIF.
" END-ENHANCEMENT-SECTION.
" Eigene Implementierung ersetzt Original:
ENHANCEMENT zei_validation_replacement.
" Eigener Code ersetzt Original
IF lv_amount < 0 OR lv_amount > 1000000.
lv_error = abap_true.
ENDIF.
ENDENHANCEMENT.

9. BAdI in RAP

" Extension Include in RAP Behavior Definition:
" managed implementation in class zbp_i_order unique;
" with additional save
" {
" ...
" determination SetDefaults on save { create; }
" }
" BAdI für RAP Extensions
INTERFACE zif_rap_order_extension PUBLIC.
METHODS: on_before_save
CHANGING ct_orders TYPE zt_orders.
METHODS: on_after_save
IMPORTING it_orders TYPE zt_orders.
ENDINTERFACE.
" Im Behavior Handler aufrufen
CLASS lhc_order DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS save_modified FOR SAVE
IMPORTING it_orders FOR CREATE order.
ENDCLASS.
CLASS lhc_order IMPLEMENTATION.
METHOD save_modified.
DATA: lo_badi TYPE REF TO zbadi_rap_order.
" BAdI vor Speicherung
GET BADI lo_badi.
DATA(lt_orders) = CORRESPONDING zt_orders( it_orders ).
CALL BADI lo_badi->on_before_save
CHANGING ct_orders = lt_orders.
" Speicherung...
" BAdI nach Speicherung
CALL BADI lo_badi->on_after_save
EXPORTING it_orders = lt_orders.
ENDMETHOD.
ENDCLASS.

10. Klassisches BAdI (Legacy)

" Klassisches BAdI aus SE18 (vor Enhancement Spots)
DATA: lo_badi TYPE REF TO if_ex_badi_name.
" Handle holen
CALL METHOD cl_exithandler=>get_instance
CHANGING instance = lo_badi.
" Methode aufrufen
IF lo_badi IS BOUND.
CALL METHOD lo_badi->method_name
EXPORTING param = value
CHANGING data = ls_data.
ENDIF.

11. BAdI-Implementierung aktivieren/deaktivieren

" Programmatisch prüfen ob BAdI aktiv
DATA: lo_badi TYPE REF TO zbadi_test.
GET BADI lo_badi.
" Prüfen ob Implementierungen existieren
DATA(lv_has_impl) = boolc( lo_badi IS BOUND ).
" In SE19:
" - Implementierung öffnen
" - Checkbox "Aktiv" setzen/entfernen
" - Aktivieren

12. BAdI mit Context

" BAdI mit zusätzlichem Kontext
INTERFACE zif_context_badi PUBLIC.
METHODS: process
IMPORTING
iv_context TYPE string
is_data TYPE ty_data
EXPORTING
es_result TYPE ty_result.
ENDINTERFACE.
" Aufruf mit Kontext für Filterung
DATA: lo_badi TYPE REF TO zbadi_context.
GET BADI lo_badi
FILTERS
context = 'SPECIAL_CASE'.
" Nur Implementierungen für diesen Kontext werden aufgerufen
CALL BADI lo_badi->process
EXPORTING
iv_context = 'SPECIAL_CASE'
is_data = ls_data
IMPORTING
es_result = ls_result.

13. Source Code Plugins (SCP)

" Source Code Plugins für ABAP Cloud
" Definiert in der Behavior Definition
" managed implementation in class zbp_i_product;
"
" define behavior for ZI_Product
" {
" ...
" // Extension point für Partner
" extension point productExtension;
" }
" Partner-Extension implementiert:
" enhance behavior for ZI_Product
" {
" extend productExtension
" {
" determination CalculateDiscount on modify { field price; }
" }
" }

14. User Exit (Legacy)

" Klassische User Exits (CMOD/SMOD)
" Werden über Includes eingebunden
" Include ZXaaau01 für Exit EXIT_SAPMM06E_001
FORM userexit_save_document_prepare.
" Kundenspezifische Logik vor Speicherung
IF sy-tcode = 'ME21N'.
" Bestellkopf modifizieren
ENDIF.
ENDFORM.

15. Enhancement Framework übersicht

" Alle Erweiterungen zu einem Objekt finden
" 1. SE84 - Repository Infosystem
" Enhancement Spots zum Objekt suchen
" 2. Im Code suchen nach:
" - ENHANCEMENT-POINT
" - ENHANCEMENT-SECTION
" - GET BADI
" 3. SE18 - BAdI-Definitionen suchen
" Verwendungsnachweis zeigt Implementierungen
" 4. SE19 - Implementierungen anzeigen
" Alle aktiven/inaktiven Implementierungen

Eigenes Enhancement Spot erstellen (Schritt für Schritt)

1. SE18 → Enhancement Spot erstellen
- Name: ZES_MY_APPLICATION
- Kurzbeschreibung eingeben
- Speichern
2. BAdI Definition hinzufügen
- Name: ZBADI_MY_BADI
- Interface erstellen: ZIF_MY_BADI
- Methoden im Interface definieren
- Optional: Filter definieren
- Optional: Fallback-Klasse angeben
3. Enhancement Spot aktivieren
4. Im Code einbauen:
DATA: lo_badi TYPE REF TO zbadi_my_badi.
GET BADI lo_badi.
CALL BADI lo_badi->my_method( ... ).
5. Implementierung erstellen (SE19)
- Enhancement Implementation: ZEI_MY_IMPL
- BAdI Implementation: ZBI_MY_IMPL
- Implementing Class: ZCL_MY_BADI_IMPL

Wichtige Transaktionen

TransaktionBeschreibung
SE18BAdI Definition / Enhancement Spot
SE19BAdI Implementierung
SE80Repository Browser (Enhancements)
SE84Repository Infosystem
SPAUModifikationsabgleich

Wichtige Hinweise / Best Practice

  • Neue BAdIs (GET/CALL BADI) bevorzugen vor klassischen.
  • Filter für kontextspezifische Implementierungen nutzen.
  • Fallback-Klasse für Default-Verhalten definieren.
  • Multiple Use wenn mehrere Implementierungen erlaubt.
  • Enhancement Spots für eigene Erweiterungspunkte.
  • Implementierungen können aktiviert/deaktiviert werden.
  • Dokumentation der BAdI-Schnittstelle nicht vergessen.
  • In RAP Extension Points verwenden.
  • Keine Modifikationen – immer Erweiterungen bevorzugen.
  • Kombinieren Sie mit Unit Testing für Testbarkeit.