L’instruction COLLECT est une commande spéciale en ABAP qui sert à condenser ou agréger des données dans une table interne. La particularité de COLLECT est :
- Elle vérifie si une ligne existe déjà dans la table cible dont la clé correspond à celle de la ligne à ajouter. La “clé” pour
COLLECTest toujours constituée de tous les champs non numériques de la ligne de table (donc tout sauf les typesI,P,F,DECFLOAT16/34). - Si une ligne avec une clé non numérique identique est trouvée : Les valeurs de tous les champs numériques de la ligne à ajouter sont additionnées aux valeurs des champs numériques correspondants de la ligne déjà existante.
- Si aucune ligne avec une clé non numérique identique n’est trouvée : La ligne à ajouter est insérée comme nouvelle entrée dans la table (similaire à
APPENDpour les tables standard ouINSERTpour les tables hash).
COLLECT est donc idéal pour former des sommes ou des comptages sur certaines caractéristiques (par ex. quantité totale par matériel et usine).
Syntaxe
COLLECT <wa> INTO <table_interne> [ASSIGNING <symbole_champ> | REFERENCE INTO <reference_donnees>].COLLECT: Le mot-clé ABAP.<wa>: Une zone de travail (structure), compatible avec le type de ligne de la<table_interne>.- Les champs non numériques dans
<wa>forment la clé pour la recherche/agrégation. - Les champs numériques dans
<wa>contiennent les valeurs qui seront éventuellement additionnées à une ligne existante.
- Les champs non numériques dans
INTO <table_interne>: La table interne cible dans laquelle on agrège ou insère.ASSIGNING <symbole_champ>/REFERENCE INTO <reference_donnees>(Optionnel) : Après l’opération, le symbole de champ ou la référence de données pointe vers la ligne de la table qui a été nouvellement insérée ou dont les valeurs numériques viennent d’être mises à jour. Utile pour un accès direct au résultat.
Fonctionnement et comportement selon le type de table (Important !)
L’adéquation et l’efficacité de COLLECT dépendent fortement du type de la table cible :
1. Tables standard (STANDARD TABLE)
COLLECTest autorisé.- La recherche d’une ligne avec une clé non numérique correspondante s’effectue par lecture séquentielle de la table. Cela peut devenir très lent pour les grandes tables !
- Si aucune clé correspondante n’est trouvée, la ligne de
<wa>est ajoutée à la fin de la table (commeAPPEND). sy-tabixest défini sur l’index de la ligne modifiée ou nouvellement ajoutée.
2. Tables hash (HASHED TABLE)
COLLECTest autorisé et souvent le cas d’utilisation le plus efficace, MAIS UNIQUEMENT SI la clé unique (UNIQUE KEY) de la table hash est constituée exactement de tous les champs non numériques de la structure de ligne et ne contient aucun champ numérique.- Si cette condition est remplie,
COLLECTutilise l’algorithme de hachage pour une recherche très rapide de la clé. - Si aucune clé correspondante n’est trouvée, la ligne est insérée (comme
INSERT). sy-tabixest indéfini ici (généralement 0), car l’index n’a pas de rôle dans les tables hash.- Attention : Si la clé définie de la table hash ne correspond pas à la clé
COLLECTimplicite (tous les champs non numériques), l’utilisation deCOLLECTconduit à une erreur d’exécution !
3. Tables triées (SORTED TABLE)
- L’utilisation de
COLLECTavec des tables triées est fortement déconseillée et conduit souvent à des erreurs d’exécution ! COLLECTignore l’ordre de tri défini de la table et travaille uniquement avec sa propre clé implicite (tous les champs non numériques). L’insertion ou l’agrégation peut violer le tri et conduire à des états incohérents ou à des abandons directs.- Pour les agrégations dans les tables triées : Utilisez plutôt une logique manuelle avec
READ TABLE <table> WITH KEY ... BINARY SEARCH, suivie deMODIFY <table> ...(si trouvé) ouINSERT <wa> INTO TABLE <table>(si non trouvé).
Champs système
sy-subrc: Est normalement toujours défini à0parCOLLECT, que ce soit une agrégation ou une nouvelle insertion. Ce n’est donc pas un bon indicateur de ce qui s’est passé.sy-tabix: Significatif uniquement pour les tables standard, où il contient l’index de la ligne traitée/nouvellement insérée. Pour les tables hash, il est 0/indéfini.
Exemples
1. Agrégation dans une table standard (Quantité par matériel)
TYPES: BEGIN OF ty_mat_quant, material TYPE string, " Clé (non numérique) quantity TYPE i, " Valeur (numérique) END OF ty_mat_quant.
DATA: lt_summary TYPE STANDARD TABLE OF ty_mat_quant, ls_data TYPE ty_mat_quant.
ls_data = VALUE #( material = 'M-01' quantity = 10 ).COLLECT ls_data INTO lt_summary.
ls_data = VALUE #( material = 'M-02' quantity = 5 ).COLLECT ls_data INTO lt_summary.
ls_data = VALUE #( material = 'M-01' quantity = 7 ). " Sera ajouté à M-01COLLECT ls_data INTO lt_summary.
cl_demo_output=>display( lt_summary )." Sortie :" Material | Quantity" ---------|---------" M-01 | 17" M-02 | 52. Agrégation efficace dans une table hash (Quantité par matériel/usine)
TYPES: BEGIN OF ty_stock, matnr TYPE matnr, " Partie de la clé werks TYPE werks_d, " Partie de la clé menge TYPE i, " Valeur END OF ty_stock.
" La clé de la table hash DOIT correspondre aux champs non numériques !DATA lt_stock_agg TYPE HASHED TABLE OF ty_stock WITH UNIQUE KEY matnr werks.DATA ls_stock TYPE ty_stock.
ls_stock = VALUE #( matnr = 'MAT1' werks = '1000' menge = 100 ).COLLECT ls_stock INTO lt_stock_agg.
ls_stock = VALUE #( matnr = 'MAT2' werks = '1000' menge = 50 ).COLLECT ls_stock INTO lt_stock_agg.
ls_stock = VALUE #( matnr = 'MAT1' werks = '1000' menge = 25 ). " Sera additionnéCOLLECT ls_stock INTO lt_stock_agg.
ls_stock = VALUE #( matnr = 'MAT1' werks = '2000' menge = 200 ). " Nouvelle entréeCOLLECT ls_stock INTO lt_stock_agg.
cl_demo_output=>display( lt_stock_agg )." Sortie (ordre non défini pour les hash) :" Matnr | Werks | Menge" ------|-------|------" MAT1 | 1000 | 125" MAT2 | 1000 | 50" MAT1 | 2000 | 2003. Utilisation de ASSIGNING
FIELD-SYMBOLS: <fs_stock_line> LIKE LINE OF lt_stock_agg.
ls_stock = VALUE #( matnr = 'MAT1' werks = '1000' menge = 5 ).COLLECT ls_stock INTO lt_stock_agg ASSIGNING <fs_stock_line>.
IF <fs_stock_line> IS ASSIGNED. WRITE: / 'Ligne agrégée/nouvelle:', <fs_stock_line>-matnr, <fs_stock_line>-werks, 'Quantité:', <fs_stock_line>-menge. " Sortie ex.: Ligne agrégée/nouvelle: MAT1 1000 Quantité: 130 (si 125 avant)ENDIF.Notes importantes / Bonnes pratiques
COLLECTest l’outil spécial pour l’agrégation de valeurs numériques basée sur une clé non numérique dans les tables internes.- Elle modifie la table cible directement.
- Pour une performance optimale, utilisez
COLLECTavec des tables hash, dont la clé est correctement définie (Unique Key = tous les champs non numériques). - N’utilisez pas
COLLECTavec des tables triées – utilisez plutôtREAD TABLE/MODIFY/INSERT. - Pour les tables standard, gardez à l’esprit les implications potentielles sur la performance avec de grands volumes de données.