The CHECK statement is a control statement in ABAP. Its main purpose is to conditionally control program flow, specifically in the following contexts:
- Within loops (
DO,WHILE,LOOP AT):CHECKevaluates a condition. If the condition is false, the current loop iteration is immediately terminated, and the program jumps to the next iteration (similar toCONTINUE). If the condition is true, processing continues normally after theCHECK. - Within subroutines (
FORM ... ENDFORM):CHECKevaluates a condition. If the condition is false, the entire subroutine (FORM) is immediately exited, and control returns to the calling program part (similar toEXITwithin a FORM). If the condition is true, processing continues normally in the subroutine after theCHECK.
Important: Using CHECK outside these two contexts (loops and FORMs) is generally not intended, leads to syntax errors, or is part of obsolete practices. In modern methods (METHOD...ENDMETHOD), CHECK is not used to exit the method (use RETURN for that); however, within a method, CHECK works normally if it’s inside a loop.
Syntax
The syntax is very simple:
CHECK <logical_expression>.<logical_expression>: This is any expression that can be evaluated to a truth value (abap_trueorabap_false). Examples are comparisons (a = b,c > 10), checks for initial values (my_var IS NOT INITIAL), function calls with boolean return values, or simply a boolean variable.
Behavior in Detail
The core logic of CHECK is: Only if the condition is true, continue.
CHECK <condition>. is functionally equivalent to:
IF NOT <condition>. " Within a loop: CONTINUE. " Within a FORM: EXIT.ENDIF." Code here is only executed if <condition> was true.This “continue if true” logic can sometimes feel inverted compared to the IF statement, where you often handle the “error case” first (IF <error_condition> THEN ... ENDIF).
Examples
1. CHECK Within a LOOP AT Loop
Process only specific entries of a table:
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: / 'Processing new orders:'.
LOOP AT lt_orders INTO ls_order. CHECK ls_order-status = 'N'. " Only continue if status is 'N' (New)
" Following code is only executed for orders 1 and 3 WRITE: / ' -> Processing order:', ls_order-order_id. " ... further processing ... ls_order-status = 'P'. " Change status (example) MODIFY lt_orders FROM ls_order INDEX sy-tabix.ENDLOOP.
WRITE: / 'Processing completed.'.Output:
Processing new orders: -> Processing order: 1 -> Processing order: 3Processing completed.2. CHECK Within a DO Loop
Skip certain iterations:
DO 5 TIMES. WRITE: / 'DO loop, iteration:', sy-index.
CHECK sy-index MOD 2 = 1. " Only continue for odd iterations (1, 3, 5)
WRITE: ' -> Odd iteration was processed.'.ENDDO.Output:
DO loop, iteration: 1 -> Odd iteration was processed.DO loop, iteration: 2DO loop, iteration: 3 -> Odd iteration was processed.DO loop, iteration: 4DO loop, iteration: 5 -> Odd iteration was processed.3. CHECK Within a FORM Subroutine
Exit the subroutine early with invalid parameters:
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'. " Invalid type PERFORM calculate_discount USING iv_amount = -50 iv_cust_type = 'B'. " Invalid amount
FORM calculate_discount USING iv_amount TYPE p DECIMALS 2 iv_cust_type TYPE c LENGTH 1.
WRITE: / 'FORM called with amount:', iv_amount, 'Type:', iv_cust_type.
" Input validations CHECK iv_amount > 0. " Exit if amount is not positive CHECK iv_cust_type = 'A' OR iv_cust_type = 'B'. " Exit if customer type is invalid
" --- Only continue here if all CHECKs were successful --- DATA lv_discount TYPE p DECIMALS 2. IF iv_cust_type = 'A'. lv_discount = iv_amount * '0.1'. " 10% ELSE. " Must be 'B' lv_discount = iv_amount * '0.05'. " 5% ENDIF. WRITE: ' -> Discount calculated:', lv_discount.
ENDFORM.Output:
FORM called with amount: 100.00 Type: A -> Discount calculated: 10.00FORM called with amount: 200.00 Type: XFORM called with amount: -50.00 Type: B(You can see that for calls 2 and 3, the processing after the failed CHECK no longer takes place).
Distinction from CONTINUE, EXIT, RETURN
CONTINUE(in loops): Always jumps to the next loop iteration.EXIT(in loops/FORMs): Always exits the entire loop or FORM.RETURN(in methods/function modules): Always exits the method/function module.CHECK <condition>.: Is conditional. Only if the condition is false, an implicitCONTINUE(in loops) orEXIT(in FORMs) is executed.
Important Notes / Best Practice
- Although
CHECKis functionally correct, many ABAP developers today prefer explicitIFconstructs withCONTINUE,EXIT, orRETURN.This is often considered more readable and clearer in expressing intent, as the" Instead of: CHECK <condition>.IF NOT <condition>.CONTINUE. " or EXIT / RETURNENDIF.IF NOTlogic can be more direct. - Understanding
CHECKis important for maintaining and analyzing existing code, especially older code that usesFORMroutines.