Interruption conditionnelle en ABAP : L

Catégorie
ABAP-Statements
Publié
Auteur
Johannes

L’instruction CHECK est une instruction de contrôle en ABAP. Son objectif principal est de piloter le flux de programme conditionnellement, spécifiquement dans les contextes suivants :

  1. Dans les boucles (DO, WHILE, LOOP AT): CHECK vérifie une condition. Si la condition est fausse, l’itération actuelle de la boucle est immédiatement interrompue, et le programme passe à l’itération suivante (similaire à CONTINUE). Si la condition est vraie, le traitement continue normalement après CHECK.
  2. Dans les sous-programmes (FORM ... ENDFORM): CHECK vérifie une condition. Si la condition est fausse, le sous-programme complet (FORM) est immédiatement quitté, et le contrôle retourne à la partie du programme appelante (similaire à EXIT dans un FORM). Si la condition est vraie, le traitement continue normalement dans le sous-programme après CHECK.

Important : L’utilisation de CHECK en dehors de ces deux contextes (boucles et FORMs) n’est généralement pas prévue, conduit à des erreurs de syntaxe ou fait partie de pratiques obsolètes. Dans les méthodes modernes (METHOD...ENDMETHOD), CHECK n’est pas utilisé pour quitter la méthode (on utilise RETURN pour cela); mais dans une méthode, CHECK fonctionne normalement lorsqu’il se trouve dans une boucle.

Syntaxe

La syntaxe est très simple :

CHECK <expression_logique>.
  • <expression_logique>: Il s’agit d’une expression arbitraire qui peut être évaluée en une valeur de vérité (abap_true ou abap_false). Les exemples sont des comparaisons (a = b, c > 10), des vérifications de valeurs initiales (my_var IS NOT INITIAL), des appels de fonction avec une valeur de retour booléenne ou simplement une variable booléenne.

Fonctionnement en détail

La logique de base de CHECK est : Continuer uniquement si la condition est vraie.

CHECK <condition>. est fonctionnellement équivalent à :

IF NOT <condition>.
" Dans une boucle :
CONTINUE.
" Dans un FORM :
EXIT.
ENDIF.
" Le code ici n'est exécuté que si <condition> était vraie.

Cette logique “continuer si vrai” peut parfois être perçue comme inverse à l’instruction IF, où l’on traite souvent le “cas d’erreur” en premier (IF <condition_erreur> THEN ... ENDIF).

Exemples

1. CHECK dans une boucle LOOP AT

Traiter uniquement certaines entrées d’une 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: / 'Traitement des nouvelles commandes :'.
LOOP AT lt_orders INTO ls_order.
CHECK ls_order-status = 'N'. " Continuer uniquement si statut 'N' (Nouveau)
" Le code suivant n'est exécuté que pour les commandes 1 et 3
WRITE: / ' -> Traitement de la commande :', ls_order-order_id.
" ... traitement supplémentaire ...
ls_order-status = 'P'. " Modifier le statut (exemple)
MODIFY lt_orders FROM ls_order INDEX sy-tabix.
ENDLOOP.
WRITE: / 'Traitement terminé.'.

Sortie :

Traitement des nouvelles commandes :
-> Traitement de la commande : 1
-> Traitement de la commande : 3
Traitement terminé.

2. CHECK dans une boucle DO

Sauter certaines itérations :

DO 5 TIMES.
WRITE: / 'Boucle DO, itération :', sy-index.
CHECK sy-index MOD 2 = 1. " Continuer uniquement pour les itérations impaires (1, 3, 5)
WRITE: ' -> Itération impaire traitée.'.
ENDDO.

Sortie :

Boucle DO, itération : 1
-> Itération impaire traitée.
Boucle DO, itération : 2
Boucle DO, itération : 3
-> Itération impaire traitée.
Boucle DO, itération : 4
Boucle DO, itération : 5
-> Itération impaire traitée.

3. CHECK dans un sous-programme FORM

Quitter prématurément le sous-programme avec des paramètres invalides :

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'. " Type invalide
PERFORM calculate_discount USING iv_amount = -50 iv_cust_type = 'B'. " Montant invalide
FORM calculate_discount USING iv_amount TYPE p DECIMALS 2
iv_cust_type TYPE c LENGTH 1.
WRITE: / 'FORM appelé avec montant :', iv_amount, 'Type :', iv_cust_type.
" Vérifications d'entrée
CHECK iv_amount > 0. " Quitter si le montant n'est pas positif
CHECK iv_cust_type = 'A' OR
iv_cust_type = 'B'. " Quitter si le type de client est invalide
" --- Continuer uniquement ici si tous les CHECKS ont réussi ---
DATA lv_discount TYPE p DECIMALS 2.
IF iv_cust_type = 'A'.
lv_discount = iv_amount * '0.1'. " 10%
ELSE. " Doit être 'B"
lv_discount = iv_amount * '0.05'. " 5%
ENDIF.
WRITE: ' -> Remise calculée :', lv_discount.
ENDFORM.

Sortie :

FORM appelé avec montant : 100.00 Type : A
-> Remise calculée : 10.00
FORM appelé avec montant : 200.00 Type : X
FORM appelé avec montant : -50.00 Type : B

(On voit que lors des appels 2 et 3, le traitement ne se poursuit plus après l’échec de CHECK).

Distinction par rapport à CONTINUE, EXIT, RETURN

  • CONTINUE (dans les boucles) : Passe toujours à l’itération suivante de la boucle.
  • EXIT (dans les boucles/FORMs) : Quitte toujours la boucle complète ou le FORM.
  • RETURN (dans les méthodes/modules fonctions) : Quitte toujours la méthode/le module fonction.
  • CHECK <condition>. : Est conditionnel. Uniquement si la condition est fausse, un CONTINUE implicite (dans les boucles) ou EXIT (dans les FORMs) est exécuté.

Remarques importantes / Bonnes pratiques

  • Bien que CHECK soit fonctionnellement correct, de nombreux développeurs ABAP préfèrent aujourd’hui des constructions IF explicites avec CONTINUE, EXIT ou RETURN.
    " Au lieu de : CHECK <condition>.
    IF NOT <condition>.
    CONTINUE. " ou EXIT / RETURN
    ENDIF.
    Cela est souvent perçu comme plus lisible et exprimant l’intention plus clairement, car la logique IF NOT peut être plus directe.
  • La compréhension de CHECK est importante pour la maintenance et l’analyse du code existant, en particulier le code plus ancien qui utilise des routines FORM.