![]() |
AW: StringList Textblöcke verschieben
Die Blöcke haben maximal 30 Zeilen und die Datei ist bis zu 80000 Zeilen lang.
|
AW: StringList Textblöcke verschieben
Bei der Menge kann die Kombination aus Insert und Delete schon deutlich in die Laufzeit gehen.
|
AW: StringList Textblöcke verschieben
Ich habe gerade das Beispiel von der vorherigen Seite getestet mit dieser Datei
Zitat:
Delphi-Quellcode:
Wenn ich 0, 5, 10 eingebe, kommt das hier als Ergebnis. Scheint etwas wackelig zu sein
VerschiebeZeilen(sl, 5, 6, 18); // Block 5-10 soll nach 15 verschoben werden
Zitat:
|
AW: StringList Textblöcke verschieben
Zitat:
Zitat:
Hier noch eine alternative Lösung (beachtet auch eventuell hinterlegte Objects):
Delphi-Quellcode:
Exchange tauscht intern nur die String-Pointer aus, ist also recht effizient.
lst.BeginUpdate;
try for I := 0 to ACount - 1 do lst.Insert(ATargetLine, ''); if ATargetLine < ASourceLine then ASourceLine := ASourceLine + ACount; for I := 0 to ACount - 1 do lst.Exchange(ASourceLine + I, ATargetLine + I); for I := 0 to ACount - 1 do lst.Delete(ASourceLine); finally lst.EndUpdate; end; Da beim Insert/Delete immer nur Leerstrings (Nil-Pointer) betroffen sind, fällt da auch kein verdeckter Verwaltungsaufwand an. |
AW: StringList Textblöcke verschieben
Zu diesem Beispiel habe ich die Frage, was denn ASourceLine ist?
Ist damit AStartLine gemeint? Wenn ja, verzeiht meine Unwissenheit :cyclops: Obwohl, so ganz habe ich noch nicht verstanden wie da was verschoben wird. Meine Ergebnisse sind immer irgendwie komisch.
Delphi-Quellcode:
VerschiebeZeilen(sl, 0, 4, 8);
Zitat:
|
AW: StringList Textblöcke verschieben
Naja, 0 ist der Start, 4 das Ende (bei Zahlen 0-x ist Position 4 die "3" hier also 0-3) und schiebt es an Position 8 (bei Zahlen 0-x ist dies also 8-1 = da wo die 7 gestanden hat).
Das Ergebnis passt also. Würdest du nun
Delphi-Quellcode:
schreiben, müsste folgendes das Ergebnis sein (Zahlen 0-14):
VerschiebeZeilen(sl, 1, 5, 11);
Vorher:
|
AW: StringList Textblöcke verschieben
So funktioniert es bei mir. Alle Leerzeichen werden auch richtig gesetzt. Anders schaffe ich das nicht. Und selbst dann ist es n9icht zuverlässig.
Ich möchte ja keine Zeilen vertauschen sondern nur einen Block von oben irgendwo ganz nach unten verschieben.
Delphi-Quellcode:
var
sl, slTemp: TStringList; i, LineStart, LineEnd, LineTarget: Integer; begin sl := TStringList.Create; slTemp := TStringList.Create; try sl.Add('0 ['); sl.Add('1'); sl.Add('2'); sl.Add('3'); sl.Add('4'); sl.Add(']'); sl.Add(''); sl.Add('5 ['); sl.Add('6'); sl.Add('7'); sl.Add('8'); sl.Add('9'); sl.Add(']'); sl.Add(''); sl.Add('10 ['); sl.Add('11'); sl.Add('12'); sl.Add('13'); sl.Add('14'); sl.Add(']'); sl.Add(''); sl.Add('15 {'); sl.Add('16'); sl.Add('17'); sl.Add('18'); sl.Add('19'); sl.Add('}'); // hier hin soll die 5-9 sl.Add(''); sl.Add('A'); sl.Add('B'); sl.Add('C'); LineStart := sl.IndexOf('0 ['); for i := LineStart to sl.Count - 1 do begin if sl.Strings[i] = ']' then begin LineEnd := i + 2; Break; end; end; LineTarget := sl.IndexOf('15 ['); for i := LineTarget to sl.Count - 1 do begin if sl.Strings[i] = ']' then begin LineTarget := i + 2; Break; end; end; sl.SaveToFile('output1.txt'); VerschiebeZeilen(sl, LineStart, LineEnd, LineTarget); sl.SaveToFile('output2.txt'); finally slTemp.Free; sl.Free; end; end; |
AW: StringList Textblöcke verschieben
Zitat:
|
AW: StringList Textblöcke verschieben
Im ersten Versuch von mir war ein grober Fehler, habe ihn oben behoben.
Hier mal eine Version in PascalScript, sollte recht einfach übertragbar sein:
Delphi-Quellcode:
program Scriptname;
procedure VerschiebeZeilen(sl : TStringList; AStartLine : Integer; ACount : Integer; ATargetLine : Integer); var slTemp : TStringList; i : Integer; begin slTemp := TStringList.Create; // Die zu verschiebenden Zeilen sammeln. for i := AStartLine to AStartLine + ACount - 1 do slTemp.Add(sl[i]); // Nun die zu verschiebenden Zeilen löschen // Es wird immer AStartLine gelöscht, da dadurch die nachfolgenden Zeilen "nach vorne rutschen". for i := 1 to ACount do sl.Delete(AStartLine); // Und anschließend an der gewünschten Position einfügen. // Dabei wird mit der letzten Zeile der gesammelten Zeilen begonnen, // da diese bei jedem Einfügen einer neuen Zeile nach "hinten" verschoben werden. // Im Ergebnis bleibt dadurch die ursprüngliche Reihenfolge erhalten. for i := slTemp.Count - 1 downto 0 do sl.Insert(ATargetLine - ACount,slTemp[i]); slTemp.Free; end; var sl : TStringList; begin sl := TStringList.Create; sl.Add('1'); sl.Add('2'); sl.Add('3'); sl.Add('4'); sl.Add('5'); sl.Add(' '); sl.Add('6'); sl.Add('7'); sl.Add('8'); sl.Add('9'); sl.Add('10'); sl.Add(' '); sl.Add('11'); sl.Add('12'); sl.Add('13'); sl.Add('14'); sl.Add('15'); VerschiebeZeilen(sl,0,5,10); ShowMessage(sl.Text); sl.Free; end. |
AW: StringList Textblöcke verschieben
Zitat:
Zunächst füge ich an der Zielposition eine ausreichende Anzahl Leerzeilen ein:
Delphi-Quellcode:
Dann korrigiere ich den Wert von ASourceLine, falls sich die entsprechenden Zeilen durch das Einfügen nach hinten verschoben haben:
for I := 0 to ACount - 1 do
lst.Insert(ATargetLine, '');
Delphi-Quellcode:
Nun tausche ich die zu verschiebenden Zeilen mit den gerade eingefügten Leerzeilen aus:
if ATargetLine < ASourceLine then
ASourceLine := ASourceLine + ACount;
Delphi-Quellcode:
Damit landen die zu verschiebenden Zeilen schon mal an der gewünschten Zielposition und an der ursprünglichen Position sind nun die Leerzeilen.
for I := 0 to ACount - 1 do
lst.Exchange(ASourceLine + I, ATargetLine + I); Im letzten Schritt werden diese Leerzeilen wieder gelöscht:
Delphi-Quellcode:
for I := 0 to ACount - 1 do
lst.Delete(ASourceLine); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz