La sentencia MODIFY se usa en ABAP para modificar filas existentes en tablas internas. Puede actualizar una sola fila (por indice o clave) o varias filas simultaneamente (con condicion WHERE). Si la fila no existe, MODIFY puede insertarla dependiendo de la variante.
Sintaxis
Existen varias variantes de la sentencia MODIFY:
1. Modificar fila por indice
MODIFY <tabla_interna> FROM <area_trabajo> INDEX <indice> [TRANSPORTING <componente1> <componente2> ...].2. Modificar o insertar fila por clave de tabla
MODIFY TABLE <tabla_interna> FROM <area_trabajo> [TRANSPORTING <componente1> <componente2> ...].3. Modificar multiples filas con condicion WHERE
MODIFY <tabla_interna> FROM <area_trabajo> TRANSPORTING <componente1> [<componente2> ...] WHERE <condicion>.4. Modificar fila actual en LOOP
LOOP AT <tabla_interna> INTO <area_trabajo>. " modificar <area_trabajo> MODIFY <tabla_interna> FROM <area_trabajo>.ENDLOOP.Componentes
<tabla_interna>: La tabla cuyas filas seran modificadas.<area_trabajo>: Una estructura con los nuevos valores. Debe ser compatible con el tipo de linea de la tabla.INDEX <indice>: La posicion de la fila a modificar (solo para tablas standard y sorted).TABLE: Identifica la variante con busqueda por clave. La fila se busca por la clave primaria.TRANSPORTING <componentes>: Limita la modificacion a los componentes especificados. Los otros campos permanecen sin cambios.WHERE <condicion>: Modifica todas las filas que cumplen la condicion.
Campos del sistema
Despues de un MODIFY se establecen los siguientes campos del sistema:
-
sy-subrc:0: Fila(s) modificada(s) con exito (o insertada conMODIFY TABLE).4: No se encontro fila coincidente (conINDEXoTABLE).
-
sy-tabix: Contiene el indice de la fila modificada (para operaciones de fila unica en tablas indexadas).
Funcionamiento segun variante
MODIFY … INDEX
Modifica la fila en la posicion de indice especificada. Todo el contenido del area de trabajo se copia a la fila (excepto con TRANSPORTING).
" Reemplazar completamente fila 3MODIFY lt_data FROM ls_new_data INDEX 3.
" Cambiar solo ciertos campos en fila 3MODIFY lt_data FROM ls_new_data INDEX 3 TRANSPORTING field1 field2.MODIFY TABLE
Busca la fila por la clave primaria en el area de trabajo:
- Encontrada: La fila se actualiza.
- No encontrada: La fila se inserta (como
INSERT).
" Buscar por clave y modificar o insertarMODIFY TABLE lt_customers FROM ls_customer.MODIFY … WHERE
Modifica todas las filas que cumplen la condicion WHERE. TRANSPORTING es obligatorio aqui.
" Modificar todas las filas con status = 'OLD'MODIFY lt_orders FROM ls_update TRANSPORTING status WHERE status = 'OLD'.MODIFY en LOOP (sin INDEX)
Dentro de un LOOP AT ... INTO, MODIFY puede usarse sin INDEX - entonces modifica automaticamente la fila actual.
LOOP AT lt_data INTO ls_data. ls_data-field = 'Nuevo valor'. MODIFY lt_data FROM ls_data.ENDLOOP.Mejor: Usa ASSIGNING en el loop para permitir modificaciones directas sin MODIFY.
Ejemplos
1. Modificar fila por indice
TYPES: BEGIN OF ty_product, id TYPE i, name TYPE string, price TYPE p DECIMALS 2, END OF ty_product.
DATA: lt_products TYPE STANDARD TABLE OF ty_product WITH EMPTY KEY, ls_product TYPE ty_product.
" Llenar tablalt_products = VALUE #( ( id = 1 name = 'Laptop' price = '999.00' ) ( id = 2 name = 'Raton' price = '29.99' ) ( id = 3 name = 'Teclado' price = '79.00' )).
" Reemplazar completamente fila 2ls_product = VALUE #( id = 2 name = 'Raton Gaming' price = '59.99' ).MODIFY lt_products FROM ls_product INDEX 2.
IF sy-subrc = 0. WRITE: / 'Fila 2 modificada.'.ENDIF.2. Cambiar solo ciertos campos (TRANSPORTING)
" Cambiar solo el precio en fila 1ls_product-price = '899.00'.MODIFY lt_products FROM ls_product INDEX 1 TRANSPORTING price.
" Nombre e ID permanecen sin cambios" Ver tambien: /es/blog/read-table-statement/READ TABLE lt_products INTO ls_product INDEX 1.WRITE: / 'Producto:', ls_product-name, 'Precio:', ls_product-price." Salida: Laptop 899.003. MODIFY TABLE (basado en clave)
TYPES: BEGIN OF ty_customer, id TYPE i, name TYPE string, city TYPE string, END OF ty_customer.
DATA: lt_customers TYPE HASHED TABLE OF ty_customer WITH UNIQUE KEY id, ls_customer TYPE ty_customer.
" Llenar tablalt_customers = VALUE #( ( id = 1 name = 'Muller GmbH' city = 'Berlin' ) ( id = 2 name = 'Schmidt AG' city = 'Munich' )).
" Modificar cliente existente (ID 1 existe)ls_customer = VALUE #( id = 1 name = 'Muller & Co. GmbH' city = 'Berlin' ).MODIFY TABLE lt_customers FROM ls_customer.
IF sy-subrc = 0. WRITE: / 'Cliente 1 modificado.'.ENDIF.
" Insertar nuevo cliente (ID 3 no existe)ls_customer = VALUE #( id = 3 name = 'Weber KG' city = 'Hamburgo' ).MODIFY TABLE lt_customers FROM ls_customer.
WRITE: / 'Cantidad de clientes:', lines( lt_customers ). " Salida: 34. Modificar multiples filas con WHERE
TYPES: BEGIN OF ty_order, order_id TYPE i, status TYPE string, amount TYPE p DECIMALS 2, END OF ty_order.
DATA: lt_orders TYPE STANDARD TABLE OF ty_order WITH EMPTY KEY, ls_update TYPE ty_order.
lt_orders = VALUE #( ( order_id = 1 status = 'NUEVO' amount = '100.00' ) ( order_id = 2 status = 'NUEVO' amount = '250.00' ) ( order_id = 3 status = 'ABIERTO' amount = '180.00' ) ( order_id = 4 status = 'NUEVO' amount = '320.00' )).
" Cambiar todos los pedidos con status 'NUEVO' a 'EN_PROCESO'ls_update-status = 'EN_PROCESO'.MODIFY lt_orders FROM ls_update TRANSPORTING status WHERE status = 'NUEVO'.
" Resultado: 3 filas modificadas (order_id 1, 2, 4)LOOP AT lt_orders INTO DATA(ls_order). WRITE: / ls_order-order_id, ls_order-status.ENDLOOP.5. MODIFY en LOOP con INTO
DATA: ls_prod TYPE ty_product.
" Aumentar todos los precios un 10%LOOP AT lt_products INTO ls_prod. ls_prod-price = ls_prod-price * '1.1'. MODIFY lt_products FROM ls_prod.ENDLOOP.6. Mejor alternativa: LOOP con ASSIGNING
FIELD-SYMBOLS: <fs_prod> TYPE ty_product.
" Aumentar todos los precios un 10% - sin MODIFYLOOP AT lt_products ASSIGNING <fs_prod>. <fs_prod>-price = <fs_prod>-price * '1.1'.ENDLOOP.
" Los cambios son efectivos inmediatamente, no se necesita MODIFY!7. MODIFY TABLE con TRANSPORTING
" Cambiar solo la ciudad de un cliente (busqueda por clave)ls_customer-id = 2. " Clave para la busquedals_customer-city = 'Colonia'. " Nuevo valor
MODIFY TABLE lt_customers FROM ls_customer TRANSPORTING city.
IF sy-subrc = 0. WRITE: / 'Ciudad del cliente 2 modificada.'.ENDIF.Comportamiento segun tipo de tabla
| Tipo de tabla | INDEX | TABLE | WHERE |
|---|---|---|---|
| STANDARD TABLE | Si | Si (busqueda lineal) | Si |
| SORTED TABLE | Si | Si (busqueda binaria) | Si |
| HASHED TABLE | No | Si (Hash-Lookup) | Si |
Importante para tablas sorted: Si modificas campos clave, esto puede violar el orden de clasificacion y causar un error de tiempo de ejecucion!
" Peligroso para SORTED TABLE con KEY id:ls_customer-id = 999. " Cambiar campo claveMODIFY TABLE lt_sorted_customers FROM ls_customer. " Puede causar dump!Diferenciacion de otras sentencias
MODIFY vs. ASSIGNING en LOOP
| Aspecto | MODIFY en LOOP | ASSIGNING |
|---|---|---|
| Sintaxis | Mas codigo | Mas compacto |
| Rendimiento | Mas lento (copiado) | Mas rapido (acceso directo) |
| Aplicacion | Codigo legacy | Recomendado |
" Con MODIFY (obsoleto)LOOP AT lt_data INTO ls_data. ls_data-field = 'X'. MODIFY lt_data FROM ls_data.ENDLOOP.
" Con ASSIGNING (recomendado)LOOP AT lt_data ASSIGNING FIELD-SYMBOL(<fs>). <fs>-field = 'X'.ENDLOOP.MODIFY vs. INSERT y APPEND
MODIFY TABLE: Modifica fila existente O inserta nueva (Upsert).INSERT: Solo inserta, falla si la clave existe.APPEND: Siempre agrega al final de una tabla standard.
MODIFY vs. UPDATE (Base de datos)
MODIFY: Para tablas internas (en memoria).UPDATE: Para tablas de base de datos (datos persistentes).
Para buscar una fila antes de modificar, ver READ TABLE.
Consejos de rendimiento
-
ASSIGNING en lugar de MODIFY en LOOP: Evita
LOOP ... INTOconMODIFYposterior. UsaASSIGNINGpara acceso de escritura directo. -
TRANSPORTING para estructuras grandes: Si solo se modifican pocos campos, limita los datos a copiar con
TRANSPORTING. -
WHERE para modificaciones masivas:
MODIFY ... WHEREes mas eficiente que un loop manual con modificaciones individuales. -
No cambiar campos clave: En tablas sorted y hash, los campos clave no deben modificarse. En su lugar: eliminar fila e insertar nueva (ver
APPENDoINSERT).
Notas importantes / Mejores practicas
- Verifica
sy-subrcdespues deMODIFYconINDEXoTABLEpara asegurar que se encontro la fila. - Prefiere
ASSIGNINGenLOOP ATpara modificaciones directas - es mas eficiente y elegante queMODIFY. - Usa
TRANSPORTINGcuando solo ciertos campos deban modificarse. MODIFY TABLEes un “Upsert” - inserta si la fila no existe.- Nunca modifiques campos clave directamente en tablas sorted o hash.
- Con
MODIFY ... WHERE,TRANSPORTINGes obligatorio. - Esta sentencia
MODIFYes para tablas internas. Para tablas de base de datos verINSERT, UPDATE, DELETE.