Resumee:
Nach Auswertung der geposteten Routinen stelle ich fest, dass der beste Lösungsansatz wohl ein 2-Schritt-Verfahren zu sein scheint.
Im 1. Schritt wird die Tabelle auf eine sortierte und verdichtete Form gebracht ( pro Monat maximal 1 Einttrag ) und im 2. Schritt wird dann gezählt wieviele Einträge pro Material vorhanden sind.
Der pragmatische Ansatz wäre
Code: Alles auswählen.
FIELD-SYMBOLS: <input> TYPE ty_input.
DATA: zaehler TYPE i.
CLEAR p_ergebnis.
* 1. Schritt - sortierte, verdichtete Tabelle
SORT t_input by material budat.
DELETE ADJACENT DUPLICATES FROM t_input COMPARING budat(6).
* 2. Schritt - zählen, wie oft jedes Material gebucht wurde
LOOP AT t_input ASSIGNING <input>.
AT NEW material.
CLEAR zaehler.
ENDAT.
ADD 1 TO zaehler.
AT END OF material.
IF zaehler = 12.
ADD 1 TO p_ergebnis-dauerbrenner.
ELSEIF zaehler >= 10.
ADD 1 TO p_ergebnis-saison.
ENDIF.
ENDAT.
ENDLOOP.
p_ergebnis-ladenhueter = p_max_matnr - p_ergebnis-dauerbrenner
- p_ergebnis-saison.
Dies ist ein übersichtlicher und für spätere Entwickler leicht zu durchschauender Code und grob das, was ich wohl bei einem Kunden so stehen lassen würde.
Die weiteren Optimierungen beruhen darauf (wie Frank ja gepostet hatte), dass ein Großteil der Rechenzeit beim Sortieren der Tabelle draufgeht .
Eine überarbeitete Version hat Frank dann ja auch schon in seinem 1. (allgemeingültigem) Posting mitgeliefert, in dem der 1. Schritt nun so aussah.
Code: Alles auswählen.
* 1. Schritt überarbeitet
LOOP AT t_input INTO my_input.
tmp_wa-material = my_input-material.
tmp_wa-m = my_input-budat+4(2).
COLLECT tmp_wa INTO tmp_input.
ENDLOOP.
Den finalen Schliff hat dann Olaf P. in seinem letzten Posting gegeben, in dem er die Hauptarbeit des Zählens in den 1. Schritt integriert hat mit dem Tool, das uns SAP zur Hand gibt - eine Tabelle und dem Befehl COLLECT. Die Methode den SY-SUBRC des Collect, den er für den 1. Schritt sowieso braucht, auszuwerten und in einer 2. Tabelle mitzählen zu lassen wie häufig pro Material der Collect wirklich einen neuen Eintrag erzeugt hat, führt zu einem effizienten und elegantem Code.
Abschließende Bemerkungen:
1.) Weitere Effizienzsteigerungen lassen sich dadurch erzielen, dass man Aussagen über die statistische Verteilung in der Tabelle INPUT machen kann und die Routinen dementsprechend anpasst.
2.) Wenn man nicht über "SORT, DELETE-ADJACENT-DUPLICATES" geht, sondern die verbesserte Version eine sortierte, verdichtete Tabelle zu erstellen verwendet, wird die Origaltabelle (INPUT) ja nicht verändert. Und da ein nicht unerheblicher Teil der Laufzeit für die Wertübergabe der Inputtabelle draufgeht, könnte man stattdessen eine Referenzübergabe verwenden (war aber nicht erlaubt lt. Aufgabenstellung - somit nur als Anmerkung)
3.) Ich habe die oben gepostete Demolösung mal mit der letzten Version von Olaf P. ( die schnellste gepostete) verglichen. Olafs Version ist bei 100.000 Einträgen ca. um den Faktor 2 schneller als die pragmatische Lösung.
Das sind Welten - aber verglichen mit der Ersparnis der Demolösung gegenüber der ursprünglichen Referenzlösung (Faktor > 100 ) nicht so viel.
Da kommts dann wohl auf das Projekt und die genauen Umgebungsparameter (Kunden) an, die bestimmen ob der pragmatische Ansatz schon ausreicht oder noch daran rumgefeilt werden muss. Möglich ist viel, wie man sieht...
4.) Danke an alle, die hier gepostet haben.
5.) Ich hänge noch eine überarbeitete Version des Programms an, welches die geposteten Lösungen enthält und es zulässt die einzelnen Versionen (bzw eigene) gegeneinander auszutesten. (Und statt des Mittelwert der Laufzeit alternativ die minimale Laufzeit bei mehreren Durchläufen als Faktor zur Berechnung zulassen kann. Hatte mich Frank drauf aufmerksam gemacht und beim Betrachten und Vergleichen der verschiedenen Lösungen bin ich auch zu der Ansicht gelangt, dass dies wohl der bessere Ansatz ist)
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.