ABAP MOVE-CORRESPONDING: Werte nach gleichen Feldnamen zwischen Strukturen/Tabellen kopieren

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

Die Anweisung MOVE-CORRESPONDING dient dazu, Werte zwischen zwei Strukturen oder zwei internen Tabellen zu kopieren, wobei nur die Komponenten (Felder) berücksichtigt werden, deren Namen in Quelle und Ziel exakt übereinstimmen. Komponenten mit unterschiedlichen Namen oder Komponenten, die nur in der Quelle oder nur im Ziel vorhanden sind, werden ignoriert. Voraussetzung für das Kopieren ist außerdem, dass die Datentypen der gleichnamigen Komponenten zuweisungskompatibel sind.

Syntax

1. Zwischen Strukturen

MOVE-CORRESPONDING <quelle_struktur> TO <ziel_struktur>
[EXPANDING NESTED TABLES]
[KEEPING TARGET LINES]. " Für Strukturen selten sinnvoll

2. Zwischen internen Tabellen

MOVE-CORRESPONDING <quelle_tabelle> TO <ziel_tabelle>
[EXPANDING NESTED TABLES]
[KEEPING TARGET LINES].

Wichtige Zusätze

  • EXPANDING NESTED TABLES: Dieser Zusatz ist wichtig, wenn die Strukturen oder die Zeilen der Tabellen selbst wieder interne Tabellen als Komponenten enthalten, die denselben Namen haben. Mit EXPANDING NESTED TABLES wird der Inhalt dieser namensgleichen, verschachtelten Tabellen ebenfalls per MOVE-CORRESPONDING-Logik (ggf. rekursiv) kopiert. Ohne diesen Zusatz werden solche Tabellenkomponenten in der Regel übersprungen (Ausnahme: Referenztypen).
  • KEEPING TARGET LINES (Hauptsächlich relevant für interne Tabellen): Verhindert das standardmäßige Löschen der Zieltabelle <ziel_tabelle> vor dem Kopiervorgang. Stattdessen werden die Werte aus den Zeilen der <quelle_tabelle> in die gleichnamigen Felder der bereits existierenden Zeilen der <ziel_tabelle> übertragen. Dies geschieht zeilenweise basierend auf dem Index. Gibt es in der Quelltabelle mehr Zeilen als in der Zieltabelle, werden die überzähligen Quellzeilen ignoriert. Gibt es in der Zieltabelle mehr Zeilen, bleiben die Werte in den entsprechenden Feldern der überzähligen Zielzeilen unverändert.
  • PERCENTAGE (Obsolet): Dieser Zusatz ist veraltet und sollte nicht mehr verwendet werden.

Funktionsweise

  1. Namensvergleich: Das System identifiziert alle Komponenten auf der obersten Ebene der Quelle und des Ziels, die denselben Namen haben. Bei Tabellen bezieht sich das auf die Komponenten der Zeilenstruktur.
  2. Typkompatibilität: Für jedes Paar gleichnamiger Komponenten wird geprüft, ob ihre Datentypen nach den ABAP-Zuweisungsregeln kompatibel sind. Eine Zuweisung ist möglich, wenn die Typen gleich sind oder eine implizite Konvertierung erlaubt ist (z. B. C nach STRING, I nach P). Bei tiefen Strukturen müssen auch die Typen der gleichnamigen Unterstrukturen kompatibel sein.
  3. Wertübertragung: Wenn Namen übereinstimmen und Typen kompatibel sind, wird der Wert von der Quellkomponente in die Zielkomponente kopiert.
  4. Verhalten bei Tabellen (Standard): Wenn MOVE-CORRESPONDING auf interne Tabellen ohne den Zusatz KEEPING TARGET LINES angewendet wird, geschieht Folgendes:
    • Die Zieltabelle wird implizit geleert (CLEAR ziel_tabelle.).
    • Das System iteriert durch die Zeilen der Quelltabelle.
    • Für jede Quellzeile wird eine neue Zeile in der Zieltabelle erzeugt, und die Werte der gleichnamigen, kompatiblen Komponenten werden aus der Quellzeile in die neue Zielzeile kopiert.
    • Die neue Zielzeile wird an die Zieltabelle angehängt (APPEND).

Moderne Alternative: Der CORRESPONDING-Operator (ab ABAP 7.40)

Für Neuentwicklungen wird dringend empfohlen, den CORRESPONDING-Operator zu verwenden. Er ist flexibler, leistungsfähiger und passt besser in die moderne ABAP-Syntax.

" Strukturzuweisung
ziel_struktur = CORRESPONDING #( quelle_struktur ).
" Tabellenzuweisung (entspricht Standard MOVE-CORRESPONDING)
ziel_tabelle = CORRESPONDING #( quelle_tabelle ).
" Mit Optionen (Beispiele):
ziel_struktur = CORRESPONDING type_von_ziel( quelle_struktur
MAPPING ziel_feld = quell_feld " Umbenennen
EXCEPT feld_a feld_b ). " Ausschließen
ziel_tabelle = CORRESPONDING #( BASE (ziel_tabelle) quelle_tabelle ). " Ähnlich KEEPING TARGET LINES

Der Operator erlaubt explizites Mapping von Feldern (MAPPING), das Ausschließen von Feldern (EXCEPT), die Verwendung einer Basis (BASE für ähnliches Verhalten wie KEEPING TARGET LINES) und kann direkt in Zuweisungen oder anderen Ausdrücken verwendet werden.

