Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Listview Daten im Hintergrund suchen und Löschen (https://www.delphipraxis.net/179971-listview-daten-im-hintergrund-suchen-und-loeschen.html)

jacky213 15. Apr 2014 02:16

Listview Daten im Hintergrund suchen und Löschen
 
Moin,

also ich habe eine Form mit 2 Listviews. Listview1 ist die Hauptliste und Listview2 besitzt einige Einträge aus Listview1 die dort besser Sortiert aufgelistet sind. Ich wollte nun einen Eintrag in Listview2 auswählen und mittels Informationen aus einem SubItem im Listview2 den Eintrag in Listview1 suchen und Löschen.

Das ganze sieht bis jetzt so aus und funktioniert soweit auch. Der gesuchte Eintrag wird im Listview1 gesucht, gefunden und gelöscht, allerdings erhalte ich diesen Fehler:

Code:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Project2.exe ist eine Exception der Klasse $C0000005 mit der Meldung 'access violation at 0x005f657c: read of address 0x00000008' aufgetreten.
---------------------------
Anhalten  Fortsetzen  Hilfe  
---------------------------
Zum suchen des Eintrags im Listview1 nutze ich folgende Prozedur:

Code:
Procedure ListviewLöschen (str: string);
  var
    i: Integer;
begin
str := Trim(str);
  for i := 0 to frmSpeisekarte.ListView1.Items.Count-1 do
    if (Trim(frmSpeisekarte.ListView1.Items.Item[i].SubItems[0]) = str) then begin
    frmSpeisekarte.SetFocus;
    frmSpeisekarte.ListView1.Items.Delete(i);
end;
end;
Aufgerufen wird das ganze so:

Code:
    ListviewLöschen(listview2.Selected.SubItems[0]);
Warum bekomme ich diese Fehlermeldung? und wie kann ich diese verhindern?

Danke!

Popov 15. Apr 2014 03:01

AW: Listview Daten im Hintergrund suchen und Löschen
 
Man sollte Listen niemals von unten (also bei Null beginnend) nach oben löschen, sondern immer von oben nach unten. Grund: löscht man man den Eintrag am Anfang zuerst, rutscht die Liste von oben nach unten nach, d. h. die Liste verkleinert sich und irgendwann greift man ins Leere, also außerhalb der Liste. Beispiel: man hat eine Liste mit 20 Einträgen und will einen Item irgendwo in der Mitte löschen. Das macht man mit
Delphi-Quellcode:
x := 0 to 19 do
. Das Problem ist, nachdem der Item (z. B. 10) gelöscht wurde, gibt es keinen Item 19 mehr, der ist jetzt 18. Trotzdem greift die Schleife irgendwann auf 19 zu. Und dann gibt es eine Fehlermeldung.

Lösung, immer von vom letzten zum ersten Item löschen, also
Delphi-Quellcode:
for x := Liste.Count - 1 downto 0 do
. Hier rutscht die Liste zwar auch nach unten, holt aber niemals die Schleife ein.

himitsu 15. Apr 2014 03:03

AW: Listview Daten im Hintergrund suchen und Löschen
 
Immer rückwärts löschen (downto), wenn eine For-Schleife verwendet wird,
oder die Schleife abbrechen (Break), nachdem der Eintrag gelöscht wurde.

Die Eingangsparameter der Forschleife werden "nur" am Anfang ausgewertet und dann wird mit einem gecachten Wert für das Schleifenende gearbeitet,
womit du auf einen Eintrag zugreifst, welcher nicht mehr existiert, also da am/nach dem Ende der Liste.


PS: Wenn du jetzt noch lernst, wie man den Debugger verwendet, dann würdest du solche Fehler selber entdecken.

jacky213 15. Apr 2014 03:06

AW: Listview Daten im Hintergrund suchen und Löschen
 
so Leute, danke für die Antworten zu dieser Stunde :-D

ich habe das Problem bereits wie folgt gelöst:

Code:
Procedure ListviewLöschen (str: string);
var
  i: Integer;
begin
for i := Pred(frmSpeisekarte.ListView1.Items.Count) downto 0 do
begin
  if frmSpeisekarte.ListView1.Items.Item[i].SubItems[0] = str then
  begin
  frmSpeisekarte.ListView1.Items.Delete(i);
  end;
end;
end;
Trotzdem vielen Dank!


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz