Algorithm 在内部表中显示重复项

Algorithm 在内部表中显示重复项,algorithm,duplicates,abap,internal-tables,Algorithm,Duplicates,Abap,Internal Tables,每个项目应具有uniquie SecondNo+图纸组合。由于误入,有些组合出现两次 我需要用ABAP创建一个报告,该报告识别这些组合,而不反映其他组合 Item: SecNo: Drawing: 121 904 5000 double 122 904 5000 double 123 816 5100 124 813 5200 125 812 4900

每个项目应具有uniquie SecondNo+图纸组合。由于误入,有些组合出现两次

我需要用ABAP创建一个报告,该报告识别这些组合,而不反映其他组合

Item:  SecNo: Drawing:
121       904      5000         double
122       904      5000         double
123       816      5100
124       813      5200
125       812      4900          double
126       812      4900          double
127       814      5300
我怎样才能解决这个问题?我尝试了两种方法,但都失败了:

  • 对数据进行排序,并在上一行的值等于下一行的值时尝试打印每个数据

  • 数一数重复项,并显示所有重复项

  • 我应该把它放在哪里?在环路区域

    我试过这个:

    REPORT  duplicates.
    
    DATA: BEGIN OF lt_duplicates OCCURS 0,
            f2(10),
            f3(10),
          END OF lt_duplicates,
          it_test TYPE TABLE OF ztest WITH HEADER LINE,
          i       TYPE i.
    
    SELECT DISTINCT f2 f3 FROM ztest INTO TABLE lt_duplicates.
    
    LOOP AT lt_duplicates.
    
      IF f2 = lt_duplicates-f2 AND f3 = lt_duplicates-f3.
      ENDIF.
    
      i = LINES( it_test ).
    
      IF i > 1.
        LOOP AT it_test.
          WRITE :/ it_test-f1,it_test-f2,it_test-f3.
        ENDLOOP.
      ENDIF.
    
    ENDLOOP.
    

    如果正确排列字段,则可以在…ENDAT使用
    AT

    TYPES: BEGIN OF t_my_line,
             secno   TYPE foo,
             drawing TYPE bar,
             item    TYPE baz, " this field has to appear AFTER the other ones in the table
           END OF t_my_line.
    
    DATA: lt_my_table TYPE TABLE OF t_my_line,
          lt_duplicates TYPE TABLE OF t_my_line.
    
    FIELD-SYMBOLS: <ls_line> TYPE t_my_line.
    
    START-OF-WHATEVER.
    
    * ... fill the table ...
    
      SORT lt_my_table BY secno drawing.
      LOOP AT lt_my_table ASSIGNING <ls_line>.
        AT NEW drawing. " whenever drawing or any field left of it changes...
          FREE lt_duplicates.
        ENDAT.
        APPEND <ls_line> TO lt_duplicates.
        AT END OF drawing.
          IF lines( lt_duplicates ) > 1.
    *       congrats, here are your duplicates...
          ENDIF.
        ENDAT.
      ENDLOOP.
    
    类型:从t_my_行开始,
    第二类foo,
    绘图类型栏,
    项目类型baz,“此字段必须出现在表中其他字段之后
    我的路线结束了。
    数据:t_my_行的lt_my_表类型表,
    lt_复制t_my_行的类型表。
    字段符号:键入t_my_line。
    无论什么开始。
    *…填好表格。。。
    按secno图纸对我的表格进行排序。
    在lt_my_表处循环分配。
    每当绘图或其左边的任何字段发生变化时。。。
    免费lt_副本。
    恩达。
    附加到lt_副本。
    在图纸的末尾。
    如果行(lt_重复)>1。
    *恭喜,这是你的副本。。。
    恩迪夫。
    恩达。
    结束循环。
    
    在ABAP 7.40中,您可以使用带有
    组大小
    单词的
    GROUP BY
    结构,以便只考虑至少包含2个元素的组

    • ABAP声明
      • 在分组行处循环:
      • 或者
    • ABAP表达
      • 在分组行处循环:
    对于这两种构造,可以通过两种方式在分组线处循环: * *

    您可能希望生成包含重复项的下表:

    SecNo   Drawing   Lines
    904      5000     [1,2]
    812      4900     [5,6]
    
    解决方案,带
    循环在。。。分组依据…

    TYPES: BEGIN OF t_line,
             item    TYPE i,
             secno   TYPE i,
             drawing TYPE i,
           END OF t_line,
           BEGIN OF t_duplicate,
             secno   TYPE i,
             drawing TYPE i,
             num_dup TYPE i, " number of duplicates
             lines   TYPE STANDARD TABLE OF REF TO t_line WITH EMPTY KEY,
           END OF t_duplicate,
           t_lines      TYPE STANDARD TABLE OF t_line WITH EMPTY KEY,
           t_duplicates TYPE STANDARD TABLE OF t_duplicate WITH EMPTY KEY.
    
    DATA(table) = VALUE t_lines(
        ( item = 121 secno = 904 drawing = 5000 )
        ( item = 122 secno = 904 drawing = 5000 )
        ( item = 123 secno = 816 drawing = 5100 )
        ( item = 124 secno = 813 drawing = 5200 )
        ( item = 125 secno = 812 drawing = 4900 )
        ( item = 126 secno = 812 drawing = 4900 )
        ( item = 127 secno = 814 drawing = 5300 ) ).
    
    DATA(expected_duplicates) = VALUE t_duplicates(
        ( secno = 904 drawing = 5000 num_dup = 2 lines = VALUE #( ( REF #( table[ 1 ] ) ) ( REF #( table[ 2 ] ) ) ) )
        ( secno = 812 drawing = 4900 num_dup = 2 lines = VALUE #( ( REF #( table[ 5 ] ) ) ( REF #( table[ 6 ] ) ) ) ) ).
    
    DATA(actual_duplicates) = VALUE t_duplicates( ).
    LOOP AT table
        ASSIGNING FIELD-SYMBOL(<line>)
        GROUP BY
        ( secno   = <line>-secno
          drawing = <line>-drawing
          gs      = GROUP SIZE )
        ASSIGNING FIELD-SYMBOL(<group_table>).
    
      IF <group_table>-gs >= 2.
        actual_duplicates = VALUE #( BASE actual_duplicates
            ( secno   = <group_table>-secno
              drawing = <group_table>-drawing
              num_dup = <group_table>-gs
              lines   = VALUE #( FOR <line2> IN GROUP <group_table> ( REF #( <line2> ) ) ) ) ).
      ENDIF.
    
    ENDLOOP.
    
    WRITE : / 'List of duplicates:'.
    SKIP 1.
    WRITE : / 'Secno       Drawing     List of concerned items'.
    WRITE : / '----------  ----------  ---------------------------------- ...'.
    LOOP AT actual_duplicates ASSIGNING FIELD-SYMBOL(<duplicate>).
      WRITE : / <duplicate>-secno, <duplicate>-drawing NO-GROUPING.
      LOOP AT <duplicate>-lines INTO DATA(line).
        WRITE line->*-item.
      ENDLOOP.
    ENDLOOP.
    
    ASSERT actual_duplicates = expected_duplicates. " short dump if not equal
    
    DATA(actual_duplicates) = VALUE t_duplicates(
        FOR GROUPS <group_table> OF <line> IN table
        GROUP BY
        ( secno   = <line>-secno
          drawing = <line>-drawing
          gs      = GROUP SIZE )
        ( secno   = <group_table>-secno
          drawing = <group_table>-drawing
          num_dup = <group_table>-gs
          lines   = VALUE #( FOR <line2> IN GROUP <group_table> ( REF #( <line2> ) ) ) ) ).
    DELETE actual_duplicates WHERE num_dup = 1.
    
    使用
    解决方案。。。值类型|#(对于组…分组依据…

    TYPES: BEGIN OF t_line,
             item    TYPE i,
             secno   TYPE i,
             drawing TYPE i,
           END OF t_line,
           BEGIN OF t_duplicate,
             secno   TYPE i,
             drawing TYPE i,
             num_dup TYPE i, " number of duplicates
             lines   TYPE STANDARD TABLE OF REF TO t_line WITH EMPTY KEY,
           END OF t_duplicate,
           t_lines      TYPE STANDARD TABLE OF t_line WITH EMPTY KEY,
           t_duplicates TYPE STANDARD TABLE OF t_duplicate WITH EMPTY KEY.
    
    DATA(table) = VALUE t_lines(
        ( item = 121 secno = 904 drawing = 5000 )
        ( item = 122 secno = 904 drawing = 5000 )
        ( item = 123 secno = 816 drawing = 5100 )
        ( item = 124 secno = 813 drawing = 5200 )
        ( item = 125 secno = 812 drawing = 4900 )
        ( item = 126 secno = 812 drawing = 4900 )
        ( item = 127 secno = 814 drawing = 5300 ) ).
    
    DATA(expected_duplicates) = VALUE t_duplicates(
        ( secno = 904 drawing = 5000 num_dup = 2 lines = VALUE #( ( REF #( table[ 1 ] ) ) ( REF #( table[ 2 ] ) ) ) )
        ( secno = 812 drawing = 4900 num_dup = 2 lines = VALUE #( ( REF #( table[ 5 ] ) ) ( REF #( table[ 6 ] ) ) ) ) ).
    
    DATA(actual_duplicates) = VALUE t_duplicates( ).
    LOOP AT table
        ASSIGNING FIELD-SYMBOL(<line>)
        GROUP BY
        ( secno   = <line>-secno
          drawing = <line>-drawing
          gs      = GROUP SIZE )
        ASSIGNING FIELD-SYMBOL(<group_table>).
    
      IF <group_table>-gs >= 2.
        actual_duplicates = VALUE #( BASE actual_duplicates
            ( secno   = <group_table>-secno
              drawing = <group_table>-drawing
              num_dup = <group_table>-gs
              lines   = VALUE #( FOR <line2> IN GROUP <group_table> ( REF #( <line2> ) ) ) ) ).
      ENDIF.
    
    ENDLOOP.
    
    WRITE : / 'List of duplicates:'.
    SKIP 1.
    WRITE : / 'Secno       Drawing     List of concerned items'.
    WRITE : / '----------  ----------  ---------------------------------- ...'.
    LOOP AT actual_duplicates ASSIGNING FIELD-SYMBOL(<duplicate>).
      WRITE : / <duplicate>-secno, <duplicate>-drawing NO-GROUPING.
      LOOP AT <duplicate>-lines INTO DATA(line).
        WRITE line->*-item.
      ENDLOOP.
    ENDLOOP.
    
    ASSERT actual_duplicates = expected_duplicates. " short dump if not equal
    
    DATA(actual_duplicates) = VALUE t_duplicates(
        FOR GROUPS <group_table> OF <line> IN table
        GROUP BY
        ( secno   = <line>-secno
          drawing = <line>-drawing
          gs      = GROUP SIZE )
        ( secno   = <group_table>-secno
          drawing = <group_table>-drawing
          num_dup = <group_table>-gs
          lines   = VALUE #( FOR <line2> IN GROUP <group_table> ( REF #( <line2> ) ) ) ) ).
    DELETE actual_duplicates WHERE num_dup = 1.
    

    我只需要根据下面使用的两个字段报告错误的重复行

    LOOP AT gt_data INTO DATA(gs_data)
    
    GROUP BY ( columnA = gs_data-columnA columnB = gs_data-columnB
    size = GROUP SIZE index = GROUP INDEX ) ASCENDING
    REFERENCE INTO DATA(group_ref).
    
    IF group_ref->size > 1.
      PERFORM insert_error USING group_ref->columnA group_ref->columnB.
    ENDIF.
    
    ENDLOOP.
    

    这是我的2p值,你可以根据你想做的来删减一些,你也应该考虑处理的数据量。这个方法只针对较小的集合。 就我个人而言,我喜欢在源代码处防止错误记录。在输入过程中捕捉错误。但如果你最终陷入困境,解决问题的方法肯定不止一种

    TYPES: BEGIN OF ty_itab,
             item    TYPE i,
             secno   TYPE i,
             drawing TYPE i,
           END OF ty_itab.
    TYPES: itab_tt TYPE STANDARD TABLE OF ty_itab.
    
    DATA: lt_itab  TYPE itab_tt,
          lt_itab2 TYPE itab_tt,
          lt_itab3 TYPE itab_tt.
    
    lt_itab = VALUE #(
                      ( item = '121' secno = '904' drawing = '5000' )
                      ( item = '122' secno = '904' drawing = '5000' )
                      ( item = '123' secno = '816' drawing = '5100' )
                      ( item = '124' secno = '813' drawing = '5200' )
                      ( item = '125' secno = '812' drawing = '4900' )
                      ( item = '126' secno = '812' drawing = '4900' )
                      ( item = '127' secno = '814' drawing = '5300' )
                    ).
    
    APPEND LINES OF lt_itab TO lt_itab2.
    APPEND LINES OF lt_itab TO lt_itab3.
    
    SORT lt_itab2 BY secno drawing.
    DELETE ADJACENT DUPLICATES FROM lt_itab2 COMPARING secno drawing.   
    
    * Loop at what is hopefully the smaller itab.
    LOOP AT lt_itab2 ASSIGNING FIELD-SYMBOL(<line>).
      DELETE TABLE lt_itab3 FROM <line>.
    ENDLOOP.
    
    * itab1 has all originals.
    * itab2 has the unique.
    * itab3 has the duplicates.
    
    
    类型:从tyu itab开始,
    项目类型i,
    第i类,
    图纸类型i,
    蒂尤伊塔布的结束。
    类型:itab_tt型ty_itab标准表。
    数据:lt_itab类型itab_tt,
    lt_itab2型itab_tt,
    lt_itab3型itab_tt。
    lt_itab=值#(
    (项目='121'序号='904'图纸='5000')
    (项目='122'序号='904'图纸='5000')
    (项目='123'序号='816'图纸='5100')
    (项目='124'序号='813'图纸='5200')
    (项目='125'序号='812'图纸='4900')
    (项目='126'序号='812'图纸='4900')
    (项目='127'序号='814'图纸='5300')
    ).
    将lt_itab的行追加到lt_itab2。
    将lt_itab的行追加到lt_itab3。
    按secno图纸对lt_itab2进行排序。
    从lt_itab2中删除相邻的重复项。
    *在较小的itab处循环。
    在lt_itab2赋值字段-SYMBOL()处循环。
    从中删除表lt_itab3。
    结束循环。
    *itab1拥有所有原件。
    *itab2具有独特的功能。
    *itab3有两个副本。
    
    我不太清楚。你在使用什么表格?什么模块?你能展示一下你到目前为止尝试了什么吗?嗨,我是这样做的:对不起,我似乎无法格式化。请在你的问题中粘贴你的代码以便可读。刚刚发现,谢谢
    TYPES: BEGIN OF ty_itab,
             item    TYPE i,
             secno   TYPE i,
             drawing TYPE i,
           END OF ty_itab.
    TYPES: itab_tt TYPE STANDARD TABLE OF ty_itab.
    
    DATA: lt_itab  TYPE itab_tt,
          lt_itab2 TYPE itab_tt,
          lt_itab3 TYPE itab_tt.
    
    lt_itab = VALUE #(
                      ( item = '121' secno = '904' drawing = '5000' )
                      ( item = '122' secno = '904' drawing = '5000' )
                      ( item = '123' secno = '816' drawing = '5100' )
                      ( item = '124' secno = '813' drawing = '5200' )
                      ( item = '125' secno = '812' drawing = '4900' )
                      ( item = '126' secno = '812' drawing = '4900' )
                      ( item = '127' secno = '814' drawing = '5300' )
                    ).
    
    APPEND LINES OF lt_itab TO lt_itab2.
    APPEND LINES OF lt_itab TO lt_itab3.
    
    SORT lt_itab2 BY secno drawing.
    DELETE ADJACENT DUPLICATES FROM lt_itab2 COMPARING secno drawing.   
    
    * Loop at what is hopefully the smaller itab.
    LOOP AT lt_itab2 ASSIGNING FIELD-SYMBOL(<line>).
      DELETE TABLE lt_itab3 FROM <line>.
    ENDLOOP.
    
    * itab1 has all originals.
    * itab2 has the unique.
    * itab3 has the duplicates.