ABAP CORRESPONDING: Strukturen und Tabellen zuordnen

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

Der CORRESPONDING-Operator kopiert Daten zwischen Strukturen oder Tabellen, wobei Felder mit gleichen Namen automatisch zugeordnet werden. Er ist die moderne Alternative zur MOVE-CORRESPONDING-Anweisung.

Syntax

CORRESPONDING <typ>(
<quelle>
[ BASE ( <basis> ) ]
[ MAPPING <ziel1> = <quelle1> ... ]
[ EXCEPT <feld1> <feld2> ... ]
)

Grundprinzip

Felder werden nach Namen zugeordnet:

  • Felder mit gleichem Namen werden kopiert
  • Felder ohne Entsprechung bleiben unverändert (oder initial)
  • Unterschiedliche Typen werden konvertiert (wenn kompatibel)

Beispiele

1. Einfache Strukturzuordnung

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 = 'max@test.de' ).
" Felder mit gleichen Namen werden kopiert
ls_target = CORRESPONDING #( ls_source ).
" ls_target-id = 1
" ls_target-name = 'Max'
" ls_target-address = '' (nicht in Quelle vorhanden)
" email wird ignoriert (nicht in Ziel vorhanden)

2. CORRESPONDING vs. MOVE-CORRESPONDING

" Klassisch
MOVE-CORRESPONDING ls_source TO ls_target.
" Modern (funktional äquivalent)
ls_target = CORRESPONDING #( ls_source ).
" Der Unterschied: CORRESPONDING ist ein Ausdruck
" und kann in anderen Ausdrücken verwendet werden
DATA(ls_result) = CORRESPONDING ty_target( ls_source ).

3. BASE – Bestehende Werte erhalten

Ohne BASE werden nicht zugeordnete Felder auf Initialwert gesetzt:

ls_target = VALUE #( id = 99 name = 'Alt' address = 'Berlin' ).
" OHNE BASE: address wird initial
ls_target = CORRESPONDING #( ls_source ).
" ls_target-address = ''
" MIT BASE: address bleibt erhalten
ls_target = VALUE #( id = 99 name = 'Alt' address = 'Berlin' ).
ls_target = CORRESPONDING #( BASE ( ls_target ) ls_source ).
" ls_target-address = 'Berlin'

4. MAPPING – Felder umbenennen

Wenn Quell- und Zielfeld unterschiedliche Namen haben:

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 = 'Müller GmbH' ort01 = 'Berlin' ).
" Mit MAPPING: Feldnamen zuordnen
ls_customer = CORRESPONDING #(
ls_db_record
MAPPING customer_id = kunnr
customer_name = name1
city = ort01
).
" ls_customer-customer_id = '1000'
" ls_customer-customer_name = 'Müller GmbH'
" ls_customer-city = 'Berlin'

5. EXCEPT – Felder ausschließen

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 = 'geheim' email = 'admin@test.de'
).
" Passwort NICHT kopieren
ls_user_safe = CORRESPONDING #( ls_user_full EXCEPT password ).
" ls_user_safe-password = '' (nicht kopiert)

6. MAPPING und EXCEPT kombinieren

TYPES: BEGIN OF ty_order_db,
aufnr TYPE string,
kdnr TYPE string,
datum TYPE d,
internal TYPE string, " Internes Feld
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. Tabellen transformieren

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 = 'anna@test.de' )
( id = 2 name = 'Bernd' email = 'bernd@test.de' )
( id = 3 name = 'Clara' email = 'clara@test.de' )
).
" Ganze Tabelle transformieren
lt_target = CORRESPONDING #( lt_source ).
" Mit MAPPING
lt_target = CORRESPONDING #(
lt_source
MAPPING id = id name = name
).

8. DEEP – Tiefe Strukturen

Für verschachtelte Strukturen mit 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 = 'Hauptstr.' city = 'Berlin' )
items = VALUE #( ( `Item1` ) ( `Item2` ) )
).
" DEEP kopiert auch verschachtelte Strukturen und Tabellen
ls_target = CORRESPONDING #( DEEP ls_source ).

9. CORRESPONDING in Methodenparametern

METHODS: process_order
IMPORTING is_api_order TYPE ty_order_api.
" Aufruf mit Transformation
process_order(
is_api_order = CORRESPONDING #( ls_db_order
MAPPING order_id = aufnr
customer_id = kdnr
)
).

10. Mit VALUE kombinieren

" Struktur erstellen und gleichzeitig transformieren
DATA(ls_output) = VALUE ty_order_api(
BASE CORRESPONDING #( ls_db_order
MAPPING order_id = aufnr
)
" Zusätzliche Felder setzen
status = 'NEW'
).

11. Tabelle filtern und transformieren

" Mit FOR und CORRESPONDING kombinieren
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

AspektCORRESPONDING #()MOVE-CORRESPONDING
TypAusdruck (liefert Wert)Anweisung
Inline nutzbarJaNein
BASEJaNein (überschreibt immer)
MAPPINGJaNein
EXCEPTJaNein
DEEPJaBegrenzt
EmpfehlungModern, bevorzugtLegacy
" MOVE-CORRESPONDING: Nur einfache Zuordnung
MOVE-CORRESPONDING ls_source TO ls_target.
" CORRESPONDING: Flexibel und mächtig
ls_target = CORRESPONDING #(
BASE ( ls_target )
ls_source
MAPPING target_field = source_field
EXCEPT unwanted_field
).

Wichtige Hinweise / Best Practice

  • CORRESPONDING #() ist ein Ausdruck – nutzen Sie es inline in anderen Ausdrücken.
  • Verwenden Sie BASE um bestehende Werte zu erhalten.
  • MAPPING ermöglicht Feldumbenennung zwischen unterschiedlichen Strukturen.
  • EXCEPT schließt sensitive oder unnötige Felder aus.
  • DEEP ist nötig für verschachtelte Strukturen und Tabellen.
  • Kombinieren Sie mit VALUE und FOR für komplexe Transformationen.
  • Bei großen Datenmengen ist CORRESPONDING effizient implementiert.
  • Achten Sie auf Typkompatibilität – inkompatible Typen führen zu Fehlern.
  • Ersetzen Sie MOVE-CORRESPONDING durch CORRESPONDING #() in neuem Code.