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

ABAP Deep Dive - CORRESPONDING

1444

In this article, a little more about the new Corresponding Statement and how to use it in detail. Let's take a look at the additional features.



We already discussed the new statement in an older article and explained some of its advantages. In this article, we want to look at some new facets and how you can make the most of them. We have also noticed that developers usually do not use the full potential of the statements to save on coding. In this context, we want to look at some innovations and special features.

 

Introduction

The new CORRESPONDING is a constructor expression, which means it creates a new element from its source object. Here you can imagine it in such a way that a new element is created for the target, is empty and then the assignment is carried out according to the corresponding rules. The values are copied and the source object is not changed. This has the nice advantage that you save yourself the clear within a loop, for example, if the loop structure is assigned to a new structure for processing.

 

Preparation

For the following examples we define separate structures and table types that we want to use. There is always a source structure and a target structure in which some field names are the same and some are different. The entire example below in the article will give you the entire example.

TYPES:
  td_text   TYPE c LENGTH 25,
  td_number TYPE i,
  td_long   TYPE string,

  BEGIN OF ts_source,
    text1    TYPE td_text,
    text3    TYPE td_text,
    num1     TYPE td_number,
    longtext TYPE td_long,
  END OF ts_source,
  tt_source TYPE STANDARD TABLE OF ts_source WITH EMPTY KEY,

  BEGIN OF ts_target,
    ident    TYPE td_number,
    num      TYPE td_number,
    longtext TYPE td_long,
    text1    TYPE td_text,
    text2    TYPE td_text,
  END OF ts_target,
  tt_target     TYPE STANDARD TABLE OF ts_target WITH EMPTY KEY,
  tt_target_key TYPE SORTED TABLE OF ts_target WITH UNIQUE KEY ident,

  BEGIN OF ts_source_nested,
    field1 TYPE td_text,
    sub    TYPE ts_source,
  END OF ts_source_nested,

  BEGIN OF ts_target_nested,
    field TYPE td_text,
    sub   TYPE ts_target,
  END OF ts_target_nested.

 

A simple MOVE of the structures therefore looks like this, only the components with the same name are moved, leaving the target structure relatively empty:

DATA(ls_source) = fill_structure( ).
DATA(ls_target) = CORRESPONDING ts_target( ls_source ).

io_out->write( |Simple move:| ).
io_out->write( ls_target ).

 

MAPPING

When using a mapping, components that do not have the same name can also be moved, whereby the source and target fields are specified in the mapping. The Content Assist (CTRL + SPACE) is also available in Eclipse for better help:

DATA(ls_source) = fill_structure( ).
DATA(ls_target) = CORRESPONDING ts_target( ls_source MAPPING text2 = text3 num = num1 ).

io_out->write( |Move with mapping:| ).
io_out->write( ls_target ).

 

The output now looks like this, the remaining and existing fields have now been successfully mapped and assigned to the target structure:

 

EXCEPT

Sometimes fields should be deleted after the assignment, then when it comes to further processing or the fields have to be empty because they are no longer needed or can lead to problems. In the past, after the assignment, the corresponding fields were cleared. You can save yourself this with the EXCEPT addition, since this ensures that the fields are not transferred to the target structure:

DATA(ls_source) = fill_structure( ).
DATA(ls_target) = CORRESPONDING ts_target( ls_source MAPPING text2 = text3 num = num1 EXCEPT longtext ).

io_out->write( |Move without longtext:| ).
io_out->write( ls_target ).

 

In the example above, we did the same mapping as before, but this time we don't want to copy the long text. The target structure now looks like this:

 

DISCARDING DUPLICATES

There are cases where a standard table should be converted into a sorted table with a key. Here, however, you have to be sure that the key only exists once in the source table, otherwise an exception will be raised and processing will be aborted. In the past you could do this with multiple statements (sorting the table and removing the duplicates). In this example we fill the table unsorted and with a duplicate and use DISCARDING DUPLICATES in the assignment, so the duplicates are removed and no exception is thrown:

DATA(lt_source) = VALUE tt_source(
  ( num1 = 14 text1 = 'Bread' )
  ( num1 = 3 text1 = 'Butter' )
  ( num1 = 7 text1 = 'Jam' )
  ( num1 = 14 text1 = 'Salt' )
  ( num1 = 11 text1 = 'Egg' )
  ( num1 = 19 text1 = 'Coffee' )
).

DATA(lt_target) = CORRESPONDING tt_target_key( lt_source DISCARDING DUPLICATES MAPPING ident = num1 ).

io_out->write( |Move table with key:| ).
io_out->write( lt_target ).

 

We map the number field to the key accordingly and remove the duplicates. The first entry in each case is transferred to the target table and the result looks like this:

 

Nested Mapping

What about nested structures? This involves structures that map another structure or table at field level and thus have several levels. Here you can also apply the mapping, as we have already done above. If you then want to address the deep structure, you have to put the element in brackets and do your own mapping there:

DATA(ls_source) = VALUE ts_source_nested(
  field1 = 'Sub structure'
  sub = fill_structure( )
).

DATA(ls_target) = CORRESPONDING ts_target_nested( ls_source
  MAPPING field = field1
  ( sub = sub MAPPING text2 = text3 num = num1 )
).

io_out->write( |Nested move:| ).
io_out->write( ls_target-field ).
io_out->write( ls_target-sub ).

 

