In this article, we’ll look at how to interact with Business Objects created via ABAP RAP. To do this, we’ll use EML (Entity Manipulation Language), part of the ABAP language, to access RAP BOs.
The code is available on Abapeur’s Github.
In the first part we’ll look at :
- READ: Read data from a Business Object entity
- CREATE : Create a Business Object entity
- UPDATE : Modify a Business Object entity
- DELETE : Delete a business Object entity
In part 2, we’ll look at more advanced notions: CREATE-BY-ASSOTIATION, ACTIONS, etc…
For our example, we’ll use the demo RAP BO provided by SAP on BTP, ABAP Environment: /DMO/I_Travel_M
Example 1 : READ
DATA : lt_keys TYPE TABLE FOR READ IMPORT /DMO/I_Travel_M.
lt_keys = VALUE #( ( %tky-%key-travel_id = '00002772' ) ).
READ ENTITY /DMO/I_Travel_M
ALL FIELDS
WITH CORRESPONDING #( lt_keys )
RESULT data(lt_travel_data_r)
FAILED DATA(lt_failed).
We’ll now read the Business Objects fields, specifying the key fields (here travel_id within %tky). This is one of the travel_ids found in the /dmo/travel_m table:
Generally speaking, I advise you to use %tky whenever possible when working on a BO RAP instance, as it contains all the elements needed to uniquely identify an entity: %key, but also %pid (in the case of late numbering) and %is_draft (in the case of draft scenario).
For further details, see here
By executing in debug mode, we see that the data are recovered:
You might as well read 2 lines in one call:
Example 2 : CREATE
DATA lt_travel_new_data TYPE TABLE FOR CREATE /dmo/i_travel_m.
lt_travel_new_data = VALUE #( ( %cid = '1'
agency_id = '070049'
customer_id = '000072'
begin_date = cl_abap_context_info=>get_system_date( ) + 1
end_date = cl_abap_context_info=>get_system_date( ) + 2
overall_status = 'O'
%control = VALUE #( agency_id = if_abap_behv=>mk-on
customer_id = if_abap_behv=>mk-on
begin_date = if_abap_behv=>mk-on
end_date = if_abap_behv=>mk-on
overall_status = if_abap_behv=>mk-on )
)
( %cid = '2'
agency_id = '070049'
customer_id = '000072'
begin_date = cl_abap_context_info=>get_system_date( ) + 1
end_date = cl_abap_context_info=>get_system_date( ) + 2
overall_status = 'O'
%control = VALUE #( agency_id = if_abap_behv=>mk-on
customer_id = if_abap_behv=>mk-on
begin_date = if_abap_behv=>mk-on
end_date = if_abap_behv=>mk-on
overall_status = if_abap_behv=>mk-on )
) ).
MODIFY ENTITY /dmo/i_travel_m
CREATE FROM lt_travel_new_data
FAILED DATA(lt_failed)
REPORTED DATA(lt_reported)
MAPPED DATA(lt_mapped).
lt_travel_new_data = VALUE #( ( %cid = '1'
agency_id = '070049'
customer_id = '000072'
begin_date = cl_abap_context_info=>get_system_date( ) + 1
end_date = cl_abap_context_info=>get_system_date( ) + 2
overall_status = 'O'
%control = VALUE #( agency_id = if_abap_behv=>mk-on
customer_id = if_abap_behv=>mk-on
begin_date = if_abap_behv=>mk-on
end_date = if_abap_behv=>mk-on
overall_status = if_abap_behv=>mk-on )
) ).
MODIFY ENTITY /dmo/i_travel_m
CREATE FROM lt_travel_new_data
FAILED lt_failed
REPORTED lt_reported
MAPPED lt_mapped.
COMMIT ENTITIES
RESPONSE OF /dmo/i_travel_m
FAILED DATA(failed_commit)
REPORTED DATA(reported_commit).
In this example, we create 3 new entities.
- We specify a %CID: The %CID is used to link the query to the generated keys.
Typically, here we’re in the case of “early numbering”: the key field (travel_id) is determined automatically by the Business Object during creation. In order to know which associated key has been created, in the MAPPED return structure, we’ll find the link between the %CID sent in the query and the generated key.
Let’s imagine that we’re creating several entities at the same time, so we need to have the %CID + associated key link in order to know which values are to be linked to which queries.
Please note:
- In the case of late numbering, keys are only created during the save phase. It is therefore not possible to return the %CIDs + keys link. What’s more, the %CID is only valid in the interaction phase, and will no longer be available in the backup phase.
For this reason, SAP has provided the %PID, which can be used to create a temporary key, also valid during the backup phase. This %PID will be replaced by the real key during the backup phase.
- Unlike %CID, which must be unique in the EML request only. The %PID must be unique for the instance (i.e. as long as the entity has not been saved). Typically, the %PID will also be stored if the BO is in DRAFT).
- Even if we’re not in “early numbering” or “late numbering”, when Behavior Definition is defined in strict( 2 ), then %CID is mandatory in the EML statement to call CREATE ( and CREATE BY, UPDATE, DELETE, actions with EXECUTE ). You might think that since we’re giving the keys directly in the query, we don’t need %CID. However, this ensures that we don’t have to modify all the EML statements if we add a numbering later on in the BO.
- We specify the fields we want in the creation: agency_id, customer_id and begin_date, end_date.
- We specify the fields created in %control to indicate that they must be taken into account during creation.
In this example, I’ll show you that you can create 2 entities with the same %CID, as long as they’re not in the same EML statement
In debug :
- The first 2 entities are correctly created:
- Then the 3rd
- Finally, to complete the interaction phase, we use COMMIT ENTITIES, which will perform the save phase.
Example 3 : UPDATE
DATA lt_travel_data TYPE TABLE FOR UPDATE /dmo/i_travel_m.
lt_travel_data = VALUE #( ( %tky-%key-travel_id = '00002772'
description = 'Vacation'
%control-description = if_abap_behv=>mk-on ) ).
MODIFY ENTITY /dmo/i_travel_m
UPDATE FROM lt_travel_data
FAILED DATA(lt_failed_u)
REPORTED DATA(lt_reported_u).
COMMIT ENTITIES
RESPONSE OF /dmo/i_travel_m
FAILED DATA(failed_commit)
REPORTED DATA(reported_commit).
Here we update the travel_id 00002772 by adding the description “Vacation”.
We specify the updated fields in %control to indicate that they must be taken into account in the update.
Example 4 : CREATE et UPDATE
In this example, I’ll show you how to create and update an entity that hasn’t yet been saved (you create it, then update it straight away without going through a COMMIT in the meantime, so the data created isn’t yet persisted).
- For creation, it’s the same as before
- For update, we use %tky to identify the entity to be modified. This %tky takes the value of the %tky returned in the MAPPED variable by the previous CREATE.
DATA lt_travel_new_data TYPE TABLE FOR CREATE /dmo/i_travel_m.
lt_travel_new_data = VALUE #( ( %cid = '1'
agency_id = '070049'
customer_id = '000072'
begin_date = cl_abap_context_info=>get_system_date( ) + 1
end_date = cl_abap_context_info=>get_system_date( ) + 2
overall_status = 'O'
%control = VALUE #( agency_id = if_abap_behv=>mk-on
customer_id = if_abap_behv=>mk-on
begin_date = if_abap_behv=>mk-on
end_date = if_abap_behv=>mk-on
overall_status = if_abap_behv=>mk-on )
) ).
MODIFY ENTITY /dmo/i_travel_m
CREATE FROM lt_travel_new_data
FAILED DATA(lt_failed)
REPORTED DATA(lt_reported)
MAPPED DATA(lt_mapped).
DATA(ls_mapped) = lt_mapped-travel[ 1 ].
DATA lt_travel_data TYPE TABLE FOR UPDATE /dmo/i_travel_m.
lt_travel_data = VALUE #( ( %tky = ls_mapped-%tky
description = 'Vacation'
%control-description = if_abap_behv=>mk-on ) ).
MODIFY ENTITY /dmo/i_travel_m
UPDATE FROM lt_travel_data
FAILED DATA(lt_failed_u)
REPORTED DATA(lt_reported_u).
COMMIT ENTITIES
RESPONSE OF /dmo/i_travel_m
FAILED DATA(failed_commit)
REPORTED DATA(reported_commit).
Example 5 : DELETE
DATA : lt_keys TYPE TABLE FOR DELETE /DMO/I_Travel_M.
lt_keys = VALUE #( ( %tky-%key-travel_id = '00002772' )
( %tky-%key-travel_id = '00002815' ) ).
MODIFY ENTITY /DMO/I_Travel_M
DELETE FROM lt_keys
FAILED DATA(failed)
REPORTED DATA(reported).
Here, we specify the keys of the entities to be deleted and perform the deletion.
Conclusion
You now know how to use a RAP BO in ABAP using EML. In Part 2, we’ll go into more detail about other EML possibilities.