ABAP CORRESPONDING : Mapper des structures et des tables

Catégorie
ABAP-Statements
Publié
Auteur
Johannes

L’opérateur CORRESPONDING copie des données entre structures ou tables, où les champs avec les mêmes noms sont automatiquement mappés. C’est l’alternative moderne à l’instruction MOVE-CORRESPONDING.

Syntaxe

CORRESPONDING <type>(
<source>
[ BASE ( <base> ) ]
[ MAPPING <cible1> = <source1> ... ]
[ EXCEPT <champ1> <champ2> ... ]
)

Principe de base

Les champs sont mappés par nom :

  • Les champs avec le même nom sont copiés
  • Les champs sans correspondance restent inchangés (ou initiaux)
  • Les types différents sont convertis (si compatibles)

Exemples

1. Mappage de structure simple

TYPES: BEGIN OF ty_source,
id TYPE i,
name TYPE string,
email TYPE string,
END OF ty_source,
BEGIN OF ty_target,
id TYPE i,
name TYPE string,
address TYPE string,
END OF ty_target.
DATA: ls_source TYPE ty_source,
ls_target TYPE ty_target.
ls_source = VALUE #( id = 1 name = 'Max' email = '[email protected]' ).
" Les champs avec les mêmes noms sont copiés
ls_target = CORRESPONDING #( ls_source ).
" ls_target-id = 1
" ls_target-name = 'Max"
" ls_target-address = '' (pas dans la source)
" email est ignoré (pas dans la cible)

2. CORRESPONDING vs. MOVE-CORRESPONDING

" Classique
MOVE-CORRESPONDING ls_source TO ls_target.
" Moderne (fonctionnellement équivalent)
ls_target = CORRESPONDING #( ls_source ).
" La différence : CORRESPONDING est une expression
" et peut être utilisé dans d'autres expressions
DATA(ls_result) = CORRESPONDING ty_target( ls_source ).

3. BASE – Conserver les valeurs existantes

Sans BASE, les champs non mappés sont mis à leur valeur initiale :

ls_target = VALUE #( id = 99 name = 'Ancien' address = 'Paris' ).
" SANS BASE : address devient initial
ls_target = CORRESPONDING #( ls_source ).
" ls_target-address = '"
" AVEC BASE : address est conservé
ls_target = VALUE #( id = 99 name = 'Ancien' address = 'Paris' ).
ls_target = CORRESPONDING #( BASE ( ls_target ) ls_source ).
" ls_target-address = 'Paris"

4. MAPPING – Renommer les champs

Quand les champs source et cible ont des noms différents :

TYPES: BEGIN OF ty_db_record,
kunnr TYPE kunnr,
name1 TYPE string,
ort01 TYPE string,
END OF ty_db_record,
BEGIN OF ty_customer,
customer_id TYPE kunnr,
customer_name TYPE string,
city TYPE string,
END OF ty_customer.
DATA: ls_db_record TYPE ty_db_record,
ls_customer TYPE ty_customer.
ls_db_record = VALUE #( kunnr = '1000' name1 = 'Dupont SARL' ort01 = 'Paris' ).
" Avec MAPPING : Mapper les noms de champs
ls_customer = CORRESPONDING #(
ls_db_record
MAPPING customer_id = kunnr
customer_name = name1
city = ort01
).
" ls_customer-customer_id = '1000"
" ls_customer-customer_name = 'Dupont SARL"
" ls_customer-city = 'Paris"

5. EXCEPT – Exclure des champs

TYPES: BEGIN OF ty_user,
id TYPE i,
name TYPE string,
password TYPE string,
email TYPE string,
END OF ty_user.
DATA: ls_user_full TYPE ty_user,
ls_user_safe TYPE ty_user.
ls_user_full = VALUE #(
id = 1 name = 'Admin' password = 'secret' email = '[email protected]"
).
" Ne PAS copier le mot de passe
ls_user_safe = CORRESPONDING #( ls_user_full EXCEPT password ).
" ls_user_safe-password = '' (non copié)

6. Combiner MAPPING et EXCEPT

TYPES: BEGIN OF ty_order_db,
aufnr TYPE string,
kdnr TYPE string,
datum TYPE d,
internal TYPE string, " Champ interne
END OF ty_order_db,
BEGIN OF ty_order_api,
order_id TYPE string,
customer_id TYPE string,
order_date TYPE d,
END OF ty_order_api.
DATA: ls_order_db TYPE ty_order_db,
ls_order_api TYPE ty_order_api.
ls_order_db = VALUE #(
aufnr = 'ORD001' kdnr = 'C100' datum = sy-datum internal = 'XYZ"
).
ls_order_api = CORRESPONDING #(
ls_order_db
MAPPING order_id = aufnr
customer_id = kdnr
order_date = datum
EXCEPT internal
).

7. Transformer des tables

TYPES: ty_source_tab TYPE TABLE OF ty_source WITH EMPTY KEY,
ty_target_tab TYPE TABLE OF ty_target WITH EMPTY KEY.
DATA: lt_source TYPE ty_source_tab,
lt_target TYPE ty_target_tab.
lt_source = VALUE #(
( id = 1 name = 'Anna' email = '[email protected]' )
( id = 2 name = 'Bruno' email = '[email protected]' )
( id = 3 name = 'Clara' email = '[email protected]' )
).
" Transformer toute la table
lt_target = CORRESPONDING #( lt_source ).
" Avec MAPPING
lt_target = CORRESPONDING #(
lt_source
MAPPING id = id name = name
).

8. DEEP – Structures imbriquées

Pour les structures imbriquées avec DEEP :

TYPES: BEGIN OF ty_address,
street TYPE string,
city TYPE string,
END OF ty_address,
BEGIN OF ty_person_full,
name TYPE string,
address TYPE ty_address,
items TYPE TABLE OF string WITH EMPTY KEY,
END OF ty_person_full.
DATA: ls_source TYPE ty_person_full,
ls_target TYPE ty_person_full.
ls_source = VALUE #(
name = 'Max"
address = VALUE #( street = 'Rue principale' city = 'Paris' )
items = VALUE #( ( `Item1` ) ( `Item2` ) )
).
" DEEP copie aussi les structures imbriquées et les tables
ls_target = CORRESPONDING #( DEEP ls_source ).

9. CORRESPONDING dans les paramètres de méthodes

METHODS: process_order
IMPORTING is_api_order TYPE ty_order_api.
" Appel avec transformation
process_order(
is_api_order = CORRESPONDING #( ls_db_order
MAPPING order_id = aufnr
customer_id = kdnr
)
).

10. Combiner avec VALUE

" Créer une structure et transformer en même temps
DATA(ls_output) = VALUE ty_order_api(
BASE CORRESPONDING #( ls_db_order
MAPPING order_id = aufnr
)
" Définir des champs supplémentaires
status = 'NEW"
).

11. Filtrer et transformer une table

" Combiner FOR et CORRESPONDING
DATA(lt_active_customers) = VALUE ty_customers_api(
FOR ls_db IN lt_customers_db
WHERE ( status = 'A' )
( CORRESPONDING #( ls_db
MAPPING customer_id = kunnr
customer_name = name1
)
)
).

CORRESPONDING vs. MOVE-CORRESPONDING

AspectCORRESPONDING #()MOVE-CORRESPONDING
TypeExpression (retourne une valeur)Instruction
Utilisable inlineOuiNon
BASEOuiNon (écrase toujours)
MAPPINGOuiNon
EXCEPTOuiNon
DEEPOuiLimité
RecommandationModerne, préféréLegacy
" MOVE-CORRESPONDING : Seulement mappage simple
MOVE-CORRESPONDING ls_source TO ls_target.
" CORRESPONDING : Flexible et puissant
ls_target = CORRESPONDING #(
BASE ( ls_target )
ls_source
MAPPING target_field = source_field
EXCEPT unwanted_field
).

Notes importantes / Bonnes pratiques

  • CORRESPONDING #() est une expression – utilisez-la inline dans d’autres expressions.
  • Utilisez BASE pour conserver les valeurs existantes.
  • MAPPING permet le renommage de champs entre structures différentes.
  • EXCEPT exclut les champs sensibles ou inutiles.
  • DEEP est nécessaire pour les structures imbriquées et les tables.
  • Combinez avec VALUE et FOR pour des transformations complexes.
  • Pour de grands volumes de données, CORRESPONDING est implémenté efficacement.
  • Faites attention à la compatibilité des types – les types incompatibles causent des erreurs.
  • Remplacez MOVE-CORRESPONDING par CORRESPONDING #() dans le nouveau code.