Hi, I provide training in SAP UI5. Also feel free to checkout my new web page https://saptechblog.com
ABAP Objects

Field Symbols and Data Reference Variables.

 

Document Prepared by: Ajith C. Enteg infotech Pvt ltd.

 

Field symbols and Data reference Variables help us in dynamic programming. Which means, we can access the contents of the data objects whose name and the properties are not known to us until the runtime.  Another big advantage of them( Field Symbols)  is the performance improvement when we use them with the internal table. This will be discussed in detail later.

 

1.   Field Symbols

 

Field symbols can be considered as the symbolic name for the data objects. They do not physically reserve any memory space when we declare them. They only point to an existing data object by using Value semantics. Which means, when we access the field symbol, we are actually working with the contents of the data object which is pointed by the field symbol, and not the content of the field symbol itself. In order to access the content of the data object by using the field symbol, we need to assign that data object to the field symbol first.

1.1.         A small introduction about the dynamic programming :

It is actually not possible to assign a data object to another data object dynamically as below.

 

clip_image002

 

 

 

 

This will give a run time error as shown below.

 

clip_image004

 

The statement in the line 15 will be the cause the of the error. Remember that the dynamic values that we give in the braces are not syntax checked and that is the reason why we do not get any error when we check the syntax before running. It will be checked only during the run time. Here since, the target of the assignment statement in the line is an integer variable, it is expecting the source to be an integer, or it will try to interpret the source as a number. However, the dynamic data object access is not supported here and that is the reason why it is giving an error.

However, the piece of the code below will work without any issue.

clip_image006

 

Here we have a field symbol <fs_var2>. To this field symbol we are assigning a data object dynamically. This is one of the advantages of the field symbols. After this assignment, we can work with the field symbol just as how we would with the original data object. So the above code will print the value 90. 

Please refer the debugger snap shown below. The control has reached the line 15 , which means the field symbol is assigned with the original data object. Now, on the right hand side, both the original data object (lv_var1) and the field symbol (<fs_var2>) are showing the same value.

 

 

clip_image008

Now, change the content of the field symbol dynamically in the debugger itself and you can see that the content of the original data object is also changed.

Click on the pencil icon near the field symbol for enabling editing.

clip_image009clip_image011

Enter some other value

clip_image013

You can see that the lv_var1 also is changed to 89.

clip_image015

 

1.2.         Defining a Field Symbol.

 

The keyword field-symbols is used to define a field symbol. The angular brackets

(‘< ‘ and ‘>‘ ) are the part of the field symbol definition.

Example is given below.

Field-symbols : <fs_int> type i.

If you specify the type of the field symbol as above, it can be assigned with only integer type data objects. Otherwise, it will give syntax error.

If you do not specify any type after the name of the field symbol, it can take any type of data object that is assigned to it. We can also define a field symbol by specifying a generic type like any, any table, simple etc.

 

 

 

Field-symbols : <fs_table> type any table.

There are however, certain limitations when we use generic type when we use them to work with reference variables and structured data objects( like internal tables ). It will not get the specific properties of the object that is assigned to it. Because this information is not known until the runtime.  And you will get a syntax error in this case.

 

 

Ex : If we assign a reference variable to a field symbol, we will not be able to access the attributes of the objects using the field symbol. Please refer the screenshot below.

 

clip_image017

 

This will produce a syntax error as shown below.

clip_image019

 

Another example, if we assign an internal table to a field symbol, it will not get the keys of the internal table. In this case we need to dynamically specify the key in brackets.

If you assign a structure( work area) to a field symbol of the generic type, you will not be able to access the components of the structure by using the ‘–‘ operator as we would do with the original structure variable. However, you can access the individual component of the field symbol by assigning  them to another field symbol. This is discussed in detail later.

When we assign a data object dynamically to the field symbol,  the sy-subrc will be set 0 if the assignment was successful. Otherwise it will be set to 4. So, it is always recommended that we check the sy-subrc value immediately after the assignment. Otherwise, the field symbol may refer to an old value.

 

You can also use offset and length addition to the data object when assigning them to the field symbol. However this is not possible when assigning a data object dynamically.

Please find the example in the below code.

clip_image021

 

1.3.         Common usages of the Field symbols with Internal Tables.

 

1.3.1.  Looping multiple lines of the internal table.

 

If you want to loop an internal table into a work area and process each records, field symbols can be found very helpful here.

clip_image023

The above example shows how we can use field symbols for processing individual lines of the internal table. Here the performance is drastically improved when compared to the similar operation by using the work area or the header line of the table. This is because the individual contents of the internal table is physically not moved around as in the case of the work area. The field symbol is pointing to the individual records of the internal table and for every loop pass it will point to the next record in the internal table.

