2016 Nov 24 1:20 PM
Hi,
I'm searching for a way to create an internal table using the VALUE #() operator with multiple FOR expressions inside.
While this works of course with a single FOR operator I can't get this working with more than one operator, right now. Maybe it's impossible at all, may be I'm still doing something wrong.
So far I tried:
DATA(lt_sel) = VALUE rsparams_tt(
FOR <v2> IN p_reason
(
selname = 'P_AUGRU'
high = <v2>-high
low = <v2>-low
option = <v2>-option
sign = <v2>-sign
)
FOR <v1> IN p_auart
(
selname = 'P_AUART'
high = <v1>-high
low = <v1>-low
option = <v1>-option
sign = <v1>-sign
)
).
to no avail.
These are non-nested FOR expressions but sequential ones that should create a single internal table from different sources.
So do you have an idea how to get this working?
Michael
2016 Nov 24 1:48 PM
Hello Michael,
How about using auxiliary variables?
DATA(lt_sel1)
= VALUE rsparams_tt(
LET
sel1 = VALUE rsparams_tt( FOR <so1> IN s_carrid
( selname = 'S_CARRID'
kind = 'S'
sign = <so1>-sign
option = <so1>-option
low = <so1>-low
high = <so1>-high ) )
sel2 = VALUE rsparams_tt( FOR <so2> IN s_connid
( selname = 'S_CARRID'
kind = 'S'
sign = <so2>-sign
option = <so2>-option
low = <so2>-low
high = <so2>-high ) )
IN
( LINES OF sel1 )
( LINES OF sel2 )
).
TBH i was not aware that multiple FORs result in a nested loop.
2016 Nov 24 1:40 PM
Hello,
As per the ABAP Documentation, the syntax is:
... VALUE dtype|#( [let_exp]
[BASE itab]
[FOR for_exp1
FOR for_exp2
... ]
( line_spec1 )
( line_spec2 )
... ) ...
Then, could you retry with the following code ?
DATA(lt_sel) = VALUE rsparams_tt(
FOR <v2> IN p_reason
FOR <v1> IN p_auart
(
selname = 'P_AUGRU'
high = <v2>-high
low = <v2>-low
option = <v2>-option
sign = <v2>-sign
)
(
selname = 'P_AUART'
high = <v1>-high
low = <v1>-low
option = <v1>-option
sign = <v1>-sign
)
).
Best regards, Nicolas
2016 Nov 24 1:53 PM
I know this from the help, however, doing this way you are nesting the FORs, equallly to nested LOOPs and you will get lines(<v2>) * lines(<v1>) in the final table.
In my case if the internal table p_reason holds 10 lines and p_auart 5 lines, the result will get 50 lines instead of expected 15 lines.
Michael
2016 Nov 24 2:04 PM
Hi Nicolas,
TBH i was not aware that the Multiple FORs would result in a nested loop 😞
I read the SAP documentation and then wrote this code snippet to check the behaviour
TABLES: sflight.
SELECT-OPTIONS:
s_carrid FOR sflight-carrid,
s_connid FOR sflight-connid.
DATA(lt_sel1)
= VALUE rsparams_tt(
LET
sel1 = VALUE rsparams_tt( FOR <so1> IN s_carrid
( selname = 'S_CARRID'
kind = 'S'
sign = <so1>-sign
option = <so1>-option
low = <so1>-low
high = <so1>-high ) )
sel2 = VALUE rsparams_tt( FOR <so2> IN s_connid
( selname = 'S_CARRID'
kind = 'S'
sign = <so2>-sign
option = <so2>-option
low = <so2>-low
high = <so2>-high ) )
IN
( LINES OF sel1 )
( LINES OF sel2 )
).
DATA(lt_sel2)
= VALUE rsparams_tt(
FOR <so1> IN s_carrid
FOR <so2> IN s_connid
( selname = 'S_CARRID'
kind = 'S'
sign = <so1>-sign
option = <so1>-option
low = <so1>-low
high = <so1>-high )
( selname = 'S_CARRID'
kind = 'S'
sign = <so2>-sign
option = <so2>-option
low = <so2>-low
high = <so2>-high )
).
cl_demo_output=>new(
)->begin_section( |Auxilliary Variables|
)->write_data( lt_sel1
)->end_section(
)->begin_section( |Multiple FORs|
)->write_data( lt_sel2
)->end_section(
)->display( ).
BR,
Suhas
PS - I don't use TABLES in productive code 😉
2016 Nov 24 1:48 PM
Hello Michael,
How about using auxiliary variables?
DATA(lt_sel1)
= VALUE rsparams_tt(
LET
sel1 = VALUE rsparams_tt( FOR <so1> IN s_carrid
( selname = 'S_CARRID'
kind = 'S'
sign = <so1>-sign
option = <so1>-option
low = <so1>-low
high = <so1>-high ) )
sel2 = VALUE rsparams_tt( FOR <so2> IN s_connid
( selname = 'S_CARRID'
kind = 'S'
sign = <so2>-sign
option = <so2>-option
low = <so2>-low
high = <so2>-high ) )
IN
( LINES OF sel1 )
( LINES OF sel2 )
).
TBH i was not aware that multiple FORs result in a nested loop.
2016 Nov 24 1:57 PM
2016 Nov 24 4:45 PM
2016 Nov 25 7:51 AM
Hi Horst,
If there are more than 2 sources than the BASE will become nested, isn't it?
BR,
Suhas
2016 Nov 24 5:20 PM
My comment is off topic, but you could also use the CORRESPONDING constructor to reduce the size of the code.
2016 Nov 25 8:08 AM
Like this ...
DATA(lt_sel1)
= VALUE rsparams_tt(
LET
sel1 = VALUE rsparams_tt( FOR <so1> IN s_carrid
( VALUE #( BASE CORRESPONDING #( <so1> )
selname = 'S_CARRID'
kind = 'S' ) ) )
sel2 = VALUE rsparams_tt( FOR <so2> IN s_connid
( VALUE #( BASE CORRESPONDING #( <so2> )
selname = 'S_CONNID'
kind = 'S' ) ) )
IN
( LINES OF sel1 )
( LINES OF sel2 )
).
I'm not sure about the readability though 😉
2016 Nov 25 9:38 AM
Is it a requirement to use only one statement?
TABLES sflight.
SELECT-OPTIONS s_carrid FOR sflight-carrid.
SELECT-OPTIONS s_connid FOR sflight-connid.
DATA lt_sel TYPE rsparams_tt.
lt_sel = VALUE #( FOR <v2> IN S_carrid ( VALUE #(
BASE CORRESPONDING #( <v2> ) selname = 'S_CARRID' ) ) ).
lt_sel = VALUE #( base lt_sel FOR <v1> IN S_cONNid ( VALUE #(
BASE CORRESPONDING #( <v1> ) selname = 'S_CONNID' ) ) ).
2016 Nov 25 9:44 AM
Is it a requirement to use only one statement?
The OP wanted to use VALUE to fill up an internal table using multiple FORs, hence:
2016 Nov 25 9:50 AM
Sometimes, the conclusion is that the question has not an expected answer, but another way to do it. I prefer another way 🙂
2016 Nov 25 11:27 AM
TYPES itab TYPE TABLE OF i WITH EMPTY KEY.
DATA(itab) = VALUE itab(
BASE VALUE itab(
BASE VALUE itab(
FOR i = 10 UNTIL i > 13 ( i ) )
FOR i = 20 UNTIL i > 23 ( i ) )
FOR i = 30 UNTIL i > 33 ( i ) ).
gives
10
11
12
13
20
21
22
23
30
31
32
33
Each FOR expression adds 4 lines to itab, one package after the other.
So, the very first example above might simply be rewritten as follows:
DATA(lt_sel) = VALUE rsparams_tt(
BASE VALUE rsparams_tt(
FOR <v2> IN p_reason
(
selname = 'P_AUGRU'
high = <v2>-high
low = <v2>-low
option = <v2>-option
sign = <v2>-sign
)
)
FOR <v1> IN p_auart
(
selname = 'P_AUART'
high = <v1>-high
low = <v1>-low
option = <v1>-option
sign = <v1>-sign
)
).