REDUCE 创建平面结构而不是 table。为什么?

REDUCE creates flat structure instead of table. Why?

我的目标是使用 FOR 循环实现以下目标。

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.

还有:

  1. LT_FIELDS中有字段名。
  2. LT_FIELDS-FIELDNAME 数据连接成特定格式。
  3. 将其附加到 LT_WHERE

结果LT_WHERECONDN

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

下面是我的代码(不确定在循环中的什么地方添加我的 lv_length 逻辑):

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

上面的代码片段正在创建一个深层结构 lt_wherefieldname,并且只包含一行数据。似乎是一个语法问题。这里需要更正什么?

如果您不介意,我宁愿先 post 与您的经典循环完全等同的构造函数表达式,这是我的评论:

  • 如果您不需要复杂的计算,请选择 VALUE 而不是 REDUCE
  • 使用LET var1 = expr1 var2 = expr2 IN计算辅助变量(只能在这个表达式中使用)。
  • 下面的代码完全反映了您的原始循环,而不是您为简单起见而引入的新结构 (ty_whr)。

完整代码:

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

有关信息,

  1. 关于您对不同结构和新逻辑的特定要求,这是您可以获得的(与之前的代码相比没有什么特别的,除了添加了 table 类型 ty_whr_lines):
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. 关于REDUCE,如果你愿意,你可以使用它,但它更复杂:
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 }| ) ) ) ).