Application Development 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: 

VALUE and multiple FOR operators to create internal table

MichiFr
Participant
0 Kudos

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

SuhaSaha
Advisor
Advisor

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

Nicolas
Active Contributor

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

0 Kudos

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

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 😉

SuhaSaha
Advisor
Advisor

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.

0 Kudos

That's it - thanks for this suggestion!

Michael

horst_keller
Product and Topic Expert
Product and Topic Expert

Use VALUE ... FOR behind BASE of VALUE?

0 Kudos

Hi Horst,

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

BR,

Suhas

Sandra_Rossi
Active Contributor

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

0 Kudos

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 😉

0 Kudos

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

0 Kudos
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.

0 Kudos

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

horst_keller
Product and Topic Expert
Product and Topic Expert
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 
 )
 ).