ABAP MOVE-CORRESPONDING: Copiar valores por nombres de campo coincidentes entre estructuras/tablas

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

La sentencia MOVE-CORRESPONDING sirve para copiar valores entre dos estructuras o dos tablas internas, considerando solo los componentes (campos) cuyos nombres coinciden exactamente en origen y destino. Los componentes con nombres diferentes o componentes que solo existen en el origen o solo en el destino se ignoran. El requisito previo para la copia es ademas que los tipos de datos de los componentes con el mismo nombre sean compatibles para asignacion.

Sintaxis

1. Entre estructuras

MOVE-CORRESPONDING <estructura_origen> TO <estructura_destino>
[EXPANDING NESTED TABLES]
[KEEPING TARGET LINES]. " Raramente util para estructuras

2. Entre tablas internas

MOVE-CORRESPONDING <tabla_origen> TO <tabla_destino>
[EXPANDING NESTED TABLES]
[KEEPING TARGET LINES].

Adiciones importantes

  • EXPANDING NESTED TABLES: Esta adicion es importante cuando las estructuras o las lineas de las tablas contienen a su vez tablas internas como componentes con el mismo nombre. Con EXPANDING NESTED TABLES, el contenido de estas tablas anidadas con el mismo nombre tambien se copia mediante la logica MOVE-CORRESPONDING (posiblemente de forma recursiva). Sin esta adicion, dichos componentes de tabla generalmente se omiten (excepcion: tipos de referencia).
  • KEEPING TARGET LINES (Principalmente relevante para tablas internas): Evita el borrado estandar de la tabla destino <tabla_destino> antes de la operacion de copia. En su lugar, los valores de las lineas de la <tabla_origen> se transfieren a los campos con el mismo nombre de las lineas ya existentes de la <tabla_destino>. Esto ocurre linea por linea basandose en el indice. Si hay mas lineas en la tabla origen que en la tabla destino, las lineas adicionales del origen se ignoran. Si hay mas lineas en la tabla destino, los valores en los campos correspondientes de las lineas adicionales de destino permanecen sin cambios.
  • PERCENTAGE (Obsoleto): Esta adicion esta obsoleta y no debe usarse.

Funcionamiento

  1. Comparacion de nombres: El sistema identifica todos los componentes en el nivel superior del origen y destino que tienen el mismo nombre. Para tablas, esto se refiere a los componentes de la estructura de linea.
  2. Compatibilidad de tipos: Para cada par de componentes con el mismo nombre, se verifica si sus tipos de datos son compatibles segun las reglas de asignacion ABAP. Una asignacion es posible si los tipos son iguales o se permite una conversion implicita (por ejemplo, C a STRING, I a P). Para estructuras profundas, los tipos de las subestructuras con el mismo nombre tambien deben ser compatibles.
  3. Transferencia de valores: Si los nombres coinciden y los tipos son compatibles, el valor se copia del componente origen al componente destino.
  4. Comportamiento con tablas (Estandar): Cuando se aplica MOVE-CORRESPONDING a tablas internas sin la adicion KEEPING TARGET LINES, ocurre lo siguiente:
    • La tabla destino se vacia implicitamente (CLEAR tabla_destino.).
    • El sistema itera a traves de las lineas de la tabla origen.
    • Para cada linea origen, se crea una nueva linea en la tabla destino, y los valores de los componentes con el mismo nombre y compatibles se copian de la linea origen a la nueva linea destino.
    • La nueva linea destino se agrega a la tabla destino (APPEND).

Alternativa moderna: El operador CORRESPONDING (desde ABAP 7.40)

Para nuevos desarrollos se recomienda encarecidamente usar el operador CORRESPONDING. Es mas flexible, potente y encaja mejor con la sintaxis ABAP moderna.

" Asignacion de estructura
estructura_destino = CORRESPONDING #( estructura_origen ).
" Asignacion de tabla (equivale a MOVE-CORRESPONDING estandar)
tabla_destino = CORRESPONDING #( tabla_origen ).
" Con opciones (ejemplos):
estructura_destino = CORRESPONDING tipo_de_destino( estructura_origen
MAPPING campo_destino = campo_origen " Renombrar
EXCEPT campo_a campo_b ). " Excluir
tabla_destino = CORRESPONDING #( BASE (tabla_destino) tabla_origen ). " Similar a KEEPING TARGET LINES

