This is a test message to test the length of the message box.
Login
ABAP ASSIGN
Created by Software-Heroes

ABAP - Assign

116

In this article, we'll look at different variations of ASSIGN and how you can use them in ABAP in everyday life to make your development more effective.



In this article, we'll discuss working with field symbols and how you can use them in everyday life. We'll look at various processing examples.

 

Introduction

The ASSIGN statement has been around for a long time in ABAP development and is part of an ABAP developer's standard toolbox. We typically work with a field symbol that represents a reference to a real variable. Field symbols and references are both pointers that don't contain real values, but point to a memory address with a real value.

 

Preparation

For the following examples, we'll use two structures with the respective types in tabular form. A simple structure contains the fields A to E, and we create a mapping that we will need later when we process the structure dynamically.

TYPES: BEGIN OF simple_mapping,
         field TYPE string,
         value TYPE string,
       END OF simple_mapping.
TYPES simple_mappings TYPE STANDARD TABLE OF simple_mapping WITH EMPTY KEY.

TYPES: BEGIN OF simple_structure,
         a TYPE string,
         b TYPE string,
         c TYPE string,
         d TYPE string,
         e TYPE string,
       END OF simple_structure.
TYPES simple_table TYPE STANDARD TABLE OF simple_structure WITH EMPTY KEY.

 

Processing

There is also an inline declaration for field symbols, such as those you can use with a LOOP or an ASSIGN, for example. In this example, we use a field symbol instead of a normal structure. The advantage of this version is also performance, since we don't have to copy the data from the table into the structure; only the pointer is changed.

LOOP AT examples ASSIGNING FIELD-SYMBOL(<line>).
  out->write( <line> ).
ENDLOOP.

 

In this scenario, however, you need to be careful, as you now have a pointer. Using this pointer, you can directly adjust and change the data in the table. In this example, we set a new value for column C and overwrite the old one.

LOOP AT examples ASSIGNING FIELD-SYMBOL(<line>).
  <line>-c = `New Value`.
ENDLOOP.

 

Basically, you can easily adjust a lot of data or add more information to the table without having to write the data back into the table.

 

Component

Let's take just one structure of our table, for example. If you want to process a structure dynamically, various methods are available. For example, you can analyze the structure using RTTI to process the various fields. In the following example, we use an ASSIGN COMPONENT, which allows us to assign a single field to a field symbol.

DO.
  ASSIGN COMPONENT sy-index OF STRUCTURE example TO FIELD-SYMBOL(<field>).
  IF sy-subrc <> 0.
    EXIT.
  ENDIF.

  result &&= <field>.
ENDDO.

 

There are currently two rules for assignment:

  • Numeric - If the value behind COMPONENT is numeric, then the x-th field of the structure is assigned to the field symbol.
  • Character - If the value consists of characters, then a field with the same name is searched for in the structure and then assigned to the field symbol.

 

In the example above, we process the fields from the 1st to the last field. If we now try to assign a field that no longer exists, the SY-SUBRC is set. In this case, we exit the loop and complete processing.

 

Mapping

In the next example, we'll work with a mapping and want to point out the dangers of this method. The mapping contains a field that doesn't currently exist in the structure.

METHOD get_mappings.
  RETURN VALUE #( ( field = `a` value = `101` )
                  ( field = `b` value = `102` )
                  ( field = `f` value = `103` )
                  ( field = `d` value = `104` )
                  ( field = `e` value = `105` ) ).
ENDMETHOD.

 

Error Case

In the following example, we create an error in processing that will go unnoticed. We get the mapping from the method and process it against our structure.

LOOP AT get_mappings( ) INTO mapping.
  ASSIGN COMPONENT mapping-field OF STRUCTURE example TO <field>.
  <field> = mapping-value.
ENDLOOP.

 

At the third position of the mapping, the field can no longer be mapped. The SUBRC is now set. However, the field symbol remains on the second field. We are thus overwriting the second field with an incorrect value and have unnoticed generated an error.

 

Solution

To avoid making such mistakes again, we should react when an error occurs. In classic development, we would now check the SUBRC to see if the assignment worked. In such a case, we can skip the current line and continue processing on the next one.

