Skip to Content
2

Strange behaviour of substring in reduce expression with cond

Dec 11, 2017 at 05:40 PM

214

avatar image

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.

10 |10000 characters needed characters left characters exceeded

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_utilities.htm

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

0

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

0

Link is not working for me

0

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.

0
* Please Login or Register to Answer, Follow or Comment.

3 Answers

Best Answer
Jacques Nomssi Dec 11, 2017 at 06:25 PM
5

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

Show 1 Share
10 |10000 characters needed characters left 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.

0
Horst Keller
Dec 12, 2017 at 07:03 AM
2

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

Show 2 Share
10 |10000 characters needed characters left characters exceeded
Former Member

Hello, Horst!

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

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

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

1
Jacques Nomssi Dec 11, 2017 at 06:15 PM
-2

Hello Christian,

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

JNN

Share
10 |10000 characters needed characters left characters exceeded