Reading the balance for loans kept in infotype 0045 may be confusing for developers and consultants. This is because loan balances are not stored in the same manner as other fields of infotype 0045. Learn about the loan data storage architecture and the code used to access loan balances to clear up the confusion and avoid mistakes.
Key Concept
Employee loan records reside in infotype 0045. This infotype helps you centrally maintain all information pertaining to a loan, including external repayments. Users may view the loan repayment plans over a certain period in a number of installment amounts. Infotype 0045 is valid for many country codes as well as international country grouping 99. It also provides country-specific features for Great Britain, Belgium, South Africa, Korea, Venezuela, and others.
Entitlement for interest-bearing or interest-free loans is a benefit that many companies provide to their employees — for example, for a house, car, or education. Upon approval of the loan request, an amount is paid to the employee, which is then deducted from the employee’s salary via nominal monthly installments over a certain period of time. Alternately, during any month, the employee may settle (partly or completely) the amount due via external repayments.
SAP HR provides infotype 0045 to store all company loan data pertaining to an employee to help users create entries quickly and easily. Since R/3 Release 4.6, the user enters data only in infotype 0045 and the system handles the relevant data storage for another loan in infotype 0078. Consequently, entries stored in infotype 0078 remain transparent to the user.
This method can cause a problem when users ask for loan balances to be displayed in reports. Users familiar with the infotype O045 screen might be surprised to learn that R/3 does not store loan balances in database tables like other infotype fields. Rather, R/3 computes their value at runtime based on payroll information and data entered on the infotype screen. SAP documentation offers little relevant information to clear up the confusion among HR consultants and ABAP programmers.
Unlike other fields of the infotype, R/3 does not allow you to view loan balances through the Data Browser. You need to use special statements and function modules for accessing them. Moreover, certain exceptional conditions may also apply. In such cases, the balance field of infotype 0045 may also not reflect the correct amount. You need to programmatically adjust the loan balance amount.
I’ll provide an explanation of the steps required to read the loan balance via custom ABAP programs and SAP Query. I will discuss what loan information is stored in payroll and in infotype tables and the way in which R/3 may use it to determine the actual loan balance amount. Using a custom ABAP program, functional analysts who have the appropriate security and authorizations can access the loan balance by following the provided steps.
Loan Data Storage
To better understand the storage mechanism of loan data, you need to understand the set of screens that you may encounter while entering this information. Since Release 4.6, R/3 allows you to enter loan amount and subsequent repayments via infotype 0045. To enter data that pertains to a given loan type, follow these steps:
Step 1. Call transaction PA30. This transaction shows the maintenance screen of employee master data.
Step 2. Enter an employee number. Choose infotype 0045, enter a suitable loan type, and click on the Create button.
Step 3. The system assigns a relevant sequential number to the loan in question. If it is the first loan for an employee of a given loan type, the system assigns a sequence number of 01. Enter a suitable start and end date for the loan.
Step 4. On the Basic data tab, enter the Approval date and Loan amount granted, as shown in Figure 1.

Figure 1
Basic data tab in the employee master data maintenance screen
Step 5. Click on the Conditions tab. Enter the Indiv. interest rate, the loan Repayment start date, and repayment installment amount (Figure 2).

Figure 2
Enter loan conditions
R/3 allows you to specify either a loan period (a beginning and end date) or an installment amount. In the former case, the system calculates the monthly installment amount based on the period specified. Conversely, if you enter an installment amount, the system determines the period and end date.
Step 6. Click on the Payments tab. Enter the date, payment type, and amount paid to the employee, as shown in Figure 3.

Figure 3
Enter loan payment
You may enter any subsequent loan repayments via payroll or externally on the same screen (Figure 4). SAP payroll does not automatically update the payments section, so users must enter data in the payments section.

Figure 4
Enter subsequent loan repayments
To view the repayment schedule for the loan, click on the repayment plan icon or press F8 on the infotype 0045 entry screen. A pop-up window appears (Figure 5).

Figure 5
Repayment plan pop-up window
You may change the parameters — the factors on which the repayment plan is based such as repayment installment and start and end dates. Press Enter and a schedule appears (Figure 6). Once the payments are entered, click on the Save button to save all the entered data.

