【问题标题】:REDUCE creates flat structure instead of table. Why?REDUCE 创建平面结构而不是表格。为什么?
【发布时间】:2021-12-28 18:17:08
【问题描述】:

我的目标是使用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

结果为@​​987654327@:

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

上面的sn-p是用fieldname创建一个深层结构lt_where,并且只保存一行数据。似乎是语法问题。这里需要纠正什么?

【问题讨论】:

标签: for-loop abap


【解决方案1】:

如果您不介意,我希望先发布与您的经典循环完全相同的构造函数表达式,以下是我的评论:

  • 如果您不需要复杂的计算,建议使用 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. 关于您对不同结构和新逻辑的特定要求,以下是您可以得到的(与之前的代码相比没有什么特别之处,只是添加了表类型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 }| ) ) ) ).

【讨论】:

  • 感谢您的详细回答。正如您所说,使用VALUE 比使用REDUCE 容易得多。我现在正在尝试使用简单的代码来理解和学习REDUCE。在这个过程中,答案真的帮助了我。
猜你喜欢
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-05
  • 2022-12-10
  • 1970-01-01
相关资源
最近更新 更多