ABAP - Work with references
Working with references is usually not as widespread in ABAP as working with field symbols. We would like to show you the most important purposes and uses.
Table of contents
How exactly do references work in ABAP and what can they be used for? We want to clarify this question in today's article and give you the details on how to use it.
General
When you work with references, in most cases they work like field symbols and so they help you, e.g. change the contents of table rows. They also serve to transfer dynamic data in interfaces of methods. Most aspects of references will be covered in this article.
GET REFERNECE OF
The command has now been replaced by the new REF variant and thus works like a value or other functions that can generate new elements. A small example to illustrate this:
DATA:
lt_database TYPE STANDARD TABLE OF t001 WITH EMPTY KEY,
lr_data TYPE REF TO DATA.
" Old Style
GET REFERENCE OF lt_database INTO lr_data.
" New Style
lr_data = REF #( lt_database ).
The use of the inline declaration of the target variable is possible with both commands and is accordingly available from Release 7.40. A reference is generated from the source variable, the value of which can be used to change the content. In other programming languages this is described as a pointer.
Usage
The use of references is possible in a variety of ways in the system, we want to show you the most common cases here. Note that this is not a complete collection.
Loop
Processing in a loop is the most common form of development construct. Individual fields can be accessed in the loop, as well as attributes or methods of a class. If you want to pass on the reference as a simple structure, this is done via dereferencing (->*) in the call.
LOOP AT lt_database REFERENCE INTO DATA(lr_database).
" Set a new value
lr_database->butxt = 'New Value'.
" Handle the structure to a method
call_a_method( lr_data->* ).
ENDLOOP.
Tables
Would you like to insert an empty record in a table so that you can continue working with the reference? No problem, because it works just as well as with field symbols.
DATA:
lt_company_code TYPE STANDARD TABLE OF t001 WITH EMPTY KEY,
lt_sorted_ccode TYPE SORTED TABLE OF t001 WITH UNIQUE-KEY bukrs.
" Insert into standard table
INSERT INITIAL LINE INTO TABLE lt_company_code REFERENCE INTO DATA(lr_standard).
" Insert into sorted table
INSERT VALUE #( bukrs = '1337' ) INTO TABLE lt_sorted_ccode REFERENCE INTO DATA(lr_sorted).
With a sorted table you have to make sure that the key of the table is already filled, you cannot append an empty line here, otherwise an exception will occur.
Table lines
Reading a line of a table and then changing the content of it, this is also no problem for references. After reading the line via the index or the key, the content can be changed freely (note the key of the table) or given to other methods for changing.
DATA:
lt_sorted_ccode TYPE SORTED TABLE OF t001 WITH UNIQUE-KEY bukrs.
" Read per index
DATA(lr_index_line) = REF #( lt_sorted_ccode[ 1 ] ).
lr_index_line->butxt = 'New Value'.
" Read per key
DATA(lr_key_line) = REF #( lt_sorted_ccode[ bukrs = '1337' ] ).
lr_key_line->butxt = 'New Value'.
Processing
Processing dynamic data shouldn't be a problem for you either. In our example we get data (a table) back as a reference. Since the reference is based on "TYPE REF TO data", we cannot simply loop over the data during processing.
To do this, we first perform a dereferencing and assign the data to a field symbol of the corresponding table type. With the loop we can then access the individual fields via assign.
FIELD-SYMBOL:
<lt_table> TYPE STANDARD TABLE.
DATA(lr_table_ref) = get_data_by_reference( ).
ASSIGN lr_table_ref->* TO <lt_table>.
LOOP AT <lt_table> INTO FIELD-SYMBOL(<ls_table_line>).
" Work with data
ENDLOOP.
Dynamic data
References are also often used to return dynamic data in returning parameters and to process them dynamically later (see processing above). But when returning the reference, you should pay attention to a few small things so that this also works.
Currently, we have only shown examples where we use the reference directly or pass it on to a method. In these cases the transfer also works as desired, since the variable on which the reference is based still exists. However, if we want to return the result as a reference via a returning parameter, a "Freed Reference" occurs.
" Definition
METHODS:
get_data_by_reference
RETURNING VALUE(rr_result) TYPE REF TO data.
" Implementation
METHOD get_data_by_reference.
SELECT * FROM t001 INTO TABLE @DATA(lt_company_codes).
rr_result = REF #( lt_company_codes ).
ENDMETHOD.
The example shown above results in an error and an exception as soon as you try to access the reference. Here you first have to generate the reference correctly before you can assign the data and output it from the method. A possible solution could therefore look like this:
METHOD get_data_by_reference.
SELECT * FROM t001 INTO TABLE @DATA(lt_company_codes).
CREATE DATA rr_result TYPE STANDARD TABLE OF t001.
ASSIGN rr_result->* TO FIELD-SYMBOL(<lt_result_table>).
<lt_result_table> = CORRESPONDING #( lt_company_codes ).
ENDMETHOD.
In the first step we create a data reference to the correct type of data and give the reference a body with the field symbol. In the last step you can then take over the data via CORRESPONDING. The reference can be returned and used.
Conclusion
Working with references and the new standard is pretty easy and with a little practice it will run into your blood. However, its use is not risk-free and you should follow the rules we have shown, then you will have a lot of fun with references in the future.