1.3.2.  Modifying the Internal table records.

 

If you want to modify the contents of the internal table, this can be found very useful. An example is given below.

 

clip_image025

Here we are not writing any modify statement itself. When we change the content of the field symbol, the content of the record to which it is pointing in the internal table itself is also changed. Here we do not have to check if the field symbol is assigned. This is because if there is no records in  the internal table, that will not enter the loop itself.

 

1.3.3.  Reading single record from the internal table.

 

You can use the assigning addition when we process single records of the internal table with the read table statement. Here we need to check the sy-subrc value to see if the read operation was successful.

 

1.3.4.  Append initial line of a field symbol

 

Another operation that is supported is appending an initial line to a field symbol which is again of internal table type. An example is given below.

 

clip_image027

 

This operation is useful when we are working with the internal table which are in the form of a field symbols.

Most of the standard SAP methods which will return an internal table will always return it in the form of a reference variable. First we need to dereference them into a field symbol. Remember that the generically types data reference variables can only be dereferenced by the use of a field symbol. (This is discussed in detail later)

 

 

 

1.3.5.      Access individual components of the generic field symbol

 

As mentioned earlier in  this tutorial, when we use a generically declared field symbol to point to a structured data object, it is not possible to access the components of the structure by using the hyphen operator. Using the keyword below, we will be able to dynamically access the individual components of the structure.

 

clip_image029

 

Here the component can be specified by giving the position number of the structure. We can also use a variable which has the name of the component instead. This offers a great advantage when it comes to the dynamic access of the components of the structure whose names are not known till the run time.

 

1.4.         Checking if the field symbol is assigned to a data object.

 

The statement which we can use in order to check if the field symbol is assigned to a data object is is assigned. This will be true if the field symbol is assigned to a data object and false if it is not assigned. Also, we can explicitly unassign a field symbol from a data object by using the unassign keyword.  

 

 

Data Reference Variable.

 

Data reference variables are the equalant of the pointers in other languages like C. As you guess, it is the data object which will hold the address of other data object. So, when we access the content of a data reference variable, we are accessing the address of another data object.  In order to access the contents of the data object which is pointed by  the data reference variable, a special technique called dereferencing has to be done. So, it is told that the data reference variable uses reference semantics  to work with data objects. One difference between the pointers in other language and the data reference variable is that, you will not be able to increment or decrement them to pint to a next address location.

 

1.     Declaring the Data Reference Variable

A data reference variable can be declared by using the type ref to keyword. We can specify a fully specified type or a generic type.

For example.

clip_image031

Here we have declared a data reference variable lr_a by using the complete type i. Which means lr_a can from now hold the address of any other data object of type integer. However, we will not be able to declare a data reference variable with an incomplete type like c or n (Incomplete type means, those data types which requires a length specification).

2.     Accessing the data object using the data reference variable.

Now, since we are ready with the reference variable, we will try assigning a data object to it.

clip_image033 

 

 

We need to use the keyword get reference of in order to assign  the address of any data object to the data reference variable. After this process, for accessing the actual content of the data object using the data reference variable, we use the dereferencing operator ( ->* ). The example code will print the below output.

 

clip_image035

 

3.     Creating a data object explicitly by using the reference variable.

 

So far we have assigned the address of an existing data object to the data reference variable. Now, we will see another variation of the data object declaration by using a generic type. The only two supported generic type are data and object. A data reference variable declared by using the type data can point to any data object where as the ones which are declared by using the object can point to objects of classes.

clip_image037

Here we have declared a generic data reference variable. And we used the create data statement to create it. This statement will create a data object in  the memory and assign the address of the data object to the data reference variable lr_data. The original name of the data object that was created by this statement is not known and it is of no interest. In this method, we will be able to use the incomplete type like c and n with the length specification as well. However will not be able to give a default value by adding the value keyword. We can also use the like keyword to refer to an object already existing. The memory for the data object is not assigned till the create data statement.   We can even declare the data reference variable with internal table type as below.

clip_image039

However, one difference of using this method is that we will not be able to work with the contents of the created data object by using only the dereferencing

operator ->*. This operator cannot be used with the data reference variable of generic type as a rule. So, we need to assign such variables to a field symbol explicitly and then we can work with the field symbol seamlessly as we work with the original data object.

 

clip_image041

In the above code, we have created a data object(internal table) of type sflight by using the generic data reference variable lr_data. Now, in order to access the contents of the internal table itself, we need to assign it to a field symbol as in the line 46. Please see the debugger snapshot, where we can see the field symbol <fs_table> is populated with the line type of sflight.

