【问题标题】:Finding duplicates in ABAP internal table via grouping通过分组在 ABAP 内部表中查找重复项
【发布时间】:2022-01-07 04:53:19
【问题描述】:

我们都知道these excellent ABAP statements 允许在单行中找到唯一值:

it_unique = VALUE #( FOR GROUPS value OF <line> IN it_itab 
                     GROUP BY <line>-field WITHOUT MEMBERS ( value ) ).

但是提取重复项呢?可以为该任务使用GROUP BY 语法吗?或者,表格解析在这里更有用?

我发现的唯一(虽然不是很优雅)的方法是:

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.

有没有更漂亮的方法可以通过任意键查找重复项?

【问题讨论】:

    标签: duplicates abap internal-tables


    【解决方案1】:

    所以,我只是把它作为答案,因为我们和弗洛里安无法想出更好的东西。
    如果有人能够改进它,那就去做吧。

    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.
    

    【讨论】:

      【解决方案2】:

      给定

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

      什么时候

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

      然后

      cl_abap_unit_assert=>assert_equals(
          act = duplicates
          exp = VALUE tt_materials( ( matnr = '42' werks = 'DE') ) ).
      

      这个解决方案的可读性太差了,你应该只在一个带有暴露名称的方法中使用它,比如collect_duplicate_keys

      另请注意,语句的长度会随着关键字段数量的增加而增加,因为添加 GROUP SIZE 需要将关键字段一一列为简单类型的列表。

      【讨论】:

      • whether you want the table of extracted duplicates to contain duplicates itself, or reduce them to unique keys,由于我的问题中给出了后者的解决方案,您可能猜到我想要前者:) 我想在不影响初始表的情况下将重复项提取到单独的表中
      • 您的问题实际上只提供了“如果我的表包含重复项,我该如何抛出错误”的解决方案。
      • it_unique 表检查第一个sn-p,它正是你的第一个用例,你已经从答案中删除了
      • 好的。更新了答案。
      • Readability of this solution is so bad ,是的,这太可怕了 :) 您的第一个变体要好得多。我做了一个solution based on it。我们可以让它更简洁吗?除了显式检查循环内,我们可以排除唯一组(大小=1)吗?
      【解决方案3】:

      经典呢?我不确定它们是否已被弃用,但我的第一个想法是要创建一个表克隆,在其上删除 ADJACENT-DUPLICATES,然后比较两行()... 我会渴望阅读新的选项。

      【讨论】:

      • 经典不方便,因为它需要删除,所以需要额外的临时标签来完成任务。如果表包含数百万条记录,那就不酷了。
      • 好的,我明白你的意思,我真的很感激 - 并且喜欢 - 它。所以,答案将是使用我不熟悉的新句子。我将把我的答案保留在这里而不是删除它,以防止更多的老人写相同的答案;)
      • 是的。 VALUE 操作符的美妙之处在于它从初始构造新表,并且初始表是untouched
      • 收集仍然是一个糟糕的选择?如果您无论如何要创建一个新的无用表,也许您可​​以将您的“关键”字段和值 1 收集到该新表中,并在任何行达到值 2 时引发您的错误......再次,我不确定如果我错了,但在我们等待更好的答案时,这次谈话很有用(至少对我来说;))
      • 如何通过COLLECT 引发错误?如果违反 COLLECT 结构中的主键,它只会导致 non-handleable 异常(短转储)。不酷:)
      猜你喜欢
      • 1970-01-01
      • 2017-02-13
      • 2021-02-10
      • 1970-01-01
      • 2018-05-03
      • 1970-01-01
      • 2020-05-17
      • 2013-09-15
      相关资源
      最近更新 更多