2

这是给你的……</p>

这段代码怎么会导致一个空表gt_test2……</p>

gt_test2 = VALUE #(
  FOR gs_test1 IN gt_test1 WHERE ( v3 = gs_test3-v3 AND v4 = gs_test3-v4 )
  FOR gs_test2 IN gt_test2 WHERE ( v1 = gs_test1-v1 AND v2 = gs_test1-v2 )
  ( gs_test2 )
).
WRITE / lines( gt_test2 ).

这会产生正确的结果吗?

DATA: gt_test2_2 LIKE gt_test2.
gt_test2_2 = VALUE #(
  FOR gs_test1 IN gt_test1 WHERE ( v3 = gs_test3-v3 AND v4 = gs_test3-v4 )
  FOR gs_test2 IN gt_test2 WHERE ( v1 = gs_test1-v1 AND v2 = gs_test1-v2 )
  ( gs_test2 )
).
WRITE / lines( gt_test2_2 ).

这是ABAP中的一个错误!?我一直认为首先评估表达式的右侧,然后将其分配给左侧。然而,在这个 ABAP 结构中,在计算右侧时,似乎在内部以某种方式使用了左侧,这导致了不正确的结果。

最小的工作示例。

REPORT ZZZ.

TYPES: BEGIN OF ty_test1,
  v1 TYPE char40,
  v2 TYPE char6,
  v3 TYPE char6,
  v4 TYPE char32,
  END OF ty_test1,
  BEGIN OF ty_test2,
    v1 TYPE char40,
    v2 TYPE char6,
    v5 TYPE numc3,
  END OF ty_test2,
  BEGIN OF ty_test3,
    v3 TYPE char6,
    v4 TYPE char32,
  END OF ty_test3.
TYPES: tty_test1 TYPE STANDARD TABLE OF ty_test1 WITH EMPTY KEY,
  tty_test2 TYPE STANDARD TABLE OF ty_test2 WITH EMPTY KEY.

INITIALIZATION.
  DATA(gt_test1) = VALUE tty_test1(
    ( v1 = '1' v2 = '007001' v3 = '0012345678' v4 = '001061' )
    ( v1 = '2' v2 = '007001' v3 = '0999999953' v4 = '001061' )
  ).
  DATA(gt_test2) = VALUE tty_test2(
    ( v1 = '1' v2 = '007001' v5 = '10' )
    ( v1 = '2' v2 = '007001' v5 = '15' )
  ).
  DATA(gs_test3) = VALUE ty_test3( v3 = '0999999953' v4 = '001061' ).

START-OF-SELECTION.
*  DATA: gt_test2_2 LIKE gt_test2.
*  gt_test2_2 =
  gt_test2 =
  VALUE #(
    FOR gs_test1 IN gt_test1 WHERE ( v3 = gs_test3-v3 AND v4 = gs_test3-v4 )
    FOR gs_test2 IN gt_test2 WHERE ( v1 = gs_test1-v1 AND v2 = gs_test1-v2 )
    ( gs_test2 )
  ).
  WRITE / lines( gt_test2 ).
*  WRITE / lines( gt_test2_2 ).
4

2 回答 2

4

使用构造函数表达式,首先清除目标数据对象,因此您遇到的结果是:内部表在循环gt_test2时为空。FOR

在您的情况下,您可以使用在清除目标数据对象之前调用的 LET 将内部表转换为辅助内部表。

ABAP 文档 - “值,内部表”

如果 VALUE 运算符用作对内部表的赋值源,则在评估可能的 LET 表达式后首先对其进行初始化,或者为其分配 itab 的内容。然后,line_spec 数据被评估并直接插入到目标表中。

在将构造函数表达式分配给内部表时,其现有行不能直接用作 line_spec 中的参数。这是因为该表在 line_spec 被 itab 的内容评估或覆盖之前被删除。但是,如果右侧需要整个内部表或左侧的行,则可以使用 LET 表达式将它们保存在本地辅助变量中,因为首先评估此表达式。

于 2020-10-27T20:21:16.653 回答
2

FILTERSandra 是对的,但是您可以使用op克服这个限制,因为它缺少令人失望的拦截器。如果您想避免创建新表,您可以重新考虑您的示例:

...
TYPES: tty_test1 TYPE SORTED TABLE OF ty_test1 WITH NON-UNIQUE KEY primary_key COMPONENTS v1 v2
                                               WITH NON-UNIQUE SORTED KEY filt COMPONENTS v3 v4,
       tty_test2 TYPE SORTED TABLE OF ty_test2 WITH NON-UNIQUE KEY primary_key COMPONENTS v1 v2.
...

gt_test1 = FILTER #( gt_test1 USING KEY filt WHERE v3 = gs_test3-v3 AND v4 = gs_test3-v4 ).
gt_test2 = FILTER #( gt_test2 IN gt_test1 WHERE v1 = v1 AND v2 = v2 ).
于 2020-10-28T10:09:51.907 回答