Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Method to check for duplicateacross the whole internal table.

0 Kudos
468

So i'm trying to develop a method to check for duplicates an internal table.

Here's an example:

field1 field 2

A B

C D

A F

G B

As you can see, my internal table has 2 fields. Given the example, I want my coding to return that the table does contain duplicates- A and B. Actually, i don't care what my duplicates are. I just want an exception to be raised if there are any duplicates, at all.

Here is my attempt:

    DATA(temp_tab) = i_tab. // i_tab is my import parameter
    SORT temp_tab BY field1.
    LOOP AT temp_tab ASSIGNING FIELD-SYMBOL(<dublicate>).
      DATA dublicate_entries LIKE temp_tab.
      AT NEW field1.
        FREE dublicate_entries.
      ENDAT.
      AT NEW field2.
        FREE dublicate_entries.
      ENDAT.
      APPEND <dublicate> TO dublicate_entries.
      IF lines( dublicate_entries ) > 1.
        RAISE EXCEPTION TYPE zek_matnr_new_old_exc
          EXPORTING
            i_textid = zek_matnr_new_old_exc=>default_textid.
      ENDIF.
    ENDLOOP.

This does work, partly. It would work if i insert a table that has a whole table roll that duplicates with another. For example:

A B

C D

C D

In this case roll C D is a duplicate and the report correctly catches that. But if i input my first example, where just one of the two elements on a roll is duplicating with any of the other elements from any other roll, it doesn't work. How can i optimise my logic?

7 REPLIES 7

FredericGirod
Active Contributor
0 Kudos
378
data lv_index_base type sytabix value 1.
data lv_index_temps type sytabix value 1.
data correction type sytabix.

data(temps_data) = i_itab.
data(base_data) = i_itab.

sort temps_data by field1 ascending, field2 ascending.
sort base_data by field1 ascending, field2 ascending.

delete adjacent duplicates from temps_data comparing field_1 field_2.


loop at base_data
     reference into data(line_base_data).
  lv_index_base = sy-tabix.
  read table temps_data
       with key field_1 = line_base_data->field_1
                field_2 = line_base_data->field_2.
  if sy-subrc ne 0. 
    raise exception type there_is_a_big_problem ...
  else.
    lv_index_temps = sy-tabix + correction.
    if lv_index_base ne lv_index_temps.
      raise exception type there_is_a_duplicate
      correction = correction + 1.
    endif.
  endif.
endloop.

joltdx
Active Contributor
378

Basically, fore each line in your table, you want to find in any following line has any of the same values...

Something like this will output the duplicate lines A F and G B in the ADT console (using the out->write( )). Raise your exception instead...

    TYPES:
      BEGIN OF ty_lines,
        field1(1) TYPE c,
        field2(1) TYPE c,
      END OF ty_lines.

    DATA temp_tab TYPE TABLE OF ty_lines.
    DATA next_index TYPE i.

    INSERT VALUE #( field1 = 'A' field2 = 'B' ) INTO TABLE temp_tab.
    INSERT VALUE #( field1 = 'C' field2 = 'D' ) INTO TABLE temp_tab.
    INSERT VALUE #( field1 = 'A' field2 = 'F' ) INTO TABLE temp_tab.
    INSERT VALUE #( field1 = 'G' field2 = 'B' ) INTO TABLE temp_tab.

    LOOP AT temp_tab ASSIGNING FIELD-SYMBOL(<dublicate>).
      next_index = sy-tabix + 1.
      LOOP AT temp_tab INTO DATA(duplicate_here)
          FROM next_index
          WHERE field1 = <dublicate>-field1 OR
                field2 = <dublicate>-field2.
        out->write( |{ duplicate_here-field1 } { duplicate_here-field2 }| ).
      ENDLOOP.
    ENDLOOP.

Now, this is a simple demo of the logic... Depending on your data this might become more or less complex. For instance if you have more than a couple of columns. Or if there are many many lines... For performance, you might for instance want to use different kind of indexes or table types depending on many things, but here is a working logic that can be used.

Have fun!

0 Kudos
378

I think you will have a problem after the first duplicate, all the other lines will be considere as duplicate

joltdx
Active Contributor
0 Kudos
378

I probably don't understand what you mean frdric.girod, because I believe this will work just fine... 😄

Please explain!

joltdx
Active Contributor
0 Kudos
378

Yes. But I think OP wants to find duplicates in any of the columns.

So I guess extending this solution by SORT + DELETE ADJACENT DUPLICATES for one column at a time would do it, since OP specified it was not important where the duplicate was found... 👍

Sandra_Rossi
Active Contributor
0 Kudos
378

It's what I said: "if you don't care to know..."

The OP says "Actually, i don't care what my duplicates are".

Sandra_Rossi
Active Contributor
0 Kudos
378

or

DATA(all_values) = VALUE string_table(
    FOR <line> IN i_tab ( |{ <line>-field1 }| ) ( |{ <line>-field2 }| ) ).
DATA(temp_all_values) = all_values.
SORT temp_all_values BY table_line.
DELETE ADJACENT DUPLICATES FROM temp_all_values COMPARING table_line.
IF lines( temp_all_values ) <> lines( all_values ).
  " duplicate value
ENDIF.