LOOP AT get_mappings( ) INTO mapping.
  ASSIGN COMPONENT mapping-field OF STRUCTURE example TO <field>.
  IF sy-subrc <> 0.
    CONTINUE.
  ENDIF.

  <field> = mapping-value.
ENDLOOP.

 

A relatively new variant is the ELSE UNASSIGN addition. If an error occurs, the field symbol is initialized, preventing the incorrect value from being overwritten. In such a case, we can then check whether the element is set without the SUBRC. This means we are no longer dependent on the system field, but can reference the element directly.

LOOP AT get_mappings( ) INTO mapping.
  ASSIGN COMPONENT mapping-field OF STRUCTURE example TO <field> ELSE UNASSIGN.
  IF <field> IS NOT ASSIGNED.
    CONTINUE.
  ENDIF.

  <field> = mapping-value.
ENDLOOP.

 

Result

Let's take a look at the results of the three variants. Column C always remains empty, and only in the first case does column B have an incorrect value. Therefore, you should always ensure proper error handling in such situations.

 

Assignment

Let's look at two more assignments in the context of references. In older releases, you usually have to assign a reference to a field symbol before you can process the table, for example. The field symbol must also be of type TABLE, otherwise the compiler will issue an error.

ASSIGN local_reference->* TO FIELD-SYMBOL(<table>).

LOOP AT <table> ASSIGNING <line>.
  out->write( <line> ).
ENDLOOP.

 

In a current release, you can save yourself the trouble and go directly via the reference. Here, the system only checks at runtime whether the reference is a table.

LOOP AT local_reference->* ASSIGNING <line>.
  out->write( <line> ).
ENDLOOP.

 

New Features

In this article, we've also incorporated three new features and special features that are possible in current releases and that didn't really work before.

  • Upper and lowercase - With ASSIGN COMPONENT, we use lowercase fields as references. Previously, the field name always had to be specified in uppercase, otherwise the field wouldn't be found. This no longer matters.
  • Inline Declaration - When assigning the reference to the field symbol, we used an inline declaration. This would be of type ANY and therefore couldn't be used for the loop. This is also no longer a problem in a current release.
  • Reference - We were also able to loop directly over de-referencing (->*) during assignment, without a field symbol or assignment. This makes direct use of references easier, as the type check only occurs at runtime.

 

Complete Example

If you would like to try out the example, you can find the complete executable class here. As described above in the special features, it may not be possible to activate it on your release.

CLASS zcl_bs_demo_assign DEFINITION
  PUBLIC FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

  PRIVATE SECTION.
    TYPES: BEGIN OF simple_mapping,
             field TYPE string,
             value TYPE string,
           END OF simple_mapping.
    TYPES simple_mappings TYPE STANDARD TABLE OF simple_mapping WITH EMPTY KEY.

    TYPES: BEGIN OF simple_structure,
             a TYPE string,
             b TYPE string,
             c TYPE string,
             d TYPE string,
             e TYPE string,
           END OF simple_structure.
    TYPES simple_table TYPE STANDARD TABLE OF simple_structure WITH EMPTY KEY.

    METHODS get_examples
      RETURNING VALUE(result) TYPE simple_table.

    METHODS get_example
      RETURNING VALUE(result) TYPE simple_structure.

    METHODS get_mappings
      RETURNING VALUE(result) TYPE simple_mappings.

    METHODS assign_in_loop
      IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.

    METHODS change_with_fieldsymbol
      IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.

    METHODS loop_structure
      IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.

    METHODS do_mapping
      IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.

    METHODS assign_reference
      IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
ENDCLASS.


