Ok, die Explode-Routine hab ich neu geschrieben und ein wenig optimiert.
Jetzt müssen nicht mehr so viele New- und Dispose-Befehle ausgeführt werden.
Delphi-Quellcode:
// Das Aufsplitten einer Zeile anhand des SepStrings übernimmt diese Routine.
// Das Ergebnis wird in einem verketteten, temporärem Record gespeichert. So
// kann es dann später leicht in verschiedene Datenformen umgewandelt werden.
procedure MyDBExplode(pHaystack: String);
var
i, n: Integer;
TmpVal, NextTmpVal: PTmyTmp;
begin
// Optimierung:
// Da eigentlich alle Felder gleich lang sind, muss myTmpVal nicht jedesmal
// gelöscht werden, sondern kann wiederverwendet werden. Evntl. muss dafür
// das Feld aber dann eben mittendrin erweitert werden, oder eben am Ende
// gestutzt.
TmpVal := myTmpVal;
n := 0;
// Jetzt nach den Trennzeichen suchen und Ergebnisse im verk. Record
// nyTmpVal speichern.
i := Pos(mySepStr, pHaystack);
while (i > 0) do begin
// Diesen gefundenen Wert jetzt im verk. Record speichern
if (myTmpVal = nil) then begin
New(myTmpVal);
TmpVal := myTmpVal;
TmpVal^.next := nil;
end
else if (n = 0) then begin
// nichts tun
end
else if (TmpVal^.next = nil) then begin
New(TmpVal^.next);
TmpVal := TmpVal^.next;
TmpVal^.next := nil;
end
else begin
TmpVal := TmpVal^.next;
end;
TmpVal^.value := Copy(pHaystack, 1, i - 1);
// Haystack um das gefundene reduzieren und weiter suchen
pHaystack := Copy(pHaystack, i + 1, Length(pHaystack) - i);
i := Pos(mySepStr, pHaystack);
Inc(n);
end;
// Letzten gefundenen Wert natürlich auch noch hinzufügen
if (pHaystack <> '') then begin
if (myTmpVal = nil) then begin
New(myTmpVal);
TmpVal := myTmpVal;
TmpVal^.next := nil;
end
else if (n = 0) then begin
// nichts tun
end
else if (TmpVal^.next = nil) then begin
New(TmpVal^.next);
TmpVal := TmpVal^.next;
TmpVal^.next := nil;
end
else begin
TmpVal := TmpVal^.next;
end;
TmpVal^.value := pHaystack;
end;
// Wenn es jetzt nach dem letzten gesp. Wert noch weitere Felder gibt
// müssen diese gelöscht werden.
if (TmpVal <> nil) then begin
NextTmpVal := TmpVal^.next;
TmpVal^.next := nil;
TmpVal := NextTmpVal;
while (TmpVal <> nil) do begin
NextTmpVal := TmpVal^.next;
Dispose(TmpVal);
TmpVal := NextTmpVal;
end;
end;
end;
Außerdem habe ich einen ziemlich gravierenden Fehler gefunden:
Delphi-Quellcode:
// Werte in der Zeile speichern
TmpVal := myTmpVal;
n := 0;
while (TmpVal <> nil) do begin
if (n < cnt) then begin
curRow^.value[n] := TmpVal^.value;
TmpVal := TmpVal^.next;
end;
Inc(n);
end;
muss natürlich lauten:
Delphi-Quellcode:
// Werte in der Zeile speichern
TmpVal := myTmpVal;
n := 0;
while (TmpVal <> nil) do begin
if (n < cnt) then
curRow^.value[n] := TmpVal^.value;
TmpVal := TmpVal^.next;
Inc(n);
end;
bzw. noch besser:
Delphi-Quellcode:
// Werte in der Zeile speichern
TmpVal := myTmpVal;
n := 0;
while ((TmpVal <> nil) and (n < cnt)) do begin
curRow^.value[n] := TmpVal^.value;
TmpVal := TmpVal^.next;
Inc(n);
end;
Die Einführung von packed records hat so gut wie gar nichts gebracht. Dafür aber die Reduzierung von Array of Shortstring auf Array of String[25]. Und zwar ganz gewaltig! Vielen Dank schonmal an Basilikum für diesen Hinweis. Jetzt muss ich noch das dyn. Array wegrationalisieren