La sentencia CHECK es una sentencia de control en ABAP. Su propósito principal es controlar condicionalmente el flujo del programa, específicamente en los siguientes contextos:
- Dentro de bucles (
DO,WHILE,LOOP AT):CHECKevalúa una condición. Si la condición es falsa, la iteración actual del bucle se interrumpe inmediatamente, y el programa salta a la siguiente iteración (similar aCONTINUE). Si la condición es verdadera, el procesamiento continúa normalmente después delCHECK. - Dentro de subrutinas (
FORM ... ENDFORM):CHECKevalúa una condición. Si la condición es falsa, se sale inmediatamente de toda la subrutina (FORM), y el control regresa a la parte del programa que la llamó (similar aEXITdentro de un FORM). Si la condición es verdadera, el procesamiento en la subrutina continúa normalmente después delCHECK.
Importante: El uso de CHECK fuera de estos dos contextos (bucles y FORMs) generalmente no está previsto, produce errores de sintaxis o es parte de prácticas obsoletas. En métodos modernos (METHOD...ENDMETHOD), CHECK no se usa para salir del método (para eso se usa RETURN); sin embargo, dentro de un método, CHECK funciona normalmente si está dentro de un bucle.
Sintaxis
La sintaxis es muy simple:
CHECK <expresion_logica>.<expresion_logica>: Esta es cualquier expresión que pueda evaluarse a un valor de verdad (abap_trueoabap_false). Ejemplos son comparaciones (a = b,c > 10), verificaciones de valores iniciales (my_var IS NOT INITIAL), llamadas a funciones con valor de retorno booleano o simplemente una variable booleana.
Funcionamiento en detalle
La lógica central de CHECK es: Solo si la condición es verdadera, se continúa.
CHECK <condicion>. es funcionalmente equivalente a:
IF NOT <condicion>. " Dentro de un bucle: CONTINUE. " Dentro de un FORM: EXIT.ENDIF." El código aquí solo se ejecuta si <condicion> era verdadera.Esta lógica de “continuar si es verdadero” a veces puede percibirse como inversa a la sentencia IF, donde a menudo se maneja primero el “caso de error” (IF <condicion_error> THEN ... ENDIF).
Ejemplos
1. CHECK dentro de un bucle LOOP AT
Procesar solo ciertas entradas de una tabla:
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: / 'Procesando pedidos nuevos:'.
LOOP AT lt_orders INTO ls_order. CHECK ls_order-status = 'N'. " Solo continuar si estado es 'N' (Nuevo)
" El siguiente código solo se ejecuta para pedidos 1 y 3 WRITE: / ' -> Procesando pedido:', ls_order-order_id. " ... procesamiento adicional ... ls_order-status = 'P'. " Cambiar estado (ejemplo) MODIFY lt_orders FROM ls_order INDEX sy-tabix.ENDLOOP.
WRITE: / 'Procesamiento completado.'.Salida:
Procesando pedidos nuevos: -> Procesando pedido: 1 -> Procesando pedido: 3Procesamiento completado.2. CHECK dentro de un bucle DO
Saltar ciertas iteraciones:
DO 5 TIMES. WRITE: / 'Bucle DO, iteración:', sy-index.
CHECK sy-index MOD 2 = 1. " Solo continuar para iteraciones impares (1, 3, 5)
WRITE: ' -> Iteración impar fue procesada.'.ENDDO.Salida:
Bucle DO, iteración: 1 -> Iteración impar fue procesada.Bucle DO, iteración: 2Bucle DO, iteración: 3 -> Iteración impar fue procesada.Bucle DO, iteración: 4Bucle DO, iteración: 5 -> Iteración impar fue procesada.3. CHECK dentro de una subrutina FORM
Salir prematuramente de la subrutina con parámetros inválidos:
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'. " Tipo inválido PERFORM calculate_discount USING iv_amount = -50 iv_cust_type = 'B'. " Importe inválido
FORM calculate_discount USING iv_amount TYPE p DECIMALS 2 iv_cust_type TYPE c LENGTH 1.
WRITE: / 'FORM llamado con importe:', iv_amount, 'Tipo:', iv_cust_type.
" Validaciones de entrada CHECK iv_amount > 0. " Salir si importe no es positivo CHECK iv_cust_type = 'A' OR iv_cust_type = 'B'. " Salir si tipo de cliente es inválido
" --- Solo continuar aquí si todos los CHECKs fueron exitosos --- DATA lv_discount TYPE p DECIMALS 2. IF iv_cust_type = 'A'. lv_discount = iv_amount * '0.1'. " 10% ELSE. " Debe ser 'B' lv_discount = iv_amount * '0.05'. " 5% ENDIF. WRITE: ' -> Descuento calculado:', lv_discount.
ENDFORM.Salida:
FORM llamado con importe: 100.00 Tipo: A -> Descuento calculado: 10.00FORM llamado con importe: 200.00 Tipo: XFORM llamado con importe: -50.00 Tipo: B(Se puede ver que en las llamadas 2 y 3 el procesamiento después del CHECK fallido ya no ocurre).
Diferencia con CONTINUE, EXIT, RETURN
CONTINUE(en bucles): Salta siempre a la siguiente iteración del bucle.EXIT(en bucles/FORMs): Sale siempre de todo el bucle o FORM.RETURN(en métodos/módulos de funciones): Sale siempre del método/módulo de funciones.CHECK <condicion>.: Es condicional. Solo si la condición es falsa, se ejecuta unCONTINUEimplícito (en bucles) oEXIT(en FORMs).
Notas importantes / Mejores prácticas
- Aunque
CHECKes funcionalmente correcto, muchos desarrolladores ABAP hoy prefieren construccionesIFexplícitas conCONTINUE,EXIToRETURN.Esto a menudo se considera más legible y expresa la intención más claramente, ya que la lógica" En lugar de: CHECK <condicion>.IF NOT <condicion>.CONTINUE. " o EXIT / RETURNENDIF.IF NOTpuede ser más directa. - Comprender
CHECKes importante para el mantenimiento y análisis de código existente, especialmente código más antiguo que usa rutinasFORM.