Figure 6
In the repayment plan, the system deducts the interest due for a particular month from the $1,000 monthly repayment installment
All the data entered on the Payments tab is stored in a separate infotype named loan payments (0078). The background table involved, in this case, is PA0078. A separate row in table PA0078 is allocated for each payment and repayment. Some loan payment types commonly used for storing information in PA0078 are shown in Table 1.
0100 |
Payment to employee (external) |
0200 |
Repayment (external) |
0250 |
Repayment (via payroll) |
|
Table 1 |
Loan payment types and description (infotype 0078) |
The payments and repayments increase and decrease the loan balance, respectively. You can use the Data Browser to view the payments (and repayments) made for a particular loan.
When you create a loan, the loan balance (open amount) field shows a zero balance. R/3 does not update this field until it runs the first payroll (after loan creation). Likewise, the system does not update the balance until executing the next payroll for subsequent payments and repayments entered in infotype 0045.
The loan balance (open amount) is not stored in any database infotype table. Rather, it is the Open amount field (technical name Q0045-OPELO) shown in Figure 1 that you can access via transaction PA30 or PA20. R/3 populates this field when the relevant loan screen is displayed. The system accesses the information of the last payroll run and determines the corresponding loan balance.
Note
The formula for calculating the loan balance at a particular date is: amount paid to employee – amount repaid by employee to date (via salary or externally) + interest due to date = loan balance.
Note
For more information regarding country-specific loan functions, refer to the SAP documentation on infotype 0045.
Access Loan Balance
You read loan balances in reports, custom ABAP programs, and queries differently than for other infotype fields. You access both loan data and repayment plan data via function modules. For more information on repayment plan data, see the sidebar "Repayment Plans." To write the code for accessing loan balances, perform the following steps, which are all necessary to write the code shown in Figure 7.
REPORT Z_READ_LOAN_BALANCE. TABLES : PERNR. INFOTYPES : 0045 , 0078. DATA: ENTIRE_DIRECTORY LIKE PC261 OCCURS 0 WITH HEADER LINE, LAST_DIRECTORY_ROW LIKE ENTIRE_DIRECTORY, LAST_PAYROLL_RESULT TYPE PAY99_RESULT, MOLGA LIKE T500L-MOLGA, CLUSTER_ID LIKE PCL2-RELID, LOAN_BALANCE LIKE PC207-BETRG, LOANTEXT LIKE T591S-STEXT, V0_WA LIKE LINE OF LAST_PAYROLL_RESULT-INTER-V0, RT_WA LIKE LINE OF LAST_PAYROLL_RESULT-INTER-RT, T500L_WA LIKE T500L. START-OF-SELECTION. GET PERNR. CLEAR LOAN_BALANCE. ** START OF SECTION 1 CALL FUNCTION ‘CU_READ_RGDIR’ EXPORTING PERSNR = PERNR-PERNR CHECK_READ_AUTHORITY = SPACE IMPORTING MOLGA = MOLGA TABLES IN_RGDIR = ENTIRE_DIRECTORY EXCEPTIONS OTHERS = 1. ** END OF SECTION 1 IF SY-SUBRC EQ 0. ** START OF SECTION 2 CALL FUNCTION ‘CD_READ_LAST_RESULT_IN_RGDIR’ IMPORTING PTX_RGDIR_NV = LAST_DIRECTORY_ROW TABLES PT_RGDIR = ENTIRE_DIRECTORY. ** END OF SECTION 2 ** START OF SECTION 3 CLEAR T500L_WA. SELECT SINGLE * FROM T500L INTO T500L_WA WHERE MOLGA = MOLGA. MOVE T500L_WA-RELID TO CLUSTER_ID. ** END OF SECTION 3 ** START OF SECTION 4 CALL FUNCTION ‘PYXX_READ_PAYROLL_RESULT’ EXPORTING CLUSTERID = CLUSTER_ID EMPLOYEENUMBER = PERNR-PERNR SEQUENCENUMBER = LAST_DIRECTORY_ROW-SEQNR READ_ONLY_INTERNATIONAL = ‘X’ CHECK_READ_AUTHORITY = ‘ ‘ CHANGING PAYROLL_RESULT = LAST_PAYROLL_RESULT EXCEPTIONS OTHERS = 1. ** END OF SECTION 4 IF SY-SUBRC EQ 0. ** START OF SECTION 5 LOOP AT P0045. LOOP AT LAST_PAYROLL_RESULT-INTER-V0 INTO V0_WA WHERE V0TYP = ‘L’. IF P0045-DLART = V0_WA-VINFO+0(4) AND P0045-OBJPS = V0_WA-VINFO+4(2). LOOP AT LAST_PAYROLL_RESULT-INTER-RT INTO RT_WA WHERE V0TYP = ‘L’ AND V0ZNR = V0_WA-V0ZNR AND LGART = ‘/LLB’. LOAN_BALANCE = RT_WA-BETRG. SELECT SINGLE STEXT INTO LOANTEXT FROM T591S WHERE SPRSL EQ SY-LANGU AND INFTY EQ ‘0045’ AND SUBTY EQ P0045-DLART. ENDLOOP. ENDIF. ENDLOOP. ENDLOOP. ** END OF SECTION 5 ENDIF. ENDIF. END-OF-SELECTION.
|
Figure 7 |
COMPLETE LISTING code |
Step 1. Create a custom program with transaction SE38. Name your program appropriately, such as Z_READ_LOAN_BALANCE, and click on the Create button. This brings you to the Attributes screen. Enter a description and other relevant entries as shown in Figure 8 and enter PNP
as the logical database. Save your program.

