The structure/data comparison process (also referred to as change validation or difference checking) is often an important requirement for many HR interfaces and audit reports. These reports are usually required to check current and previous data values to help minimize the amount of data being manipulated, transferred, or exported. This in turn reduces overall interface complexity and troubleshooting should errors be identified during the interface process. The code that is created in this article can be used in any SAP module, not just HR. Because this is a technical “behind-the-scenes” functionality, end users are sometimes not even aware that it is being executed to obtain the expected results or information that they desire.
Key Concept
ABAP Objects are SAP’s answer to the IT industry’s trend toward object-oriented (OO) programming. ABAP Objects provide flexibility and reusability to ABAP programming.
Field symbols allow programmers to dynamically access data objects within ABAP programs. Unlike named variables or fields in a program, field symbols can point to any data area defined by the program’s DATA statements. You can think of them as a variable field name that can be assigned to any data object already existing in a program.
Dynamic subroutines are ABAP modules generated dynamically during the runtime of your program. They allow you to code and generate ABAP programs customized to specific situations that can only be determined during the runtime of a host program. Dynamic subroutines allow programmers to give a reusable host program the ability to react to new situations and eliminate the need for new program development.
All SAP HR teams have at one time or another faced the requirement for specialized interfaces for third-party benefit providers or payroll outsource companies. These interfaces often involve sending data values only from the employee records that have changed since the last interface period to minimize the volume of data being manipulated and exported. These interfaces require data record formats that are usually unique to a specific third party and used by no other system or business partner.
Given the singular quality of these interfaces, HR functional process designers typically request the development of a new and different custom ABAP interface program specifically for each situation. It’s usually left up to the ABAP developer to figure out how to determine which values on the third-party data records have changed. This task amounts to comparing a previous version of a record to a current version of a record to determine which fields have been altered.
Since these interface data records or structures are unique, no standardized change detection routines are available. Each program is always different from any of the other interface programs and requires complete “end-to-end” testing in both the development and quality assurance SAP environments. Although there is no standard, programs of this type generally involve the coding of a long and laborious IF
test something like:
IF |
structure1-field1 <> structure2-field1 OR |
|
structure1-field2 <> structure2-field2 OR |
|
structure1-field3 <> structure2-field3 OR |
|
structure1-field1 <> structure2-field4 OR |
|
structure1-field5 <> structure2-field5 OR |
|
structure1-field6 <> structure2-field6 . . . |
While coding this type of tedious test, the programmer may be tempted to duplicate a single line many times to speed development, which can lead to the type of typographical error shown in line 4 above. Even if you get it right, all you get out of this test is that something changed, not what changed. And let’s hope that the structures to be compared are never adjusted!
Suggested Solution
Here’s one alternative that not only eliminates the onerous coding but also provides a standardized change detection ABAP routine that delivers a list of the changed fields and automatically adapts if the compared structures or record formats themselves are adjusted. Standardizing change detection for all custom interfaces saves a lot of testing as well as program coding.
To create this change detection tool, you use two ABAP data reference technologies: field symbols and ABAP Objects. You also bring in an SAP-delivered function module named GET_COMPONENT_LIST.
How It Works
The heart of this change detection tool uses the ASSIGN OMPONENT operation within a loop to examine each field in a pair of identical structures via field symbols. Function module GET_COMPONENT_LIST is called to read the attributes of a structure defined within your specified program. This function module returns an internal table of field names sorted in structure sequence order. Looping at the table of field names provides you with not only the field name but also the sequence number of the field via the system variable SY-TABIX. Looping through the table of field names, field symbols are assigned to each subsequent component of both structures. If the values of any field pair are different, the field name is appended to a changed field internal table.
The real trick is to make your change detector flexible so that it can be used to compare any two structures without any programming changes or adjustments — a genuine “plug-and-play” programming tool. This is accomplished by two means: using the SAP system command GENERATE SUBROUTINE POOL
to create a temporary program tailored to your specific structure used in the compare, and using importing parameters of type STRING
to handle data structures of any length.
How to Create the Class
First, you need to create an ABAP Object class using transaction SE24. Call your object ZCL_XX_DIFFERENCE_ENGINE
where XX is a development area code used by your organization. (Of course you can name your object anything you want, but I like the allusion to the work of Charles Babbage.) A good description would be Detect difference in two identical structures of data
.
Next, click on the Types button on the SE24 toolbar to create two local types. They are I_RSTRUCINFO type standard table of RSTRUCINFO and I_RFIELDLIST type standard table of RFIELDLIST.
Now add the attributes, including references to the two local types you just created. Notice which attributes are public and which are private. See Figure 1 for the names, types, and reference type of the six attributes.

