[英]Finding duplicates in ABAP internal table via grouping
We all know these excellent ABAP statements which allows finding unique values in one-liner:我们都知道这些优秀的 ABAP 语句可以在单行中找到唯一值:
it_unique = VALUE #( FOR GROUPS value OF <line> IN it_itab
GROUP BY <line>-field WITHOUT MEMBERS ( value ) ).
But what about extracting duplicates?但是如何提取重复项呢? Can one utilize
GROUP BY
syntax for that task or, maybe, table comprehensions are more useful here?可以为该任务使用
GROUP BY
语法,或者,表格推导式在这里更有用吗?
The only (though not very elegant) way I found is:我发现的唯一(虽然不是很优雅)方式是:
LOOP AT lt_marc ASSIGNING FIELD-SYMBOL(<fs_marc>) GROUP BY ( matnr = <fs_marc>-matnr
werks = <fs_marc>-werks )
ASSIGNING FIELD-SYMBOL(<group>).
members = VALUE #( FOR m IN GROUP <group> ( m ) ).
IF lines( members ) > 1.
"throw error
ENDIF.
ENDLOOP.
Is there more beautiful way of finding duplicates by arbitrary key?有没有更漂亮的方式通过任意键查找重复项?
So, I just put it as answer, as we with Florian weren't able to think out something better.所以,我只是把它作为答案,因为我们和弗洛里安无法想出更好的办法。
If somebody is able to improve it, just do it.如果有人能够改进它,那就去做吧。
TYPES tt_materials TYPE STANDARD TABLE OF marc WITH DEFAULT KEY.
DATA duplicates TYPE tt_materials.
LOOP AT materials INTO DATA(material)
GROUP BY ( id = material-matnr
status = material-pstat
size = GROUP SIZE )
ASCENDING REFERENCE INTO DATA(group_ref).
CHECK group_ref->*-size > 1.
duplicates = VALUE tt_materials( BASE duplicates FOR <status> IN GROUP group_ref ( <status> ) ).
ENDLOOP.
Given给定的
TYPES: BEGIN OF key_row_type,
matnr TYPE matnr,
werks TYPE werks_d,
END OF key_row_type.
TYPES key_table_type TYPE
STANDARD TABLE OF key_row_type
WITH DEFAULT KEY.
TYPES: BEGIN OF group_row_type,
matnr TYPE matnr,
werks TYPE werks_d,
size TYPE i,
END OF group_row_type.
TYPES group_table_type TYPE
STANDARD TABLE OF group_row_type
WITH DEFAULT KEY.
TYPES tt_materials TYPE STANDARD TABLE OF marc WITH DEFAULT KEY.
DATA(materials) = VALUE tt_materials(
( matnr = '23' werks = 'US' maabc = 'B' )
( matnr = '42' werks = 'DE' maabc = 'A' )
( matnr = '42' werks = 'DE' maabc = 'B' ) ).
When什么时候
DATA(duplicates) =
VALUE key_table_type(
FOR key IN VALUE group_table_type(
FOR GROUPS group OF material IN materials
GROUP BY ( matnr = material-matnr
werks = material-werks
size = GROUP SIZE )
WITHOUT MEMBERS ( group ) )
WHERE ( size > 1 )
( matnr = key-matnr
werks = key-werks ) ).
Then然后
cl_abap_unit_assert=>assert_equals(
act = duplicates
exp = VALUE tt_materials( ( matnr = '42' werks = 'DE') ) ).
Readability of this solution is so bad that you should only ever use it in a method with a revealing name like collect_duplicate_keys
.这个解决方案的可读性太差了,你应该只在像
collect_duplicate_keys
这样具有显着名称的方法中使用它。
Also note that the statement's length increases with a growing number of key fields, as the GROUP SIZE
addition requires listing the key fields one by one as a list of simple types.另请注意,语句的长度随着关键字段数量的增加而增加,因为
GROUP SIZE
添加要求将关键字段作为简单类型列表一一列出。
What about the classics?那经典呢? I'm not sure if they are deprecated or so, but my first think is about to create a table clone, DELETE ADJACENT-DUPLICATES on it and then just compare both lines( )... I'll be eager to read new options.
我不确定它们是否已被弃用,但我的第一个想法是创建一个表克隆,在其上删除 ADJACENT-DUPLICATES,然后比较两行()...我会渴望阅读新选项.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.