简体   繁体   English

通过分组在ABAP内部表中查找重复项

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM