Enhancements, user exits & BAdI's
SAP-standaardgedrag aanpassen zonder de standaard te wijzigen: user exits, customer exits (SMOD/CMOD), klassieke en nieuwe BAdI's, expliciete en impliciete enhancement points, en hoe je ze terugvindt.
01Waarom enhancements bestaan
De gouden regel in SAP: wijzig nooit SAP-standaardcode. Een "modificatie" van standaardobjecten maakt elke upgrade en elke patch riskant en duur. Daarom heeft SAP door de jaren heen een reeks officiële "haakjes" ingebouwd waar klanten hun eigen logica veilig kunnen inpluggen — die haakjes heten samen enhancements.
Typische toepassingen: extra validaties bij het opslaan van een order, klantvelden automatisch vullen, afwijkende prijsbepaling, extra controles bij goederenbewegingen. De volgorde hieronder is grofweg ook de historische volgorde — en je komt ze in een gemiddeld systeem allemaal tegen.
| Mechanisme | Generatie | Techniek | Herkenbaar aan |
|---|---|---|---|
| User exit | Oudste (R/3) | Lege FORM-routine in een SAP-include die klanteigendom is | PERFORM userexit_..., includes als MV45AFZZ |
| Customer exit | Klassiek | Functiemodule EXIT_<prog>_<nnn> met een Z-include, geactiveerd via project | Transacties SMOD/CMOD, includes ZXV45U01 e.d. |
| BAdI | Modern | Interface die je implementeert met een eigen class (OO) | GET BADI/CALL BADI of CL_EXITHANDLER |
| Enhancement framework | Nieuwste (7.0+) | Expliciete/impliciete enhancement points in standaardcode | ENHANCEMENT-POINT, "spiraal"-icoon in de editor |
02User exits — lege FORM-routines
De oudste vorm, vooral in SD (verkoop). SAP levert een include die formeel klantterrein is; de standaard roept de FORM-routines erin op vaste punten aan.
" in SAP-include MV45AFZZ (verkooporderverwerking, klantterrein):
FORM userexit_save_document_prepare.
" jouw logica vlak vóór het opslaan van een verkooporder,
" bijv. een extra verplicht-veld-controle:
IF vbak-bstnk IS INITIAL.
MESSAGE e001(zsd) WITH 'Klantreferentie is verplicht'.
ENDIF.
ENDFORM.
- Bekende SD-includes:
MV45AFZZ(order),MV50AFZ1(levering),RV60AFZZ(facturering). - De globale variabelen van het standaardprogramma (
vbak,vbap,xvbap…) zijn hier direct beschikbaar — krachtig, maar foutgevoelig: je zit middenin de standaardverwerking. - Formeel is dit een modificatie-vrije techniek, maar hij vergt een objectsleutel bij eerste aanleg en er is er maar één per systeem — meerdere teams delen dezelfde include, dus verwacht hier historisch gegroeide spaghetti.
03Customer exits — SMOD & CMOD
Gestructureerder dan user exits: SAP definieert per toepassing een enhancement (verzameling exit-functiemodules, schermuitbreidingen en klantvelden), en de klant activeert die in een eigen project.
SMOD— de catalogus van door SAP geleverde enhancements (bijv.M06B0005voor inkooporders).CMOD— het klantproject waarin één of meer enhancements worden geactiveerd. Zonder actief project draait je code niet — de meest voorkomende reden dat een exit "niets doet".- De exit-functiemodule heet
EXIT_<programmanaam>_<nummer>en bevat precies één regel: eenINCLUDE ZX...— dáár schrijf je je code.
FUNCTION exit_saplmebo_001.
INCLUDE zxm06u01. " ← jouw code leeft in deze Z-include
ENDFUNCTION.
Varianten binnen een enhancement: functiemodule-exits (logica), screen exits (extra subschermen met klantvelden, zie dynpro's) en menu exits (eigen menu-opties).
04BAdI's — Business Add-Ins
De object-georiënteerde opvolger: SAP definieert een interface, jij levert een class die hem implementeert. Meerdere implementaties naast elkaar zijn mogelijk, en filter-BAdI's kiezen per situatie (land, ordersoort…) de juiste implementatie.
Klassieke vs. nieuwe BAdI's
| Klassieke BAdI | Nieuwe BAdI (kernel-BAdI, 7.0+) | |
|---|---|---|
| Aanroep in standaardcode | via CL_EXITHANDLER=>GET_INSTANCE en een method-call op de proxy | GET BADI gevolgd door CALL BADI (taal-statements) |
| Definitie/implementatie | SE18 / SE19 | Ook SE18/SE19, maar ondergebracht in een enhancement spot |
| Performance | Extra laag via proxy-object | In de kernel geïntegreerd, sneller |
" nieuwe BAdI — zo ziet de aanroep in standaardcode eruit:
DATA lo_badi TYPE REF TO badi_naam.
GET BADI lo_badi
FILTERS land = ls_kop-land. " filter bepaalt welke implementatie(s)
CALL BADI lo_badi->controleer_document
EXPORTING is_kop = ls_kop
CHANGING ct_meldingen = lt_meldingen.
Zelf een BAdI-implementatie maken
- Zoek de BAdI-definitie (documentatie, of zoektechnieken hieronder).
- Maak in
SE19een implementatie; het systeem genereert een classZCL_IM_...die de BAdI-interface implementeert. - Vul de interfacemethoden met jouw logica; parameters geven je de context (documentkop, regels) en vaak een terugkoppeltabel voor meldingen.
- Activeer de implementatie — vergeten activeren is hier de klassieke "hij doet niets"-oorzaak.
ME_PROCESS_PO_CUST (inkooporder), BADI_SD_SALES/SD_SALES_ITEM (verkooporder, S/4), AC_DOCUMENT (financiële boeking), WORKORDER_UPDATE (productieorder).05Enhancement framework — points & sections
Sinds NetWeaver 7.0 kan vrijwel elke regel standaardcode uitgebreid worden zónder vooraf gedefinieerde exit. Dit is het enhancement framework; BAdI's zijn er formeel een onderdeel van.
| Vorm | Wat het is |
|---|---|
| Expliciet enhancement point | Door SAP gemarkeerde plek (ENHANCEMENT-POINT naam SPOTS spot.) waar je code mag toevoegen |
| Expliciete enhancement section | Door SAP gemarkeerd blok dat je mag vervangen door eigen code (ENHANCEMENT-SECTION ... END-ENHANCEMENT-SECTION) |
| Impliciet enhancement point | Automatisch bestaande punten: begin/einde van elke method, FORM of functiemodule, en einde van elke include of structuurdefinitie |
Jouw code komt in een enhancement implementation te staan en is in de editor zichtbaar als grijs blok tussen ENHANCEMENT en ENDENHANCEMENT. Impliciete enhancements aan het begin/einde van een method zijn in de praktijk het "laatste redmiddel" als er geen user exit of BAdI beschikbaar is.
SPAU_ENH toont de gevolgen). Voorkeursvolgorde bij nieuwbouw: BAdI → customer exit → expliciet point → impliciet point.06Exits en BAdI's terugvinden
Het halve werk is uitzoeken wélke exit op het juiste moment afgaat. Beproefde technieken:
- Debuggen op de aanroep — zet een breakpoint op statement
CALL BADIof op de methodCL_EXITHANDLER=>GET_INSTANCE(via "breakpoint at statement/method" in de debugger) en voer de transactie uit: elke gepasseerde BAdI komt langs. - Zoeken in de programmacode — in het hoofdprogramma van de transactie (via Systeem → Status het programma opzoeken) zoeken naar
userexit,customer-function(customer exits) ofenhancement. - SE84 / repository-informatiesysteem — BAdI-definities en enhancements per pakket/toepassingscomponent opzoeken.
- ST05-trace — een SQL-trace verraadt vaak in welke programmadelen iets gebeurt, en dus waar je moet zoeken.
- Bestaande implementaties —
SE19toont per BAdI-definitie welke Z-implementaties er al zijn; vaak is de helft van je vraag al eens beantwoord in bestaand maatwerk.
CALL CUSTOMER-FUNCTION '001' in standaardcode, dan kijk je naar een customer exit (de bijbehorende functiemodule heet EXIT_<programma>_001). Zie je GET BADI/CALL BADI of CL_EXITHANDLER, dan is het een BAdI.