L’instruction MODIFY est utilisee en ABAP pour modifier des lignes existantes dans les tables internes. Elle peut mettre a jour une seule ligne (par index ou cle) ou plusieurs lignes simultanement (avec une condition WHERE). Si la ligne n’existe pas, MODIFY peut aussi l’inserer selon la variante.
Syntaxe
Il existe plusieurs variantes de l’instruction MODIFY :
1. Modifier une ligne par index
MODIFY <table_interne> FROM <zone_de_travail> INDEX <index> [TRANSPORTING <composant1> <composant2> ...].2. Modifier ou inserer une ligne par cle de table
MODIFY TABLE <table_interne> FROM <zone_de_travail> [TRANSPORTING <composant1> <composant2> ...].3. Modifier plusieurs lignes avec condition WHERE
MODIFY <table_interne> FROM <zone_de_travail> TRANSPORTING <composant1> [<composant2> ...] WHERE <condition>.4. Modifier la ligne courante dans un LOOP
LOOP AT <table_interne> INTO <zone_de_travail>. " modifier <zone_de_travail> MODIFY <table_interne> FROM <zone_de_travail>.ENDLOOP.Composants
<table_interne>: La table dont les lignes doivent etre modifiees.<zone_de_travail>: Une structure avec les nouvelles valeurs. Doit etre compatible avec le type de ligne de la table.INDEX <index>: La position de la ligne a modifier (uniquement pour les tables standard et triees).TABLE: Indique la variante avec recherche par cle. La ligne est recherchee par la cle primaire.TRANSPORTING <composants>: Limite la modification aux composants specifies. Les autres champs restent inchanges.WHERE <condition>: Modifie toutes les lignes qui satisfont la condition.
Champs systeme
Apres un MODIFY, les champs systeme suivants sont definis :
-
sy-subrc:0: Ligne(s) modifiee(s) avec succes (ou inseree avecMODIFY TABLE).4: Aucune ligne correspondante trouvee (avecINDEXouTABLE).
-
sy-tabix: Contient l’index de la ligne modifiee (pour les operations sur une seule ligne dans les tables indexees).
Fonctionnement par variante
MODIFY … INDEX
Modifie la ligne a la position d’index specifiee. Le contenu entier de la zone de travail est copie dans la ligne (sauf avec TRANSPORTING).
" Remplacer completement la ligne 3MODIFY lt_data FROM ls_new_data INDEX 3.
" Modifier seulement certains champs de la ligne 3MODIFY lt_data FROM ls_new_data INDEX 3 TRANSPORTING field1 field2.MODIFY TABLE
Recherche la ligne par la cle primaire dans la zone de travail :
- Trouvee : La ligne est mise a jour.
- Non trouvee : La ligne est inseree (comme
INSERT).
" Recherche par cle et modifie ou insereMODIFY TABLE lt_customers FROM ls_customer.MODIFY … WHERE
Modifie toutes les lignes qui satisfont la condition WHERE. TRANSPORTING est obligatoire ici.
" Modifier toutes les lignes avec status = 'OLD"MODIFY lt_orders FROM ls_update TRANSPORTING status WHERE status = 'OLD'.MODIFY dans LOOP (sans INDEX)
Dans un LOOP AT ... INTO, MODIFY peut etre utilise sans INDEX - il modifie alors automatiquement la ligne courante.
LOOP AT lt_data INTO ls_data. ls_data-field = 'Nouvelle valeur'. MODIFY lt_data FROM ls_data.ENDLOOP.Mieux : Utilisez ASSIGNING dans le loop pour des modifications directes sans MODIFY.
Exemples
1. Modifier une ligne par index
TYPES: BEGIN OF ty_product, id TYPE i, name TYPE string, price TYPE p DECIMALS 2, END OF ty_product.
DATA: lt_products TYPE STANDARD TABLE OF ty_product WITH EMPTY KEY, ls_product TYPE ty_product.
" Remplir la tablelt_products = VALUE #( ( id = 1 name = 'Ordinateur' price = '999.00' ) ( id = 2 name = 'Souris' price = '29.99' ) ( id = 3 name = 'Clavier' price = '79.00' )).
" Remplacer completement la ligne 2ls_product = VALUE #( id = 2 name = 'Souris Gaming' price = '59.99' ).MODIFY lt_products FROM ls_product INDEX 2.
IF sy-subrc = 0. WRITE: / 'Ligne 2 modifiee.'.ENDIF.2. Modifier seulement certains champs (TRANSPORTING)
" Modifier seulement le prix de la ligne 1ls_product-price = '899.00'.MODIFY lt_products FROM ls_product INDEX 1 TRANSPORTING price.
" Le nom et l'ID restent inchanges" Voir aussi : /read-table-statement/READ TABLE lt_products INTO ls_product INDEX 1.WRITE: / 'Produit:', ls_product-name, 'Prix:', ls_product-price." Sortie : Ordinateur 899.003. MODIFY TABLE (base sur la cle)
TYPES: BEGIN OF ty_customer, id TYPE i, name TYPE string, city TYPE string, END OF ty_customer.
DATA: lt_customers TYPE HASHED TABLE OF ty_customer WITH UNIQUE KEY id, ls_customer TYPE ty_customer.
" Remplir la tablelt_customers = VALUE #( ( id = 1 name = 'Dupont SARL' city = 'Paris' ) ( id = 2 name = 'Martin SA' city = 'Lyon' )).
" Modifier un client existant (ID 1 existe)ls_customer = VALUE #( id = 1 name = 'Dupont & Co SARL' city = 'Paris' ).MODIFY TABLE lt_customers FROM ls_customer.
IF sy-subrc = 0. WRITE: / 'Client 1 modifie.'.ENDIF.
" Inserer un nouveau client (ID 3 n'existe pas)ls_customer = VALUE #( id = 3 name = 'Weber SAS' city = 'Marseille' ).MODIFY TABLE lt_customers FROM ls_customer.
WRITE: / 'Nombre de clients:', lines( lt_customers ). " Sortie : 34. Modifier plusieurs lignes avec WHERE
TYPES: BEGIN OF ty_order, order_id TYPE i, status TYPE string, amount TYPE p DECIMALS 2, END OF ty_order.
DATA: lt_orders TYPE STANDARD TABLE OF ty_order WITH EMPTY KEY, ls_update TYPE ty_order.
lt_orders = VALUE #( ( order_id = 1 status = 'NOUVEAU' amount = '100.00' ) ( order_id = 2 status = 'NOUVEAU' amount = '250.00' ) ( order_id = 3 status = 'OUVERT' amount = '180.00' ) ( order_id = 4 status = 'NOUVEAU' amount = '320.00' )).
" Passer toutes les commandes avec statut 'NOUVEAU' a 'EN_TRAITEMENT"ls_update-status = 'EN_TRAITEMENT'.MODIFY lt_orders FROM ls_update TRANSPORTING status WHERE status = 'NOUVEAU'.
" Resultat : 3 lignes modifiees (order_id 1, 2, 4)LOOP AT lt_orders INTO DATA(ls_order). WRITE: / ls_order-order_id, ls_order-status.ENDLOOP.5. MODIFY dans LOOP avec INTO
DATA: ls_prod TYPE ty_product.
" Augmenter tous les prix de 10%LOOP AT lt_products INTO ls_prod. ls_prod-price = ls_prod-price * '1.1'. MODIFY lt_products FROM ls_prod.ENDLOOP.6. Meilleure alternative : LOOP avec ASSIGNING
FIELD-SYMBOLS: <fs_prod> TYPE ty_product.
" Augmenter tous les prix de 10% - sans MODIFYLOOP AT lt_products ASSIGNING <fs_prod>. <fs_prod>-price = <fs_prod>-price * '1.1'.ENDLOOP.
" Les modifications sont immediatement effectives, pas de MODIFY necessaire !7. MODIFY TABLE avec TRANSPORTING
" Modifier seulement la ville d'un client (recherche par cle)ls_customer-id = 2. " Cle pour la recherchels_customer-city = 'Nice'. " Nouvelle valeur
MODIFY TABLE lt_customers FROM ls_customer TRANSPORTING city.
IF sy-subrc = 0. WRITE: / 'Ville du client 2 modifiee.'.ENDIF.Comportement par type de table
| Type de table | INDEX | TABLE | WHERE |
|---|---|---|---|
| STANDARD TABLE | Oui | Oui (recherche lineaire) | Oui |
| SORTED TABLE | Oui | Oui (recherche binaire) | Oui |
| HASHED TABLE | Non | Oui (recherche par hash) | Oui |
Important pour les tables triees : Si vous modifiez les champs cle, cela peut violer l’ordre de tri et provoquer une erreur d’execution !
" Dangereux avec SORTED TABLE avec KEY id :ls_customer-id = 999. " Modifier le champ cleMODIFY TABLE lt_sorted_customers FROM ls_customer. " Peut provoquer un dump !Distinction avec d’autres instructions
MODIFY vs. ASSIGNING dans LOOP
| Aspect | MODIFY dans LOOP | ASSIGNING |
|---|---|---|
| Syntaxe | Plus de code | Plus compact |
| Performance | Plus lent (copie) | Plus rapide (acces direct) |
| Utilisation | Code legacy | Recommande |
" Avec MODIFY (obsolete)LOOP AT lt_data INTO ls_data. ls_data-field = 'X'. MODIFY lt_data FROM ls_data.ENDLOOP.
" Avec ASSIGNING (recommande)LOOP AT lt_data ASSIGNING FIELD-SYMBOL(<fs>). <fs>-field = 'X'.ENDLOOP.MODIFY vs. INSERT et APPEND
MODIFY TABLE: Modifie une ligne existante OU insere une nouvelle (Upsert).INSERT: Insere seulement, echoue si la cle existe.APPEND: Ajoute toujours a la fin d’une table standard.
MODIFY vs. UPDATE (Base de donnees)
MODIFY: Pour les tables internes (en memoire).UPDATE: Pour les tables de base de donnees (donnees persistantes).
Pour rechercher une ligne avant de la modifier, voir READ TABLE.
Conseils de performance
-
ASSIGNING au lieu de MODIFY dans LOOP : Evitez
LOOP ... INTOsuivi deMODIFY. UtilisezASSIGNINGpour un acces direct en ecriture. -
TRANSPORTING pour les grandes structures : Si seulement quelques champs sont modifies, limitez les donnees copiees avec
TRANSPORTING. -
WHERE pour les modifications de masse :
MODIFY ... WHEREest plus efficace qu’une boucle manuelle avec modifications individuelles. -
Ne pas modifier les champs cle : Pour les tables triees et hash, les champs cle ne devraient pas etre modifies. Plutot : supprimer la ligne et en inserer une nouvelle (voir
APPENDouINSERT).
Remarques importantes / Bonnes pratiques
- Verifiez
sy-subrcapresMODIFYavecINDEXouTABLEpour vous assurer que la ligne a ete trouvee. - Preferez
ASSIGNINGdansLOOP ATpour les modifications directes - c’est plus performant et plus elegant queMODIFY. - Utilisez
TRANSPORTINGquand seuls certains champs doivent etre modifies. MODIFY TABLEest un “Upsert” - il insere si la ligne n’existe pas.- Ne modifiez jamais les champs cle directement pour les tables triees ou hash.
- Pour
MODIFY ... WHERE,TRANSPORTINGest obligatoire. - Cette instruction
MODIFYest pour les tables internes. Pour les tables de base de donnees, voirINSERT, UPDATE, DELETE.