1

My goal is to achieve the following using FOR loop.

DATA(lt_wherecondn) = VALUE string_table( ).
DATA(lt_fields) = VALUE rsds_frange_t( 
    ( fieldname = 'A~FLD1' ) ( fieldname = 'A~FLD2' ) ).
DATA(lv_lines) = lines( lt_fields ).
LOOP AT lt_fields ASSIGNING FIELD-SYMBOL(<fields>).
  DATA(lv_length) = strlen( <fields>-fieldname ) - 2.
  DATA(lv_line) = COND string( 
        WHEN lv_lines <> sy-tabix
        THEN <fields>-fieldname+2(lv_length) && | IN | && |@| && <fields>-fieldname && | AND |
        ELSE <fields>-fieldname+2(lv_length) && | IN | && |@| && <fields>-fieldname ).
  APPEND lv_line TO lt_wherecondn.
ENDLOOP.

Also:

  1. There are field names in LT_FIELDS.
  2. Concatenate LT_FIELDS-FIELDNAME data into a specific format.
  3. Append it to LT_WHERE.

Result in LT_WHERECONDN:

FLD1 IN @A~FLD1 AND
FLD2 IN @A~FLD2

Below is my code (not sure where to add my lv_length logic in the loop):

TYPES: BEGIN OF ty_whr,
         fieldname TYPE string,
       END OF ty_whr.

DATA(lt_where) = REDUCE ty_whr(
                   INIT whereclause = VALUE ty_whr( )
                   FOR <fields> IN lt_fields
                   NEXT whereclause-fieldname = 
                     COND #( WHEN whereclause IS NOT INITIAL
                             THEN <fields>-fieldname && | IN | && |@| && <fields>-fieldname && | AND |
                             ELSE <fields>-fieldname && | IN | && |@| && <fields>-fieldname ) ).

The above snippet is creating a deep structure lt_where with fieldname and holds only one line of data. Seems to be a syntax issue. What needs to be corrected here?

Suncatcher
  • 10,355
  • 10
  • 52
  • 90
isekaid_maou
  • 273
  • 1
  • 9
  • 19

1 Answers1

4

If you don't mind, I would prefer to first post the Constructor Expression which is exactly equivalent to your classic loop, and here are my remarks:

  • Prefer VALUE to REDUCE if you don't need a complex calculation.
  • Use LET var1 = expr1 var2 = expr2 IN to calculate Auxiliary variables (can be used only inside this expression).
  • The below code reflects exactly your original loop, not the new structure you have introduced (ty_whr) for sake of simplicity in the answer.

Full code:

DATA(lt_fields) = VALUE rsds_frange_t(
    ( fieldname = 'A~FLD1' ) ( fieldname = 'A~FLD2' ) ).
DATA(lv_lines) = lines( lt_fields ).

DATA(lt_wherecondn) = VALUE string_table(
    FOR <fields> IN lt_fields INDEX INTO lv_line
    LET lv_length = strlen( <fields>-fieldname ) - 2 IN
    ( COND #( WHEN lv_lines <> lv_line
      THEN |{ <fields>-fieldname+2(lv_length) } IN @{ <fields>-fieldname } AND |
      ELSE |{ <fields>-fieldname+2(lv_length) } IN @{ <fields>-fieldname }| ) ) ).

For information,

  1. concerning your specific requirement with different structures and a new logic, here's what you could get (nothing special compared to the previous code, except that the table type ty_whr_lines was added):
TYPES: BEGIN OF ty_whr,
         fieldname TYPE string,
       END OF ty_whr,
       ty_whr_lines TYPE STANDARD TABLE OF ty_whr WITH EMPTY KEY.

DATA(lt_fields) = VALUE rsds_frange_t(
    ( fieldname = 'A~FLD1' ) ( fieldname = 'A~FLD2' ) ).
DATA(lv_lines) = lines( lt_fields ).

DATA(lt_where) = VALUE ty_whr_lines(
    FOR <fields> IN lt_fields INDEX INTO lv_line
    ( fieldname = COND #( WHEN lv_lines <> lv_line
                  THEN |{ <fields>-fieldname } IN @{ <fields>-fieldname } AND |
                  ELSE |{ <fields>-fieldname } IN @{ <fields>-fieldname }| ) ) ).
  1. about REDUCE, you may use it if you prefer, but it's more complex:
TYPES: BEGIN OF ty_whr,
         fieldname TYPE string,
       END OF ty_whr,
       ty_whr_lines TYPE STANDARD TABLE OF ty_whr WITH EMPTY KEY.

DATA(lt_fields) = VALUE rsds_frange_t(
    ( fieldname = 'A~FLD1' ) ( fieldname = 'A~FLD2' ) ).
DATA(lv_lines) = lines( lt_fields ).

DATA(lt_where) = REDUCE #(
    INIT whereclause = VALUE ty_whr_lines( )
    FOR <fields> IN lt_fields
    NEXT whereclause = VALUE #( BASE whereclause
    ( fieldname = COND #( WHEN whereclause IS NOT INITIAL
                  THEN |{ <fields>-fieldname } IN @{ <fields>-fieldname } AND |
                  ELSE |{ <fields>-fieldname } IN @{ <fields>-fieldname }| ) ) ) ).
Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
  • 2
    Thanks for the detailed answer. As you say, using `VALUE` is much easier than `REDUCE`. I am trying to understand and learn `REDUCE` using simple code for now. The answer really helped me in the process. – isekaid_maou Nov 18 '21 at 08:29