El operador permite mapeo explicito de campos (MAPPING), exclusion de campos (EXCEPT), uso de una base (BASE para comportamiento similar a KEEPING TARGET LINES) y puede usarse directamente en asignaciones u otras expresiones.

Ejemplos para MOVE-CORRESPONDING

1. Estructura a estructura

TYPES: BEGIN OF type_source,
matnr TYPE matnr, " Numero de material
werks TYPE werks_d, " Centro
menge TYPE i, " Cantidad
extra TYPE string, " Campo adicional origen
END OF type_source.
TYPES: BEGIN OF type_target,
matnr TYPE matnr, " Numero de material (igual)
werks TYPE werks_d, " Centro (igual)
stock TYPE i, " Cantidad (nombre diferente)
info TYPE string, " Campo adicional destino
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 = 'Info origen'.
target_data-stock = 50. " Valor existente en destino
target_data-info = 'Info destino'.
WRITE: / 'Destino ANTES:', target_data-matnr, target_data-werks, target_data-stock, target_data-info.
MOVE-CORRESPONDING source_data TO target_data.
WRITE: / 'Destino DESPUES:', target_data-matnr, target_data-werks, target_data-stock, target_data-info.

Salida:

Destino ANTES: 1000 50 Info destino
Destino DESPUES: MAT01 1000 50 Info destino

(Solo matnr y werks fueron copiados, ya que solo estos nombres coinciden. stock e info en destino permanecen sin cambios, menge y extra del origen fueron ignorados).

2. Tabla a tabla (Estandar)

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. " Linea existente en destino
WRITE: / 'Lineas destino ANTES:', lines( lt_target ).
MOVE-CORRESPONDING lt_source TO lt_target.
WRITE: / 'Lineas destino DESPUES:', lines( lt_target ). " Destino fue vaciado primero, luego llenado
LOOP AT lt_target INTO DATA(ls_target).
WRITE: / '-> Destino F2:', ls_target-f2, ' | Destino F3:', ls_target-f3.
ENDLOOP.

Salida:

Lineas destino ANTES: 1
Lineas destino DESPUES: 2
-> Destino F2: AA | Destino F3: 00000000
-> Destino F2: BB | Destino F3: 00000000

(La tabla destino fue vaciada, luego se agregaron 2 lineas, copiando solo el campo f2).

3. Tabla a tabla con KEEPING TARGET LINES

" ... lt_source y lt_target llenados como en ejemplo 2 ...
WRITE: / 'Lineas destino ANTES (KEEPING):', lines( lt_target ).
MOVE-CORRESPONDING lt_source TO lt_target KEEPING TARGET LINES.
WRITE: / 'Lineas destino DESPUES (KEEPING):', lines( lt_target ). " Cantidad permanece igual
LOOP AT lt_target INTO DATA(ls_target_k).
WRITE: / '-> Destino F2:', ls_target_k-f2, ' | Destino F3:', ls_target_k-f3.
ENDLOOP.

Salida:

Lineas destino ANTES (KEEPING): 1
Lineas destino DESPUES (KEEPING): 1
-> Destino F2: AA | Destino F3: <fecha de ayer>

(La tabla destino conserva su(s) linea(s). Solo para la primera linea se copia f2 de la primera linea del origen. f3 permanece intacto. La segunda linea del origen se ignora, ya que el destino solo tiene una linea).

Notas importantes / Mejores practicas

  • MOVE-CORRESPONDING es util cuando muchos campos coinciden y quieres ahorrar escritura.
  • Riesgo: Puede llevar a resultados inesperados si las coincidencias de nombres no son intencionales o si pierdes la vision general de que campos realmente se copian. Los campos faltantes en el destino no se crean automaticamente.
  • Presta atencion a la compatibilidad de tipos para evitar errores de tiempo de ejecucion o conversiones no deseadas.
  • Con tablas muy grandes, el rendimiento puede ser peor en comparacion con asignaciones especificas o el operador CORRESPONDING.
  • Recomendacion: Usa el operador CORRESPONDING mas flexible y a menudo mas claro para nuevos desarrollos. Sin embargo, MOVE-CORRESPONDING sigue siendo relevante para comprender y mantener codigo antiguo.