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 :
- Dans les boucles (
DO,WHILE,LOOP AT):CHECKvé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èsCHECK. - Dans les sous-programmes (
FORM ... ENDFORM):CHECKvé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 àEXITdans un FORM). Si la condition est vraie, le traitement continue normalement dans le sous-programme aprèsCHECK.
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_trueouabap_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 : 3Traitement 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 : 2Boucle DO, itération : 3 -> Itération impaire traitée.Boucle DO, itération : 4Boucle 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.00FORM appelé avec montant : 200.00 Type : XFORM 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, unCONTINUEimplicite (dans les boucles) ouEXIT(dans les FORMs) est exécuté.
Remarques importantes / Bonnes pratiques
- Bien que
CHECKsoit fonctionnellement correct, de nombreux développeurs ABAP préfèrent aujourd’hui des constructionsIFexplicites avecCONTINUE,EXITouRETURN.Cela est souvent perçu comme plus lisible et exprimant l’intention plus clairement, car la logique" Au lieu de : CHECK <condition>.IF NOT <condition>.CONTINUE. " ou EXIT / RETURNENDIF.IF NOTpeut être plus directe. - La compréhension de
CHECKest importante pour la maintenance et l’analyse du code existant, en particulier le code plus ancien qui utilise des routinesFORM.