Figure 1
Attributes of class
After adding the attributes, you are ready to define the two public methods. They are: CONSTRUCTOR with the description ‘CONSTRUCTOR’; GET_CHANGED_FIELDS
with the description Get the changed fields
.
See Figure 2 for the parameters for method CONSTRUTOR and Figure 3 for method implementation coding. (There are two available code listings for this. One is in HTML format and the other is a text version. To download them, click here: HTML code download or text code download.)
See Figure 4 for the parameters for method GET_CHANGED_FIELDS and Figure 5 for its implementation coding.
.

Figure 2
Parameters for method CONSTRUCTOR
method get_changed_fields. clear me->changedfields. perform difference in program (temp_progname) tables changed_fields using string_1 string_2. me->changedfields = changed_fields. endmethod.
|
|
Figure 5 |
Implementation coding for method GET_CHANGED_FIELDS |
|
How to Detect Changes
As an example of how to put your new change detector to use, I have included a sample program, ZFIND_KOSTL_CHANGES, which is shown in Figure 6. Note that in Figure 6 form routine FIND_CHANGES shows an example of my change detection logic used in reverse. This time, the table of changed field names is used to retrieve the values associated with the changed fields to produce an informative report listing the changes to the screen or spool output for possible further analysis by HR personnel.
You must declare an instance of the class in your program using the DATA
statement like this:
DATA: change_finder TYPE REF TO zcl_xx_difference_engine.
Declare a variable for your program name and two identical structures for comparison:
DATA: my_prog TYPE progname,
compare_struc1 type CSKS,
compare_struc2 type CSKS.
Also declare a table for the changed fields, work fields, and two string variables:
When you issue the CREATE OBJECT
command to create the instance of object, you supply the name of your program and the name of one of the structures within your program that you want to compare.
my_prog = sy-repid.
CREATE OBJECT change_finder
EXPORTING
progname = my_prog
ref_structure = compare_struc1.
As you process each set of old and new records within a looping code structure, move each record to one of the string variables and call method GET_CHANGED_FIELDS
of your change detector object as shown to obtain your list of changed fields.
move p_csksz_old to string_1.
move p_csksz_new to string_2.
call method wk_chg_detect->get_changed_fields
exporting
string_1 = string_1
string_2 = string_2
receiving
changed_fields = changed_fields.
Note
The structure used for the REF_STRUCTURE
parameter in the CREATE OBJECT
command must be a flat structure. An internal table header line, type, or table type does not work.
Since the CHANGED_FIELDS table is defined in your class definition as a receiving type parameter, it may be used directly in a functional method call as an alternate means of detecting any changes (Figure 7).
. . check not wk_chg_detect->get_changed_fields( string_1 = string_1 string_2 = string_2 ) is initial. loop at wk_chg_detect->changedfields into field_line1. . . .
|
|
Figure 7 |
Alternate technique |
|
Note
Be sure the CREATE OBJECT
command is outside of any looping structures and is issued only once in the program. You may have as many different change detector objects within a program as you want, but the CREATE OBJECT
command for each change detector must be issued only once per program run.
In this manner, processing continues only if one or more changed fields are found. When used in a functional method call, the data within the CHANGED_FIELDS table is only temporarily available for the test and is deleted immediately afterward. The class definition accounts for this problem by providing a table of changed fields as one of the class’s attributes. The CHANGED_FIELDS table from the object’s attributes may be used in the same manner as the CHANGED_FIELDS table returned from the GET_CHANGED_FIELDS
method call.
Jim McCallum
Jim McCallum is a senior technical consultant with SAP America who has specialized in HR ABAP since 1995. He has given many technical presentations on HR ABAP, ABAP Controls, and ABAP Objects on the local and national levels, including the HR 2004 and HR 2005 conferences.
You may contact the author at jim.mccallum@mccallumalliance.com.
If you have comments about this article or publication, or would like to submit an article idea, please contact the editor.