Hallo jobo, bin etwas erstaunt, dachte, die Fragestellung wäre recht einfach. Irrtum offenbar.
Es geht um ein Auswertprogramm für eine jährliche Datenerhebung, die seit über 10 Jahren läuft. Sie liegt im DBF-Format vor. Ich lese sie mit TDbf ein (dessen Aktualisierung schon nervig genug ist) und werte die Abfragen mit AbsoluteDatabase aus (da AbsDB In-Memory-Tables bietet). Das klappt alles einwandfrei.
Jetzt würde ich mich gern unabhängig von AbsDB machen, dessen umfangreiche
DB-Funktionalität ich überhaupt nicht brauche. Die Daten sind statisch und werden ausschließlich gelesen (außer beim Einlesen der
DB), und Mehrbenutzer ist auch nicht notwendig.
Hauptgrund ist aber die jährliche Aktualisierung. Die Erhebung wird jedes Jahr etwas verändert. Die Variablennamen werden nach Gruppen geordnet fortlaufend nummeriert. Fällt auch nur eine Variable weg oder wird hinzugefügt, ändert sich die Bezeichnung aller nachfolgenden. Dieses Jahr ist die 4. Variable weggefallen. Jetzt stehe ich vor nervtötenden Aufgabe, 100 Variablennamen, Bezeichnungen und Wertebezeichnungen neu anzupassen. (Auf die Struktur der
DB habe ich keinerlei Einfluss).
Daher habe ich mich entschlossen, die lang gehegte Absicht anzugehen, das Programm generisch zu gestalten. Hierfür habe ich ein Konzept, das funktionierten müsste. Dazu brauche ich volle Gestaltung, was mit einem
DB-Programm nicht möglich ist.
Ich habe keine Ahnung, nach welchem Algorithmus die
SQL-Befehle von AbsDB arbeiten. Ich habe mich entschlossen, einfach die Kirche im Dorf zu lassen. Einfache Zähl- und Sortiervorgänge auch von einer Million Daten sind selbst bei älteren Prozessoren dermaßen schnell, dass auch deutlich suboptimale Algorithmen unter einer Sekunde brauchen. Das reicht völlig.
Ich kam dann relativ rasch darauf, dass bei diesem Ansatz das Problem darin besteht, ein zweidimensionales Array zu sortieren. In VB kein Problem, in Delphi augenscheinlich schon! Ich habe mich dann - wie so oft - nach
diesem Beitrag von Altmeister David Heffernan gerichtet.
Mein Ansatz ist also bisher folgender:
1. Deklaration einer Klasse mit einem TStringDynArray als einzigem Inhalt (= Datensatz)
2. Deklaration einer Klasse TObjectList vom obigen Typ.
3. Einlesen der DBF-Daten über TDbf als string (ja, ja!)
Das Einlesen per TDbf, Überführen in die Liste inklusive Umwandeln zu string sowie testweise Sortieren nach einer Integervariable (mit 3.000 Mal Umwandeln von string zu integer im Comparer) dauert keine Sekunde auf einem Notebook mit einem älteren i3. Feierabend!
Mein weiteres Vorgehen wäre jetzt so, dass ich sortiere, zähle und das Ergebnis in die Form bringe, die mir zurzeit von
SQL geliefert wird, damit ich den bisherigen Code nahtlos weiterverwenden kann. Bei Kreuztabellen mit 2 oder gar 3 Variablen würde ich dann immer die erforderlichen kleinen Abschnitte der Liste in eine temporäre Arbeitsliste kopieren, sortieren und zählen. Einfacher wäre es vermutlich, Quicksort den Bereich des zu Sortierenden zu übergeben, aber dann müsste ich direkt auf Quicksort gehen. Da nur die Referenzen kopiert werden und alles im Arbeitsspeicher abläuft, gehe ich davon aus, dass das so blitzschnell vor sich geht, dass auch diese Suboptimalität keine praktischen Konsequenzen hat.
Das ist jetzt mein Stand. Alles etwas vom Hobbyhandwerker, aber wenn's funktioniert?
Wenn natürlich jemand mit einer Profilösung um die Ecke kommt - herzlich willkommen!