2021 Jan 13 10:47 PM
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?
2021 Jan 14 6:56 AM
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.
2021 Jan 14 7:06 AM
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!
2021 Jan 14 9:07 AM
I think you will have a problem after the first duplicate, all the other lines will be considere as duplicate
2021 Jan 14 9:13 AM
I probably don't understand what you mean frdric.girod, because I believe this will work just fine... 😄
Please explain!
2021 Jan 14 7:57 AM
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... 👍
2021 Jan 14 7:59 AM
It's what I said: "if you don't care to know..."
The OP says "Actually, i don't care what my duplicates are".
2021 Jan 14 1:21 PM
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.