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: 

ABAP: Unexpected behaviour of reduce expression

ChristianGünter
Contributor

Today I stumbled across an unexpected behaviour in a reduce table expression and couldn't find any hint in the documentation.

Consider these two reduce operations.

    TYPES: BEGIN OF ty_output,
             head     TYPE string,
             position TYPE string,
           END OF ty_output.


    SELECT FROM t100
           FIELDS *
           WHERE sprsl = @sy-langu
           ORDER BY PRIMARY KEY
           INTO TABLE @DATA(t100_tab)
           UP TO 10 ROWS.


    DATA(output) = REDUCE ty_output( INIT result = VALUE ty_output( )
                                     FOR GROUPS group OF ls_t100 IN t100_tab
                                     INDEX INTO index
                                     GROUP BY ( arbgb = ls_t100-arbgb
                                                msgnr = ls_t100-msgnr )
                                     FOR <ls_t100> IN GROUP group
                                     NEXT result = VALUE #( position = result-position && |\n{ <ls_t100>-text }| ) ). " <=== difference here


    DATA(output2) = REDUCE ty_output( INIT result = VALUE ty_output( )
                                      FOR GROUPS group OF ls_t100 IN t100_tab
                                      INDEX INTO index
                                      GROUP BY ( arbgb = ls_t100-arbgb
                                                 msgnr = ls_t100-msgnr )
                                      FOR <ls_t100> IN GROUP group
                                      NEXT result-position = result-position && |\n{ <ls_t100>-text }| ). " <=== difference here


    " fails:
*    ASSERT output = output2.

    cl_demo_output=>write( output-position ).
    cl_demo_output=>write( output2-position ).
    cl_demo_output=>display( ).

I expected that both return the same value. They don't.

Can anybody explain that? Is that documented somewhere?

Maybe horst.keller is around 😉

Thanks.

Christian

P.s. You can also find the code in this abapGit repo.

1 ACCEPTED SOLUTION

glensimpson
Explorer

Hi Christian

This is just a semi-educated guess but I think that OUTPUT only gets the last message in the internal table due to the VALUE #( ) operator in the last line of the first REDUCE statement.

NEXT result = VALUE #( position = result-position && |\n{ <ls_t100>-text }| ) )

My understanding of the VALUE operator is that it initialises the left hand side (in your case, the RESULT structure) *before* it constructs the right hand side. So RESULT-POSITION is always empty when it concatenates the next message.

The second REDUCE doesn not use the VALUE operator and so doesn't clear the RESULT structure in each iteration... resulting in a longer string.

Of course, I could be wrong. 🙂

Regards
Glen

6 REPLIES 6

glensimpson
Explorer

Hi Christian

This is just a semi-educated guess but I think that OUTPUT only gets the last message in the internal table due to the VALUE #( ) operator in the last line of the first REDUCE statement.

NEXT result = VALUE #( position = result-position && |\n{ <ls_t100>-text }| ) )

My understanding of the VALUE operator is that it initialises the left hand side (in your case, the RESULT structure) *before* it constructs the right hand side. So RESULT-POSITION is always empty when it concatenates the next message.

The second REDUCE doesn not use the VALUE operator and so doesn't clear the RESULT structure in each iteration... resulting in a longer string.

Of course, I could be wrong. 🙂

Regards
Glen

0 Kudos

Yes, that would be a reasonable explanation. But it came a bit as a surprise to me. Therefore I hoped to find something about in the documentation. But hadn't any luck yet.

horst_keller
Product and Topic Expert
Product and Topic Expert

Glen's answer is correct

ChristianGünter
Contributor

Yep, that's it.

And we have the BASE or LET addition, to circumvent that.

There are examples in the documentation too.

https://help.sap.com/http.svc/rc/abapdocu_752_index_htm/7.52/en-US/index.htm?file=abenvalue_construc...

ChristianGünter
Contributor
0 Kudos

Thanks to Glens and Horsts answers I was able to solve my issue with the base addition of the value constructor expression. I updated the repo if anybody is interested.

    DATA(output) = REDUCE ty_output( INIT result = VALUE ty_output( )
                                     FOR GROUPS group OF ls_t100 IN t100_tab
                                     INDEX INTO index
                                     GROUP BY ( arbgb = ls_t100-arbgb
                                                msgnr = ls_t100-msgnr )
                                     FOR <ls_t100> IN GROUP group
                                     NEXT result = VALUE #( BASE result
                                                            position = result-position && |\n{ <ls_t100>-text }| ) ). " <=== solution with base
*                                     NEXT result = VALUE #( position = result-position && |\n{ <ls_t100>-text }| ) ). " <=== difference here