As of ABAP 740, there is a new iteration expression available – FOR. This can be used along with VALUE to populate the desired data. Lets see how it works.
Introduction
ABAP 740 has lot of new features and FOR is one of them. FOR is the Iteration Expression. An iteration expression is to perform the iteration on the table. The FOR can be used with Constructor Operators – like NEW, VALUE. It is like the LOOP but using the different pattern.
I have already used the FOR in the ABAP 740 – Mesh Path – Forward and Inverse Association articles, you must have known it by now 🙂
Syntax
At simple level, the syntax is like this:
DATA(t_city) = VALUE tt_citys( FOR ls_cust IN t_customres INDEX INTO cust_index ( ls_cust-city ) ).
Point to note:
- You need to specify the work area of the field symbol. The type of the work area is determined with the type of the internal table. These are only visible within the FOR expression. They can’t be used outside of the FOR.
- The INDEX specification will assign the index of the table in current row
- You can specify the where condition. This is pretty much same as what you do for LOOP.
- You can also specify the LET expression. This is a new expression which you can use for specifying some values for few of the components. This can be the calculation or simple default value.
Example 1 – Append value of 1 field into another table using FOR
In this simple use of FOR, single column table is populated using FOR and VALUE.
TYPES: BEGIN OF ty_customer, customer TYPE char10, name TYPE char30, city TYPE char30, route TYPE char10, END OF ty_customer. TYPES: tt_customers TYPE SORTED TABLE OF ty_customer WITH UNIQUE KEY customer. TYPES: tt_citys TYPE STANDARD TABLE OF char30 WITH EMPTY KEY. DATA(t_customres) = VALUE tt_customers( ( customer = 'C0001' name = 'Test Customer 1' city = 'NY' route = 'R0001' ) ( customer = 'C0002' name = 'Customer 2' city = 'LA' route = 'R0003' ) ( customer = 'C0003' name = 'Good Customer 3' city = 'DFW' route = 'R0001' ) ( customer = 'C0004' name = 'Best Customer 4' city = 'CH' route = 'R0003' ) ). * FOR to get the column CITY DATA(t_city) = VALUE tt_citys( FOR ls_cust IN t_customres ( ls_cust-city ) ).
As you see, the debugger shows that values are actually moved from the T_CUSTOMERS to T_CITY.
Example 2 – FOR with WHERE condition
Here Moving the field CITY from T_CUSTOMERS to T_CITY_IN_03 only where ROUTE is some specific value
DATA(t_city_in_03) = VALUE tt_citys( FOR ls_cust IN t_customres WHERE ( route = 'R0001' ) ( ls_cust-city ) ).
Same, debugger shows the values in the T_CITY_IN_03:
Also NOTE that LS_CUST is declared in both examples. There is any syntax error here as the visibility is only within the specific FOR.
Example 3 – Nested FOR with 2 tables
Here Added few more table in the bunch. The FOR is a nested where the 2nd FOR has the WHERE condition to only loop where the value is same. FOR can be used with multiple nested loops. This is same as Nested LOOPs using the LOOP AT and LOOP AT WHERE.
TYPES: BEGIN OF ty_route_config, route TYPE char10, c_type TYPE char10, c_value TYPE char40, END OF ty_route_config. TYPES: tt_route_config TYPE SORTED TABLE OF ty_route_config WITH UNIQUE KEY route c_type. TYPES: BEGIN OF ty_routes, route TYPE char10, name TYPE char40, END OF ty_routes. TYPES: tt_routes TYPE SORTED TABLE OF ty_routes WITH UNIQUE KEY route. DATA(t_routes) = VALUE tt_routes( ( route = 'R0001' name = 'Route 1' ) ( route = 'R0002' name = 'Route 2' ) ( route = 'R0003' name = 'Route 3' ) ). DATA(t_rc) = VALUE tt_route_config( ( route = 'R0001' c_type = 'RTYPE' c_value = 'DSD' ) ( route = 'R0001' c_type = 'MAX' c_value = '10' ) ( route = 'R0002' c_type = 'RTYPE' c_value = 'WH' ) ( route = 'R0002' c_type = 'MAX' c_value = '100' ) ( route = 'R0003' c_type = 'RTYPE' c_value = 'WH' ) ( route = 'R0004' c_type = 'RTYPE' c_value = 'DSD' ) ). * Nested FOR - 2 levels TYPES: tt_names TYPE STANDARD TABLE OF char40 WITH DEFAULT KEY. DATA(t_route_names) = VALUE tt_names( FOR ls_cust_1 IN t_customres FOR ls_route IN t_routes WHERE ( route = ls_cust_1-route ) ( ls_route-name ) ).
In debugger, you can see the final table has name of the route.
Example 4 – Nested LOOP with multiple tables
Same as example 3, but one more table in the FOR
* Nested FOR - 3 levels TYPES: BEGIN OF ty_routes_max, route TYPE char10, name TYPE char40, c_value TYPE char40, END OF ty_routes_max. TYPES: tt_routes_max TYPE STANDARD TABLE OF ty_routes_max WITH DEFAULT KEY. DATA(t_routes_max) = VALUE tt_routes_max( FOR ls_cust_2 IN t_customres FOR ls_route_2 IN t_routes WHERE ( route = ls_cust_2-route ) FOR ls_rc_2 IN t_rc WHERE ( route = ls_route_2-route AND c_type = 'MAX' ) ( route = ls_route_2-route name = ls_route_2-name c_value = ls_rc_2-c_value ) ).
In the debugger, you can see the result table has only routes with MAX config.
Example 5 – LET with specific (and default) value with FOR
Here you can see the FOR is used with LET. The LV_NAME is read using the tabular expression or [ ] from the table. The LV_ROUE is also read using the tabular expression but for only first row [1].
TYPES: BEGIN OF ty_routes_cust, route TYPE char10, name TYPE char40, customer TYPE char10, END OF ty_routes_cust. TYPES: tt_routes_cust TYPE STANDARD TABLE OF ty_routes_cust WITH DEFAULT KEY. *data(t_routes_cust) = * value tt_routes_cust( * for ls_cust_l in t_customres * "where ( customer = 'C0001' ) * let LV_NAME = 'teSTING name' * LV_ROUTE = 'TESTING ROUTE' * IN NAME = LV_NAME * ROUTE = LV_ROUTE * ( CUSTOMER = ls_cust_L-CUSTOMER ) * ). DATA(t_routes_cust) = VALUE tt_routes_cust( FOR ls_cust_l IN t_customres INDEX INTO cust_index "where ( customer = 'C0001' ) LET lv_name = t_routes[ route = t_customres[ cust_index ]-route ]-name lv_route = t_routes[ 1 ]-route IN name = lv_name route = lv_route ( customer = ls_cust_l-customer ) ).
Debugger is like this for this example:
Example 6 – FOR with LET to populate the RANGE
This is cool. You can use the FOR with LET to specify the default value and fill up the range. Awesome!
TYPES: tt_route_range TYPE RANGE OF char10. DATA(t_route_range) = VALUE tt_route_range( "( sign = 'I' option = 'BT' low = '001' high = '002' ) FOR ls_cust_r IN t_customres LET s = 'I' o = 'EQ' IN sign = s option = o ( low = ls_cust_r-route ) ).
Note that range is populated with the fixed I and EQ.
For with GROUP –
There are more into the FOR. You can specify the GROUP to only obtain the unique rows. I don’t have system with this yet so, explore 🙂 – ABAP 740 – FOR at ABAP Help
Table of Content – ABAP 740 Concepts
- ABAP 740 – NEW Operator to instantiate the objects
- ABAP 740 – NEW Operator to create ITAB entries
- ABAP 740 – VALUE Operator to create ITAB entries
- ABAP 740 – Table Expressions to Read & Modify ITAB line
- ABAP 740 – LINE_EXISTS to check record in ITAB
- ABAP 740 – Meshes – A new complex type of Structures
- ABAP 740 – Mesh Path – Forward and Inverse Association
- ABAP 740 – FOR Iteration Expression
- ABAP 740 SWITCH – Conditional Operator
- ABAP 740 – LOOP AT with GROUP BY
- ABAP 740 – Is CONSTANT not a Static Attribute anymore?
- SALV IDA (Integrated Data Access) – Introduction
- SALV IDA – Selection Conditions
- SALV IDA – New Calculated Fields
- SALV IDA – Column Settings
- SALV IDA – Add and Handle Hotspot (Hyperlink)
Really very nice and clear explanation..
Best site to stay up to date with latest ABAP changes !! 🙂
this is super and good.
I have one question, in the table and workarea comes as inline declaration.
how we will use it if the table is declaration or if i am using the existing structure or custom one
@Gokul,
The inline declaration is smart and knows which structure is being return back based on the type. So, this would declare T_ROUTE_MAX with type TT_ROUTE_MAX
Thanks,
Naimesh Patel
There is any why to use the FOR command and get not doplicated values?
@TashTash – I haven’t tried but it should be possible with the GROUP BY addition for the FOR. I would give a try and see if it gives Unique values.