clip_image043

 

 

4.     Creating a data object dynamically.

The main advantage of the data reference variable is that we can create data objects of dynamic types using  them. The below example shows this.

 

clip_image045

 

Here the type of the data object is given in the braces dynamically. This must be a character data object. This is one big advantage of the data reference variable. Note that we will not be able to use like keyword when we declare the data objects dynamically as shown above. So, using this method, we are able to create data objects whose type and properties are not known to us in the beginning.

 

5.     Accessing the components of structure using the data reference variable.

In the below example, the data reference variable lr_data is pointing to a structure variable ls_data. Now, if we need to access the components of the structure using the data reference variable lr_data, we use the component selector operator ( -> ) and not the hyphen (-) or dereferencing operator ( ->*).

clip_image047

 

 

 

 

6.     How to check if the data reference variable is pointing to an object?

There is a special statement which can be used in order to check if the data reference variable is pointing  to an object. is [not] bound is the statement. This statement will be true if the data reference variable can be dereferenced to access a data object. As in the case of object referenced, the system routine garbage collector will periodically check for the data reference variables which are not bound and remove them.

7.     Some Scenarios

 

7.1.       Making an Interface parameter generic.

Imagine that we have a function module or a method which should take an internal table whose type we do not know till the run time. In this case, we need to have a generic type as the importing parameter of the function module or the method. We can have a generic data reference variable of type data as the importing parameter here. Please refer the method in the screen shot below.

 

clip_image049

We have an importing parameter im_table which is a generic data reference variable. Now, imagine that you need to call those method from a report and pass an internal table to it.

clip_image051

You can see that we have populated an internal table with values. We are taking the reference of this internal table to the data reference variable lr_data and passing to the interface of the generic_int method of the zcl_utilities class. Now, inside this method, as we know we need to have a field symbol to access the contents of the internal table.

 

clip_image053

 

Now, let us see the field symbol in  the debugger mode.

clip_image055

 

 

 

So, the internal table is successfully passed to this method through the generic importing parameter im_table. Like this, it can take any data object whose type are not known to us. We just need to assign this to a field symbol for accessing the actual content of it. Now imagine that we need to print the internal table values from this method. How do we do that?

The internal table is already available in the form of the field symbol <fs_table>. We need to loop it record by record to a work area and then print it. We can declare another field symbol as work area. This will again be a generic one since we do not know the type of the internal table till the run time. Please refer the code below.

 

clip_image057

We have declared another field symbol <fs_line> for the work area. We are looping the internal table <fs_table> to <fs_line> one by one and printing the individual fields. This code might look okay at the first time. However this will give us a syntax error as below.

 

clip_image059

 

Note that the field symbol <fs_line> is a generic one ( type any ) and it has to be a generic one since we do not know the line type of the internal table when we write this method. So, any statement which is trying to access the components of this generic field symbol will throw an error as above. So, in this we need to access the fields/ components of the work area (ls_line) using the assign component of structure keyword which we saw earlier.

Please refer the code below.

 

clip_image061

 

Since we do not know how many components are there in the line type of the internal table, we need a mechanism to know it. When we assign each components of the structure to another field symbol <fs_field>, if the assignment was successful, the sy-subrc will be initial. So, when it is not initial, we can assume that there are no more components or columns.

7.2.       Displaying the contents of a database table dynamically.

The  below program takes the name of the database table from the user. After this a data object of type internal table is created dynamically using this table name. As we know, if we need to start using this dynamically created internal table, we need to assign it  to a field symbol. Finally, we call the standard method factory() of the class cl_salv_table to create an instance of the alv class to lr_alv object reference variable by passing the internal table(<fs_table>). After getting this reference, we use the instance method display() to display  the table in the ALV format.

 

clip_image063

 

The input and output screen look like below.

Input:

clip_image065

Output:

clip_image067 

 

About Arun

11 Comments:

  1. Good post how about more things on ABAP OOPS for a beginner in OOPS like me ?

    ReplyDelete
  2. awesome..very very good article..

    ReplyDelete
  3. very usefull article.. Thanks guys.. Keep Posting on

    ReplyDelete
  4. Very detailed explanation, thank you,,,

    ReplyDelete
  5. Very nice artical..great work (y)

    ReplyDelete
  6. Nice post,everyone easily can understand

    ReplyDelete
  7. nice post sir but how about populating data in a dynamic intern table?

    ReplyDelete
  8. I understand but what is difference between field symbol and data referecess. could you please explain that?

    ReplyDelete
  9. This is very good. Thanks for putting it together in a format like that. I find when I can see examples I understand so much better.
    Regards, Martin.

    ReplyDelete

Powered by Blogger.