Agregacja dat do zakresów begda-endda

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

Agregacja dat do zakresów begda-endda

Post autor: emil »

Sprawa ma się następująco:
ITAB zawiera trzy kolumny: pernr, begda, endda. Zawartość jak niżej (puste linie są tylko po to, by tu łatwiej się czytało zawartość tabeli):

123 | 01.12.2022 | 01.12.2022
123 | 02.12.2022 | 02.12.2022

123 | 12.12.2022 | 12.12.2022
123 | 13.12.2022 | 13.12.2022
123 | 14.12.2022 | 14.12.2022
123 | 15.12.2022 | 15.12.2022
123 | 16.12.2022 | 16.12.2022

123 | 28.12.2022 | 28.12.2022
123 | 29.12.2022 | 29.12.2022
123 | 30.12.2022 | 30.12.2022

456 | 13.12.2022 | 13.12.2022

789 | 05.12.2022 | 05.12.2022
789 | 06.12.2022 | 06.12.2022
789 | 07.12.2022 | 07.12.2022
789 | 08.12.2022 | 08.12.2022
789 | 09.12.2022 | 09.12.2022

789 | 12.12.2022 | 12.12.2022

789 | 27.12.2022 | 27.12.2022
789 | 28.12.2022 | 28.12.2022
789 | 29.12.2022 | 29.12.2022
789 | 30.12.2022 | 30.12.2022

Muszę uzyskać stan, w którym dla pernr`s będę miał zagregowane daty kolejnych dni, czyli powyższy itab musi być przekształcony w coś takiego:

123 | 01.12.2022 | 02.12.2022
123 | 12.12.2022 | 16.12.2022
123 | 28.12.2022 | 30.12.2022

456 | 13.12.2022 | 13.12.2022

789 | 05.12.2022 | 09.12.2022
789 | 12.12.2022 | 12.12.2022
789 | 27.12.2022 | 30.12.2022

Wydawać by się mogło, że sensowny kierunek podpowiada wpis na answers.sap, ale niestety przykład z przytoczonej strony przeprocesuje mi w ramach pernr WSZYSTKIE daty, a nie tylko te, które następują po sobie.

Czy kojarzycie jakiś FM agregujący sąsiednie daty?
Ewentualnie mogę liczyć na jakieś sugestie dot. rozwiązania powyższego przypadku?

(zaczynam się zastanawiam, czy nie przydałby się na forum jakiś temat z tego typu zadaniami i rozwiązaniami, pomogłoby to nabrać sprytu przy tego typu przypadkach).
K602
Posty: 133
Rejestracja: śr sie 24, 2022 11:50 am
Has thanked: 60 times
Been thanked: 86 times

Re: Agregacja dat do zakresów begda-endda

Post autor: K602 »

Podszedłbym do tego tak:

Założenie: Daty początkowe (BEGDA) następują zawsze po sobie - brak dziur.
Prerekwizyt: Posortowane po wszystkich polach.

1. Lecimy w LOOP AT... GROUP BY PERNR... i potem LOOP po podgrupach.
2. W danej podgrupie sprawdzamy, czy po podaniu 1 do BEGDA otrzymujemy BEDGDA (n+1) Jeśli tak, to weź ENDDA (n+1) i wstaw za ENDDA (n)... i tak do przejścia całej podgrupy. Wtedy BEGDA pozostanie z 1 wiersza podgrupy, a ENDDA z ostatniego wiersza podgrupy.

Powyższe zadziała tylko z założeniem, o którym wspomniałem, a które nałożyłem widząc powyższe dane...
SAP ABAP Certified Developer
K602
Posty: 133
Rejestracja: śr sie 24, 2022 11:50 am
Has thanked: 60 times
Been thanked: 86 times

Re: Agregacja dat do zakresów begda-endda

Post autor: K602 »

Albo jeszcze prościej, zauważając pewną zależność:

Wcześniej posortowane podgrupy, sortujemy dodatkowo po PERNER i BEGDA (już posortowane rosnąco po tej kolumnie) i bierzemy BEGDA z pierwszego wiersza. Zapisujemy taką datę początkową dla danego PERNR. Potem sortujemy po PERNR i ENDDA (malejąco ta ostatnia) i bierzemy ENDDA z pierwszego wiersza.

Składamy całość z podgrupy: PERNR, LV_BEGDA, LV_ENDDA
SAP ABAP Certified Developer
emil
Posty: 133
Rejestracja: pt gru 27, 2019 11:02 am
Has thanked: 29 times
Been thanked: 42 times

Re: Agregacja dat do zakresów begda-endda

Post autor: emil »

K602 pisze: pn sty 16, 2023 10:16 am Założenie: Daty początkowe (BEGDA) następują zawsze po sobie - brak dziur.
Gdyby tak było, nie byłoby problemu. Niestety mogą być dziury pomiędzy begdami w ramach jednego numeru ewid.
To przekreśla (tak mi się zdaje) Twoje sugestie.
K602
Posty: 133
Rejestracja: śr sie 24, 2022 11:50 am
Has thanked: 60 times
Been thanked: 86 times

Re: Agregacja dat do zakresów begda-endda

Post autor: K602 »

emil pisze: czw sty 19, 2023 7:08 am
K602 pisze: pn sty 16, 2023 10:16 am Założenie: Daty początkowe (BEGDA) następują zawsze po sobie - brak dziur.
Gdyby tak było, nie byłoby problemu. Niestety mogą być dziury pomiędzy begdami w ramach jednego numeru ewid.
To przekreśla (tak mi się zdaje) Twoje sugestie.
To tak na przyszłość. Jak przekazujesz jakąś próbkę danych, to fajnie aby była reprezentatywna. W tej co podałeś, jest brak dziur :)

Pomijając, w takim razie w pierwszym poście opisałem, jakbym do tego podszedł. To jest odporne na dziury :)
SAP ABAP Certified Developer
emil
Posty: 133
Rejestracja: pt gru 27, 2019 11:02 am
Has thanked: 29 times
Been thanked: 42 times

Re: Agregacja dat do zakresów begda-endda

Post autor: emil »

Jak nie ma dziur, jeśli są?
Chyba, że coś inaczej rozumiemy:

Kod: Zaznacz cały

123 | 01.12.2022 | 01.12.2022
123 | 02.12.2022 | 02.12.2022
[b]<dziura od 3go do 11go grudnia>[/b]
123 | 12.12.2022 | 12.12.2022
123 | 13.12.2022 | 13.12.2022
123 | 14.12.2022 | 14.12.2022
123 | 15.12.2022 | 15.12.2022
123 | 16.12.2022 | 16.12.2022
K602
Posty: 133
Rejestracja: śr sie 24, 2022 11:50 am
Has thanked: 60 times
Been thanked: 86 times

Re: Agregacja dat do zakresów begda-endda

Post autor: K602 »

Ok, zmyliły mnie te przerwy dla tego samego klucza.

Wracając do tematu i pierwszego zaproponowanego rozwiązania. Próbujesz tak zrobić?
SAP ABAP Certified Developer
emil
Posty: 133
Rejestracja: pt gru 27, 2019 11:02 am
Has thanked: 29 times
Been thanked: 42 times

Re: Agregacja dat do zakresów begda-endda

Post autor: emil »

Nie miałem noża na gardle, więc mogłem powoli ogarniać temat.
Finalnie stanęło na rozwiązaniu podpowiedzianym przez współpracownika (użyj while`a!):

