Conditional Exit in ABAP: The CHECK Statement in LOOP, DO and FORM Explained

Category
ABAP-Statements
Published
Author
Johannes

The CHECK statement is a control statement in ABAP. Its main purpose is to conditionally control program flow, specifically in the following contexts:

  1. Within loops (DO, WHILE, LOOP AT): CHECK evaluates a condition. If the condition is false, the current loop iteration is immediately terminated, and the program jumps to the next iteration (similar to CONTINUE). If the condition is true, processing continues normally after the CHECK.
  2. Within subroutines (FORM ... ENDFORM): CHECK evaluates a condition. If the condition is false, the entire subroutine (FORM) is immediately exited, and control returns to the calling program part (similar to EXIT within a FORM). If the condition is true, processing continues normally in the subroutine after the CHECK.

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_true or abap_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: 3
Processing 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: 2
DO loop, iteration: 3
-> Odd iteration was processed.
DO loop, iteration: 4
DO 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.00
FORM called with amount: 200.00 Type: X
FORM 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 implicit CONTINUE (in loops) or EXIT (in FORMs) is executed.

Important Notes / Best Practice

  • Although CHECK is functionally correct, many ABAP developers today prefer explicit IF constructs with CONTINUE, EXIT, or RETURN.
    " Instead of: CHECK <condition>.
    IF NOT <condition>.
    CONTINUE. " or EXIT / RETURN
    ENDIF.
    This is often considered more readable and clearer in expressing intent, as the IF NOT logic can be more direct.
  • Understanding CHECK is important for maintaining and analyzing existing code, especially older code that uses FORM routines.