ABAP MOVE-CORRESPONDING: Copy Values by Matching Field Names Between Structures/Tables

Category
ABAP-Statements
Published
Author
Johannes

The MOVE-CORRESPONDING statement is used to copy values between two structures or two internal tables, where only the components (fields) whose names exactly match in source and target are considered. Components with different names or components that exist only in the source or only in the target are ignored. A prerequisite for copying is also that the data types of the matching components are assignment-compatible.

Syntax

1. Between Structures

MOVE-CORRESPONDING <source_structure> TO <target_structure>
[EXPANDING NESTED TABLES]
[KEEPING TARGET LINES]. " Rarely useful for structures

2. Between Internal Tables

MOVE-CORRESPONDING <source_table> TO <target_table>
[EXPANDING NESTED TABLES]
[KEEPING TARGET LINES].

Important Additions

  • EXPANDING NESTED TABLES: This addition is important when the structures or table rows themselves contain internal tables as components with the same name. With EXPANDING NESTED TABLES, the content of these same-named, nested tables is also copied using MOVE-CORRESPONDING logic (recursively if needed). Without this addition, such table components are usually skipped (exception: reference types).
  • KEEPING TARGET LINES (Mainly relevant for internal tables): Prevents the default clearing of the target table <target_table> before the copy operation. Instead, the values from the source table rows are transferred to the matching fields of the already existing rows in the target table. This happens row by row based on the index. If the source table has more rows than the target table, the excess source rows are ignored. If the target table has more rows, the values in the corresponding fields of the excess target rows remain unchanged.
  • PERCENTAGE (Obsolete): This addition is deprecated and should no longer be used.

How It Works

  1. Name comparison: The system identifies all components at the top level of source and target that have the same name. For tables, this refers to the components of the row structure.
  2. Type compatibility: For each pair of same-named components, the system checks whether their data types are compatible according to ABAP assignment rules. An assignment is possible if the types are equal or implicit conversion is allowed (e.g., C to STRING, I to P). For deep structures, the types of same-named substructures must also be compatible.
  3. Value transfer: When names match and types are compatible, the value is copied from the source component to the target component.
  4. Behavior for tables (default): When MOVE-CORRESPONDING is applied to internal tables without the KEEPING TARGET LINES addition, the following happens:
    • The target table is implicitly cleared (CLEAR target_table.).
    • The system iterates through the rows of the source table.
    • For each source row, a new row is created in the target table, and the values of matching, compatible components are copied from the source row to the new target row.
    • The new target row is appended to the target table (APPEND).

Modern Alternative: The CORRESPONDING Operator (from ABAP 7.40)

For new developments, it is strongly recommended to use the CORRESPONDING operator. It is more flexible, more powerful, and fits better with modern ABAP syntax.

" Structure assignment
target_structure = CORRESPONDING #( source_structure ).
" Table assignment (equivalent to standard MOVE-CORRESPONDING)
target_table = CORRESPONDING #( source_table ).
" With options (examples):
target_structure = CORRESPONDING type_of_target( source_structure
MAPPING target_field = source_field " Rename
EXCEPT field_a field_b ). " Exclude
target_table = CORRESPONDING #( BASE (target_table) source_table ). " Similar to KEEPING TARGET LINES

The operator allows explicit field mapping (MAPPING), excluding fields (EXCEPT), using a base (BASE for similar behavior to KEEPING TARGET LINES), and can be used directly in assignments or other expressions.

Examples for MOVE-CORRESPONDING

1. Structure to Structure

TYPES: BEGIN OF type_source,
matnr TYPE matnr, " Material number
werks TYPE werks_d, " Plant
menge TYPE i, " Quantity
extra TYPE string, " Additional source field
END OF type_source.
TYPES: BEGIN OF type_target,
matnr TYPE matnr, " Material number (same)
werks TYPE werks_d, " Plant (same)
stock TYPE i, " Quantity (different name)
info TYPE string, " Additional target field
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. " Existing value in target
target_data-info = 'Target Info'.
WRITE: / 'Target BEFORE:', target_data-matnr, target_data-werks, target_data-stock, target_data-info.
MOVE-CORRESPONDING source_data TO target_data.
WRITE: / 'Target AFTER:', target_data-matnr, target_data-werks, target_data-stock, target_data-info.

Output:

Target BEFORE: 1000 50 Target Info
Target AFTER: MAT01 1000 50 Target Info

(Only matnr and werks were copied, as only these names match. stock and info in the target remain unchanged, menge and extra from the source were ignored).

2. Table to Table (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. " Existing row in target
WRITE: / 'Target rows BEFORE:', lines( lt_target ).
MOVE-CORRESPONDING lt_source TO lt_target.
WRITE: / 'Target rows AFTER:', lines( lt_target ). " Target was cleared first, then filled
LOOP AT lt_target INTO DATA(ls_target).
WRITE: / '-> Target F2:', ls_target-f2, ' | Target F3:', ls_target-f3.
ENDLOOP.

Output:

Target rows BEFORE: 1
Target rows AFTER: 2
-> Target F2: AA | Target F3: 00000000
-> Target F2: BB | Target F3: 00000000

(The target table was cleared, then 2 rows were added, with only field f2 being copied).

3. Table to Table with KEEPING TARGET LINES

" ... fill lt_source and lt_target as in Example 2 ...
WRITE: / 'Target rows BEFORE (KEEPING):', lines( lt_target ).
MOVE-CORRESPONDING lt_source TO lt_target KEEPING TARGET LINES.
WRITE: / 'Target rows AFTER (KEEPING):', lines( lt_target ). " Count stays the same
LOOP AT lt_target INTO DATA(ls_target_k).
WRITE: / '-> Target F2:', ls_target_k-f2, ' | Target F3:', ls_target_k-f3.
ENDLOOP.

Output:

Target rows BEFORE (KEEPING): 1
Target rows AFTER (KEEPING): 1
-> Target F2: AA | Target F3: <yesterday's date>

(The target table keeps its row(s). Only for the first row is f2 copied from the first row of the source. f3 remains untouched. The second row of the source is ignored since the target only has one row).

Best Practices

  • MOVE-CORRESPONDING is useful when many fields match and you want to save typing effort.
  • Risk: It can lead to unexpected results if name matches are unintentional or if you lose track of which fields are actually being copied. Missing fields in the target are not automatically created.
  • Pay attention to type compatibility to avoid runtime errors or unwanted conversions.
  • For very large tables, performance may be worse compared to targeted assignments or the CORRESPONDING operator.
  • Recommendation: For new developments, use the more flexible and often clearer CORRESPONDING operator. MOVE-CORRESPONDING remains relevant for understanding and maintaining older code.