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

ABAP - Loops


With New ABAP, new loops and possibilities for restricting table contents were created. We'll take a closer look at these new commands in this article.

In the first step, we can tell you that the LOOP has not yet become completely obsolete and that you can continue to use it. With the new possibilities, only more efficient and shorter functions have been created in some places.



Finally there is also a FOR loop in ABAP, the developers have waited a long time for it. But is the loop good for replacing the classic LOOP? Not quite, we can tell you, especially if you want to put a little more logic into the loop. Accordingly, the design comes in two classic variants.

The first step is an overview of the data type that we want to use for the following examples. This consists partly of technical data and partly of company code data.

  BEGIN OF ts_idata,
    index TYPE sy-tabix,
    adate TYPE d,
    bukrs TYPE t001-bukrs,
    butxt TYPE t001-butxt,
    land1 TYPE t001-land1,
  END OF ts_idata,



In other programming languages this loop would be known as FOR EACH, in ABAP you simply use the classic FOR loop with the IN addition to iterate over the data and attach them to the target table. At the same time we enrich the data with the table index and set the current date. In the following example, once for the classic way with LOOP and the new variant.

" Old
DATA(lt_old) = VALUE tt_idata( ).
LOOP AT lt_bukrs INTO DATA(ls_bukrs) WHERE land1 = 'DE'.
  DATA(ld_tabix) = sy-tabix.

    bukrs = ls_bukrs-bukrs
    butxt = ls_bukrs-butxt
    land1 = ls_bukrs-land1
    adate = sy-datum
    index = ld_tabix
  ) INTO TABLE lt_old.
" New  
DATA(lt_new) = VALUE tt_idata(
  FOR ls_bukrs IN lt_bukrs INDEX INTO ld_index WHERE ( land1 = 'DE' ) (
    bukrs = ls_bukrs-bukrs
    butxt = ls_bukrs-butxt
    land1 = ls_bukrs-land1
    adate = sy-datum
    index = ld_index


Counting Loop

There is also now the classic counting loop if you want to count through once and want to initialize a table with test data, for example. The variable is defined in the loop and given a start value. Another data type than a string table can be used accordingly.

  lt_text TYPE string_table.

it_strings = VALUE #( FOR ld_x = 1 THEN ld_x + 2 WHILE ld_x < 50 ( |{ ld_x }| ) ).



The new command can get a bit complex to understand, but is basically a reduction of table data (1-n table iterations) into a new data type. This can be a table, but also a number if, for example, a summation was made.

In the following example we reduce the data in the source table and merge it in a new table, some field contents are changed. At the end we create our new target table using an inline declaration.

DATA(lt_new) = REDUCE tt_idata(
  INIT lt_result TYPE tt_idata
  FOR ls_old_bukrs IN lt_bukrs WHERE ( land1 <> 'DE' )
  NEXT lt_result = VALUE #( BASE lt_result
    ( bukrs = ls_old_bukrs-bukrs butxt = |+{ ls_old_bukrs-bukrs+1(3) }| land1 = ls_old_bukrs-land1 )


Hint: You probably won't come across this command too often, but you should have understood it roughly.



The filter is a very interesting new command, as it provides a multitude of possibilities to filter the data in a table and to return a new table directly. There is the possibility of working with a WHERE condition or simply using another table as a filter. The target data type does not have to be specified and can be derived from the original data.

To do this, we define a structure and the corresponding table types. It should be noted that the table receives a primary and a secondary key, as this is required for the use of the FILTER command.

  BEGIN OF ts_data,
    lnum TYPE i,
    text TYPE string,
    date TYPE d,
  END OF ts_data,
                                       WITH NON-UNIQUE SORTED KEY by_text COMPONENTS text.


In the following example we compare the classic and new variants for you. As you can see, the block has now become a bit shorter and clearer.

" Old                                       
DATA(lt_result) = VALUE tt_data( ).
LOOP AT mt_data INTO DATA(ls_data) WHERE date < CONV d( '20200201' ).
  INSERT ls_data INTO TABLE lt_result.

" New
DATA(lt_result) = FILTER #( mt_data WHERE date < CONV d( '20200201' ) ).    


If you want to filter the data using a secondary key, you have to specify this explicitly so that the command can recognize this and use the index. In the following example we want to use the text key that we defined above.

DATA(lt_result) = FILTER #( mt_data USING KEY by_text WHERE text = `Nails` ).



As you have seen in the examples, the new commands give you the opportunity to write shorter source code, but here too you should be careful with the formatting. Even badly formatted source code can quickly lose readability and this is not about readability for you as the writer, but for your colleagues.


SAP Documentation - FOR
SAP Documentation - REDUCE
SAP Documentation - FILTER

Included topics:
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 - Type Casting

Category - ABAP

How do you actually get the original type of a class or instance if it is passed in a generic table? In this article we examine the possibilities.



Category - ABAP

After all these years, the “real” return in ABAP has finally arrived. In this article we will show you how it works and what it can do.


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?


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.


ABAP Developer still relevant

Category - ABAP

In this article we look at whether ChatGPT can already replace an ABAP developer or whether it can be used as a help in everyday life.