Skip to Content

Strange behaviour of substring in reduce expression with cond

Today I stumbled about something which didn't make any sense at all to me. Consider this sample data which I want to reduce to a string omiting the first 5 characters and if there are less than 5 characters I'd insert a line break.

" sample data
DATA(text_tab) = VALUE stringtab( ( `-----Test` )
                                  ( ` ` )
                                  ( `-----Test` )
                                  ( `-----Test` ) ).

The desired result would be `Test\nTestTest`.

Let's try to solve this with reduce expressions. This one gives me the desired result.

DATA(string) = REDUCE string( INIT result = ||
                              FOR line IN text_tab
                              NEXT result = result && 
                                   COND #( WHEN strlen( line ) < 5 THEN |\n|
                                           ELSE substring( val = line
                                                           off = 5 ) ) ).

cl_demo_output=>display( string ).

Now this slightly changed expression does something strange.

DATA(string) = REDUCE string( INIT result = ||
                              FOR line IN text_tab
                              NEXT result = result && 
                                   COND #( WHEN strlen( line ) < 5 
                                           THEN cl_abap_char_utilities=>newline
                                           ELSE substring( val = line
                                                           off = 5 ) ) ).
cl_demo_output=>display( string ).

The only difference between the two examples it the use of string template line break |\n| compared to cl_abap_char_utilities=>newline.

It becomes even stranger.

If I use cl_abap_char_utilities=>cr_lf I get yet another result.

DATA(string) = REDUCE string( INIT result = ||
                              FOR line IN text_tab
                              NEXT result = result && 
                                   COND #( WHEN strlen( line ) < 5 
                                           THEN cl_abap_char_utilities=>cr_lf
                                           ELSE substring( val = line
                                                           off = 5 ) ) ).

cl_demo_output=>display( string ).

That doesn't seem right to me and I can't explain. Am I missing the obvious or is there something rotten in the state of denmark?

Maybe Horst Keller is around?

Regards Christian.

P.S. I'm on S/4 Hana with this kernel.

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

3 Answers

  • Best Answer
    Dec 11, 2017 at 06:25 PM

    I tried it now, the 2nd problem is the type inference in operator COND #( ). COND string( ) should work.

    Add comment
    10|10000 characters needed characters exceeded

    • You're right. I somehow assumed that the type inference detects string as datatype. I think now it makes sense. cl_abap_char_utilities=>cr_lf has length two and cl_abap_char_utilities=>newline has length one.

  • Dec 12, 2017 at 07:03 AM

    Jacques answer regarding type inference is correct.

    As you can see from the syntax error in

    DATA result TYPE string.
    result = `x` && CONV #( 'yy' ).
    

    there is no type inference possible inside the string expression.

    Because of that, the documented behavior of COND takes place, where the type of the operand behind the first THEN is taken.

    DATA result TYPE string.
    result = `x` && COND #( WHEN 1 = 2 THEN 'yy' ELSE 'zzzzzzzzzz' ) .
    

    Add comment
    10|10000 characters needed characters exceeded

    • Yes. Type inference produces c of length 1 originating from built-in constant space. To that the value 777 is assigned, which is too long. The rest is explained by the conversion rule from i to c.

      Look it up.

      (People some times say "SAP celebrates christmas")

  • Dec 11, 2017 at 06:15 PM
    -2

    Hello Christian,

    I would try |\\n| instead of |\n|.

    JNN

    Add comment
    10|10000 characters needed characters exceeded