Autor |
Beitrag |
Knulli
      
Beiträge: 116
Erhaltene Danke: 2
Win2k, Win7, Win10
D5, D2005, D2006, D2007, D10.4.2
|
Verfasst: Fr 21.06.13 16:39
Hi Leute,
ich hab in nem RichEdit etliche Zeilen Text (Logging)
Nun will ich all diejenigen Zeilen rauswerfen, in denen ein bestimmter Text NICHT vorkommt.
Das klappt auch etliche Male und bei einer bestimmten Zeile hängt sich mein Programm auf. Es kommt aus RichEdit1.Lines.Delete(IDXZeile); nicht wieder.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| CntZeile := RichEdit1.Lines.Count; IDXZeile := 0;
while IDXZeile < CntZeile do begin Zeile := RichEdit1.Lines[IDXZeile];
.....
if Not bHalten then begin RichEdit1.Lines.Delete(IDXZeile); Dec(CntZeile); end else Inc(IDXZeile); end; |
Ich hab mal in die Sourcen reindebuggt, er kommt aus dem SendMessage(RichEdit.Handle, EM_REPLACESEL, 0, Longint(Empty)); nicht wieder.
Kennt das jemand? Es scheint übrigens an einer bestimmten Konstellation zu liegen. Lösche ich andere Zeilen, hängt er sich nicht auf.
Falls jemand Lust hat: Im Anhang die RTF, alle Zeilen löschen, außer die mit "DeviceId": "AnimalPort 3". Bei verbleibenden 258 Zeilen knallts.
RichEdit.Refresh zwischendurch hilft auch nicht
Knulli
Einloggen, um Attachments anzusehen!
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Fr 21.06.13 16:47
Was passiert denn, wenn Du eine TStringlist anlegst, die Zeilen aus dem RichEdit hineinkopierst, dann die betreffenden Zeilen aus dieser Liste löschst und zum Schluss alles wieder zurückschreibst?
[edit] Also ungefähr so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| var Liste: TStringlist; i: integer; begin RichEdit1.Lines.BeginUpdate; try Liste := TStringlist.Create; try Liste.Assign(RichEdit1.Lines); for i := Liste.Count - 1 downto 0 do if not Bedingung then Liste.Delete(i); RichEdit1.Lines.Assign(Liste); finally Liste.Free; end; finally RichEdit1.Lines.EndUpdate; end; end; | [/edit]
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Sa 22.06.13 00:30
|
|
jaenicke
      
Beiträge: 19313
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 22.06.13 08:50
Eine separate Stringliste wie von WasWeißDennIch vorgeschlagen ist dennoch besser, da das deutlich schneller ist als die GUI Komponente ständig zu aktualisieren...
// EDIT:
Woher kommen die Daten eigentlich? Wenn die nicht vom Benutzer dort eingegeben werden, wäre es sinnvoller die zuerst zu bearbeiten und dann in die Richedit Komponente zu packen.
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Sa 22.06.13 11:05
jaenicke hat folgendes geschrieben : | da das deutlich schneller ist als die GUI Komponente ständig zu aktualisieren... |
Dann setzt man halt ein "RichEdit1.Lines.BeginUpdate;" davor und ein "RichEdit1.Lines.EndUpdate;" danach. Ich kann mir jedenfalls kaum vorstellen, daß die Variante mit der StringList deutlich schneller ist.
|
|
jaenicke
      
