2023 Nov 02 7:09 PM
Hello,
this is a question and a challenge at the same time 😉
I'd like your opinion about the best writing of a case inside a IF condition, to avoid repeating the same variable again and again:
IF country = 'FR' OR country = 'DE' OR country = 'BE' OR country = 'IT'.<br>ENDIF.
Best writing means a best combination of easy to write and to maintain, short, performing, smart, etc., but of course it's completely subjective, there's no good and bad answer, except people will prefer one or another.
There is no straight ABAP construct to simplify it except CASE, which cannot be used inside IF, but there are many workarounds, which one do you prefer and use?
The challenge is to NOT use CASE, as shown here:
CASE country.
WHEN 'FR' OR 'DE' OR 'BE' OR 'IT'.
ENDCASE.
For information (in case you're looking for it): Clean ABAP - Prefer CASE to ELSE IF for multiple alternative conditions.
Have fun!
Sandra
PS: no price to win 😉
2023 Nov 02 9:44 PM
I think I would move values to a range.
REPORT zza.
PARAMETERS country TYPE char2.
DATA eu_countries TYPE RANGE OF char2.
LOAD-OF-PROGRAM."
eu_countries = VALUE #( ( sign = 'I' option = 'EQ' low = 'FR' )
( sign = 'I' option = 'EQ' low = 'DE' )
( sign = 'I' option = 'EQ' low = 'BE' )
( sign = 'I' option = 'EQ' low = 'IT' )
).
START-OF-SELECTION.
IF country IN eu_countries.
message i000(38) with country 'is in Europe'.
ENDIF.
2023 Nov 03 5:25 AM
2023 Nov 03 6:54 AM
I guess this one is really a bad idea = true for any country code containing one of these characters B, D, E, F, I, R or T 😉
2023 Nov 03 5:31 AM
A variant on the answer of chaouki.akir:
TYPES:
tt_country TYPE RANGE OF country.
IF country IN VALUE tt_country(
sign = 'I'
option = 'EQ'
( low = 'FR' )
( low = 'DE' )
( low = 'BE' )
( low = 'IT' ) ).
ENDIF.
2023 Nov 03 9:21 AM
Hi sandra.rossi Trick question.
I don't like to go against best practices but is necessary need to understand what they want to do, to properly ignore it where follow may reach a worst situation.
The guidance is to prefer CASE instead IF to keep code clean, but in my opinion it only make sense to cover cases like one option exclusive... CASE A, B, C, D... not with OR's because this can have an additional pattern point to "groups".
Extending the situation of OR's, I may reach "groups" of countries and in such scenario I may prefer IF/ELSIF + RANGE keep my clear, concise and reusable as I probably need this information of groups used elsewhere.
IF country in lr_Europe.
ELSIF country in lr_America.
ELSIF country in lt_Asia.
ENDIF.
Regards, Fernando Da Rós
2023 Nov 03 9:26 AM
Follow another option that I may use in rare scenarios, but in my opinion is worst than range:
DATA(country) = CONV t005-land1( 'FR' ).
DATA(lv_temp) = |*{ country };*|.
IF 'FR;DE;BE;IT;' CP lv_temp.
ENDIF.
2023 Nov 03 10:29 AM
It doesn't seem to work:
DATA(country) = CONV t005-land1( 'FR' ).
DATA(lv_temp) = |{ country };*|.
IF lv_temp CP 'FR;DE;BE;IT;'.
WRITE |{ Country } is part of FR;DE;BE;IT;|.
ELSE.
WRITE |{ Country } is NOT part of FR;DE;BE;IT;|.
ENDIF.
2023 Nov 03 10:39 AM
Sorry, due to missing code/test I didn't catch my two mistakes, follow a code that works:
DATA(country) = CONV t005-land1( 'FR' ).
DATA(lv_temp) = |*{ country };*|.
IF 'FR;DE;BE;IT;' CP lv_temp.
WRITE |{ country } is part of FR;DE;BE;IT;|.
ELSE.
WRITE |{ country } is NOT part of FR;DE;BE;IT;|.
ENDIF.
2023 Nov 03 10:42 AM
Is it possible that you update directly your answer, just to clarify at the source? Thanks!
2023 Nov 03 9:41 AM
2023 Nov 03 10:40 AM
Hi fedaros, sure.
I don't think there's just one "best way" to organize the code. So, sometimes it may looks better to use one way, sometimes another way. I guess it should be discussed one example at a time, and finally deduce the rules and preferred ways if there are some agreements (like it's done in the Clean ABAP guide).
Business rules are sometimes very complex, so making indented would be against this other Clean ABAP rule: Keep the nesting depth low.
A workaround is possibly using BRF+ or any other business rule management system.
2023 Nov 03 11:30 AM
Proposal after ideas from chaouki.akir, jack.graus2, tomas.buryanek and fedaros:
IF in_list( val = country list = |{ 'FR' };{ 'DE' };{ 'BE' };{ 'IT' }| sep = ';' ).
ENDIF.
2023 Nov 03 12:03 PM
As you had stated that business rules can sometimes be very complex (and also subject to change), I would potentially opt for BRF+ depending on what needs to happen inside the IF. Call BRF+ and as long as my contract for inputs/outputs does not require change (requires some forethought/assumption), then the resulting actions be modified without ever having to recompile the program.
2023 Nov 03 3:45 PM
Regular expressions are rarely easy to read and maintain, but this simple example might be an exception
IF matches( val = country regex = 'FR|DE|BE|IT' ).
ENDIF.
2023 Nov 03 6:32 PM
Hmmm nice but alas the performance of POSIX regular expressions is really very bad... Possibly PCRE (from ABAP 7.55), would be interesting to see what is its performance compared to a simple IF/CASE.
2023 Nov 04 11:24 AM
This is a summary of all answers. I'll try to update and add indicators of performance, legibility, maintainability, etc.
| Example code |
──┼───────────────────────────────────────────┼
1 | • DATA countries TYPE RANGE OF land1. |
| • countries = VALUE #( sign = 'I' option |
| = 'EQ' ( low = 'FR' ) ( low = 'DE' ) ). |
| • IF country IN countries. |
──┼───────────────────────────────────────────┼
2 | IF country IN VALUE tt_country( |
| sign = 'I' option = 'EQ' ( low = 'FR' ) |
| ( low = 'DE' ) ). |
──┼───────────────────────────────────────────┼
3 | IF 'FR;DE;' CP |*{ country };*|. |
──┼───────────────────────────────────────────┼
4 | IF is_country_eu( country ). |
──┼───────────────────────────────────────────┼
5 | IF matches( val = country regex = |
| 'FR|DE|BE|IT' ). |
──┼───────────────────────────────────────────┼
6 | Use BRF+ |
──┼───────────────────────────────────────────┼
7 | IF in_list( val = country list = |
| |{ 'FR' };{ 'DE' };|. |