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.
Table of contents
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.
FOR
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.
TYPES:
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,
tt_idata TYPE STANDARD TABLE OF ts_idata WITH EMPTY KEY.
FOR-EACH Loop
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.
INSERT VALUE #(
bukrs = ls_bukrs-bukrs
butxt = ls_bukrs-butxt
land1 = ls_bukrs-land1
adate = sy-datum
index = ld_tabix
) INTO TABLE lt_old.
ENDLOOP.
" 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.
DATA:
lt_text TYPE string_table.
it_strings = VALUE #( FOR ld_x = 1 THEN ld_x + 2 WHILE ld_x < 50 ( |{ ld_x }| ) ).
REDUCE
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.
FILTER
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.
TYPES:
BEGIN OF ts_data,
lnum TYPE i,
text TYPE string,
date TYPE d,
END OF ts_data,
tt_data TYPE SORTED TABLE OF ts_data WITH NON-UNIQUE KEY date
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.
ENDLOOP.
" 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` ).
Conclusion
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.
Source:
SAP Documentation - FOR
SAP Documentation - REDUCE
SAP Documentation - FILTER