FM do sprawdzania, czy w itab są duplikaty

Jeśli programujesz, administrujesz, integrujesz i masz wątpliwość lub obawę, to właśnie najlepsze miejsce dla Ciebie. Pisz śmiało...
ODPOWIEDZ
emil
Posty: 133
Rejestracja: pt gru 27, 2019 11:02 am
Has thanked: 29 times
Been thanked: 42 times

FM do sprawdzania, czy w itab są duplikaty

Post autor: emil »

Od jakiegoś czasu, używam do sprawdzania czy są w itab duplikaty, poniższego kodu:

"sprawdzamy, czy są duplikaty, jeśli tak - przerwać
"program i wyjść do menu głównego / ekranu selekcji

DATA: lv_0035 TYPE i.
DATA: lv_0035_spr TYPE i.
DATA: it_0035_spr TYPE zhcm_it_im_0035.
DATA: it_0035 TYPE zhcm_it_im_0035.

it_0035_spr[] = it_0035[].
DESCRIBE TABLE it_0035_spr LINES lv_0035_spr.
DELETE ADJACENT DUPLICATES FROM it_0035_spr COMPARING pernr begda endda rodzaj datum .
DESCRIBE TABLE it_0035 LINES lv_0035.
DESCRIBE TABLE it_0035_spr LINES lv_0035_spr.
IF lv_0035 <> lv_0035_spr.
MESSAGE 'W pliku wsadowym są wpisy ze zdublowanymi polami kluczowymi!' TYPE 'I' DISPLAY LIKE 'E'.
LEAVE TO SCREEN 0.
ENDIF.

Działa to fajnie, jest ok, ale... Na tyle spopularyzował mi się ten kawałeczek, że chętnie przekułbym go w moduł funkcyjny.
Zastanawiam się, jak do tego podejść, bo chciałbym do FM podawać jako parametr dowolną tabelę wewnętrzną z dowolną strukturą, a także itaba z listą pól, które mają być porównane.

Na ten moment pomysł mam następujący:
- jako parametr podać itab z listą pól do porównania
- jako parametr podać typ tabeli/struktury (wszystko wrzucam do słownika) którą chcę przebadać
- jako parametr podać zawartość tabeli... i tu jest problem.

podając jakiś element importu/eksportu przy tworzeniu FM, zawsze muszę podać typ referencji dla tabeli, którą chcę przesłać do FM.
W momencie, gdy chcę stworzyć "uniwersalny" FM dla dowolnej tabeli, nie mogę z góry zdefiniować tego elementu.

Mogę poprosić o sugestie, jak podejść do tego zagadnienia?
dominik.tylczynski
Posty: 8326
Rejestracja: wt kwie 03, 2007 4:05 pm
Has thanked: 1915 times
Been thanked: 1474 times
Kontakt:

Re: FM do sprawdzania, czy w itab są duplikaty

Post autor: dominik.tylczynski »

Przede wszystkim nie robiłbym modułu funkcyjnego. FM są już passé.
Zrób lepiej klasę z metodą statyczną. Możesz wtedy użyć generycznego typu TABLE czy ANY TABLE:
20220812_2120.png
20220812_2120.png (14.79 KiB) Przejrzano 1184 razy


Możesz też użyć innych generycznych typów tablicowych:
SAP Help: Generic ABAP Types pisze:
  • any table Internal table with any table category
  • hashed table Hashed table
  • index table Index table
  • sorted table Sorted table
  • standard table Standard table
  • table Standard table
wojtas7
Posty: 1058
Rejestracja: pt mar 14, 2008 12:51 pm
Has thanked: 71 times
Been thanked: 313 times

Re: FM do sprawdzania, czy w itab są duplikaty

Post autor: wojtas7 »

a masz posortowana tabele zanim robisz delete duplicates?

f module nie sa passe :-) ja z kolei nie lubie metod statycznych.
dominik.tylczynski
Posty: 8326
Rejestracja: wt kwie 03, 2007 4:05 pm
Has thanked: 1915 times
Been thanked: 1474 times
Kontakt:

Re: FM do sprawdzania, czy w itab są duplikaty

Post autor: dominik.tylczynski »

Ok, FM nie są jeszcze oficjalnie obsolete, ale kilka technik w nich wykorzystywanych już tak - SAP Help Obsolete Modularization: Function Modules

Statyczne metody choć działają +/- jak FM mają kilka zalet, np. FM vs metody to w dużej mierze kwestia gustu, a de gustibus non est disputandum :wink:
K602
Posty: 135
Rejestracja: śr sie 24, 2022 11:50 am
Has thanked: 60 times
Been thanked: 86 times
Kontakt:

Re: FM do sprawdzania, czy w itab są duplikaty

Post autor: K602 »

Skupię się nad samym kodem. Trochę zmodyfikowałbym ten kod z początku. Szkoda czasu na liniowe sprawdzanie ilości elementów tabeli, skoro mamy właściwość sy-subrc:

Kod: Zaznacz cały

DATA: lt_duplikat TYPE SORTED TABLE OF c WITH NON-UNIQUE KEY table_line.

lt_duplikat = VALUE #( ( 'a' )
                       ( 'b' )
                       ( 'c' )
                       ( 'd' )
                       ( 'e' )
                       ( 'f' )
                       ( 'a' )
                     ).

DELETE ADJACENT DUPLICATES FROM lt_duplikat USING KEY primary_key COMPARING ALL FIELDS.
IF sy-subrc EQ 0.
  cl_demo_output=>display_text( 'Były duplikaty' ).
ELSE.
  cl_demo_output=>display_text( 'Brak duplikatów' ).
ENDIF.
Osobiście użyłbym jednak groupera:

Kod: Zaznacz cały

LOOP AT lt_duplikat ASSIGNING FIELD-SYMBOL(<fs_duplikat>) USING KEY primary_key GROUP BY ( line = <fs_duplikat>-line group_size = GROUP SIZE group_index = GROUP INDEX ) REFERENCE INTO DATA(lo_group).

  IF lo_group->group_size GT 1.
    cl_demo_output=>display_text( 'Były duplikaty' ).
    lv_duplikat = 'X'.
    EXIT.
  ENDIF.
ENDLOOP.

IF lv_duplikat IS INITIAL.
  cl_demo_output=>display_text( 'Brak duplikatów' ).
ENDIF.
* BST warto używać powyżej +/-50 rekordów
SAP ABAP Certified Developer
ODPOWIEDZ