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: 

Strange behaviour of substring in reduce expression with cond

ChristianGünter
Contributor

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.

1 ACCEPTED SOLUTION

nomssi
Active Contributor

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

11 REPLIES 11

ChristianGünter
Contributor
0 Kudos
REPORT zdemo.

CLASS demo DEFINITION.
  PUBLIC SECTION.
    METHODS: start.

  PRIVATE SECTION.
    METHODS:
      _get_line_break
        RETURNING VALUE(r_line_break) TYPE string.
ENDCLASS.

CLASS demo IMPLEMENTATION.

  METHOD start.

    DATA(text_tab) = VALUE stringtab( ( `-----Test` )
                                      ( ` ` )
                                      ( `-----Test` )
                                      ( `-----Test` ) ).

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

    cl_demo_output=>display( string ).

  ENDMETHOD.

  METHOD _get_line_break.

    r_line_break = |\n|.

  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.
  NEW demo( )->start( ).

horst_keller
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hmm, see the assertions under https://help.sap.com/http.svc/rc/abapdocu_752_index_htm/7.52/en-US/index.htm?file=abencl_abap_char_u...

I'll have a closer look tomorrow, dancing class starts now.

ChristianGünter
Contributor
0 Kudos

Link is not working for me

ChristianGünter
Contributor
0 Kudos

Btw. I don't care about the line break. My main point is that the substring function does strange things.

nomssi
Active Contributor
0 Kudos

Hello Christian,

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

JNN

nomssi
Active Contributor

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

0 Kudos

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.

horst_keller
Product and Topic Expert
Product and Topic Expert
0 Kudos

Oops, authorization was for "SAP Employees only" (I guess because I uploaded a new version on friday).

I raised it to "everyone".

Please check again.

horst_keller
Product and Topic Expert
Product and Topic Expert

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

0 Kudos

Hello, Horst!

Could you explain to me why lv_val = '*' ?

DATA(lv_val) = COND #( WHEN 1 = 2 THEN space ELSE 777 ).

horst_keller
Product and Topic Expert
Product and Topic Expert

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")