ABAP CORRESPONDING: Mapear estructuras y tablas

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

El operador CORRESPONDING copia datos entre estructuras o tablas, donde los campos con nombres iguales se mapean automáticamente. Es la alternativa moderna a la instrucción MOVE-CORRESPONDING.

Sintaxis

CORRESPONDING <tipo>(
<fuente>
[ BASE ( <base> ) ]
[ MAPPING <destino1> = <fuente1> ... ]
[ EXCEPT <campo1> <campo2> ... ]
)

Principio básico

Los campos se mapean por nombre:

  • Los campos con el mismo nombre se copian
  • Los campos sin correspondencia permanecen sin cambios (o iniciales)
  • Los tipos diferentes se convierten (si son compatibles)

Ejemplos

1. Mapeo simple de estructuras

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]' ).
" Los campos con nombres iguales se copian
ls_target = CORRESPONDING #( ls_source ).
" ls_target-id = 1
" ls_target-name = 'Max'
" ls_target-address = '' (no presente en fuente)
" email se ignora (no presente en destino)

2. CORRESPONDING vs. MOVE-CORRESPONDING

" Clásico
MOVE-CORRESPONDING ls_source TO ls_target.
" Moderno (funcionalmente equivalente)
ls_target = CORRESPONDING #( ls_source ).
" La diferencia: CORRESPONDING es una expresión
" y puede usarse en otras expresiones
DATA(ls_result) = CORRESPONDING ty_target( ls_source ).

3. BASE – Preservar valores existentes

Sin BASE, los campos no mapeados se establecen al valor inicial:

ls_target = VALUE #( id = 99 name = 'Antiguo' address = 'Madrid' ).
" SIN BASE: address se vuelve inicial
ls_target = CORRESPONDING #( ls_source ).
" ls_target-address = ''
" CON BASE: address se preserva
ls_target = VALUE #( id = 99 name = 'Antiguo' address = 'Madrid' ).
ls_target = CORRESPONDING #( BASE ( ls_target ) ls_source ).
" ls_target-address = 'Madrid'

4. MAPPING – Renombrar campos

Cuando los campos fuente y destino tienen nombres diferentes:

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' ).
" Con MAPPING: Mapear nombres de campos
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 – Excluir campos

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 = 'secreto' email = '[email protected]'
).
" NO copiar password
ls_user_safe = CORRESPONDING #( ls_user_full EXCEPT password ).
" ls_user_safe-password = '' (no copiado)

6. Combinar MAPPING y EXCEPT

TYPES: BEGIN OF ty_order_db,
aufnr TYPE string,
kdnr TYPE string,
datum TYPE d,
internal TYPE string, " Campo interno
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. Transformar tablas

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 = 'Ana' email = '[email protected]' )
( id = 2 name = 'Bruno' email = '[email protected]' )
( id = 3 name = 'Clara' email = '[email protected]' )
).
" Transformar tabla completa
lt_target = CORRESPONDING #( lt_source ).
" Con MAPPING
lt_target = CORRESPONDING #(
lt_source
MAPPING id = id name = name
).

8. DEEP – Estructuras anidadas

Para estructuras anidadas con 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 = 'Calle Principal' city = 'Madrid' )
items = VALUE #( ( `Item1` ) ( `Item2` ) )
).
" DEEP también copia estructuras anidadas y tablas
ls_target = CORRESPONDING #( DEEP ls_source ).

9. CORRESPONDING en parámetros de métodos

METHODS: process_order
IMPORTING is_api_order TYPE ty_order_api.
" Llamada con transformación
process_order(
is_api_order = CORRESPONDING #( ls_db_order
MAPPING order_id = aufnr
customer_id = kdnr
)
).

10. Combinar con VALUE

" Crear estructura y transformar simultáneamente
DATA(ls_output) = VALUE ty_order_api(
BASE CORRESPONDING #( ls_db_order
MAPPING order_id = aufnr
)
" Establecer campos adicionales
status = 'NEW'
).

11. Filtrar y transformar tabla

" Combinar FOR y 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

AspectoCORRESPONDING #()MOVE-CORRESPONDING
TipoExpresión (retorna valor)Instrucción
Usable inlineNo
BASENo (siempre sobrescribe)
MAPPINGNo
EXCEPTNo
DEEPLimitado
RecomendaciónModerno, preferidoLegacy
" MOVE-CORRESPONDING: Solo mapeo simple
MOVE-CORRESPONDING ls_source TO ls_target.
" CORRESPONDING: Flexible y potente
ls_target = CORRESPONDING #(
BASE ( ls_target )
ls_source
MAPPING target_field = source_field
EXCEPT unwanted_field
).

Notas importantes / Mejores prácticas

  • CORRESPONDING #() es una expresión – úsela inline en otras expresiones.
  • Use BASE para preservar valores existentes.
  • MAPPING permite renombrar campos entre estructuras diferentes.
  • EXCEPT excluye campos sensibles o innecesarios.
  • DEEP es necesario para estructuras anidadas y tablas.
  • Combine con VALUE y FOR para transformaciones complejas.
  • Con grandes volúmenes de datos, CORRESPONDING está implementado eficientemente.
  • Tenga cuidado con la compatibilidad de tipos – tipos incompatibles causan errores.
  • Reemplace MOVE-CORRESPONDING por CORRESPONDING #() en código nuevo.