Beispiele für MOVE-CORRESPONDING

1. Struktur zu Struktur

TYPES: BEGIN OF type_source,
matnr TYPE matnr, " Materialnummer
werks TYPE werks_d, " Werk
menge TYPE i, " Menge
extra TYPE string, " Zusätzliches Feld Quelle
END OF type_source.
TYPES: BEGIN OF type_target,
matnr TYPE matnr, " Materialnummer (gleich)
werks TYPE werks_d, " Werk (gleich)
stock TYPE i, " Menge (anderer Name)
info TYPE string, " Zusätzliches Feld Ziel
END OF type_target.
DATA: source_data TYPE type_source,
target_data TYPE type_target.
source_data-matnr = 'MAT01'.
source_data-werks = '1000'.
source_data-menge = 100.
source_data-extra = 'Source Info'.
target_data-stock = 50. " Vorhandener Wert in Ziel
target_data-info = 'Target Info'.
WRITE: / 'Ziel VORHER:', target_data-matnr, target_data-werks, target_data-stock, target_data-info.
MOVE-CORRESPONDING source_data TO target_data.
WRITE: / 'Ziel NACHHER:', target_data-matnr, target_data-werks, target_data-stock, target_data-info.

Ausgabe:

Ziel VORHER: 1000 50 Target Info
Ziel NACHHER: MAT01 1000 50 Target Info

(Nur matnr und werks wurden kopiert, da nur diese Namen übereinstimmen. stock und info im Ziel bleiben unverändert, menge und extra aus der Quelle wurden ignoriert).

2. Tabelle zu Tabelle (Standard)

TYPES: BEGIN OF ty_s1, f1 TYPE i, f2 TYPE c LENGTH 2, END OF ty_s1.
TYPES: BEGIN OF ty_s2, f2 TYPE c LENGTH 2, f3 TYPE d, END OF ty_s2.
DATA: lt_source TYPE STANDARD TABLE OF ty_s1,
lt_target TYPE STANDARD TABLE OF ty_s2.
APPEND VALUE #( f1 = 1 f2 = 'AA' ) TO lt_source.
APPEND VALUE #( f1 = 2 f2 = 'BB' ) TO lt_source.
APPEND VALUE #( f2 = 'XX' f3 = sy-datum - 1 ) TO lt_target. " Vorhandene Zeile im Ziel
WRITE: / 'Zielzeilen VORHER:', lines( lt_target ).
MOVE-CORRESPONDING lt_source TO lt_target.
WRITE: / 'Zielzeilen NACHHER:', lines( lt_target ). " Ziel wurde erst gelöscht, dann gefüllt
LOOP AT lt_target INTO DATA(ls_target).
WRITE: / '-> Ziel F2:', ls_target-f2, ' | Ziel F3:', ls_target-f3.
ENDLOOP.

Ausgabe:

Zielzeilen VORHER: 1
Zielzeilen NACHHER: 2
-> Ziel F2: AA | Ziel F3: 00000000
-> Ziel F2: BB | Ziel F3: 00000000

(Die Zieltabelle wurde geleert, dann wurden 2 Zeilen hinzugefügt, wobei nur das Feld f2 kopiert wurde).

3. Tabelle zu Tabelle mit KEEPING TARGET LINES

" ... lt_source und lt_target wie in Bsp. 2 füllen ...
WRITE: / 'Zielzeilen VORHER (KEEPING):', lines( lt_target ).
MOVE-CORRESPONDING lt_source TO lt_target KEEPING TARGET LINES.
WRITE: / 'Zielzeilen NACHHER (KEEPING):', lines( lt_target ). " Anzahl bleibt gleich
LOOP AT lt_target INTO DATA(ls_target_k).
WRITE: / '-> Ziel F2:', ls_target_k-f2, ' | Ziel F3:', ls_target_k-f3.
ENDLOOP.

Ausgabe:

Zielzeilen VORHER (KEEPING): 1
Zielzeilen NACHHER (KEEPING): 1
-> Ziel F2: AA | Ziel F3: <Datum von gestern>

(Die Zieltabelle behält ihre Zeile(n). Nur für die erste Zeile wird f2 aus der ersten Zeile der Quelle kopiert. f3 bleibt unberührt. Die zweite Zeile der Quelle wird ignoriert, da das Ziel nur eine Zeile hat).

Wichtige Hinweise / Best Practice

  • MOVE-CORRESPONDING ist nützlich, wenn viele Felder übereinstimmen und man sich Tipparbeit sparen will.
  • Risiko: Es kann zu unerwarteten Ergebnissen führen, wenn Namensgleichheiten unbeabsichtigt sind oder wenn man den Überblick verliert, welche Felder tatsächlich kopiert werden. Fehlende Felder im Ziel werden nicht automatisch erzeugt.
  • Achten Sie auf Typkompatibilität, um Laufzeitfehler oder unerwünschte Konvertierungen zu vermeiden.
  • Bei sehr großen Tabellen kann die Performance im Vergleich zu gezielten Zuweisungen oder dem CORRESPONDING-Operator schlechter sein.
  • Empfehlung: Nutzen Sie für neue Entwicklungen den flexibleren und oft klareren CORRESPONDING-Operator. MOVE-CORRESPONDING ist aber für das Verständnis und die Wartung von älterem Code weiterhin relevant.