这是this one的后续问题,但我不是聚合,而是要根据某些条件处理组,因此无法找出正确的语法。如果组中至少有一个成员具有此状态,则需要排除包含状态为“已删除”的文档的组。
到目前为止,我已经尝试了GROUP...WITHOUT MEMBERS
,LOOP...FOR GROUPS
,REDUCE
,这是我最终得到的解决方案
DATA(lt_valid_doc) = VALUE tt_struct(
FOR ls_valid IN VALUE tt_struct(
FOR GROUPS <group_key> OF <wa> IN lt_ilot
GROUP BY ( guid = <wa>-guid guid2 = <wa>-guid2 ) ASCENDING
LET not_deleted = REDUCE #( INIT valid TYPE t_ref_s_struct
FOR <m> IN GROUP <group_key>
NEXT valid = COND #(
WHEN valid IS NOT BOUND OR <m>-stat = 'I1040'
THEN REF #( <m> ) ELSE valid ) )
IN ( not_deleted->* ) )
WHERE ( status NE 'I1040' )
( ls_valid ) ).
但是,此解决方案对我来说似乎是多余的(I1040
过滤器已两次显示)。是否有任何语法可以在一个语句(REDUCE
,GROUP
或其他任何语句)中执行此操作,而无需像我现在所做的那样即时构造嵌套表并对其进行过滤?
如果我在以上所有语句(WHERE
,GROUP...WITHOUT MEMBERS
和LOOP...FOR GROUPS
)上使用REDUCE
条件,它只会过滤 base 行,分组而不是分组本身。我需要与SQL中的HAVING
类似。
更新好,这是基于BSEG表的实际可编译示例。任务是仅查找未经精加工的文档,即排除所有行(XNEGP = true)颠倒的文档。
TYPES: BEGIN OF t_s_bseg,
bukrs TYPE bseg-bukrs,
belnr TYPE bseg-belnr,
gjahr TYPE bseg-gjahr,
buzei TYPE bseg-buzei,
xnegp TYPE bseg-xnegp,
END OF t_s_bseg,
tt_bseg TYPE SORTED TABLE OF t_s_bseg WITH EMPTY KEY.
TYPES: t_ref_s_bseg TYPE REF TO t_s_bseg.
DATA(lt_valid_fi_doc) = VALUE tt_bseg(
FOR ls_valid IN VALUE tt_bseg(
FOR GROUPS <group_key> OF <wa> IN lt_bseg
GROUP BY ( bukrs = <wa>-bukrs belnr = <wa>-belnr gjahr = <wa>-belnr ) ASCENDING
LET not_reversed = REDUCE #( INIT valid TYPE t_ref_s_bseg
FOR <m> IN GROUP <group_key>
NEXT valid = COND #(
WHEN valid IS NOT BOUND OR <m>-xnegp = abap_true
THEN REF #( <m> ) ELSE valid ) )
IN ( not_reversed->* ) )
WHERE ( xnegp NE abap_true )
( ls_valid ) ).
输入行
bukrs belnr gjahr buzei xnegp
1000 0100000001 2019 1
1000 0100000001 2019 2
1000 0100000003 2019 1
1000 0100000003 2019 2
1000 0100000004 2019 1
1000 0100000004 2019 2 X
Doc 0100000004的行已反转,因此结果应为
bukrs belnr gjahr buzei xnegp
1000 0100000001 2019
1000 0100000003 2019
答案 0 :(得分:1)
这是一个不重复选择的解决方案,但是还有一个问题,那真的“更好”吗?
该解决方案基于如果一组线包含状态为“ I1040”的一行,则生成一个空行,而不是保留不想要的行。我不确定,但是也许其他类似的解决方案也可以保留对行(not_deleted
)的引用,并添加一个辅助变量来知道是否保留引用。我发现使用表索引(INDEX INTO
)更直观,但是如果tt_struct
是哈希表类型,那可能行不通。
我为代码提供了ABAP单元测试,以便您可以自己快速尝试。
CLASS ltc_main DEFINITION FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS test FOR TESTING.
METHODS cut.
TYPES : BEGIN OF ty_struct,
guid TYPE string,
stat TYPE string,
END OF ty_struct,
tt_struct TYPE STANDARD TABLE OF ty_struct WITH EMPTY KEY,
t_ref_s_struct TYPE REF TO ty_struct.
DATA: lt_ilot TYPE tt_struct,
lt_valid_doc TYPE tt_struct.
ENDCLASS.
CLASS ltc_main IMPLEMENTATION.
METHOD cut.
lt_valid_doc = VALUE #(
FOR ls_valid IN VALUE tt_struct(
FOR GROUPS <group_key> OF <wa> IN lt_ilot
GROUP BY ( guid = <wa>-guid ) ASCENDING
LET x1 = REDUCE #(
INIT x2 = 0
FOR <m> IN GROUP <group_key> INDEX INTO x3
NEXT x2 = COND #(
WHEN <m>-stat = 'I1040' THEN -1
ELSE COND #( WHEN x2 <> 0 THEN x2 ELSE x3 ) ) )
IN ( COND #( WHEN x1 <> -1 THEN lt_ilot[ x1 ] ) ) )
WHERE ( table_line IS NOT INITIAL )
( ls_valid ) ).
ENDMETHOD.
METHOD test.
lt_ilot = VALUE #(
( guid = 'A' stat = 'I1000' )
( guid = 'A' stat = 'I1040' )
( guid = 'B' stat = 'I1020' )
( guid = 'C' stat = 'I1040' )
( guid = 'D' stat = 'I1040' )
( guid = 'D' stat = 'I1000' ) ).
cut( ).
cl_abap_unit_assert=>assert_equals( act = lt_valid_doc
exp = VALUE tt_struct( ( guid = 'B' stat = 'I1020' ) ) ).
ENDMETHOD.
ENDCLASS.
答案 1 :(得分:-1)
我真的希望那是某种个人测试用例,并且不要在生产环境中使用此编码。如果仅在编码方面我不得不理解您想要实现的目标,我会讨厌您;)。
轻松解决此问题的关键是对表进行排序,以使删除条件始终位于要处理的组的第一行:
解决方案1 输出唯一列表:
DATA: lt_bseg TYPE STANDARD TABLE OF t_s_bseg.
SORT lt_bseg BY belnr xnegp DESCENDING.
DELETE ADJACENT DUPLICATES FROM lt_bseg COMPARING belnr.
DELETE lt_bseg WHERE xnegp = abap_true.
解决方案2
输出非唯一列表:
DATA: lt_bseg TYPE STANDARD TABLE OF t_s_bseg,
lf_prev_belnr TYPE belnr,
lf_delete TYPE char1.
SORT lt_bseg BY belnr xnegp DESCENDING.
LOOP AT lt_bseg ASSIGNING FIELD-SYMBOL(<ls_bseg>).
IF <ls_bseg>-belnr <> lf_prev_belnr.
lf_delete = <ls_bseg>-xnegp.
lf_prev_belnr = <ls_bseg>-belnr.
ENDIF.
IF lf_delete = abap_true.
DELETE lt_bseg.
ENDIF.
ENDLOOP.
答案 2 :(得分:-2)
以下解决方案可能不是最漂亮的,但很简单。如果一个成员满足条件,则删除整个组要比所有成员均不符合条件的情况添加整个组要容易。只是一个主意。
#data getting is a list eg. [10, 12]
from tkinter import *
import tkinter.font
#main Window using Tk
win = Tk()
win.title("v1.0")
win.geometry('800x480')
win.configure(background='#CD5C5C')
#Labels
voltage = Label(win, text = "voltage")
voltage.place(x=15, y=100)
current = Label(win, text = "current")
current.place(x=15, y=200)
#display measured values
#how to display here !!!
currentValues = Label(win, text = "want to display somewhere like this")
currentValues.place(x=200, y=100)
voltageValues = Label(win, text = "want to display somewhere like this")
voltageValues.place(x=200, y=200)
mainloop()