Die CHECK
-Anweisung ist eine Kontrollanweisung in ABAP. Ihr Hauptzweck ist es, den Programmfluss bedingt zu
steuern, und zwar spezifisch in den folgenden Kontexten:
- Innerhalb von Schleifen (
DO
,WHILE
,LOOP AT ... ENDLOOP
):CHECK
prüft eine Bedingung. Ist die Bedingung * falsch*, wird der aktuelle Schleifendurchlauf sofort abgebrochen, und das Programm springt zum nächsten Durchlauf (ähnlich wieCONTINUE
). Ist die Bedingung wahr, läuft die Verarbeitung nach demCHECK
normal weiter. - Innerhalb von Unterprogrammen (
FORM ... ENDFORM
):CHECK
prüft eine Bedingung. Ist die Bedingung falsch, wird das gesamte Unterprogramm (FORM
) sofort verlassen, und die Kontrolle kehrt zum aufrufenden Programmteil zurück (ähnlich wieEXIT
innerhalb eines FORM). Ist die Bedingung wahr, läuft die Verarbeitung im Unterprogramm nach demCHECK
normal weiter.
Wichtig: Die Verwendung von CHECK
außerhalb dieser beiden Kontexte (Schleifen und FORMs) ist in der Regel nicht
vorgesehen, führt zu Syntaxfehlern oder ist Teil obsoleter Praktiken. In modernen Methoden (METHOD...ENDMETHOD
) wird
CHECK
nicht zum Verlassen der Methode verwendet (dafür nimmt man RETURN
); innerhalb einer Methode funktioniert
CHECK
aber normal, wenn es innerhalb einer Schleife steht.
Syntax
Die Syntax ist sehr einfach gehalten:
CHECK <logischer_ausdruck>.
<logischer_ausdruck>
: Dies ist ein beliebiger Ausdruck, der zu einem Wahrheitswert ausgewertet werden kann (abap_true
oderabap_false
). Beispiele sind Vergleiche (a = b
,c > 10
), Prüfungen auf Initialwerte (my_var IS NOT INITIAL
), Funktionsaufrufe mit booleschem Rückgabewert oder einfach eine boolesche Variable.
Funktionsweise im Detail
Die Kernlogik von CHECK
ist: Nur wenn die Bedingung wahr ist, wird fortgefahren.
CHECK <bedingung>.
ist funktional äquivalent zu:
IF NOT <bedingung>. " Innerhalb einer Schleife: CONTINUE. " Innerhalb eines FORM: EXIT.ENDIF." Code hier wird nur ausgeführt, wenn <bedingung> wahr war.
Diese “Weiter bei Wahr”-Logik kann manchmal als umgekehrt zur IF
-Anweisung empfunden werden, wo man oft den ”
Fehlerfall” zuerst behandelt (IF <fehlerbedingung> THEN ... ENDIF
).
Beispiele
1. CHECK
innerhalb einer LOOP AT
-Schleife
Nur bestimmte Einträge einer Tabelle verarbeiten:
TYPES: BEGIN OF ty_order, order_id TYPE i, status TYPE c LENGTH 1, " N=New, P=Processed, E=Error END OF ty_order.
DATA: lt_orders TYPE STANDARD TABLE OF ty_order, ls_order TYPE ty_order.
APPEND VALUE #( order_id = 1 status = 'N' ) TO lt_orders.APPEND VALUE #( order_id = 2 status = 'P' ) TO lt_orders.APPEND VALUE #( order_id = 3 status = 'N' ) TO lt_orders.APPEND VALUE #( order_id = 4 status = 'E' ) TO lt_orders.
WRITE: / 'Verarbeite neue Aufträge:'.
LOOP AT lt_orders INTO ls_order. CHECK ls_order-status = 'N'. " Nur weitermachen, wenn Status 'N' (Neu) ist
" Folgender Code wird nur für Aufträge 1 und 3 ausgeführt WRITE: / ' -> Verarbeite Auftrag:', ls_order-order_id. " ... weitere Verarbeitung ... ls_order-status = 'P'. " Status ändern (Beispiel) MODIFY lt_orders FROM ls_order INDEX sy-tabix.ENDLOOP.
WRITE: / 'Verarbeitung abgeschlossen.'.
Ausgabe:
Verarbeite neue Aufträge: -> Verarbeite Auftrag: 1 -> Verarbeite Auftrag: 3Verarbeitung abgeschlossen.
2. CHECK
innerhalb einer DO
-Schleife
Bestimmte Iterationen überspringen:
DO 5 TIMES. WRITE: / 'DO-Schleife, Durchlauf:', sy-index.
CHECK sy-index MOD 2 = 1. " Nur weitermachen für ungerade Durchläufe (1, 3, 5)
WRITE: ' -> Ungerader Durchlauf wurde verarbeitet.'.ENDDO.
Ausgabe:
DO-Schleife, Durchlauf: 1 -> Ungerader Durchlauf wurde verarbeitet.DO-Schleife, Durchlauf: 2DO-Schleife, Durchlauf: 3 -> Ungerader Durchlauf wurde verarbeitet.DO-Schleife, Durchlauf: 4DO-Schleife, Durchlauf: 5 -> Ungerader Durchlauf wurde verarbeitet.
3. CHECK
innerhalb eines FORM
-Unterprogramms
Das Unterprogramm bei ungültigen Parametern vorzeitig verlassen:
START-OF-SELECTION. PERFORM calculate_discount USING iv_amount = 100 iv_cust_type = 'A'. PERFORM calculate_discount USING iv_amount = 200 iv_cust_type = 'X'. " Ungültiger Typ PERFORM calculate_discount USING iv_amount = -50 iv_cust_type = 'B'. " Ungültiger Betrag
FORM calculate_discount USING iv_amount TYPE p DECIMALS 2 iv_cust_type TYPE c LENGTH 1.
WRITE: / 'FORM aufgerufen mit Betrag:', iv_amount, 'Typ:', iv_cust_type.
" Eingabeprüfungen CHECK iv_amount > 0. " Verlassen, wenn Betrag nicht positiv ist CHECK iv_cust_type = 'A' OR iv_cust_type = 'B'. " Verlassen, wenn Kundentyp ungültig ist
" --- Nur hier weiter, wenn alle CHECKS erfolgreich waren --- DATA lv_discount TYPE p DECIMALS 2. IF iv_cust_type = 'A'. lv_discount = iv_amount * '0.1'. " 10% ELSE. " Muss 'B' sein lv_discount = iv_amount * '0.05'. " 5% ENDIF. WRITE: ' -> Rabatt berechnet:', lv_discount.
ENDFORM.
Ausgabe:
FORM aufgerufen mit Betrag: 100.00 Typ: A -> Rabatt berechnet: 10.00FORM aufgerufen mit Betrag: 200.00 Typ: XFORM aufgerufen mit Betrag: -50.00 Typ: B
(Man sieht, dass bei Aufruf 2 und 3 die Verarbeitung nach dem fehlgeschlagenen CHECK
nicht mehr stattfindet).
Abgrenzung zu CONTINUE
, EXIT
, RETURN
CONTINUE
(in Schleifen): Springt immer zum nächsten Schleifendurchlauf.EXIT
(in Schleifen/FORMs): Verlässt immer die gesamte Schleife bzw. das FORM.RETURN
(in Methoden/Funktionsbausteinen): Verlässt immer die Methode/den Funktionsbaustein.CHECK <bedingung>.
: Ist bedingt. Nur wenn die Bedingung falsch ist, wird ein implizitesCONTINUE
(in Schleifen) oderEXIT
(in FORMs) ausgeführt.
Wichtige Hinweise / Best Practice
- Obwohl
CHECK
funktional korrekt ist, bevorzugen viele ABAP-Entwickler heute expliziteIF
-Konstrukte mitCONTINUE
,EXIT
oderRETURN
.Dies wird oft als lesbarer und die Absicht klarer ausdrückend empfunden, da die" Statt: CHECK <bedingung>.IF NOT <bedingung>.CONTINUE. " oder EXIT / RETURNENDIF.IF NOT
-Logik direkter sein kann. - Das Verständnis von
CHECK
ist wichtig für die Wartung und Analyse von bestehendem Code, insbesondere älterem Code, derFORM
-Routinen verwendet.