Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

VALUE and multiple FOR operators to create internal table

MichiFr
Participant
0 Likes
7,590

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

1 ACCEPTED SOLUTION
Read only

SuhaSaha
Product and Topic Expert
Product and Topic Expert
5,857

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.

13 REPLIES 13
Read only

Nicolas
Active Contributor
5,857

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

Read only

0 Likes
5,857

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

Read only

SuhaSaha
Product and Topic Expert
Product and Topic Expert
5,857

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 😉

Read only

SuhaSaha
Product and Topic Expert
Product and Topic Expert
5,858

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.

Read only

0 Likes
5,857

That's it - thanks for this suggestion!

Michael

Read only

retired_member
Product and Topic Expert
Product and Topic Expert
5,857

Use VALUE ... FOR behind BASE of VALUE?

Read only

SuhaSaha
Product and Topic Expert
Product and Topic Expert
0 Likes
5,857

Hi Horst,

If there are more than 2 sources than the BASE will become nested, isn't it?

BR,

Suhas

Read only

Sandra_Rossi
Active Contributor
5,857

My comment is off topic, but you could also use the CORRESPONDING constructor to reduce the size of the code.

Read only

SuhaSaha
Product and Topic Expert
Product and Topic Expert
0 Likes
5,857

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 😉

Read only

0 Likes
5,857

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' ) ) ).
Read only

SuhaSaha
Product and Topic Expert
Product and Topic Expert
0 Likes
5,857
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:

  • single VALUE operator,
  • auxiliary variables.
Read only

0 Likes
5,857

Sometimes, the conclusion is that the question has not an expected answer, but another way to do it. I prefer another way 🙂

Read only

retired_member
Product and Topic Expert
Product and Topic Expert
5,857
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 
 )
 ).