Kod: Zaznacz cały


      DATA: lv_start TYPE pa9501-begda.
      DATA: lv_koniec TYPE pa9501-endda.
      DATA: lv_przedzial_1 TYPE pa9501-endda.
      DATA: lv_przedzial_2 TYPE pa9501-endda.
      DATA: lv_begda TYPE pa9501-begda.

      lv_start = pn-begda.
      lv_koniec = pn-endda.

      WHILE ( lv_start <= lv_koniec ).

        "sprawdź, czy dla obecnej daty jest termin pracy zdalnej
        LOOP AT it_tmp INTO wa_tmp WHERE begda EQ lv_start.
        ENDLOOP.
        IF sy-subrc EQ 0.
          IF lv_przedzial_1 IS INITIAL. "jeśli nie ma daty startowej to wstaw dane z tmp
            lv_przedzial_1 = wa_tmp-begda.
          ENDIF."jeśli nie ma daty startowej to wstaw dane z tmp

          lv_przedzial_2 = wa_tmp-endda. "zawsze dodawaj datę końcową jeśli jest zgodna z założeniami

        ELSE. "nie znaleziono kolejnego dnia na zasadzie "poprzedni + 1 " = ZAPIS DANYCH
          IF lv_przedzial_1 IS NOT INITIAL.
            wa_alv-begda = lv_przedzial_1.
            wa_alv-endda = lv_przedzial_2.
            wa_alv-pernr = wa_tmp-pernr.
            APPEND wa_alv TO it_alv.
            CLEAR: wa_alv ,  wa_tmp , lv_przedzial_1 , lv_przedzial_2.
          ENDIF.

        ENDIF.

        IF ( lv_start EQ lv_koniec ) AND ( lv_przedzial_1 IS NOT INITIAL AND lv_przedzial_2 IS NOT INITIAL ).
          wa_alv-begda = lv_przedzial_1.
          wa_alv-endda = lv_przedzial_2.
          wa_alv-pernr = wa_tmp-pernr.
          APPEND wa_alv TO it_alv.
          CLEAR: wa_alv ,  wa_tmp , lv_przedzial_1 , lv_przedzial_2.
        ENDIF.

        lv_start = lv_start + 1.
      ENDWHILE.

...czyli tak naprawdę to lecę whilem po datach z zakresu otrzymanego z ekranu selekcji i sprawdzam, czy jest ciągłość.
Jeśli tak - rozszerzam zakres finalny, jeśli nie - wrzucam kolejne begda=endda jako zakres finalny ;)