Hallo zusammen,
ich habe ein Programm, das viele Werte zeitraumsgenau einliest. In meinem Falle sind es Planstellen, aber da ich weiß, dass die meisten hier mit MM mehr anfangen können als mir HCM, sagen wir mal, es seien Materialien. Nehmen wir an, ein Material X habe 10 Attribute (Name, Werkszugehörigkeit, Verkaufspreis ...). Jedes einzelne davon kann sich im Laufe der Zeit ändern. Wenn ich also eine Liste machen möchte, die vom 01.01.2017 bis zum 31.12.2017 das Material mit all seinen Attributen darstellt, dann muss ich das Jahr in Teilzeiträume zerhacken. Jedes Mal, wenn (mindestens) eines der Attribute seinen Wert ändert, brauche ich eine neue Tabellenzeile.
So weit verständlich? Dann geht es weiter: Die Liste soll nicht nur ein Material umfassen, sondern viele Materialien. Bei jedem Material, dessen Attribute sich innerhalb des Jahres nicht verändert haben, reicht mir eine Zeile, deren Spalten halt die Attribute enthält. Bei allen anderen Materialien enthält die Liste mehrere Zeilen für dasselbe Material mit entsprechendem Beginn- und Endedatum.
Einfaches Beispiel:
Code: Alles auswählen.
Material von bis Att 1 Att 2 Att 3
X 01.01.2017 30.06.2017 AA BB CC
X 01.07.2017 31.12.2017 FF BB CC
Y 01.01.2017 31.12.2017 DD UU KK
Jetzt will ich so eine Liste in einer internen Tabelle aufbauen. Jedes Attribut steht in einer anderen, beginn- und endedatumbehafteten Datenbanktabelle. Die Zeiträume der verschiedenen Attribute können sich natürlich beliebig überlappen. Es kann auch sein, dass ein Attribut für ein Material in einem bestimmten Teilzeitraum gar nicht definiert ist. All dies gilt es, zeitraumgerecht in der internen Tabelle abzumischen. Die Aufgabe hat natürlich eine gewisse Komplexität.
Ich habe das so gelöst, dass ich zuerst das erste Attribut für das gesamte Jahr (also ggf. mehrere Teilzeiträume) in eine interne Tabelle AUSGANGSTABELLE einlese. Dann mache ich einen LOOP über die AUSGANGSTABELLE, lese das zweite Attribut dazu (wobei ich die Zeiträume aus AUSGANGSTABELLE ggf. in zusätzliche Teilzeiträume zerhacken und zu diesem Zweck vervielfältigen muss) und lege das Ergebnis in einer Zieltabelle B ab.
Dann mache ich einen einfachen Befehl
AUSGANGSTABELLE[] = B[]. REFRESH B. und mache wieder einen LOOP über die AUSGANGSTABELLE, lese das dritte Attribut dazu und lege wieder in B ab. Das Ganze wiederhole ich so oft, bis ich sämtliche Attribute eingelesen habe.
Ob es performant ist, nach jedem Attribut per
AUSGANGSTABELLE[] = B[]. den gesamten Tabelleninhalt umzukopieren, möchte ich an dieser Stelle gern außen vor lassen. Ich habe diesen Weg gewählt, weil er mir am besten geeignet schien, die enorme Komplexität mit den vielen einander überlappenden Teilzeiträumen der einzelnen Attribute beherrschbar zu machen.
Das Ganze funktioniert auch. Bei großen Materialanzahlen laufe ich aber in das Problem, dass ich einen Dump der Form
TSV_TNEW_PAGE_ALLOC_FAILED "Kein Speicher für Erweiterung einer internen Tabelle mehr verfügbar" bekomme. Dass die Tabelle selbst so groß geworden ist, dass sie nicht mehr in den Speicher passt, kann ich mir nicht vorstellen. Meine Befürchtung ist, dass ABAP beim Umkopieren des Tabelleninhalts (wobei ja immer der alte Inhalt von AUSGANGSTABELLE durch den neuen ersetzt wird), den vom alten Tabelleninhalt belegten Speicher nicht direkt freigibt, sondern zunächst noch belegt lässt. Da es in meinem Programm weit mehr als nur 10 Attribute gibt, die dieserart abgemischt werden, ist meine Befürchtung, dass auf diese Weise viele herrenlose Kopien des Tabelleninhalts im Speicher entstehen. Die würden vermutlich früher oder später vom Garbage Collector abgeholt werden. Doch vorher kommt es bereits zum Dump.
Wie kann ich das vermeiden? Sollte ich jedesmal zwischendurch einen FREE-Befehl absetzen? Das wäre performancemäßig noch schlimmer, und ich meine irgendwo gelesen zu haben, dass auch FREE nicht direkt freigibt, sondern die Sache nur dem Garbage Collector anheimstellt.
Vielleicht gäbe es ja auch eine bessere Variante als das Umkopieren? Sie muss nur halt programmiertechnisch beherrschbar sein, ohne dass die Komplexität (oder die Programmlaufzeit) aus dem Ruder läuft.