Instructions ITAB en ABAP #
Is initial #
Objectifs #
- Vérifier si une table interne est vide ou non
- Comprendre l’usage des crochets
[] - Utiliser
IS INITIALouIS NOT INITIALpour tester le contenu d’une table interne - Savoir que
IS INITIALfonctionne aussi avec des variables simples
Définition #
IF itab[] IS INITIAL.
" La table est vide
ENDIF.
IF [NOT] itab[] IS [NOT] INITIAL.
" La table contient au moins une ligne
ENDIF.
L’expression
IS INITIALvérifie si une donnée est vide ou non initialisée.
Pour les tables internes, les crochets[]signifient qu’on évalue le contenu complet de la table.
itab[] IS INITIAL→ la table ne contient aucune ligneitab[] IS NOT INITIAL→ la table contient au moins une ligne
Analogie #
Imagine une boîte :
- Si la boîte ne contient aucun objet, elle est initiale (vide).
- Si elle contient au moins un objet, elle n’est pas initiale.
De la même façon :
itab[] IS INITIAL→ la boîte est vide.NOT itab[] IS INITIAL→ la boîte contient quelque chose.
Exemple complet #
TYPES: BEGIN OF ty_citizen,
country TYPE char3,
name TYPE char20,
age TYPE numc2,
END OF ty_citizen.
DATA: lt_citizen TYPE STANDARD TABLE OF ty_citizen,
ls_citizen TYPE ty_citizen.
" --- Vérification avant ajout ---
IF lt_citizen[] IS INITIAL.
WRITE: / 'La table est vide au départ.'.
ENDIF.
" --- Ajout d'un enregistrement ---
ls_citizen-country = 'FR'.
ls_citizen-name = 'Thierry'.
ls_citizen-age = '24'.
APPEND ls_citizen TO lt_citizen.
" --- Vérification après ajout ---
IF NOT lt_citizen[] IS INITIAL.
WRITE: / 'La table contient au moins un enregistrement.'.
ENDIF.
- Avant le
APPEND, la table est vide →IS INITIALrenvoie VRAI.- Après le
APPEND, elle contient une ligne →IS NOT INITIALrenvoie VRAI.
Attention #
- Si vous oubliez les crochets
[], vous testez la référence de la table, pas son contenu. - Une table peut être “non initiale” même si elle n’a plus de lignes si elle a été initialisée ailleurs.
→ Utilisez toujoursitab[] IS INITIALavec les crochets.
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
| Toujours tester avant traitement | Évite les erreurs de boucle sur table vide |
Utiliser IS INITIAL avec [] |
Spécifie clairement que le test concerne le contenu |
Utiliser ... IS NOT INITIAL |
Vérifie qu’il y a au moins une ligne dans la table |
| Appliquer aussi à des variables | Permet de contrôler l’initialisation d’une donnée |
Préférer IS INITIAL à LINES( itab ) = 0 |
Plus lisible et plus rapide |
Exemples résumé #
1 – Table vide #
DATA lt_data TYPE TABLE OF string.
IF lt_data[] IS INITIAL.
WRITE: / 'La table est vide.'.
ENDIF.
2 – Table non vide #
APPEND 'Hello' TO lt_data.
IF NOT lt_data[] IS INITIAL.
WRITE: / 'La table contient au moins une valeur.'.
ENDIF.
Résumé #
IS INITIALpermet de vérifier si une table interne ou une variable est vide.
itab[] IS INITIAL→ table videitab[] IS NOT INITIAL→ table non vide- Fonctionne aussi pour variables et structures simples
Bon réflexe : toujours vérifier avant de traiter ou boucler sur une table.
Tester si une boîte contient quelque chose avant d’essayer de prendre un objet à l’intérieur.
Clear table #
Objectifs #
- Supprimer toutes les lignes d’une table interne avec
CLEAR - Comprendre la syntaxe avec les crochets
[] - Savoir que
CLEARpeut aussi être utilisé sur des variables simples - Différencier
CLEAR itab[]etREFRESH itab - Vérifier le contenu d’une table avant et après effacement
Définition #
CLEAR: itab[],
var1.
L’instruction
CLEARpermet de supprimer toutes les données d’une table interne ou de remettre à zéro des variables.
Imaginez un tableau blanc rempli d’informations.
CLEAR itab[]= effacer complètement le tableau (toutes les lignes).CLEAR var1= effacer le contenu d’une seule cellule du tableau.
Les crochets
[]sont essentiels : sans eux, seule la structure est effacée, pas son contenu.
Exemples #
1 – Clear sur une table interne #
TYPES: BEGIN OF ty_citizen,
country TYPE char3,
name TYPE char20,
age TYPE numc2,
END OF ty_citizen.
DATA: lt_citizen TYPE STANDARD TABLE OF ty_citizen,
ls_citizen TYPE ty_citizen,
gv_count TYPE i.
" REMPLISSAGE DE LA TABLE
ls_citizen-country = 'FR'.
ls_citizen-name = 'Thierry'.
ls_citizen-age = '24'.
APPEND ls_citizen TO lt_citizen.
ls_citizen-country = 'ES'.
ls_citizen-name = 'Luis'.
ls_citizen-age = '32'.
APPEND ls_citizen TO lt_citizen.
gv_count = lines( lt_citizen ). " Nombre de lignes avant CLEAR
WRITE:/ 'Lignes avant suppression :', gv_count.
CLEAR lt_citizen[]. " Supprime toutes les lignes de la table
gv_count = lines( lt_citizen ). " Recalcul du nombre de lignes
WRITE:/ 'Lignes apres CLEAR :', gv_count.
- Avant
CLEAR, la table contient 2 lignes.- Après
CLEAR, la table est complètement vide.
Le
CLEAR lt_citizen(sans[]) n’efface pas les lignes, il ne fait que remettre la variable au statut initial (structure vide).
2 – Clear sur variable simple #
DATA: gv_total TYPE i VALUE 125.
WRITE:/ 'Avant CLEAR :', gv_total.
CLEAR gv_total.
WRITE:/ 'Apres CLEAR :', gv_total.
Le
CLEARsur une variable simple remet sa valeur à zéro (ou initiale).
Par exemple
- Numérique → 0
- Caractère → vide
- Booléen → ’ ’ (faux)
3 – Clear sur plusieurs objets en une seule fois #
DATA: gv_counter TYPE i VALUE 10,
gv_name TYPE string VALUE 'Thierry',
lt_data TYPE STANDARD TABLE OF ty_citizen.
CLEAR: gv_counter, gv_name, lt_data[].
Il est possible d’effacer plusieurs éléments en une seule instruction.
Pratique pour remettre un environnement à zéro avant de relancer un traitement.
4 – Différence entre clear et refresh #
DATA: lt_table TYPE STANDARD TABLE OF ty_citizen.
CLEAR lt_table[]. " Efface le contenu de la table
REFRESH lt_table. " Efface aussi le contenu (comportement identique depuis ABAP 7.40)
Le
CLEAR itab[]est préféré dans le code moderne.
LeREFRESHest conservé pour compatibilité avec les anciens programmes.
5 – Clear sur structure complète #
DATA: ls_person TYPE ty_citizen.
ls_person-country = 'FR'.
ls_person-name = 'Thierry'.
ls_person-age = '24'.
WRITE:/ 'Avant CLEAR :', ls_person-country, ls_person-name, ls_person-age.
CLEAR ls_person.
WRITE:/ 'Apres CLEAR :', ls_person-country, ls_person-name, ls_person-age.
Le
CLEARsur une structure remet chaque champ à sa valeur initiale (vidée ou zéro).
6 – Clear dynamique avec field-symbol #
FIELD-SYMBOLS: <lfs_tab> TYPE STANDARD TABLE.
ASSIGN lt_citizen TO <lfs_tab>.
IF <lfs_tab> IS ASSIGNED.
CLEAR <lfs_tab>[].
ENDIF.
Très utile pour écrire des programmes dynamiques manipulant plusieurs tables internes sans les nommer directement.
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
| Toujours vérifier le nombre de lignes | LINES( itab ) avant/après CLEAR permet de confirmer la suppression |
| Utiliser CLEAR avec [] | Indique explicitement que toute la table est effacée |
| CLEAR peut combiner plusieurs variables | Réduit le code et garde la logique claire |
| Préférer CLEAR à REFRESH dans le code | Syntaxe plus moderne, même effet |
| Ne pas oublier les crochets [] | Sans crochets, seule la variable est remise à zéro, pas le contenu |
| Eviter CLEAR sur des références non testées | Toujours vérifier IS ASSIGNED avant CLEAR sur FIELD-SYMBOLS |
Résumé #
CLEARest une instruction simple mais puissante
CLEAR itab[]: efface toutes les lignes d’une table interneCLEAR var: remet une variable à sa valeur initialeCLEAR structure: réinitialise tous les champs de la structureCLEARpeut être combiné sur plusieurs objetsCLEARavec[]est l’équivalent moderne deREFRESH[!TIP] C’est comme appuyer sur “Réinitialiser” – on remet tout à zéro avant de recommencer proprement.
Sort #
Objectifs #
- Comprendre le fonctionnement de l’instruction
SORTpour les tables internes - Savoir trier selon la clé primaire ou des champs spécifiques
- Identifier les options
ASCENDING,DESCENDING,AS TEXTetSTABLE - Savoir quand trier avant certaines opérations comme
DELETE ADJACENT DUPLICATES
Définition #
SORT itab [ASCENDING|DESCENDING] [AS TEXT] [STABLE]
BY c1 [ASCENDING|DESCENDING] [AS TEXT]
...
cn [ASCENDING|DESCENDING] [AS TEXT].
L’instruction
SORTorganise une table interne (itab) de typeSTANDARDouHASHEDselon
- sa clé primaire si définie
- ou une liste de champs
c1àcn[!NOTE]
ASCENDING/DESCENDING: tri croissant ou décroissantAS TEXT: tri des chaînes de caractères selon la langue locale définie parSET LOCALE LANGUAGESTABLE: maintien de l’ordre relatif pour les valeurs égales
Imaginez un classeur de fiches
- Vous pouvez trier par identifiant, nom ou plusieurs critères combinés (ex. nom puis âge)
- L’option
STABLEgarantit que les fiches ayant le même critère restent dans le même ordre relatif
- Les tables
SORTEDne peuvent pas être triées avecSORT, car leur ordre est fixe- Le tri est obligatoire avant certaines opérations comme
DELETE ADJACENT DUPLICATESpour STANDARD TABLE
Exemples #
Tri simple #
TYPES: BEGIN OF ty_citizen,
country TYPE char3,
name TYPE char20,
age TYPE numc2,
END OF ty_citizen.
DATA: lt_citizen TYPE STANDARD TABLE OF ty_citizen,
ls_citizen TYPE ty_citizen.
" Ajout des données
ls_citizen-country = 'FR'.
ls_citizen-name = 'Thierry'.
ls_citizen-age = '24'.
APPEND ls_citizen TO lt_citizen.
ls_citizen-country = 'ES'.
ls_citizen-name = 'Luis'.
ls_citizen-age = '32'.
APPEND ls_citizen TO lt_citizen.
ls_citizen-country = 'BR'.
ls_citizen-name = 'Renata'.
ls_citizen-age = '27'.
APPEND ls_citizen TO lt_citizen.
ls_citizen-country = 'FR'.
ls_citizen-name = 'Floriane'.
ls_citizen-age = '32'.
APPEND ls_citizen TO lt_citizen.
Tri descendant sur toute la table #
SORT lt_citizen DESCENDING.
Tri par champs spécifiques #
SORT lt_citizen BY country ASCENDING age DESCENDING.
- Si aucun
BYn’est spécifié et qu’il n’existe pas de clé primaire, le tri peut être instable et aléatoireSTABLEgarantit un résultat identique lors de tris multiples- Obligatoire avant
DELETE ADJACENT DUPLICATESpourSTANDARD TABLE
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
| Toujours préciser les champs pour BY | Évite un tri aléatoire sur STANDARD TABLE |
| Utiliser ASCENDING ou DESCENDING | Contrôle le sens du tri |
| Utiliser AS TEXT pour chaînes locales | Respecte l’ordre linguistique |
| STABLE pour tris répétitifs | Maintient l’ordre relatif des valeurs égales |
| Trier avant DELETE ADJACENT DUPLICATES | Assure la suppression correcte des doublons |
Résumé #
SORTorganise les lignes d’une table interne selon une clé primaire ou des champs spécifiques.[!NOTE] Le
ASCENDING,DESCENDING,AS TEXT,STABLE[!TIP] trier un classeur selon un ou plusieurs critères tout en gardant l’ordre relatif des doublons si nécessaire
Insert into itab #
Objectifs #
- Comprendre le fonctionnement de l’instruction
INSERTpour les tables internes - Savoir insérer une structure, une ligne vide ou des lignes d’une autre table
- Maîtriser l’insertion à un index précis dans la table cible
- Simplifier le code en évitant des boucles manuelles pour ajouter plusieurs lignes
Définition #
L’instruction
INSERTpermet d’ajouter des lignes dans une table interne (itab).
Elle peut provenir de différentes sources
- Une structure (
ls)- Une ligne vide (
INITIAL LINE)- Une autre table interne (
LINES OF jtab) avec possibilité de spécifier un intervalle (FROM idx1 TO idx2)
Imaginez un classeur de fiches
- Ajouter une fiche complète (structure)
- Glisser une page blanche (
INITIAL LINE)- Copier certaines pages d’un autre classeur (
LINES OF) à une position précise
- L’option
INDEXpermet de contrôler l’ordre final des lignes.- Si aucun
INDEXn’est spécifié, la ligne est ajoutée en fin de table.- Très pratique pour insérer plusieurs lignes d’un coup, sans boucle.
Déclaration et exemple #
TYPES: BEGIN OF ty_citizen,
country TYPE char3,
name TYPE char20,
age TYPE numc2,
END OF ty_citizen.
DATA: lt_citizen1 TYPE TABLE OF ty_citizen,
lt_citizen2 TYPE TABLE OF ty_citizen,
ls_citizen TYPE ty_citizen.
1️⃣ Insertion d’une structure dans la table #
ls_citizen-country = 'FR'.
ls_citizen-name = 'Thierry'.
ls_citizen-age = '24'.
INSERT ls_citizen INTO TABLE lt_citizen1.
2️⃣ Création de plusieurs enregistrement dans une autre table #
ls_citizen-country = 'ES'.
ls_citizen-name = 'Luis'.
ls_citizen-age = '32'.
INSERT ls_citizen INTO TABLE lt_citizen2.
ls_citizen-country = 'BR'.
ls_citizen-name = 'Renata'.
ls_citizen-age = '27'.
INSERT ls_citizen INTO TABLE lt_citizen2.
ls_citizen-country = 'FR'.
ls_citizen-name = 'Floriane'.
ls_citizen-age = '32'.
INSERT ls_citizen INTO TABLE lt_citizen2.
3️⃣ Insertion d’une ligne vide a un index précis #
INSERT INITIAL LINE INTO lt_citizen1 INDEX 1.
4️⃣ Insertion de plusieurs lignes d’une autre table #
INSERT LINES OF lt_citizen2 FROM 2 TO 3 INTO lt_citizen1 INDEX 1.
- Une structure sert de modèle de ligne pour la table interne.
- On peut insérer une ligne unique, une ligne vide ou plusieurs lignes d’une autre table.
- L’ordre des lignes est contrôlé par
INDEX.
Résultat final de lt_citizen1 #
| COUNTRY | NAME | AGE |
|---|---|---|
| BR | Renata | 27 |
| FR | Floriane | 32 |
| FR | Thierry | 24 |
L’ordre final reflète la position des insertions et l’usage des
INDEX.
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
| Définir clairement les structures | Facilite la lecture et la maintenance |
| Préciser l’index si nécessaire | Contrôle l’ordre final des enregistrements |
Utiliser LINES OF pour copier des plages |
Évite les boucles manuelles et simplifie le code |
| Vérifier la présence de la table cible | Prévenir les erreurs d’insertion |
Exercices #
1 – Créer et insérer des enregistrements #
Déclarer une table interne
lt_employeesavec une structurety_employee
- id (CHAR5)
- nom (CHAR20)
- departement (CHAR10)
Insérer deux employés et afficher les données.
SOLUTION
TYPES: BEGIN OF ty_employee,
id TYPE char5,
nom TYPE char20,
departement TYPE char10,
END OF ty_employee.
DATA: lt_employees TYPE TABLE OF ty_employee,
ls_employee TYPE ty_employee.
ls_employee-id = 'E001'.
ls_employee-nom = 'Dupont'.
ls_employee-departement = 'RH'.
INSERT ls_employee INTO TABLE lt_employees.
ls_employee-id = 'E002'.
ls_employee-nom = 'Martin'.
ls_employee-departement = 'IT'.
INSERT ls_employee INTO TABLE lt_employees.
LOOP AT lt_employees INTO ls_employee.
WRITE: / ls_employee-id, ls_employee-nom, ls_employee-departement.
ENDLOOP.
2 – Insérer une ligne vide #
Ajouter une ligne vide à l’index 2 et afficher la table.
SOLUTION
INSERT INITIAL LINE INTO lt_employees INDEX 2.
LOOP AT lt_employees INTO ls_employee.
WRITE: / ls_employee-id, ls_employee-nom, ls_employee-departement.
ENDLOOP.
3 – Copier des lignes d’une autre table #
Créer
lt_new_employeesavec deux lignes et les insérer danslt_employeesà l’index 1.
SOLUTION
DATA: lt_new_employees TYPE TABLE OF ty_employee.
ls_employee-id = 'E003'.
ls_employee-nom = 'Renata'.
ls_employee-departement = 'FIN'.
INSERT ls_employee INTO TABLE lt_new_employees.
ls_employee-id = 'E004'.
ls_employee-nom = 'Luis'.
ls_employee-departement = 'LOG'.
INSERT ls_employee INTO TABLE lt_new_employees.
INSERT LINES OF lt_new_employees INTO lt_employees INDEX 1.
LOOP AT lt_employees INTO ls_employee.
WRITE: / ls_employee-id, ls_employee-nom, ls_employee-departement.
ENDLOOP.
Résumé #
INSERT→ ajouter une ligne, une ligne vide ou plusieurs lignes d’une autre table.INDEX→ contrôle la position de la ou des lignes.[!TIP] glisser des fiches dans un classeur à l’emplacement désiré, en copiant ou créant de nouvelles fiches.
[!IMPORTANT] définir clairement la structure, vérifier la table cible et éviter les boucles pour insérer plusieurs lignes.
Append to itab #
Objectifs #
- Comprendre le fonctionnement de l’instruction
APPENDpour les tables internes - Savoir ajouter une structure, une ligne vide, ou des lignes d’une autre table à la fin d’une table
- Identifier les limitations selon le type de table interne
- Comparer
APPENDetINSERTselon le type de table
Définition #
APPEND { ls | {INITIAL LINE} | {LINES OF jtab [FROM idx1] [TO idx2]} }
TO itab.
L’instruction
APPENDajoute des données toujours à la fin d’une table interne (itab).
Elle fonctionne commeINSERT, mais le paramètre de destination est toujoursTO itab.
Imaginez un classeur :
- Vous collez toujours les nouvelles fiches à la fin.
- Vous pouvez :
- Ajouter une fiche complète (
STRUCTURE)- Glisser une page blanche (
INITIAL LINE)- Copier des pages d’une autre table interne (
LINES OF itab)
APPENDest simple et rapide pourSTANDARDetRANGE TABLE.- Pour
HASHEDouSORTED TABLE, il faut utiliserINSERT INTO TABLEpour respecter les contraintes.
Exemple standard table #
ls_citizen-country = 'ES'.
ls_citizen-name = 'Luiza'.
ls_citizen-age = '31'.
APPEND ls_citizen TO lt_citizen1.
ls_citizen-country = 'BR'.
ls_citizen-name = 'Felipe'.
ls_citizen-age = '25'.
APPEND ls_citizen TO lt_citizen1.
Contenu final de
lt_citizen1:
| COUNTRY | NAME | AGE |
|---|---|---|
| BR | Renata | 27 |
| FR | Floriane | 32 |
| FR | Thierry | 24 |
| ES | Luiza | 31 |
| BR | Felipe | 25 |
Limitations pour sorted et hashed table #
APPENDfonctionne uniquement pourSTANDARDetRANGE TABLE.- Pour
HASHEDouSORTED TABLE, il fautINSERT INTO TABLE.- Sur une
SORTED TABLE, ajouter en fin peut violé l’ordre défini par la clé →DUMP.
Exemple sorted table – Dump #
TYPES: BEGIN OF ty_country,
land TYPE char3,
END OF ty_country.
DATA: lt_country TYPE SORTED TABLE OF ty_country WITH NON-UNIQUE KEY land,
ls_country TYPE ty_country.
ls_country-land = 'ES'.
APPEND ls_country TO lt_country.
ls_country-land = 'BR'.
APPEND ls_country TO lt_country. " DUMP : ordre non respecté
Exemple sorted table – Pas de dump #
ls_country-land = 'BR'.
APPEND ls_country TO lt_country.
ls_country-land = 'ES'.
APPEND ls_country TO lt_country. " Ordre respecté, pas de DUMP
- APPEND ne contrôle pas l’ordre sur SORTED TABLE.
- L’usage correct dépend de la clé et de l’ordre défini.
- HASHED TABLE ne peut jamais utiliser APPEND car il n’y a pas d’ordre séquentiel.
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
| Vérifier le type de table avant APPEND | Évite DUMP sur SORTED ou HASHED TABLE |
| Utiliser APPEND uniquement pour STANDARD/RANGE | Garantit insertion en fin sans violation de clé |
| Pour SORTED/HASHED TABLE, privilégier INSERT | Maintient l’ordre ou l’unicité des clés |
| Vérifier l’ordre des clés avant insertion | Prévenir erreurs et DUMP |
Exercices #
1 – Ajouter des employés a une standard table #
Déclarer
lt_employeesavec la structurety_employee:
- id (CHAR5)
- nom (CHAR20)
- departement (CHAR10)
Ajouter deux employés avec APPEND et afficher la table.
SOLUTION
DATA: lt_employees TYPE TABLE OF ty_employee,
ls_employee TYPE ty_employee.
ls_employee-id = 'E001'.
ls_employee-nom = 'Dupont'.
ls_employee-departement = 'RH'.
APPEND ls_employee TO lt_employees.
ls_employee-id = 'E002'.
ls_employee-nom = 'Martin'.
ls_employee-departement = 'IT'.
APPEND ls_employee TO lt_employees.
LOOP AT lt_employees INTO ls_employee.
WRITE: / ls_employee-id, ls_employee-nom, ls_employee-departement.
ENDLOOP.
2 – Ajouter une ligne vide #
Ajouter une ligne vide à la fin de
lt_employeeset afficher la table.
SOLUTION
APPEND INITIAL LINE TO lt_employees.
LOOP AT lt_employees INTO ls_employee.
WRITE: / ls_employee-id, ls_employee-nom, ls_employee-departement.
ENDLOOP.
3 – Copier des lignes d’une autre table #
Copier toutes les lignes de
lt_new_employeesà la fin delt_employees.
SOLUTION
INSERT LINES OF lt_new_employees INTO TABLE lt_employees. " ou APPEND si STANDARD
Résumé #
APPEND→ ajoute toujours à la fin d’une table interne.- Compatible avec
STANDARDetRANGE, interdit surSORTED/HASHEDsauf précaution.[!CAUTION] DUMP si l’ordre est violé sur
SORTED TABLE.[!TIP] coller de nouvelles fiches à la fin d’un classeur, en respectant l’ordre si nécessaire.
[!IMPORTANT] vérifier le type de table et utiliser
INSERTpourSORTED/HASHED.
Modify where #
Objectifs #
- Comprendre le fonctionnement de
MODIFY ... WHERE - Savoir modifier des lignes spécifiques d’une table interne en utilisant une condition
- Identifier la différence avec
MODIFY INDEXetMODIFY TABLE - Utiliser TRANSPORTING pour limiter les champs modifiés
Définition #
MODIFY itab FROM ls
TRANSPORTING comp1 comp2 ...
WHERE cond.
MODIFY ... WHEREmet à jour une table interne (itab) en utilisant une condition pour sélectionner les lignes à modifier.
La structurelsfournit les nouvelles valeurs etTRANSPORTINGpermet de modifier uniquement certains champs.
Imaginez un classeur
- Vous cherchez les fiches correspondant à un critère précis (WHERE)
- Vous modifiez uniquement les informations nécessaires
- Les autres fiches restent inchangées
- Fonctionne pour
STANDARD,SORTEDetHASHED TABLE- Utile lorsque la clé n’est pas connue ou lorsqu’une condition complexe doit être appliquée
- Comparable à un WHERE dans SQL
Déclaration et exemple #
TYPES: BEGIN OF ty_country,
land TYPE char3,
age TYPE i,
END OF ty_country.
DATA: lt_country TYPE HASHED TABLE OF ty_country WITH UNIQUE KEY land,
ls_country TYPE ty_country.
" Remplissage initial
ls_country-land = 'FR'.
ls_country-age = 23.
COLLECT ls_country INTO lt_country.
ls_country-land = 'IT'.
ls_country-age = 20.
COLLECT ls_country INTO lt_country.
ls_country-land = 'IT'.
ls_country-age = 55.
COLLECT ls_country INTO lt_country.
ls_country-land = 'FR'.
ls_country-age = 5.
COLLECT ls_country INTO lt_country.
" CLEAR de la clé pour modification conditionnelle
CLEAR ls_country-land.
ls_country-age = 10.
" Modification avec WHERE
MODIFY lt_country FROM ls_country TRANSPORTING age
WHERE land = 'IT'.
- La clause
WHEREsélectionne la ou les lignes à modifierTRANSPORTINGrestreint la modification aux champs listés- Contrairement à
MODIFY TABLE, la recherche ne se fait pas via la clé mais via la condition- Idéal pour des modifications conditionnelles complexes
État de la table #
Avant le MODIFY :
| LAND | AGE |
|---|---|
| FR | 28 |
| IT | 75 |
Après le MODIFY :
| LAND | AGE |
|---|---|
| FR | 28 |
| IT | 10 |
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
| Vérifier la clause WHERE | Assure que seule la ligne souhaitée sera modifiée |
| Utiliser TRANSPORTING pour champs ciblés | Limite la modification aux champs nécessaires |
| Initialiser correctement la structure | Évite de réécrire des valeurs indésirables |
| Comparer avec MODIFY TABLE | Savoir quand utiliser la clé ou une condition |
| Tester sur un sous-ensemble de la table | Prévenir les modifications accidentelles |
Exercices #
1 – Modifier par condition simple #
Modifier l’âge des pays
'FR'à 35.
SOLUTION
CLEAR ls_country-land.
ls_country-age = 35.
MODIFY lt_country FROM ls_country TRANSPORTING age
WHERE land = 'FR'.
2 – Modifier plusieurs lignes avec condition #
Ajouter 5 ans à tous les pays dont l’âge est inférieur à 30.
SOLUTION
LOOP AT lt_country INTO ls_country.
IF ls_country-age < 30.
ls_country-age = ls_country-age + 5.
MODIFY lt_country FROM ls_country TRANSPORTING age
WHERE land = ls_country-land.
ENDIF.
ENDLOOP.
3 – Comparaison avec modify table #
Expliquer la différence pratique entre
MODIFY TABLEetMODIFY WHERE.
Explication
MODIFY TABLE: modifie une ligne via la cléMODIFY WHERE: modifie une ou plusieurs lignes via une condition- WHERE est nécessaire lorsque la clé n’est pas connue ou plusieurs lignes doivent être mises à jour
- TRANSPORTING reste utile pour modifier uniquement certains champs
Résumé #
MODIFY ... WHEREmet à jour des lignes d’une table interne selon une condition- Permet de modifier tous les champs ou seulement certains via TRANSPORTING
- Différence avec
MODIFY INDEX: sélection par condition au lieu d’un index- Différence avec
MODIFY TABLE: sélection par condition au lieu de la clé[!TIP] modifier certaines fiches dans un classeur en fonction d’un critère précis
[!IMPORTANT] vérifier la clause
WHERE, initialiser la structure et utiliserTRANSPORTING
Modify with index #
Objectifs #
- Comprendre le fonctionnement de
MODIFY ... INDEX - Savoir modifier des lignes spécifiques d’une table interne en utilisant une condition
- Identifier la différence avec
MODIFY INDEXetMODIFY TABLE - Utiliser TRANSPORTING pour limiter les champs modifiés
Définition #
Pour l’instruction MODIFY, il existe trois formes de syntaxe possibles.
MODIFY itab [INDEX idx] FROM ls
[TRANSPORTING comp1 comp2 ...].
L’instruction MODIFY va modifier la table interne itab à partir de la structure ls_. Il est possible d’indiquer l’index de la ligne à modifier (INDEX idx) ainsi que la liste des champs à modifier (TRANSPORTING comp1 comp2…).
Déclaration et exemple #
TYPES: BEGIN OF ty_country,
land TYPE char3,
age(3) TYPE i,
END OF ty_country.
DATA: lt_country TYPE STANDARD TABLE OF ty_country WITH NON-UNIQUE KEY land,
ls_country TYPE ty_country.
ls_country-land = 'FR'.
ls_country-age = 23.
COLLECT ls_country INTO lt_country.
ls_country-land = 'IT'.
ls_country-age = 20.
COLLECT ls_country INTO lt_country.
ls_country-land = 'IT'.
ls_country-age = 55.
COLLECT ls_country INTO lt_country.
ls_country-land = 'FR'.
ls_country-age = 5.
COLLECT ls_country INTO lt_country.
ls_country-land = 'FR'.
ls_country-age = 10.
MODIFY lt_country INDEX 1 FROM ls_country TRANSPORTING age.
Avant le
MODIFY, la structurels_countryest initialisée avec les valeurs souhaitées. Ensuite, le programme va modifier la table internelt_countryà l’index 1, à partir de la structurels_country, afin de modifier uniquement le champAGE.
lt_country avant le MODIFY
| LAND | AGE |
|---|---|
| FR | 28 |
| IT | 75 |
lt_country après le MODIFY
| LAND | AGE |
|---|---|
| FR | 10 |
| IT | 75 |
Copy table #
Objectifs #
- Copier toutes les lignes d’une table interne vers une autre
- Comprendre l’usage des crochets
[]pour copier le contenu complet - Savoir que cette opération duplique toutes les données et non la référence
- Connaître les précautions à prendre avant une copie
- Être capable de vérifier la réussite d’une copie
Définition #
itab_dest[] = itab_src[]
L’instruction
COPY TABLE(écrite en ABAP sous la formeitab_dest[] = itab_src[]) permet de copier toutes les lignes d’une table interne vers une autre.
Imaginez deux classeurs
itab_src= classeur d’origine rempli de fichesitab_dest= classeur vide
Copieritab_src[]versitab_dest[]revient à photocopier toutes les fiches du premier pour les ranger dans le second.
Exemples #
1 – Copie complète d’une table interne #
TYPES: BEGIN OF ty_citizen,
country TYPE char3,
name TYPE char20,
age TYPE numc2,
END OF ty_citizen.
DATA: lt_citizen_src TYPE STANDARD TABLE OF ty_citizen,
lt_citizen_dest TYPE STANDARD TABLE OF ty_citizen,
ls_citizen TYPE ty_citizen.
" REMPLISSAGE DE LA TABLE SOURCE
ls_citizen-country = 'FR'.
ls_citizen-name = 'Thierry'.
ls_citizen-age = '24'.
APPEND ls_citizen TO lt_citizen_src.
ls_citizen-country = 'ES'.
ls_citizen-name = 'Luis'.
ls_citizen-age = '32'.
APPEND ls_citizen TO lt_citizen_src.
" COPIE DE TOUTES LES LIGNES
lt_citizen_dest[] = lt_citizen_src[].
" AFFICHAGE DE LA TABLE DESTINATION
LOOP AT lt_citizen_dest ASSIGNING FIELD-SYMBOLS(<lfs_citizen>).
WRITE:/ <lfs_citizen>-country, <lfs_citizen>-name, <lfs_citizen>-age.
ENDLOOP.
La table
lt_citizen_destcontient maintenant exactement les mêmes lignes quelt_citizen_src.
Si
lt_citizen_destcontenait déjà des données, elles seront remplacées (pas ajoutées).
2 – Copie avec structure identique mais vide #
DATA: lt_empty_src TYPE STANDARD TABLE OF ty_citizen,
lt_copy TYPE STANDARD TABLE OF ty_citizen.
lt_copy[] = lt_empty_src[].
Si la table source est vide, la table de destination sera vide aussi.
Cela peut être utile pour réinitialiser une table sans utiliserCLEAR.
3 – Copie avec déclaration dynamique #
FIELD-SYMBOLS: <lfs_src> TYPE STANDARD TABLE,
<lfs_dest> TYPE STANDARD TABLE.
DATA: lt_people TYPE STANDARD TABLE OF ty_citizen.
ASSIGN lt_people TO <lfs_src>.
ASSIGN lt_citizen_dest TO <lfs_dest>.
IF <lfs_src> IS ASSIGNED AND <lfs_dest> IS ASSIGNED.
<lfs_dest>[] = <lfs_src>[].
ENDIF.
Cette méthode est utilisée dans les programmes où les noms de tables varient selon les contextes.
Elle permet de copier dynamiquement sans connaître le nom exact des tables.
Utile dans les modules génériques, les fonctions réutilisables, ou les boucles traitant plusieurs tables internes différentes.
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
| Toujours vérifier le contenu avec LINES() | Permet de confirmer que la copie a bien été effectuée |
| Utiliser [] pour indiquer le contenu complet | Sans crochets, seule la référence de la table serait copiée, pas ses données |
| Préparer la table destination | Si elle contient déjà des données, elles seront remplacées |
| Eviter les copies inutiles | Pour des grandes tables, cela peut ralentir le programme |
| Favoriser les FIELD-SYMBOLS pour modifier | Si le but est de manipuler directement, pas besoin de dupliquer les données |
Résumé #
itab_dest[] = itab_src[]est la méthode la plus simple pour copier intégralement une table interne.
- Les crochets
[]signifient “copie de tout le contenu”- Les données sont dupliquées, pas seulement la référence
- Les anciennes lignes sont remplacées
- Possibilité d’utiliser des FIELD-SYMBOLS pour un traitement dynamique
[!TIP] Copier une table, c’est comme scanner un classeur entier pour en faire une copie fidèle, sans toucher à l’original.
Move corresponding #
Objectifs #
- Copier uniquement les valeurs des champs correspondants entre tables internes
- Comprendre la différence entre
COPY TABLEetMOVE-CORRESPONDING - Savoir combiner plusieurs tables sources vers une même table cible
- Apprendre à manipuler des structures différentes sans erreur de type
Définition #
MOVE-CORRESPONDING itab_src TO itab_dest.
L’instruction
MOVE-CORRESPONDINGpermet de copier seulement les champs portant le même nom entre une table interne source et une table interne destination.
Imaginez deux formulaires avec des rubriques similaires (par exemple : Nom, Pays, Âge).
MOVE-CORRESPONDINGcopie seulement les rubriques ayant le même intitulé, sans toucher aux autres champs.
- Si la source et la destination ont des champs différents, seuls les champs correspondants sont copiés.
- Les champs qui n’existent pas dans l’autre structure sont ignorés sans erreur.
- L’opération peut être répétée pour fusionner plusieurs tables dans la même cible.
Exemple 1 – Copie entre tables différentes #
TYPES: BEGIN OF ty_citizen_src,
country TYPE char3,
name TYPE char20,
age TYPE numc2,
END OF ty_citizen_src.
TYPES: BEGIN OF ty_citizen_dest,
name TYPE char20,
country TYPE char3,
END OF ty_citizen_dest.
DATA: lt_citizen_src TYPE STANDARD TABLE OF ty_citizen_src,
lt_citizen_dest TYPE STANDARD TABLE OF ty_citizen_dest,
ls_src TYPE ty_citizen_src.
" --- REMPLISSAGE DE LA TABLE SOURCE ---
ls_src-country = 'FR'.
ls_src-name = 'Thierry'.
ls_src-age = '24'.
APPEND ls_src TO lt_citizen_src.
ls_src-country = 'ES'.
ls_src-name = 'Luis'.
ls_src-age = '32'.
APPEND ls_src TO lt_citizen_src.
" --- TRANSFERT DES CHAMPS CORRESPONDANTS ---
MOVE-CORRESPONDING lt_citizen_src TO lt_citizen_dest.
" --- VERIFICATION ---
LOOP AT lt_citizen_dest ASSIGNING FIELD-SYMBOLS(<llfs_dest>).
WRITE:/ <llfs_dest>-country, <llfs_dest>-name.
ENDLOOP.
lt_citizen_srccontient un champageabsent danslt_citizen_dest.MOVE-CORRESPONDINGne copie que les champscountryetname, car ils existent dans les deux structures.
Le système gère automatiquement la correspondance des noms sans tenir compte de l’ordre des champs.
Exemple 2 – Fusion de plusieurs tables #
DATA: lt_additional TYPE STANDARD TABLE OF ty_citizen_src.
" Remplissage d'une autre table source
ls_src-country = 'DE'.
ls_src-name = 'Klaus'.
ls_src-age = '28'.
APPEND ls_src TO lt_additional.
" Copie successive dans la table cible
MOVE-CORRESPONDING lt_citizen_src TO lt_citizen_dest.
MOVE-CORRESPONDING lt_additional TO lt_citizen_dest.
Comme remplir un registre commun à partir de plusieurs listes :
chaqueMOVE-CORRESPONDINGajoute les lignes compatibles sans provoquer d’erreur.
Les lignes ne sont pas fusionnées champ par champ, mais ajoutées à la table destination.
Cela peut créer des doublons si les données se répètent.
Exemple 3 – Avec déclarations dynamiques #
FIELD-SYMBOLS: <lfs_src> TYPE STANDARD TABLE,
<lfs_dest> TYPE STANDARD TABLE.
DATA: lt_source TYPE STANDARD TABLE OF ty_citizen_src,
lt_target TYPE STANDARD TABLE OF ty_citizen_dest.
ASSIGN lt_source TO <lfs_src>.
ASSIGN lt_target TO <lfs_dest>.
IF <lfs_src> IS ASSIGNED AND <lfs_dest> IS ASSIGNED.
MOVE-CORRESPONDING <lfs_src> TO <lfs_dest>.
ENDIF.
Ce type d’instruction est très utile dans les programmes génériques ou les rapports qui manipulent différentes structures dynamiquement.
Préférer cette approche quand le programme doit traiter plusieurs types de tables internes avec des champs similaires.
Différence avec copy table #
| Instruction | Description | Type de correspondance |
|---|---|---|
itab1[] = itab2[] |
Copie tous les champs (même structure obligatoire) | Correspondance totale |
MOVE-CORRESPONDING itab2 TO itab1 |
Copie uniquement les champs de même nom, structures différentes acceptées | Correspondance partielle |
COPY TABLE= copie brute (toutes les colonnes doivent exister).MOVE-CORRESPONDING= copie intelligente (seules les colonnes communes sont transférées).
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
| Toujours vérifier les noms des champs | La correspondance se base sur les noms, pas sur la position |
| Utiliser MOVE-CORRESPONDING pour structures différentes | Évite les erreurs de type |
| Vérifier les doublons lors de fusions | Plusieurs MOVE-CORRESPONDING peuvent ajouter des lignes identiques |
| Préférer les FIELD-SYMBOLS pour programmes génériques | Permet de manipuler des structures inconnues à l’avance |
Résumé #
MOVE-CORRESPONDINGpermet de transférer uniquement les champs communs entre deux structures ou tables internes.
- Idéal pour les structures différentes mais similaires
- Ignore les champs inexistants sans erreur
Delete #
Objectifs #
- Comprendre le fonctionnement de l’instruction
DELETEpour les tables internes - Savoir supprimer des lignes en fonction de l’index, de la clé ou d’une condition
WHERE - Identifier les limitations selon le type de table interne
- Utiliser DELETE de manière sûre et performante
Définition #
DELETE { TABLE itab { FROM ls }
| { WITH TABLE KEY [keyname COMPONENTS]
{comp_name1|(name1)} = operand1
{comp_name2|(name2)} = operand2 ...}
| itab INDEX idx
| itab WHERE cond }.
L’instruction
DELETEretire des lignes d’une table interne (itab).
Trois formes principales
DELETE itab INDEX idx: supprime la ligne à l’index spécifiéDELETE itab FROM ls: supprime la ligne correspondant à la structure / cléDELETE itab WHERE cond: supprime toutes les lignes respectant la condition
Imaginez un classeur
- Retirer une fiche à une position précise
- Supprimer la fiche correspondant à un identifiant
- Retirer toutes les fiches correspondant à un critère spécifique
- Les lignes supprimées disparaissent définitivement
- Les index des lignes suivantes sont ajustés automatiquement pour les STANDARD TABLE
- HASHED TABLE et SORTED TABLE gèrent la suppression via clé ou condition
Exemples #
Delete par index #
" Supprimer la première ligne de lt_country (STANDARD TABLE uniquement)
DELETE lt_country INDEX 1.
Delete par structure / Clé #
ls_country-land = 'FR'.
DELETE lt_country FROM ls_country. " Supprime la ligne dont la clé LAND = 'FR'
Delete avec where #
DELETE lt_country WHERE age < 30. " Supprime toutes les lignes avec age < 30
INDEX: applicable uniquement auxSTANDARD TABLEFROM/ clé : fonctionne pourSTANDARDetHASHED TABLE(basé sur la clé)WHERE: applicable à toutes les tables, permet de supprimer plusieurs lignes selon un critère- Les lignes supprimées sont retirées définitivement et l’index des lignes suivantes est ajusté automatiquement
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
| Vérifier le type de table | INDEX uniquement pour STANDARD |
| Initialiser correctement la structure | Assurer la suppression ciblée avec FROM |
| Utiliser WHERE pour plusieurs lignes | Supprime toutes les lignes répondant à la condition |
| Éviter DELETE en boucle inutile | Prévenir des impacts sur les performances |
| Confirmer les lignes à supprimer | Limiter les suppressions accidentelles |
Exercices #
1 – Delete par index #
supprimer la première ligne de lt_country.
SOLUTION
DELETE lt_country INDEX 1.
2 – Delete par structure / Clé #
supprimer la ligne avec LAND = ‘IT’.
SOLUTION
CLEAR ls_country-land.
ls_country-land = 'IT'.
DELETE lt_country FROM ls_country.
3 – Delete avec where #
supprimer toutes les lignes où AGE < 25.
SOLUTION
DELETE lt_country WHERE age < 25.
4 – Comparaison des méthodes #
expliquer quand utiliser INDEX, FROM, WHERE.
Explication
DELETE INDEX: rapide, applicable uniquement aux STANDARD TABLEDELETE FROM: supprime la ligne correspondant à la clé ou à la structureDELETE WHERE: supprime toutes les lignes correspondant à un critère, utile pour des suppressions conditionnelles- Utiliser WHERE pour des suppressions multiples et INDEX/FROM pour des suppressions ciblées
Résumé #
DELETEsupprime une ou plusieurs lignes d’une table interne selon l’index, la clé ou une condition WHERE[!TIP] retirer des fiches d’un classeur soit par position, soit par identifiant, soit par critère spécifique
[!IMPORTANT] vérifier le type de table, initialiser la structure, utiliser WHERE pour plusieurs lignes et éviter les suppressions inutiles en boucle
Delete Adjacent Duplicates #
Objectifs #
- Comprendre le fonctionnement de
DELETE ADJACENT DUPLICATES - Savoir supprimer les doublons dans une table interne selon une clé ou des champs spécifiques
- Identifier les contraintes liées au type de table et à l’ordre des données
- Utiliser correctement
COMPARINGpour sélectionner les champs pertinents
Définition #
DELETE ADJACENT DUPLICATES FROM itab
[COMPARING {comp1 comp2 ...}].
L’instruction
DELETE ADJACENT DUPLICATESsupprime les lignes consécutives en doublon dans une table interne (itab).
- Si aucun champ n’est précisé avec
COMPARING, la suppression se base sur la clé primaire de la table.- Si des champs sont précisés via
COMPARING, seuls ces champs sont utilisés pour détecter les doublons.
Imaginez un classeur trié
- Les fiches consécutives avec le même identifiant ou les mêmes informations sont fusionnées en une seule
- Les fiches uniques restent intactes
- Pour STANDARD TABLE, un tri préalable est obligatoire avant suppression
- Pour SORTED TABLE, le tri est assuré automatiquement par la clé
- La suppression ne retire que les doublons adjacents, pas les doublons dispersés
Déclaration et exemples #
Table sorted #
TYPES: BEGIN OF ty_citizen,
country TYPE char3,
name TYPE char20,
age TYPE numc2,
END OF ty_citizen.
DATA: lt_citizen TYPE SORTED TABLE OF ty_citizen WITH NON-UNIQUE KEY country,
ls_citizen TYPE ty_citizen.
" Insertion des données
ls_citizen-country = 'FR'.
ls_citizen-name = 'Thierry'.
ls_citizen-age = '24'.
INSERT ls_citizen INTO TABLE lt_citizen.
ls_citizen-country = 'ES'.
ls_citizen-name = 'Luis'.
ls_citizen-age = '32'.
INSERT ls_citizen INTO TABLE lt_citizen.
ls_citizen-country = 'BR'.
ls_citizen-name = 'Renata'.
ls_citizen-age = '27'.
INSERT ls_citizen INTO TABLE lt_citizen.
ls_citizen-country = 'FR'.
ls_citizen-name = 'Floriane'.
ls_citizen-age = '32'.
INSERT ls_citizen INTO TABLE lt_citizen.
" Suppression des doublons adjacents (clé primaire)
DELETE ADJACENT DUPLICATES FROM lt_citizen.
Table standard #
DATA: lt_citizen_std TYPE TABLE OF ty_citizen.
" Ajout des données
APPEND ls_citizen TO lt_citizen_std.
" ... (autres enregistrements)
" Tri obligatoire avant suppression
SORT lt_citizen_std BY country.
DELETE ADJACENT DUPLICATES FROM lt_citizen_std COMPARING country.
STANDARD TABLE: tri obligatoire pour que les doublons soient adjacentsSORTED TABLE: suppression basée automatiquement sur la cléCOMPARINGpermet de cibler les champs précis pour détecter les doublons- Les champs listés dans
COMPARINGdoivent correspondre à ceux utilisés pour le tri
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
| Toujours trier la table avant suppression | Nécessaire pour STANDARD TABLE |
| Utiliser COMPARING si clé non pertinente | Cible uniquement les champs nécessaires |
| Vérifier les doublons avant suppression | Prévenir la perte de données importantes |
| Respecter l’ordre des champs | Aligné avec le tri pour éviter des suppressions incorrectes |
| Appliquer sur tables conséquentes | Eviter la suppression incomplète si doublons non adjacents |
Exercices #
1 – Supprimer les doublons sur sorted table #
supprimer les doublons consécutifs sur la clé country.
SOLUTION
DELETE ADJACENT DUPLICATES FROM lt_citizen.
2 – Supprimer les doublons sur standard table #
supprimer les doublons consécutifs sur le champ country.
SOLUTION
SORT lt_citizen_std BY country.
DELETE ADJACENT DUPLICATES FROM lt_citizen_std COMPARING country.
3 – Supprimer les doublons sur plusieurs champs #
supprimer les doublons où country et age sont identiques.
SOLUTION
SORT lt_citizen_std BY country age.
DELETE ADJACENT DUPLICATES FROM lt_citizen_std COMPARING country age.
Résumé #
DELETE ADJACENT DUPLICATESsupprime les lignes consécutives en doublon dans une table interne- Sans
COMPARING: suppression basée sur la clé primaire- Avec
COMPARING: suppression basée sur les champs spécifiésSTANDARD TABLE: trier avant suppressionSORTED TABLE: suppression basée sur la clé primaire automatiquement[!TIP] retirer les fiches identiques consécutives dans un classeur trié
Read Table #
Objectifs #
- Lire une ligne d’une table interne avec
READ TABLE - Utiliser les options
WITH KEY,INDEXpour localiser la ligne - Comprendre les modes de stockage du résultat :
INTO,ASSIGNING,TRANSPORTING NO FIELDS - Maîtriser l’usage de FIELD-SYMBOLS pour manipuler directement la mémoire
- Vérifier les retours avec
SY-SUBRCet connaître l’index viaSY-TABIX
Définition #
READ TABLE itab
{ INTO ls | ASSIGNING <lfs_> | TRANSPORTING NO FIELDS }
{ FROM ls | WITH KEY { comp1 = obj1 comp2 = obj2 ... } [BINARY SEARCH] | INDEX idx }.
L’instruction
READ TABLEpermet de lire une ligne d’une table interne (itab) selon différents critères.
rechercher une fiche dans un classeur, soit par exemple de fiche, soit par critère précis, soit par numéro.
Exemples avec structure #
Read avec une structure et condition #
Version simple du READ avec une condition où les données de la ligne trouvée/lue sont stockées dans une structure déclarée en amont.
Les conditions sont indispensables pour identifier la ligne souhaité. Il est donc impératif de bien renseigner le ou les conditions nécessaires à son identification.
DATA: ls_struct TYPE ty_struct.
READ TABLE lt_citizen INTO ls_struct WITH KEY country = 'FR'.
IF sy-subrc = 0.
WRITE:/ 'READ FROM structure :', ls_struct-country, ls_struct-name, ls_struct-age.
ENDIF.
Read avec une structure et conditions #
Version simple du READ avec plusieurs conditions où les données de la ligne trouvée/lue sont stockées dans une structure déclarée en amont.
Les conditions sont indispensables pour identifier la ligne souhaité. Il est donc impératif de bien renseigner le ou les conditions nécessaires à son identification.
DATA: ls_struct TYPE ty_struct.
READ TABLE lt_citizen INTO ls_struct WITH KEY country = 'FR' name = 'Thierry'.
IF sy-subrc = 0.
WRITE:/ 'READ FROM structure :', ls_struct-country, ls_struct-name, ls_struct-age.
ENDIF.
Read avec une structure sur la 1ère ligne (index 1) #
Version du READ ciblant la 1ère ligne où les données de cette ligne sont pointées dans un field-symbol déclaré en amont.
DATA: ls_struct TYPE ty_struct.
READ TABLE lt_citizen INTO ls_struct INDEX 1.
IF sy-subrc = 0.
WRITE:/ 'READ FROM structure :', ls_struct-country, ls_struct-name, ls_struct-age.
ENDIF.
Read avec une structure et condition + paramètre transporting no fields #
Version simple du READ avec une condition où aucune donnée n’est récupérée. Ici le READ sert avant tout a vérifier la présence d’une entrée correspondante.
Les conditions sont indispensables pour identifier la ligne souhaité. Il est donc impératif de bien renseigner le ou les conditions nécessaires à son identification.
DATA: ls_struct TYPE ty_struct.
READ TABLE lt_citizen WITH KEY country = 'FR' TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
WRITE:/ 'Nous avons bien trouvé une ligne !'.
ENDIF.
Read avec structure déclarée dynamiquement #
Version simple du READ avec plusieurs conditions où les données de la ligne trouvée/lue sont stockées dans une structure déclarée dynamiquement.
Les conditions sont indispensables pour identifier la ligne souhaité. Il est donc impératif de bien renseigner le ou les conditions nécessaires à son identification.
READ TABLE lt_citizen INTO DATA(ls_struct) WITH KEY country = 'FR' name = 'Thierry'.
IF sy-subrc = 0.
WRITE:/ 'READ FROM structure :', ls_struct-country, ls_struct-name, ls_struct-age.
ENDIF.
Exemples avec field-symbol #
Read avec field-symbol et condition #
Version du READ ciblant une ligne via condition et où les données de cette ligne sont pointées dans un field-symbol déclaré en amont.
Les conditions sont indispensables pour identifier la ligne souhaité. Il est donc impératif de bien renseigner le ou les conditions nécessaires à son identification.
FIELD-SYMBOLS: <lfs_citizen> TYPE ty_citizen.
READ TABLE lt_citizen ASSIGNING <lfs_citizen> WITH KEY country = 'FR'.
IF sy-subrc = 0.
WRITE:/ 'READ FROM structure :', <lfs_citizen>-country, <lfs_citizen>-name, <lfs_citizen>-age.
ENDIF.
Read avec field-symbol et conditions #
Version du READ ciblant une ligne via conditions et où les données de cette ligne sont pointées dans un field-symbol déclaré en amont.
Les conditions sont indispensables pour identifier la ligne souhaité. Il est donc impératif de bien renseigner le ou les conditions nécessaires à son identification.
FIELD-SYMBOLS: <lfs_citizen> TYPE ty_citizen.
READ TABLE lt_citizen ASSIGNING <lfs_citizen> WITH KEY country = 'FR' name = 'Thierry'.
IF sy-subrc = 0.
WRITE:/ 'READ FROM structure :', <lfs_citizen>-country, <lfs_citizen>-name, <lfs_citizen>-age.
ENDIF.
Read avec field-symbol sur la 1ère ligne (index 1) #
Version du READ ciblant la 1ère ligne où les données de cette ligne sont pointées dans un field-symbol déclaré en amont.
FIELD-SYMBOLS: <lfs_citizen> TYPE ty_citizen.
READ TABLE lt_citizen ASSIGNING <lfs_citizen> INDEX 1.
IF sy-subrc = 0.
WRITE:/ 'READ FROM structure :', <lfs_citizen>-country, <lfs_citizen>-name, <lfs_citizen>-age.
ENDIF.
Read avec field-symbol avec condition + paramètre transporting no fields #
Version du READ avec une condition où aucune donnée n’est récupérée. Ici le READ sert avant tout a vérifier la présence d’une entrée correspondante.
Les conditions sont indispensables pour identifier la ligne souhaité. Il est donc impératif de bien renseigner le ou les conditions nécessaires à son identification.
FIELD-SYMBOLS: <lfs_citizen> TYPE ty_citizen.
READ TABLE lt_citizen ASSIGNING <lfs_citizen> WITH KEY country = 'FR' TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
WRITE:/ 'Nous avons bien trouvé une ligne !'.
ENDIF.
Read avec field-symbol déclarée dynamiquement #
Version simple du READ avec plusieurs conditions où les données de la ligne trouvée/lue sont pointées dans une structure déclarée dynamiquement.
Les conditions sont indispensables pour identifier la ligne souhaité. Il est donc impératif de bien renseigner le ou les conditions nécessaires à son identification.
READ TABLE lt_citizen ASSIGNING FIELD-SYMBOL(<lfs_citizen>) WITH KEY country = 'FR' name = 'Thierry'.
IF sy-subrc = 0.
WRITE:/ 'READ FROM structure :', <lfs_citizen>-country, <lfs_citizen>-name, <lfs_citizen>-age.
ENDIF.
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
Toujours tester SY-SUBRC |
Assure que la ligne a été trouvée avant d’accéder aux champs |
Utiliser ASSIGNING <fs> pour performance |
Évite la copie de la ligne, modifie directement la mémoire |
TRANSPORTING NO FIELDS pour vérification |
Vérifie juste l’existence sans copier ni modifier |
| Comparer avec READ TABLE INDEX et KEY | Savoir choisir la méthode adaptée au type de table et à la clé |
Résumé #
READ TABLEpermet de localiser et accéder à une ligne dans une table interne.
- Options de recherche :
WITH KEY,INDEX- Options de récupération :
INTO,ASSIGNING,TRANSPORTING NO FIELDS- Variables système :
SY-SUBRCetSY-TABIX[!TIP] rechercher une fiche dans un classeur et pointer directement dessus pour modification.
Binary Search #
Objectifs #
- Comprendre l’option
BINARY SEARCHavecREAD TABLE - Savoir l’utiliser pour optimiser les recherches dans une table interne
- Connaître la condition nécessaire pour que la recherche binaire fonctionne
- Identifier les avantages par rapport à une recherche linéaire
Définition #
L’option
BINARY SEARCHutilisée avecREAD TABLEpermet de réaliser une recherche binaire dans une table interne, optimisant ainsi les performances du programme.Principe de la recherche binaire
- Comparer la valeur recherchée à la valeur du milieu de la plage
- Si égal → retour de l’index, fin de recherche
- Si valeur > milieu → recherche dans la moitié inférieure
- Si valeur < milieu → recherche dans la moitié supérieure
- Répéter jusqu’à trouver la valeur ou épuiser la plage
la table doit être triée (
SORT) sauf si elle est de typeSORTED.
Chercher un nom dans un annuaire trié par ordre alphabétique en ouvrant toujours à la page du milieu pour diviser les recherches.
Exemple #
TYPES: BEGIN OF ty_citizen,
country TYPE char3,
name TYPE char20,
age TYPE numc2,
END OF ty_citizen.
DATA: lt_citizen TYPE STANDARD TABLE OF ty_citizen,
ls_citizen TYPE ty_citizen.
FIELD-SYMBOLS: <lfs_citizen> TYPE ty_citizen.
" Remplissage de la table
ls_citizen-country = 'FR'. ls_citizen-name = 'Thierry'. ls_citizen-age = '24'. APPEND ls_citizen TO lt_citizen.
ls_citizen-country = 'ES'. ls_citizen-name = 'Luis'. ls_citizen-age = '32'. APPEND ls_citizen TO lt_citizen.
ls_citizen-country = 'BR'. ls_citizen-name = 'Renata'. ls_citizen-age = '27'. APPEND ls_citizen TO lt_citizen.
ls_citizen-country = 'FR'. ls_citizen-name = 'Floriane'.ls_citizen-age = '32'. APPEND ls_citizen TO lt_citizen.
" Tri obligatoire pour BINARY SEARCH
SORT lt_citizen BY country name.
" Recherche binaire
READ TABLE lt_citizen WITH KEY country = 'FR' name = 'Floriane' BINARY SEARCH ASSIGNING <lfs_citizen>.
IF sy-subrc = 0.
WRITE:/ 'Enregistrement trouvé à la ligne :', sy-tabix, 'Pays:', <lfs_citizen>-country, 'Nom:', <lfs_citizen>-name.
ENDIF.
Bonnes pratiques #
| Bonne pratique | Explication |
|---|---|
| Trier la table avant BINARY SEARCH | Obligatoire pour tables STANDARD |
| Utiliser ASSIGNING |
Évite la copie de la ligne, modifie directement la mémoire |
| Vérifier SY-SUBRC | S’assurer que l’enregistrement a été trouvé |
| Comparer BINARY SEARCH vs recherche linéaire | Réduction significative du nombre de comparaisons |
| Utiliser BY avec tous les champs clés | Permet une recherche précise et correcte |
Exercices #
1 – Recherche binaire simple + déclaration dynamique en field-symbol #
Trier
lt_citizenparcountrypuisnameet lire l’enregistrement dontcountry = 'ES'etname = 'Luis'en utilisantBINARY SEARCH. Afficherage.
SOLUTION
SORT lt_citizen BY country name.
READ TABLE lt_citizen WITH KEY country = 'ES' name = 'Luis' BINARY SEARCH ASSIGNING FIELD-SYMBOL(<lfs_citizen>).
IF sy-subrc = 0.
WRITE:/ 'Âge du citoyen Luis en ES :', <lfs_citizen>-age.
ENDIF.
2 – Vérifier l’existence sans copier #
Vérifier si un enregistrement
country = 'BR'etname = 'Renata'existe danslt_citizenavecBINARY SEARCH, sans copier la ligne (TRANSPORTING NO FIELDS). Afficher un message.
SOLUTION
READ TABLE lt_citizen WITH KEY country = 'BR' name = 'Renata' BINARY SEARCH TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
WRITE:/ 'Enregistrement BR-Renata trouvé !'.
ELSE.
WRITE:/ 'Enregistrement BR-Renata non trouvé.'.
ENDIF.
Résumé #
BINARY SEARCHpermet une recherche rapide dans une table interne triée.
- Condition : table triée ou de type SORTED
- Réduit le nombre de comparaisons par rapport à une recherche linéaire
- Retourne l’
INDEXviaSY-TABIXet le code retour viaSY-SUBRC[!TIP] feuilleter un annuaire trié en ouvrant toujours au milieu pour diviser les recherches et trouver la personne plus rapidement.
Loop At #
Objectifs #
- Parcourir une table interne ligne par ligne avec
LOOP AT - Utiliser les options
INTO,ASSIGNING <fs>etTRANSPORTING NO FIELDS - Filtrer avec
WHERE,FROMetTO - Déclarer dynamiquement les structures et FIELD-SYMBOLS pour plus de flexibilité
- Modifier directement les lignes via FIELD-SYMBOLS
- Comprendre les variables système
SY-SUBRCetSY-TABIX - Utiliser les ruptures
AT FIRST,AT NEW,AT END OF,AT LAST - Utiliser des filtres complexes avec
WHEREsur un ou plusieurs champs
Définition #
LOOP AT itab
{ INTO ls | ASSIGNING <lfs_> | TRANSPORTING NO FIELDS }
[FROM idx1] [TO idx2]
[WHERE condition]
...
AT ...
...
ENDAT.
...
ENDLOOP.
L’instruction
LOOP ATpermet de parcourir une table interne (itab) ligne par ligne.
Les données peuvent être copiées (INTO), référencées en mémoire (ASSIGNING <fs>) ou simplement vérifiées (TRANSPORTING NO FIELDS).
Parcourir un classeur ligne par ligne
INTO= photocopier la ficheASSIGNING <lfs\_>= pointer directement sur la fiche pour modifierTRANSPORTING NO FIELDS= juste vérifier si la fiche existe
Exemples simples #
Loop avec into #
DATA: ls_citizen TYPE ty_citizen.
LOOP AT lt_citizen INTO ls_citizen WHERE country = 'FR'.
WRITE:/ 'Pays:', ls_citizen-country, 'Nom:', ls_citizen-name, 'Âge:', ls_citizen-age.
ENDLOOP.
Copie de la ligne dans
ls_citizen. Modification dels_citizenn’affectera paslt_citizen.
Loop avec assigning field-symbol #
FIELD-SYMBOLS: <lfs_citizen> TYPE ty_citizen.
LOOP AT lt_citizen ASSIGNING <lfs_citizen> WHERE country = 'ES'.
<lfs_citizen>-age = <lfs_citizen>-age + 1.
WRITE:/ 'Pays:', <lfs_citizen>-country, 'Nom:', <lfs_citizen>-name, 'Nouvel âge:', <lfs_citizen>-age.
ENDLOOP.
Modification directe dans la table sans utiliser
MODIFY.
Loop avec transporting no fields #
LOOP AT lt_citizen TRANSPORTING NO FIELDS WHERE name = 'Renata'.
IF sy-subrc = 0.
WRITE:/ 'Renata est présente dans la table.'.
ENDIF.
ENDLOOP.
Vérifier simplement l’existence sans copier ni modifier la ligne.
Loop avec from / to #
LOOP AT lt_citizen INTO ls_citizen FROM 2 TO 3.
WRITE:/ 'Pays:', ls_citizen-country, 'Nom:', ls_citizen-name.
ENDLOOP.
Limite la boucle aux lignes 2 et 3 pour traiter une plage précise.
Loop avec déclaration dynamique #
DATA: lt_dyn TYPE STANDARD TABLE OF ty_citizen.
LOOP AT lt_dyn INTO DATA(ls_dyn).
ls_dyn-country = 'IT'.
WRITE:/ 'Pays mis à jour:', ls_dyn-country, 'Nom:', ls_dyn-name.
ENDLOOP.
LOOP AT lt_dyn ASSIGNING FIELD-SYMBOLS(<lfs_dyn_row>).
<lfs_dyn_row>-country = 'IT'.
WRITE:/ 'Pays mis à jour:', <lfs_dyn_row>-country, 'Nom:', <lfs_dyn_row>-name.
ENDLOOP.
Utile pour créer ou manipuler des structures au fur et à mesure, et pour éviter les conflits de
FIELD-SYMBOLS.
Loop avec at first / at new / at end of / at last #
SORT lt_citizen BY country.
LOOP AT lt_citizen ASSIGNING <lfs_citizen>.
AT FIRST.
WRITE: 'Début de la liste'.
ULINE.
ENDAT.
AT NEW country.
WRITE:/ 'Début pays : ', <lfs_citizen>-country.
ENDAT.
WRITE:/ 'Nom : ', <lfs_citizen>-name, 'Age : ', <lfs_citizen>-age.
AT END OF country.
WRITE:/ 'Fin pays : ', <lfs_citizen>-country.
ULINE.
ENDAT.
AT LAST.
WRITE: 'Fin de la liste'.
ENDAT.
ENDLOOP.
Permet de gérer des ruptures pour grouper ou démarquer des sections dans la table.
Exemples avancés – where #
1 – Where sur un champ #
LOOP AT lt_citizen INTO ls_citizen WHERE country = 'FR'.
WRITE:/ 'Pays:', ls_citizen-country, 'Nom:', ls_citizen-name.
ENDLOOP.
Vérifie toutes les lignes dont le champ
country= ‘FR’.
2 – Where sur deux champs (clé et non-clé) #
LOOP AT lt_citizen ASSIGNING <lfs_citizen> WHERE country = 'ES' AND age > '30'.
WRITE:/ 'Pays:', <lfs_citizen>-country, 'Nom:', <lfs_citizen>-name, 'Âge:', <lfs_citizen>-age.
ENDLOOP.
On peut combiner plusieurs champs avec
AND.
les champs non-clés peuvent être utilisés pour filtrer.
3 – Where avec comparaisons multiples #
LOOP AT lt_citizen INTO ls_citizen WHERE age >= '25' AND age <= '32'.
WRITE:/ 'Nom:', ls_citizen-name, 'Âge:', ls_citizen-age.
ENDLOOP.
Permet de sélectionner des plages de valeurs.
chercher toutes les fiches entre 25 et 32 ans.
4 – Where sur plusieurs champs clés et non-clés #
LOOP AT lt_citizen ASSIGNING <lfs_citizen> WHERE country = 'FR' AND age = '24' AND name = 'Thierry'.
WRITE:/ 'Citoyen trouvé:', <lfs_citizen>-name, 'Pays:', <lfs_citizen>-country.
ENDLOOP.
Si la table n’est pas triée correctement pour les clés, l’utilisation d’
AT NEWavec ce filtre pourrait ne pas fonctionner comme attendu.
5 – Where avec conditions complexes #
LOOP AT lt_citizen INTO ls_citizen WHERE (country = 'BR' OR country = 'IT') AND age < '30'.
WRITE:/ 'Nom:', ls_citizen-name, 'Pays:', ls_citizen-country, 'Âge:', ls_citizen-age.
ENDLOOP.
On peut combiner
ANDetORen respectant la priorité des parenthèses.
6 – Where dynamique (avec field-symbol) #
DATA: lv_country TYPE char3 VALUE 'ES'.
LOOP AT lt_citizen ASSIGNING FIELD-SYMBOLS(<dyn_citizen>) WHERE country = lv_country AND age > '30'.
WRITE:/ 'Nom:', <dyn_citizen>-name, 'Pays:', <dyn_citizen>-country, 'Âge:', <dyn_citizen>-age.
ENDLOOP.
Permet d’utiliser des variables dynamiques dans les conditions.
Bonnes pratiques #
| Bonne pratique | Explications |
|---|---|
| Toujours trier la table avant AT NEW | Nécessaire pour les tables STANDARD si vous utilisez des ruptures |
| Préférer ASSIGNING pour modifier | Évite la copie et permet de travailler directement en mémoire |
| Utiliser WHERE pour filtrer | Réduit le nombre de lignes parcourues |
| Vérifier SY-SUBRC | Utile si vous utilisez TRANSPORTING NO FIELDS |
| FIELD-SYMBOLS uniques par scope | Évite les erreurs et conflits dans les boucles imbriquées |
| FROM/TO pour limiter les plages | Optimise les traitements si seules certaines lignes sont concernées |
| Parenthèses avec AND/OR | Clarifie les conditions complexes et évite les erreurs |
Exercices #
1 – Where sur un seul champ #
Parcourir
lt_citizenet afficher les citoyens dontcountry = 'FR'.
SOLUTION
LOOP AT lt_citizen INTO ls_citizen WHERE country = 'FR'.
WRITE:/ 'Pays:', ls_citizen-country, 'Nom:', ls_citizen-name.
ENDLOOP.
2 – Where sur plusieurs champs #
Afficher les citoyens dont
country = 'ES'etage > 30.
SOLUTION
LOOP AT lt_citizen ASSIGNING <lfs_citizen> WHERE country = 'ES' AND age > '30'.
WRITE:/ 'Nom:', <lfs_citizen>-name, 'Pays:', <lfs_citizen>-country, 'Âge:', <lfs_citizen>-age.
ENDLOOP.
3 – Where avec plage d’âge #
Afficher les citoyens âgés entre 25 et 32 ans.
SOLUTION
LOOP AT lt_citizen INTO ls_citizen WHERE age >= '25' AND age <= '32'.
WRITE:/ 'Nom:', ls_citizen-name, 'Âge:', ls_citizen-age.
ENDLOOP.
4 – Where dynamique #
Afficher tous les citoyens dont
country = lv_countryetage > 30.
SOLUTION
DATA: lv_country TYPE char3 VALUE 'ES'.
LOOP AT lt_citizen ASSIGNING FIELD-SYMBOLS(<dyn_citizen>) WHERE country = lv_country AND age > '30'.
WRITE:/ 'Nom:', <dyn_citizen>-name, 'Pays:', <dyn_citizen>-country, 'Âge:', <dyn_citizen>-age.
ENDLOOP.
5 – Where complexe avec or et and #
Afficher tous les citoyens dont
country = 'BR'oucountry = 'IT'etage < 30.
SOLUTION
LOOP AT lt_citizen INTO ls_citizen WHERE (country = 'BR' OR country = 'IT') AND age < '30'.
WRITE:/ 'Nom:', ls_citizen-name, 'Pays:', ls_citizen-country, 'Âge:', ls_citizen-age.
ENDLOOP.
Résumé #
LOOP ATpermet de parcourir les tables internes ligne par ligne.
INTO: copie de la ligneASSIGNING: référence directe en mémoireTRANSPORTING NO FIELDS: vérification uniquementWHERE: filtrage simple ou complexe (un ou plusieurs champs, AND/OR, variables dynamiques)FROM/TO: filtrage par plageFIELD-SYMBOLS: modification directeSY-SUBRC/SY-TABIX: code retour et indexAT FIRST/AT NEW/AT END OF/AT LAST: gestion des ruptures