SAP provides a number of standard classes (and methods) for updating records in infotypes. Learn the detailed steps required to create new records in an infotype, delete a record, and change fields of an already-existing infotype record.
Key Concept
Casting allows you to carry out assignments between two reference variables. Once the assignment is successful, the destination variable points to the same object pointed to by the source reference variable. The special casting operator ?= is used when the static type of the source variable is more general than the type of the destination variable.
In addition to reading data from employee infotypes, developers often need to offer the option of updating data in standard and custom infotypes. A number of techniques exist for doing so. These include obsolete techniques such as using Batch Data Communication (BDC) sessions as well as function modules, such as HR_INFOTYPE_OPERATION, that are not released for custom use. A more elegant and recommended approach is to use the standard classes provided by SAP to meet such requirements. This can be easily used by SAP ERP HCM developers, so having knowledge of these classes is absolutely essential.
I start with a brief introduction of the standard classes and methods that SAP provides for changing infotype data in custom programs, and then discuss the detailed steps required to insert records in an infotype. Next, I explain how you can use the standard methods to delete a single infotype record. Finally, I show how to modify an existing record in an infotype. Throughout the article, I use infotype 0006 (Addresses) as my example.
In my previous HR Expert article about infotypes, “How to Read Infotype Data Using Standard Classes and Methods,” I covered how to read data and infotype texts for an employee infotype. In this second installment, I show you how to update data in infotypes. This includes creating, deleting, and modifying an existing record in an infotype.
Note
The primary audience for this article is SAP HR developers and users. I provide coding examples and necessary screenprints to illustrate my points. Readers can easily adapt the coding examples used in this article to suit their requirements.
An Overview of the Classes and Interfaces for Updating Infotype Data
Before diving into the details of the programming steps related to infotype data access, let’s take a look at the classes and methods used for this purpose. In this section, I discuss the main classes and methods needed to change data residing in infotypes. These classes let you read the data from both standard and custom-developed infotypes. Later in this article, I discuss the coding required to use these classes to update infotype data.
One of the most important classes used in the writing process is class CL_HRPA_MASTERDATA_BL. This class provides an important factory method, GET_INSTANCE, which returns a reference to the class CL_HRPA_MASTERDATA_BL. The class is based on the IF_HRPA_MASTERDATA_BL interface, which is one of the most important interfaces used. The necessary methods of this interface and their purposes are shown in Table 1.
Method name |
Purpose |
READ |
Reads a set of records from an infotype table. For the DELETE and MODIFY methods, you first need to fetch the corresponding record. |
INSERT |
Inserts a record into an infotype |
DELETE |
Deletes an infotype record |
MODIFY |
Modifies an infotype record |
Table 1
The methods of the IF_HRPA_MASTERDATA_BL interface
In addition, SAP provides two important methods, ENQUEUE_BY_PERNR and DEQUEUE_BY_PERNR, residing in class CL_HRPA_MASTERDATA_ENQ_DEQ, used for locking and unlocking employees, respectively. For each operation (e.g., delete, insert, and modify), it is necessary to enclose the code between the ENQUEUE and DEQUEUE method calls.
Note
Any dynamic actions associated with the infotype that is being updated are not executed automatically by programs that use the steps mentioned in this article. You must program the dynamic actions to be executed manually. In addition, any custom-specific validation checks written in a function exit for enhancement PBAS0001 are not called when the methods mentioned are called.
How to Insert New Records in Infotypes
In this section, I show how to use the standard classes and methods to create new records for an infotype. As an example, I show how to create a record in infotype 0006 (Addresses) for employee number 1006 for the Permanent Address (subtype 1).
Step 1. Define Infotype Structures and Assign Data Values
The first step is to define a structure (in this case, WA_P0006) based on the Dictionary structure P0006. Figure 1 shows the definition of structure WA_P0006.
data wa_p0006 type p0006.
Figure 1
Define the infotype structure
Next, assign appropriate values to the fields of structure WA_P0006 (Figure 2). You must ensure that all the required fields for the infotype are specified in this block of code. (Make sure the wa_p0006-infty field is assigned the number of the infotype you are dealing with, in this case, 0006.)
data wa_p0006 type p0006.
Figure 2
Assign values to structure WA_P0006
Step 2. Lock the Employee’s Record
The next step is to call the ENQUEUE _BY_PERNR method to lock the employee’s record whose data has to be created. Before that can occur, you need to define a message handler object to generate the messages that result from the lock method call.
Define a reference (MESSAGE_HANDLER_OBJ) for the class (CL_HRPA_MESSAGE_LIST) and create its object using the CREATE OBJECT method (Figure 3).
data message_handler_obj type ref to cl_hrpa_message_list.
create object message_handler_obj.
Figure 3
Define and create a message handler
Now you ready to lock the given employee’s record. Call the static method ENQUEUE_BY_PERNR of the class CL_HRPA_MASTERDATA_ENQ_DEQ. Then you must specify the number of the employee to be locked via the PERNR parameter, and also pass the MESSAGE_HANDLER_OBJ object as a parameter (Figure 4).
data: is_ok type xfeld.
cl_hrpa_masterdata_enq_deq=>enqueue_by_pernr(
exporting
tclas = 'A'
pernr = wa_p0006-pernr
message_handler = message_handler_obj
importing
is_ok = is_ok ).
Figure 4
Lock the employee’s record
If the employee’s record is successfully locked, the variable IS_OK contains the value 'X' after the method call (otherwise it contains a blank space). If the personnel number is already locked, IS_OK contains a blank space.
Step 3. Call the Business Logic
Once the employee’s record is successfully locked, you can call the GET_INSTANCE static method of the CL_HRPA_MASTERDATA_BL class (Figure 5).
data lr_masterdata_bl type ref to if_hrpa_masterdata_bl.
cl_hrpa_masterdata_bl=>get_instance(
importing masterdata_bl = lr_masterdata_bl ).
Figure 5
Call the business logic method
This method call returns a reference to the class CL_HRPA_MASTERDATA_BL.
Step 4. Call the GET_INFTY_CONTAINER Method
Next, you call the GET_INFTY_CONTAINER method of the IF_HRPA_MASTERDATA_BL interface using the reference to the given interface LR_MASTERDATA_BL. You pass, as parameters, the TCLAS (in this case 'A' – Employee). Most importantly, you need to pass parameter PSKEY (which corresponds to the key of the record to be inserted).
The same MESSAGE_HANDLER_OBJ object that was used earlier is now used for any message generated as a result of the execution of the method. If there are any problems with the method, the IS_OK parameter contains a value space; otherwise, it contains 'X'. The code for this is shown in Figure 6.
data lr_container type ref to if_hrpa_infty_container.
lr_masterdata_bl->get_infty_container(
exporting
tclas = 'A'
pskey = wa_p0006-pskey
no_auth_check = 'X'
message_handler = message_handler_obj
importing
container = lr_container
is_ok = is_ok ).
Figure 6
Call the GET_INFTY_CONTAINER method
LR_CONTAINER is an internal table that acts as temporary storage. This is where you first store the data that is later inserted into the infotype table. Once the data is stored in LR_CONTAINER, the insert is performed via the INSERT method (details about this are covered in the next step).
Note
You must ensure that the provided key is the same one that was used for retrieving the infotype container in step 3. In this case, I filled the fields of the key as shown in Figure 2. If this is not done, a short dump occurs.
Step 5. Assign Data Values to a Container
In this step you specify the complete set of values for each field of the infotype record that is being created. The container does not have any method to perform such an operation. Rather, the required MODIFY_PRIMARY_RECORD method belongs to the interface IF_HRPA_INFTY_CONTAINER_DATA. Therefore, down-cast the container to one using the IF_HRPA_INFTY_CONTAINER_DATA interface (Figure 7).
data lr_container_data type ref to if_hrpa_infty_container_data.
if is_ok is not initial.
lr_container_data ?= lr_container.
"downcasting to IF_HRPA_INFTY_CONTINER_DATA
lr_container ?= lr_container_data->modify_primary_record( wa_p0006 ) .
endif.
Figure 7
Fill the container with the necessary data
Note
There are two forms of typecasting. When the static type of the source variable is more general than the static type of the destination variable, it is known as downcasting. On the other hand, upcasting occurs when the static type of the source reference variable is more specific than, or the same as, the static type of the destination variable. The special casting operator ?= can be used in both cases. For more information about casting, refer to this SAP Help link:
https://help.sap.com/abapdocu_750/en/abapmove_cast.htm.
Table LR_CONTAINER is required in the next step, so typecast the container again into the LR_CONTAINER table.
Step 6. Call the INSERT Method
The next step is to insert the data held in the container into the actual infotype table (in this case, PA0006) using the INSERT method (Figure 8).
lr_masterdata_bl->insert(
exporting
no_auth_check = space
message_handler = message_handler_obj
importing
is_ok = is_ok
changing
container = lr_container ).
Figure 8
Call the INSERT method
Any error and warning messages generated as a result executing the method are returned in the LR_MESSAGE_HANDLER object. If the INSERT method is executed successfully, the variable L_OK has a value space; otherwise, it has a value equal to 'X'.
Step 7. Commit Changes to the Database
To commit (update) the changes to the database (actually in the infotype table), you need to call the FLUSH method of the interface using the reference variable LR_MASTER_DATA_BL (Figure 9).
if is_ok is not initial.
lr_masterdata_bl->flush(
exporting
no_commit = space ).
endif.
Figure 9
Call the FLUSH method
Here you pass a space as the value for the NO_COMMIT parameter.
Once the changes are done and committed to the database you need to call the static method DEQUEUE_BY_PERNR of the CL_HRPA_MASTERDATA_ENQ_DEQ class. Here you pass the employee number as a parameter (Figure 10).
cl_hrpa_masterdata_enq_deq=>dequeue_by_pernr(
exporting
tclas = 'A'
pernr = wa_p0006-pernr ).
Figure 10
Unlock the given employee's records
The complete code listing for the insertion is shown in Figure 11.
data wa_p0006 type p0006.
data message_handler_obj type ref to cl_hrpa_message_list.
create object message_handler_obj.
data: is_ok type xfeld.
cl_hrpa_masterdata_enq_deq=>enqueue_by_pernr(
exporting
tclas = 'A'
pernr = wa_p0006-pernr
message_handler = message_handler_obj
importing
is_ok = is_ok ).
check is_ok eq 'X'.
data lr_masterdata_bl type ref to if_hrpa_masterdata_bl.
cl_hrpa_masterdata_bl=>get_instance(
importing masterdata_bl = lr_masterdata_bl ).
data lr_container type ref to if_hrpa_infty_container.
lr_masterdata_bl->get_infty_container(
exporting
tclas = 'A'
pskey = wa_p0006-pskey
no_auth_check = 'X'
message_handler = message_handler_obj
importing
container = lr_container
is_ok = is_ok ).
check is_ok eq 'X'.
data lr_container_data type ref to if_hrpa_infty_container_data.
if is_ok is not initial.
lr_container_data ?= lr_container.
"downcasting to IF_HRPA_INFTY_CONTINER_DATA
lr_container ?= lr_container_data->modify_primary_record( wa_p0006 ) .
endif.
lr_masterdata_bl->insert(
exporting
no_auth_check = space
message_handler = message_handler_obj
importing
is_ok = is_ok
changing
container = lr_container ).
if is_ok is not initial.
lr_masterdata_bl->flush(
exporting
no_commit = space ).
endif.
cl_hrpa_masterdata_enq_deq=>dequeue_by_pernr(
exporting
tclas = 'A'
pernr = wa_p0006-pernr ).
Figure 11
The complete code for insertion
Once the program is executed, you can create a new record as shown in Figure 12.

