EML (Entity Manipulation Language) es el lenguaje para acceder a Business Objects en el RESTful ABAP Programming Model (RAP). Proporciona una sintaxis declarativa para operaciones CRUD, acceso a asociaciones y ejecucion de acciones.
Principios basicos
EML opera sobre entidades definidas en Behavior Definitions
Las operaciones siempre son basadas en conjuntos (multiples instancias)
Manejo de transacciones mediante Draft o Direct Save
Manejo de errores integrado mediante estructuras FAILED y REPORTED
Sintaxis basica
READ ENTITIES
READ ENTITIES OF <RootEntity>
[FIELDS ( field1 field2 ... ) | ALL FIELDS]
MODIFY ENTITIES
MODIFY ENTITIES OF <RootEntity>
Ejemplos
1. Leer entidades con campos especificos
DATA : lt_keys TYPE TABLE FOR READ IMPORT zi_salesorder,
lt_result TYPE TABLE FOR READ RESULT zi_salesorder.
( SalesOrderId = '1000000001' )
( SalesOrderId = '1000000002' )
READ ENTITIES OF zi_salesorder
FIELDS ( SalesOrderId CustomerName OrderDate NetAmount )
WITH CORRESPONDING #( lt_keys )
REPORTED DATA (lt_reported).
LOOP AT lt_result INTO DATA (ls_order).
WRITE : / ls_order-SalesOrderId, ls_order-CustomerName, ls_order-NetAmount.
2. Leer todos los campos
READ ENTITIES OF zi_salesorder
WITH VALUE #( ( SalesOrderId = '1000000001' ) )
3. Crear entidades (CREATE)
DATA : lt_create TYPE TABLE FOR CREATE zi_salesorder.
CustomerName = 'Nuevo cliente'
CustomerName = 'Otro cliente'
MODIFY ENTITIES OF zi_salesorder
CREATE SET FIELDS WITH lt_create
REPORTED DATA (lt_reported).
" Verificar claves creadas
LOOP AT lt_mapped-salesorder INTO DATA (ls_mapped).
WRITE : / 'Creado:' , ls_mapped-%cid, '->' , ls_mapped-SalesOrderId.
4. Actualizar entidades (UPDATE)
DATA : lt_update TYPE TABLE FOR UPDATE zi_salesorder.
( SalesOrderId = '1000000001'
%control-CustomerName = if_abap_behv=>mk-on
CustomerName = 'Nombre actualizado' )
( SalesOrderId = '1000000002'
%control-NetAmount = if_abap_behv=>mk-on
MODIFY ENTITIES OF zi_salesorder
UPDATE SET FIELDS WITH lt_update
REPORTED DATA (lt_reported).
IF lt_failed-salesorder IS INITIAL .
WRITE : / 'Actualizacion exitosa' .
5. Eliminar entidades (DELETE)
DATA : lt_delete TYPE TABLE FOR DELETE zi_salesorder.
( SalesOrderId = '1000000001' )
( SalesOrderId = '1000000002' )
MODIFY ENTITIES OF zi_salesorder
REPORTED DATA (lt_reported).
6. Leer asociaciones
" Leer entidad padre con entidades hijas
READ ENTITIES OF zi_salesorder
FIELDS ( ItemNumber MaterialNumber Quantity Price )
WITH VALUE #( ( SalesOrderId = '1000000001' ) )
" lt_link contiene las relaciones
LOOP AT lt_items INTO DATA (ls_item).
WRITE : / ls_item-ItemNumber, ls_item-MaterialNumber, ls_item-Quantity.
7. Crear entidades anidadas (Deep Create)
" Crear pedido con posiciones
MODIFY ENTITIES OF zi_salesorder
CREATE SET FIELDS WITH VALUE #(
CustomerName = 'Nuevo cliente'
MaterialNumber = 'MAT-001'
MaterialNumber = 'MAT-002'
REPORTED DATA (lt_reported).
8. Ejecutar acciones
" Ejecutar accion definida en Behavior Definition
MODIFY ENTITIES OF zi_salesorder
( SalesOrderId = '1000000001' )
( SalesOrderId = '1000000002' )
REPORTED DATA (lt_reported).
9. Accion con parametros
" Accion con parametros de entrada
MODIFY ENTITIES OF zi_salesorder
( SalesOrderId = '1000000001'
%param-NewStatus = 'APPROVED' )
10. Modo local (IN LOCAL MODE)
" Acceder sin verificaciones de autorizacion
READ ENTITIES OF zi_salesorder IN LOCAL MODE
WITH VALUE #( ( SalesOrderId = '1000000001' ) )
11. Multiples operaciones en una sentencia
MODIFY ENTITIES OF zi_salesorder
UPDATE SET FIELDS WITH VALUE #(
( SalesOrderId = '1000000001'
%control-NetAmount = if_abap_behv=>mk-on
" Crear nuevas posiciones
CREATE SET FIELDS WITH VALUE #(
MaterialNumber = 'MAT-003'
( SalesOrderId = '1000000001'
REPORTED DATA (lt_reported).
12. Manejo de errores
MODIFY ENTITIES OF zi_salesorder
UPDATE SET FIELDS WITH lt_update
REPORTED DATA (lt_reported).
IF lt_failed-salesorder IS NOT INITIAL .
LOOP AT lt_failed-salesorder INTO DATA (ls_failed).
WRITE : / 'Fallo para:' , ls_failed-SalesOrderId,
'Razon:' , ls_failed-%fail-cause.
" Procesar mensajes de error
IF lt_reported-salesorder IS NOT INITIAL .
LOOP AT lt_reported-salesorder INTO DATA (ls_reported).
IF ls_reported-%msg IS BOUND .
DATA (lv_text) = ls_reported-%msg->if_message~get_text( ).
WRITE : / 'Mensaje:' , lv_text.
13. Funciones (sin efectos secundarios)
" Llamar funcion definida en Behavior Definition
READ ENTITIES OF zi_salesorder
FROM VALUE #( ( SalesOrderId = '1000000001' ) )
RESULT DATA (lt_availability).
14. Usar %control para actualizaciones parciales
DATA : ls_update TYPE STRUCTURE FOR UPDATE zi_salesorder.
" Solo actualizar campos especificos
SalesOrderId = '1000000001'
CustomerName = 'Nuevo nombre'
" Marcar cuales campos deben actualizarse
CustomerName = if_abap_behv=>mk-on
NetAmount = if_abap_behv=>mk-on
" OrderDate no se actualiza, aunque el valor este establecido
MODIFY ENTITIES OF zi_salesorder
UPDATE FROM VALUE #( ( ls_update ) ).
15. Crear con asociacion (Create by Association)
" Crear posiciones para pedido existente
MODIFY ENTITIES OF zi_salesorder
( SalesOrderId = '1000000001'
MaterialNumber = 'MAT-NEW'
Estructuras EML
Estructura Descripcion TABLE FOR READ IMPORTClaves para operaciones de lectura TABLE FOR READ RESULTResultados de lectura TABLE FOR CREATEDatos para crear TABLE FOR UPDATEDatos para actualizar TABLE FOR DELETEClaves para eliminar TABLE FOR ACTION IMPORTParametros de accion TABLE FOR ACTION RESULTResultados de accion
Valores de %fail-cause
Valor Significado if_abap_behv=>cause-not_foundEntidad no encontrada if_abap_behv=>cause-unauthorizedSin autorizacion if_abap_behv=>cause-lockedBloqueada por otro usuario if_abap_behv=>cause-conflictConflicto de version if_abap_behv=>cause-unspecificError inespecifico
Notas importantes / Mejores practicas
Las sentencias EML son basadas en conjuntos - procesar siempre multiples registros de una vez.
Usar IN LOCAL MODE solo cuando las verificaciones de autorizacion deban omitirse explicitamente.
%cid se usa para referencias en operaciones Create antes de que exista la clave real.
%cid_ref referencia al %cid padre en Deep Creates.
%control controla cuales campos se incluyen en actualizaciones.
Verificar siempre FAILED y REPORTED para manejo de errores.
COMMIT ENTITIES al final de la transaccion (o automaticamente mediante el framework).
EML trabaja con Business Objects - no con tablas de base de datos directamente.
Usar CORRESPONDING #( ) para conversion de tipos entre diferentes estructuras EML.