In the example we have mapped the main field and opened another mapping for the deep structure. The output must be done in two steps because the output method does not support deep structures:

 

Entire example

As always, you can find the complete example here in the form of an executable ABAP class. The individual examples have been moved to individual methods to ensure better readability:

CLASS zcl_bs_demo_corresponding_deep DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

    TYPES:
      td_text   TYPE c LENGTH 25,
      td_number TYPE i,
      td_long   TYPE string,

      BEGIN OF ts_source,
        text1    TYPE td_text,
        text3    TYPE td_text,
        num1     TYPE td_number,
        longtext TYPE td_long,
      END OF ts_source,
      tt_source TYPE STANDARD TABLE OF ts_source WITH EMPTY KEY,

      BEGIN OF ts_target,
        ident    TYPE td_number,
        num      TYPE td_number,
        longtext TYPE td_long,
        text1    TYPE td_text,
        text2    TYPE td_text,
      END OF ts_target,
      tt_target     TYPE STANDARD TABLE OF ts_target WITH EMPTY KEY,
      tt_target_key TYPE SORTED TABLE OF ts_target WITH UNIQUE KEY ident,

      BEGIN OF ts_source_nested,
        field1 TYPE td_text,
        sub    TYPE ts_source,
      END OF ts_source_nested,

      BEGIN OF ts_target_nested,
        field TYPE td_text,
        sub   TYPE ts_target,
      END OF ts_target_nested.

  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS:
      fill_structure
        RETURNING VALUE(rs_source) TYPE ts_source,

      move_simple_structure
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      move_with_mapping
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      move_without_fields
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      move_duplicate_tables
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      move_nested_structure
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out.
ENDCLASS.


CLASS zcl_bs_demo_corresponding_deep IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    move_simple_structure( out ).
    move_with_mapping( out ).
    move_without_fields( out ).
    move_duplicate_tables( out ).
    move_nested_structure( out ).
  ENDMETHOD.


  METHOD fill_structure.
    rs_source  = VALUE ts_source(
      text1 = 'Some value'
      text3 = 'New values'
      num1 = 12
      longtext = `This is a very long ABAP string in a structure field`
    ).
  ENDMETHOD.


  METHOD move_simple_structure.
    DATA(ls_source) = fill_structure( ).

    DATA(ls_target) = CORRESPONDING ts_target( ls_source ).

    io_out->write( |Simple move:| ).
    io_out->write( ls_target ).
  ENDMETHOD.


  METHOD move_with_mapping.
    DATA(ls_source) = fill_structure( ).

    DATA(ls_target) = CORRESPONDING ts_target( ls_source MAPPING text2 = text3 num = num1 ).

    io_out->write( |Move with mapping:| ).
    io_out->write( ls_target ).
  ENDMETHOD.


  METHOD move_without_fields.
    DATA(ls_source) = fill_structure( ).

    DATA(ls_target) = CORRESPONDING ts_target( ls_source MAPPING text2 = text3 num = num1 EXCEPT longtext ).

    io_out->write( |Move without longtext:| ).
    io_out->write( ls_target ).
  ENDMETHOD.


  METHOD move_duplicate_tables.
    DATA(lt_source) = VALUE tt_source(
      ( num1 = 14 text1 = 'Bread' )
      ( num1 = 3 text1 = 'Butter' )
      ( num1 = 7 text1 = 'Jam' )
      ( num1 = 14 text1 = 'Salt' )
      ( num1 = 11 text1 = 'Egg' )
      ( num1 = 19 text1 = 'Coffee' )
    ).

    DATA(lt_target) = CORRESPONDING tt_target_key( lt_source DISCARDING DUPLICATES MAPPING ident = num1 ).

    io_out->write( |Move table with key:| ).
    io_out->write( lt_target ).
  ENDMETHOD.


  METHOD move_nested_structure.
    DATA(ls_source) = VALUE ts_source_nested(
      field1 = 'Sub structure'
      sub = fill_structure( )
    ).

    DATA(ls_target) = CORRESPONDING ts_target_nested( ls_source
      MAPPING field = field1
      ( sub = sub MAPPING text2 = text3 num = num1 )
    ).

    io_out->write( |Nested move:| ).
    io_out->write( ls_target-field ).
    io_out->write( ls_target-sub ).
  ENDMETHOD.
ENDCLASS.

 

Conclusion

The new statement is more powerful than you might think. Together with the older article on CORRESPONDING, you get the full overview of the new statement and how you can use it sensibly.


Included topics:
Deep DiveCorrespondingNew ABAP
Comments (0)



And further ...

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


ABAP Deep Dive - FOR (Loops)

Category - ABAP

Let's take a closer look at the FOR loop. How does it work? What do I have to consider and what can I do with it?

04/14/2023

ABAP Deep Dive - Table access (internal)

Category - ABAP

In this article, let's take a look at table access to internal tables and how they replace READ TABLE.

02/03/2023

ABAP Deep Dive - VALUE

Category - ABAP

In this article we want to look at the value statement again in all its forms and how you can use it in your daily work.

11/11/2022

ABAP - Corresponding and Value

Category - ABAP

The two expressions focus primarily on creating structures and moving data content in the context of tables. We want to show you today the two statements and which commands they replace.

12/07/2018

ABAP - XCO Libraries

Category - ABAP

What can you do with the library in ABAP and ABAP Cloud and how do you use the objects the best way? Find out more here.

11/12/2024