CLASS zcl_bs_demo_assign IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    assign_in_loop( out ).
    change_with_fieldsymbol( out ).
    loop_structure( out ).
    do_mapping( out ).
    assign_reference( out ).
  ENDMETHOD.


  METHOD get_examples.
    RETURN VALUE #( ( a = `1` b = `2` c = `3` d = `4` e = `5` )
                    ( a = `6` b = `7` c = `8` d = `9` e = `10` )
                    ( a = `11` b = `12` c = `13` d = `14` e = `15` )
                    ( a = `16` b = `17` c = `18` d = `19` e = `20` ) ).
  ENDMETHOD.


  METHOD get_example.
    RETURN VALUE #( a = `1`
                    b = `2`
                    c = `3`
                    d = `4`
                    e = `5` ).
  ENDMETHOD.


  METHOD get_mappings.
    RETURN VALUE #( ( field = `a` value = `101` )
                    ( field = `b` value = `102` )
                    ( field = `f` value = `103` )
                    ( field = `d` value = `104` )
                    ( field = `e` value = `105` ) ).
  ENDMETHOD.


  METHOD assign_in_loop.
    DATA(examples) = get_examples( ).

    LOOP AT examples ASSIGNING FIELD-SYMBOL(<line>).
      out->write( <line> ).
    ENDLOOP.
  ENDMETHOD.


  METHOD change_with_fieldsymbol.
    DATA(examples) = get_examples( ).

    LOOP AT examples ASSIGNING FIELD-SYMBOL(<line>).
      <line>-c = `New Value`.
    ENDLOOP.

    out->write( examples ).
  ENDMETHOD.


  METHOD loop_structure.
    DATA(example) = get_example( ).
    DATA(result) = ``.

    DO.
      ASSIGN COMPONENT sy-index OF STRUCTURE example TO FIELD-SYMBOL(<field>).
      IF sy-subrc <> 0.
        EXIT.
      ENDIF.

      result &&= <field>.
    ENDDO.

    out->write( result ).
  ENDMETHOD.


  METHOD do_mapping.
    DATA mapping TYPE zcl_bs_demo_assign=>simple_mapping.
    DATA example TYPE simple_structure.
    FIELD-SYMBOLS <field> TYPE data.

    LOOP AT get_mappings( ) INTO mapping.
      ASSIGN COMPONENT mapping-field OF STRUCTURE example TO <field>.
      <field> = mapping-value.
    ENDLOOP.

    out->write( example ).
    CLEAR example.

    LOOP AT get_mappings( ) INTO mapping.
      ASSIGN COMPONENT mapping-field OF STRUCTURE example TO <field>.
      IF sy-subrc <> 0.
        CONTINUE.
      ENDIF.

      <field> = mapping-value.
    ENDLOOP.

    out->write( example ).
    CLEAR example.

    LOOP AT get_mappings( ) INTO mapping.
      ASSIGN COMPONENT mapping-field OF STRUCTURE example TO <field> ELSE UNASSIGN.
      IF <field> IS NOT ASSIGNED.
        CONTINUE.
      ENDIF.

      <field> = mapping-value.
    ENDLOOP.

    out->write( example ).
  ENDMETHOD.


  METHOD assign_reference.
    FIELD-SYMBOLS <line> TYPE zcl_bs_demo_assign=>simple_structure.

    DATA(examples) = get_examples( ).
    DATA(local_reference) = REF #( examples ).

    ASSIGN local_reference->* TO FIELD-SYMBOL(<table>).

    LOOP AT <table> ASSIGNING <line>.
      out->write( <line> ).
    ENDLOOP.

    LOOP AT local_reference->* ASSIGNING <line>.
      out->write( <line> ).
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

 

Conclusion

The ASSIGN still helps ensure reliable generic processing and adapt content quickly and reliably. You'll have to get used to it a bit at first, but the benefits are greater and will quickly become second nature.


Included topics:
New ABAPASSIGNELSE
Comments (0)



And further ...

Are you satisfied with the content of the article? We post new content in the ABAP area every Tuesday and Friday and irregularly in all other areas. Take a look at our tools and apps, we provide them free of charge.


ABAP - XCO Generation and Info System

Category - ABAP

How can you use ABAP Cloud tools to generate new objects in the system and obtain information about them? Let's take a closer look at this using an example.

06/27/2025

ABAP - XCO Call Stack and Tenant

Category - ABAP

How do you use the XCO classes to access the ABAP Call Stack and obtain further information about the current tenant? In this article, we'll take a closer look.

06/06/2025

ABAP - XCO UUID

Category - ABAP

How do you generate unique IDs in ABAP using the XCO classes? In this article, you will learn how quickly and easily this can be done.

01/28/2025

ABAP - XCO System Fields

Category - ABAP

Is there an alternative for SY or SYST in the XCO Library in ABAP Cloud? It's definitely worth a look.

01/24/2025

ABAP - XCO Strings

Category - ABAP

In this article we look at the XCO class for generating and processing strings for ABAP Cloud and compare it with the classic statements.

11/22/2024