Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Listbox auslesen (https://www.delphipraxis.net/215330-listbox-auslesen.html)

oldmann 14. Jun 2024 08:53

Listbox auslesen
 
Hallo,
ich habe folgendes Problem.
Ich habe eine For Schleife mit der ich eine Listbox auslese.
Stimmt der Wert in Listbox1, dann wird der Wert in Listbox2 geschrieben.
Stimmt der Wert nicht, wird er mit Delete gelöscht.
Dadurch stimmt aber Form1.ListBox1.Items.Count nicht mehr und es gibt eine Fehlermeldung.
Meine Frage lautet: Wie kann ich das Problem lösen???
Gruss Oldmann

for i := 0 to Form1.ListBox1.Items.Count-1 do
if Form1.ListBox1.Items[i] = text then
Begin
Form5.ListBox2.Items.Add(Form1.ListBox1.Items[i]);
End else
begin
Form1.ListBox1.Items.Delete(i);
end;

dummzeuch 14. Jun 2024 09:03

AW: Listbox auslesen
 
Üblicherweise durch eine for Schleife von count-1 bis 0:

Delphi-Quellcode:
for i := Form1.ListBox1.Items.Count-1 downto 0 do begin
// hier verarbeiten
end;
Das hat allerdings den Nachteil, dass in der listbox2 dann die Einträge in umgekehrter Reihenfolge erscheinen. Das kann man lösen, indem man Insert(0, ...) statt Add(...) verwendet.

DeddyH 14. Jun 2024 09:24

AW: Listbox auslesen
 
Oder man nimmt eine while-Schleife, dann darf man aber nicht vergessen, die Laufvariable auch zu erhöhen, sonst kommt man da ggf. nie wieder raus.
Aus dem Kopf:
Delphi-Quellcode:
i := 0;
while i < ListBox.Items.Count do
  begin
    if Bedingung then
      begin
        TuWas;
        inc(i);
      end
    else
      ListBox.Items.Delete(i);
  end;

oldmann 14. Jun 2024 09:28

AW: Listbox auslesen
 
Hallo,

danke an die beiden Antworten.
Das hat mir sehr geholfen.
Jetzt klappt es.
Gruss Oldmann

himitsu 14. Jun 2024 10:43

AW: Listbox auslesen
 
Wenn du auf die globale Variable "Form1" zugreifen mußt, dann läuft da bestimmt irgendwas falsch.

Wenn man nach dem "einen" Löschen die Schleife abbricht, dann ist es egal, ob vor oder zurück. (wobei zurück theoretisch einen Hauch an Speicher und Bytecode einspart, also vermutlich eine millionstel Nanosekunde schneller würde)

Delphi-Quellcode:
//for var i := 0 to ListBox1.Items.Count - 1 do // egal wierum
for var i := ListBox1.Items.Count - 1 downto 0 do
  if ListBox1.Items[i] = text then begin
    ListBox1.Items.Delete(i);
    Break;
  end;
Alternativ geht es auch, wenn man vorher eine Kopie der Liste anfertigt, mit welcher dann gearbeitet wird.
Da ist es auch vollkommen egal, ob sich Indize verschieben, also Items gelöscht/erstellt/verschoben werden.

Delphi-Quellcode:
//for var S in ListBox1.Items do // ohne Kopie
for var S in ListBox1.Items.ToStringArray do
  if S = text then
    ListBox1.Items.Delete(ListBox1.Items.IndexOf(S));

Problem ist einfach, dass FOR sich vom SchleifenEnde zu Beginn eine Kopie macht und Diese verwendet.
Das ist bei WHILE und REPEAT anders.
Delphi-Quellcode:
// aus
for i := 0 to X.Length - 1 do
  X.Delete(i);

// wird intern ein
Kopie := X.Length - 1;
for i := 0 to Kopie do
  X.Delete(i); // hier ändert sich Length, aber dass bekommt die Schleife nicht mit
Drum funktioniert es rückwärts, da sich hierbei das untere Ende der Liste (0) nicht ändert.

Hobbycoder 17. Jun 2024 11:46

AW: Listbox auslesen
 
Ich hätte da auch noch eine Möglichkeit:

Delphi-Quellcode:
procedure xyz(SuchStr: string);
var
  i: Integer;
  sl: TStringList;
begin
  sl:=TStringList.Create;
  try
    sl.assign(Listbox1.items);
    for i:=0 to sl.count-1 do
      if sl[i].contains(SuchStr) then //oder if pos(SuchStr, SL[i])>0 then
      begin
        ListBox2.Items.Add(sl[i]);
        ListBox1.items.delete(ListBox1.items.IndexOf(sl[i]));
      end;
  finally
     sl.free;
  end;
end;
So würde die Reihenfolge von ListBox2 nicht ungekehrt.

Uwe Raabe 17. Jun 2024 12:12

AW: Listbox auslesen
 
Ein ganz anderer Ansatz wäre MoveSelection (geht aber nur wenn MultiSelect = true ist):
Delphi-Quellcode:
  for var I := 0 to ListBox1.Count - 1 do
    ListBox1.Selected[I] := (ListBox1.Items[I] = text);
  ListBox1.MoveSelection(ListBox2);


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:17 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