Beiträge: 19313
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 22.06.13 13:36
Gerd Kayser hat folgendes geschrieben : | Dann setzt man halt ein "RichEdit1.Lines.BeginUpdate;" davor und ein "RichEdit1.Lines.EndUpdate;" danach. Ich kann mir jedenfalls kaum vorstellen, daß die Variante mit der StringList deutlich schneller ist. |
Ich empfehle dir sehr einen Blick in den Quelltext von TRichEdit, dann würdest du das nicht sagen...
Kurz gesagt:
Zuerst wird der Anfang der Zeile über das Handle und den Zeilenindex von Windows erfragt, wenn diese existiert auch das Ende der Zeile. Dann wird dieser Teil des Textes wiederum über die Windows API markiert. Und schließlich wird dieser markierte Teil durch einen Leerstring ersetzt.
Was passiert bei TStringList:
Es wird anhand reiner Integervergleiche geprüft, ob der Index im gültigen Bereich liegt. Dann wird der Record mit den Daten des Eintrags gelöscht und die anderen Einträge um diesen freigewordenen Platz im Array verschoben. Es werden dabei nur wenige Bytes angefasst, da die Pointer auf die Strings verschoben werden. Die anderen Zeilen werden da gar nicht angefasst.
Probier es aus, wenn du es trotzdem nicht glaubst. Es ist deutlich schneller. Und zudem ist es auch sinnvoller solche Sachen ohne Beteiligung der GUI zu machen.
Für diesen Beitrag haben gedankt: Gerd Kayser
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Sa 22.06.13 15:07
jaenicke hat folgendes geschrieben : | Es ist deutlich schneller. |
Stimmt. Gerade mit der Datei des Fragestellers getestet. Meine Variante 0,163 Sekunden, die Variante mit der Stringlist 0,010 Sekunden (jeweils beste Zeiten aus mehreren Durchläufen genommen). Bei dieser (kleineren) Datei fällt das einem bei der Programmausführung aber kaum auf. Aber je größer die Datei ist, desto größer fallen die Zeitunterschiede aus. RichEdit wird da extrem langsam im Vergleich zur StringList-Variante.
|
|
Knulli 
      
Beiträge: 116
Erhaltene Danke: 2
Win2k, Win7, Win10
D5, D2005, D2006, D2007, D10.4.2
|
Verfasst: Do 27.06.13 13:45
So, erstmal Danke für die vielen Ideen.
Das mit einer zweiten Liste hab ich nicht gemacht, weil dabei die Text-Formatierungen verlorengehen. Das mit dem rot und blau hilft nämlich zusätzlich, den Überblick in den vielen Zeilen zu behalten.
Geschwindigkeit ist hier nicht so das Problem, da es um eine Fehleranalyse geht, es soll also aus den Log-Daten der Grund für ein Fehlverhalten der Anlage gewonnen werden.
Leider ist in den LogDaten eben auch viel anderes Zeugs mit drin.
Ich probier mal die Idee mit dem Löschen von Hintem aus.
Knulli
|
|
Knulli 
      
Beiträge: 116
Erhaltene Danke: 2
Win2k, Win7, Win10
D5, D2005, D2006, D2007, D10.4.2
|
Verfasst: Do 27.06.13 14:12
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Do 27.06.13 14:20
Und was machst Du, wenn JSONobject nil wird? Wird dann gelöscht oder nicht?
|
|
Knulli 
      
Beiträge: 116
Erhaltene Danke: 2
Win2k, Win7, Win10
D5, D2005, D2006, D2007, D10.4.2
|
Verfasst: Di 23.07.13 15:43
Dann ist bHalten == false und die aktuelle Zeile wird gelöscht. Stand ja sowieso Müll (oder nix) oder eben nicht das gesuchte Wort drin...
|
|
jaenicke
      
Beiträge: 19313
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 23.07.13 16:01
Nein, ist es nicht. Dann ist es nicht initialisiert...
Du setzt es nur in if JSONobject <> Nil then, liest es danach aber immer aus.
Der Compiler sollte da auch eine Warnung ausgeben.
|
|
Knulli 
      
Beiträge: 116
Erhaltene Danke: 2
Win2k, Win7, Win10
D5, D2005, D2006, D2007, D10.4.2
|
Verfasst: So 28.07.13 18:56
bHalten wird auch immer erstmal auf false gesetzt (Zeile über ParseText).
Der Compiler meckert nicht...
|
|
jaenicke
      
Beiträge: 19313
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 28.07.13 19:49
Knulli hat folgendes geschrieben : | bHalten wird auch immer erstmal auf false gesetzt (Zeile über ParseText). |
Hinten in der Zeile... ach du Schreck...
Wer Quelltext so formatiert... ohjemine. Ja, da hast du Recht, da steht es... aber durch die abenteuerliche Formatierung mit mehreren Befehlen in einer Zeile sieht man das halt nicht so schnell...
|
|
wq121984
Hält's aus hier
Beiträge: 1
|
Verfasst: Di 06.08.13 07:30
This is a very good post, I like it very much
|
|