This takes you to a screen where you can enter code that allows you to add the COMPLETE LISTING code in Figure 7.
Step 2. Access the data from the last payroll run. You must retrieve the latest payroll result of the employee in question. This involves the use of a number of standard function modules.
First, you need to read the payroll (entire) results directory of an employee. You do this via the function module CU_READ_RGDIR, as shown in section 1 of Figure 7. This method returns the payroll directory and the country grouping of the employee in the internal table ENTIRE_DIRECTORY and the variable MOLGA, respectively.
Since you need the results from the latest payroll, you must access the last entry (row) of the payroll directory (in this case, internal table ENTIRE_DIRECTORY). Use function module CD_READ_LAST_RESULT_IN_RGDIR, shown in section 2 of Figure 7.
To access the payroll details, you need to know the cluster ID of table PCL2 in which your results reside. The ID may be read from database table T500L for your country grouping (MOLGA). The SELECT statement in section 3 of Figure 7 returns the cluster ID for the given country grouping.
Once you access the latest directory row and the cluster ID, you may easily read the recent payroll information via function module PYXX_READ_PAYROLL_RESULT, as shown in section 4 of Figure 7. This function module populates the internal table LAST_PAYROLL_RESULT with the payroll information from the last payroll run.
Step 3. Gather the relevant loan information from the payroll results. R/3 stores data pertaining to loans in payroll information in two internal tables: variable assignment (V0) and results (RT), shown in Figure 9.

R/3 stores the loan balance in field BETRG of table RT against wage type /LLB. However, you may not access it directly. For each payroll, the system assigns a certain number to each loan type (e.g., 01, 02), which is stored in field V0ZNR. This loan number is linked to an entry residing in the variable assignment table (V0).
In my example, an employee has taken two loans from the company: a car loan (ZCAR) and a loan for a child’s private school tuition (ZCHI) for the second and third time, respectively. This information is stored in field VINFO of the table V0. The system assigns an appropriate number to each loan, 02 and 03 in this case.
Table RT stores the corresponding balance of each loan against wage type /LLB and the loan’s number (01, etc.) in a similar field, also named V0ZNR. To retrieve the balance (/LLB) from the RT table, you need to programmatically determine the V0ZNR number of the loan that you are interested in from table V0.
In the code that reads the balance in section 5 of Figure 7, I assume that the P0045 row has the header of the loan type for which the balance is to be determined. This code reads the row of table V0 that matches the loan type and sequential number of the loan in question via a LOOP
statement. This row contains the field V0ZNR of the given loan in the current payroll. An inner loop then reads the record in table RT with the wage type equaling /LLB and field V0ZNR equaling that of table V0. Finally, variable LOAN_BALANCE stores the loan balance.
Note
To access loan balance data via a custom ABAP program, you have the option of using the logical database PNP, depending on the scenario and requirements. Although it is not always necessary, logical database PNP is used many times in queries and custom ABAP programs because it offers features such as providing a selection screen and authorization checks as well as minimizing code. My example uses PNP, but the code I’ll provide works with or without it.
For simplicity’s sake, I have ignored the impact of any accrued interest. If you need to take the effect of interest, you need to explicitly adjust them via coding.
Exceptions
As already mentioned, the system reads the balance from the most recent payroll. This is applicable in most cases. However, in some exceptional circumstances, this strategy may not suffice. You need to make programming provisions in such cases.
One example is when a month’s payroll has not been run and an external repayment exists for the current month. In this case, the payroll result would reflect the balance of the previous month not including the effect of any external repayments occurring within the current month. In other words, the loan balance would be overstated. You need to explicitly read any information residing in PA0078 that pertains to repayments for the current month. The code that deals with this exception is shown in Figure 10.
…………… LOOP AT P0078 WHERE ZAHLA EQ ‘0200’ AND DLART EQ P0045-DLART AND OBJID EQ P0045-OBJPS AND BEGDA LE PAYROLL_END AND ENDDA GE PAYROLL_START. LOAN_BALANCE = LOAN_BALANCE - P0078-BETRG. ENDLOOP.
|
Figure 10 |
Code for when a month’s payroll has not been run and an external repayment exists for the current month |
This fragment may be inserted at the end of the previously written code, assuming that the start and end dates of the current payroll month are stored in PAYROLL_START and PAYROLL_END, respectively.
Another exception is when no payroll results exist for an employee, but that employee has taken a loan. In this case, you need to manually determine the loan balance by taking into account the loan payment amount and any external repayments that exist in table PA0078. The code that deals with the requirement is shown in Figure 11.
…………… CLEAR LOAN_BALANCE. LOOP AT P0078 WHERE DLART EQ P0045-DLART AND OBJID EQ P0045-OBJPS. IF P0078-ZAHLA EQ ‘0100’ . LOAN_BALANCE = LOAN_BALANCE + P0078-BETRG. ELSEIF P0078-ZAHLA EQ ‘0200’. LOAN_BALANCE = LOAN_BALANCE – P0078-BETRG. ENDIF. ENDLOOP.
|
Figure 11 |
Code for when an employee with no payroll results takes out a loan |
In this case, the system reads all records of the loan in question from infotype 0078. If a payment is found, R/3 increments the loan balance. The system decreases the loan balance if it encounters an external repayment.
Mostly users require the current loan balance. However, in some cases, your users may ask for the loan balance to be displayed at some past point in time. In this case, you need to vary the code slightly to access the loan balance at a previous date.
You must replace the code in section 2 of Figure 7 that calls function module CD_READ_LAST_RESULT_IN_RGDIR with a loop statement.
If the system stores the date at which the loan balance is to be determined in variable PREVIOUS_DATE, the loop would be as follows:
LOOP AT ENTIRE_DIRECTORY WHERE
FPBEG LE PREVIOUS_DATE AND
FPEND GE PREVIOUS_DATE.
ENDLOOP.
This reads the payroll directory row and loan balance at a previous date.
The code (and exception handling) may also be used in SAP Query for determining the balance amount of a particular loan type. As I showed in the “Retrieve Infotype Text in SAP Query” section of my infotype text article “Use Clusters to Access Infotype Texts,” this involves the creation of an additional field and then writing the code in the additional field code.
Troubleshooting Tips
If you try to access the balance of a loan and the system displays the wrong amount, you need to check whether R/3 is correctly executing the code and accessing the relevant month’s payroll results. Proceed as follows:
Step 1. Call transaction SE38. Type the name of the program created (in my example it is Z_READ_LOAN_BALANCE) in the Program field and click on Display. In case of a query, access the code of the additional field via the available editor.
Step 2. Place the cursor on the line that calls the function CU_READ_RGDIR. Set a breakpoint by clicking on the stop icon. Alternately, particularly in SAP Query, you may also write the statement BREAK
followed by the user name before the function call for example, BREAK JOHN
).
Step 3. Execute the custom program or query. The program stops in the debugging mode if you’ve set a breakpoint, as mentioned in step 2.
Step 4. Execute each line of the program by pressing F5. This allows you to monitor the values of the variables involved in the loan balance computation, thus helping you track the cause of the error.
Sidebar: Repayment Plans
PCL0_BUILD_REPAYMENT_PLANPCL0_COMPUTE_REPAYMENT_PLANPA30PA20If you need to retrieve plan details in custom programs, you may use these modules to determine the relevant data. An excerpt from a program that reads the repayment plan for a given loan is shown in Figure 1.
. . INFOTYPES : 0001, 0045, 0078. ……………………. DATA : repayment_plan TYPE pclo_repay OCCURS 0 WITH HEADER LINE. DATA: loan_data TYPE pclo_loan_data. DATA : currency TYPE waers. DATA : loan_id TYPE PCLO_ID occurs 0 with header line . START-OF-SELECTION. GET pernr. loan_data-currc = currency. “ currency e.g USD, EUR etc rp_provide_from_last p0045 space ‘18000101’ ‘99991231’. rp_provide_from_last p0078 space ‘18000101’ ‘99991231’. move-corresponding p0045 to loan_id. append loan_id. CALL FUNCTION ‘PCLO_COMPUTE_REPAYMENT_PLAN’ EXPORTING pf_first = p0045-begda pf_curr = currency pt_p0001 = p0001[] pt_p0045 = p0045[] pt_p0078 = p0078[] ps_loan = loan_data ps_loid = loan_id IMPORTING psx_loan = loan_data CHANGING ptx_rep = repayment_plan[] EXCEPTIONS OTHERS = 2. .
|
Figure 1 |
Code that reads a loan’s repayment plan |
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.