Figure 12
A new record is created
How to Delete Records from an Infotype
In this section, I show how to delete records from a standard infotype. The benefit of this method is that all the necessary standard checks are carried out while performing the delete operation.
Note
For simplicity’s sake, I show how to delete a single record. This code can be adapted to suit your users’ requirements. In addition, the steps for locking and unlocking employee records (described in the previous section) are necessary, but have been omitted from this section. Refer back to the first section for details about how to do this.
In this example, I am using the record created previously in infotype 006, as shown in Figure 12.
Step 1. Call the GET_INSTANCE Method
First, declare a reference variable pertaining to the interface IF_HRPA_MASTERDATA_BL. Then call the static method GET_INSTANCE of the class CL_HRPA_MASTERDATA. The returned reference (containing the instance of the business logic) is stored in the reference variable A_MASTERDATA_BL. This reference variable is used later to call the delete method for deleting the relevant row from the infotype. The code is shown in Figure 13.
"Step 1
DATA a_masterdata_bl TYPE REF TO if_hrpa_masterdata_bl.
cl_hrpa_masterdata_bl=>get_instance(
IMPORTING masterdata_bl = a_masterdata_bl ).
Figure 13
Call the GET_INSTANCE method
Step 2. Declare a Message Handler
Next, declare a reference to the class CL_HRPA_MESSAGE_LIST. You also create a MESSAGE_HANDLER object using the CREATE OBJECT statement (Figure 14).
"Step 2
DATA message_handler TYPE REF TO cl_hrpa_message_list.
create object message_handler.
Figure 14
The message handler declaration
Step 3. Call the READ Method
Here you declare a CONTAINER_TAB internal table (based on Dictionary type HRPAD_INFTY_CONTAINER_TAB). Then, call the READ method of the interface IF_HRPA_MASTERDATA_BL (Figure 15). This method allows you to read the infotype record to be deleted. The data read is returned in the CONTAINER_TAB internal table that you already declared. The method has a number of parameters that allow you to specify the criteria for reading data from the infotype.
" Step 3
DATA container_tab TYPE hrpad_infty_container_tab.
a_masterdata_bl->read(
exporting
tclas = 'A'
pernr = '1006'
infty = '0006'
subty = '1'
objps = ' '
sprps = ' '
mode = '4'
seqnr = '000'
begda = '20160101'
endda = '99991231'
no_auth_check = ' '
message_handler = message_handler
importing
container_tab = container_tab ).
Figure 15
Call the READ method
As you can see in the code in Figure 15, the infotype 0006 row for employee 1006 has subtype 1 (Permanent Address), with start and end dates of 01.01.2016 and 31.12.9999, respectively. The most important parameter is MODE, the value of which (in this case, 4) allows you to read the single record matching the supplied values.
Note
In the example code, I have supplied a value of 4 for the MODE parameter in the READ method call. The MODE parameter may be passed a number of values in addition to the value 4. Check the other permissible values that correspond to the parameter via the method signature to see if they may better suit your requirements.
Any messages generated as a result of the method call are returned via the variable MESSAGE_HANDLER. After the method is executed, the data read is contained in the container tab CONTAINER_TAB.
Step 4. Fetch Specific Container Rows for Deletion
For this step, you need to know which specific row within the CONTAINER_TAB internal table corresponds to the infotype record to be deleted. A field symbol <fs> is defined for pointing to this line in the internal table CONTAINER_TAB (Figure 16). The READ TABLE statement is then used to assign its reference to the field symbol <fs>. (For simplicity’s sake, let’s assume that the row to be deleted is the first row of the container table.)
" Step 4
FIELD-SYMBOLS <fs> LIKE LINE OF container_tab.
READ TABLE container_tab INDEX 1 ASSIGNING <fs>.
Figure 16
Get a single container record
Step 5. Call the Delete Method
If the read is successful, the CHECK statement for SY-SUBRC allows the program to proceed. Then call the DELETE method of the interface IF_HRPA_ MASTERDATA_BL to delete the relevant infotype row. The row indicated by the field symbol <fs> is supplied for the formal parameter CONTAINER of the DELETE method (Figure 17).
"Step 5
CHECK sy-subrc EQ 0.
DATA is_ok TYPE boole_d.
a_masterdata_bl->delete(
EXPORTING
container = <fs>
no_auth_check = ' '
message_handler = message_handler
IMPORTING
is_ok = is_ok ).
Figure 17
Call the DELETE method
Step 6. Call the Flush Method to Commit Changes to the Database
Next, check the value of the IS_OK variable. If the DELETE method was successful, the value of IS_OK becomes 'X'. In this case, the FLUSH method is called to commit the changes to the database. The NO_COMMIT parameter is supplied with the value SPACE (Figure 18).
" Step 6
data messages_tab type hrpad_message_tab.
IF is_ok IS INITIAL.
message_handler->get_message_list(
importing
messages = messages_tab ).
ELSE.
a_masterdata_bl->flush(
EXPORTING
no_commit = space ).
ENDIF.
Figure 18
Call the FLUSH method
If the deletion attempt is unsuccessful, use the GET_MESSAGE_LIST method (of the class CL_HRPA_MESSAGE_LIST) with the reference variable MESSAGE_HANDLER to read the messages generated as a result of the unsuccessful attempt. The messages are returned in the MESSAGES_TAB internal table declared earlier in this step.
Once the code is executed, it deletes the record for employee 1006, subtype 1 with BEGDA and ENDDA equal to 01.01.2016 and 31.12.9999, respectively, from the database.
How to Update Infotype Records
In this section, I show how to change records of a standard infotype. As an example, I change the Street (STRAS field) of the infotype record created in the Insert section. Here are the steps in detail.
Steps 1–3. Call the GET_INSTANCE Method, Create the Message Handler, and Call the READ Method
The first three steps are the same as shown previously in the previous section of this article. Declare a reference variable pertaining to the interface IF_HRPA_MASTERDATA_BL, and call the static method GET_INSTANCE of the class CL_HRPA_MASTERDATA. Then declare an internal table CONTAINER_TAB (based on Dictionary type HRPAD_INFTY_CONTAINER_TAB). You also declare a reference to the class CL_HRPA_MESSAGE_LIST. Then create an object MESSAGE_HANDLER using the CREATE OBJECT statement.
Next, you call the READ method for the interface IF_HRPA_MASTERDATA_BL. This method allows you to read the record that is to be changed. The read data is returned in the CONTAINER_TAB you declared earlier. The code written so far is shown in Figure 19.
"Step 2
DATA message_handler TYPE REF TO cl_hrpa_message_list.
create object message_handler.
DATA container_tab TYPE hrpad_infty_container_tab.
" Step 3
a_masterdata_bl->read(
EXPORTING
tclas = 'A'
pernr = '1006'
infty = '0006'
subty = '1'
objps = ' '
sprps = ' '
mode = '4'
seqnr = '000'
begda = '20160101'
endda = '99991231'
no_auth_check = ' '
message_handler = message_handler
IMPORTING
container_tab = container_tab ).
Figure 19
The first three steps for the program to change the infotype
As you can see, the row of the infotype 0006 for employee 1006 has subtype 1, with start and end dates of 01.01.2016 and 31.12.9999, respectively. Any messages generated as a result of the method call are returned via the variable MESSAGE_HANDLER. After the method is executed, the data read is contained in the container tab CONTAINER_TAB.
Step 4. Find Specific Rows to be Changed
Next, you need to know which specific row within the internal table CONTAINER_TAB corresponds to the infotype record to be deleted. A field symbol <fs> is defined for pointing to this line in CONTAINER_TAB (Figure 20). The READ TABLE statement is then used to assign its reference to the field symbol <fs>.
" Step 4
FIELD-SYMBOLS <fs> LIKE LINE OF container_tab.
READ TABLE container_tab INDEX 1 ASSIGNING <fs>.
Figure 20
Read the first line of CONTAINER_TAB
If the read is successful, the CHECK statement for SY-SUBRC allows the program to proceed.
Step 5. Get the Existing Infotype Row and Specify the Fields to be Changed
Before calling the MODIFY method, you need two container references. The first reference must point to the original container (containing the existing infotype record) and the second must refer to the container of the record representing what the record looks after the change has been made.
The field symbol <fs> points to the existing container record. Using this, form the container for the changed record, the reference of which is stored in the CHANGED_RECORD_DATA variable. Define two references, LR_CONTAINER_DATA and CHANGED_RECORD_DATA, to the interfaces IF_HRPA_INFTY_CONTAINER_DATA and IF_HRPA_INFTY_CONTAINER, respectively.
"Step 5 (a)
CHECK sy-subrc EQ 0.
DATA is_ok TYPE boole_d.
data lr_container_data type ref to if_hrpa_infty_container_data.
data changed_record_data type ref to if_hrpa_infty_container.
lr_container_data ?= <fs>.
Figure 21
Get the existing record's container
Assign the field symbol <fs> to the LR_CONTAINER_DATA variable.
To get the contents of the currently stored record in the infotype, call the PRIMARY_RECORD_REF method using the LR_CONTAINER_DATA variable (Figure 22). The retrieved row is stored in WA_P0006.
"Step 5 (b)
data wa_p0006 type ref to data .
lr_container_data->primary_record_ref(
importing pnnnn_ref = wa_p0006 )
Figure 22
Get the existing infotype record
Next, change the value of the STRAS field of this structure to 'Salwa Road' using field symbol <fs1> and the ASSIGN statement.
Then call the MODIFY_PRIMARY_RECORD method for the LR_CONTAINER_DATA variable and assign the returned CHANGED_RECORD_DATA container reference. Now the CHANGED_RECORD_DATA reference points to the container corresponding to the infotype 6 record for which 'Salwa Road' is stored in the STRAS field (Figure 23).
"Step 5 (c)
field-symbols <fs1> type p0006.
assign wa_p0006->* to <fs1>.
<fs1>-stras = 'Salwa Road'.
changed_record_data ?=
lr_container_data->modify_primary_record(<fs1>).
Figure 23
Specify the fields to be changed
Finally, the MODIFY method is called (Figure 24). It is passed appropriate values pertaining to parameters OLD_CONTAINER (current values) and CONTAINER (modified values).
"Step 5 (d)
a_masterdata_bl->modify(
exporting
old_container = <fs>
no_auth_check = ' '
message_handler = message_handler
importing
is_ok = is_ok
changing
container = changed_record_data ).
Figure 24
Call the MODIFY method
Check the value of the IS_OK variable. If the MODIFY method was successful, the value of IS_OK becomes X. In this case, the FLUSH method is called to commit the changes to the database. Then supply the NO_COMMIT parameter with the value SPACE (Figure 25).
" Step 6
data messages_tab type hrpad_message_tab.
IF is_ok IS INITIAL.
message_handler->get_message_list(
importing
messages = messages_tab ).
ELSE.
a_masterdata_bl->flush(
EXPORTING
no_commit = space ).
ENDIF.
Figure 25
Call the FLUSH method
If the attempt is unsuccessful, use the GET_MESSAGE_LIST method (of the class CL_HRPA_MESSAGE_LIST) with the reference variable MESSAGE_HANDLER to read the messages generated as a result of the unsuccessful attempt. The messages are returned in the MESSAGES_TAB internal table declared earlier in this step.
Once the code is executed, it modifies the record for employee 1006, subtype, with BEGDA and ENDDA equal to 01.01.2016 and 31.12.9999, respectively, from the database.
As you can see in Figure 26, the Street and House No field is successfully changed to Salwa Road.

Figure 26
The modified record in infotype 0006
Rehan Zaidi
Rehan Zaidi is a consultant for several international SAP clients (both on-site and remotely) on a wide range of SAP technical and functional requirements, and also provides writing and documentation services for their SAP- and ABAP-related products. He started working with SAP in 1999 and writing about his experiences in 2001. Rehan has written several articles for both SAP Professional Journal and HR Expert, and also has a number of popular SAP- and ABAP-related books to his credit.
You may contact the author at erpdomain@gmail.com.
If you have comments about this article or publication, or would like to submit an article idea, please contact the editor.