Home > Blockchain >  REDUCE creates flat structure instead of table. Why?
REDUCE creates flat structure instead of table. Why?

Time:11-19

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?

CodePudding user response:

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 ) ) ) ).
  • Related