![]() |
Listbox Einträge vergl., bei Doppelbelegung einen Löschen
Hallo, ich habe folgendes Problem, also ich will die einträge einer Listbox an bestimmten stellen
vergleichen und bei Doppelbelegung einen rauslöschen. Ich habe es mit einer 'repeat' Schleife wie folgt versucht:
Delphi-Quellcode:
Allerdings löscht er nicht den doppelten Eintrag sondern einfach den ersten in der Listbox, dass ist das Problem....if listbox0.Items.Count = 5 then begin o:=0; p:=0; repeat o := o + 1; p := p + 1; if (listbox0.Items[o][5] + listbox0.Items[o][7] + listbox0.Items[o][9]) = (listbox0.Items[p][5] + listbox0.Items[p][7] + listbox0.Items[p][9]) then listbox0.Items.Delete(o); until (listbox0.Items.Count <> 5) or (o = 5); end; Wäre toll wenn jemand eine Idee hätte ! Also die Einträge sind nur an den bestimmten Stellen gleich. also es sieht zB ein gleicher Eintrag so aus: 1) 0 1 1 4) 0 1 1 |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
o und p sind immer gleich, und dadurch ergibt dein Vergleich auch immer "true". Du müsstest wenn mit einer Doppelschleife anrücken.
Wäre es jedoch nicht prinzipiell einfacher, vor dem Einfügen eines neuen Eintrages zu prüfen ob er schon vorhanden ist, und ggf. diesen zu verwerfen? |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Hallo,
p und o sind bei Dir doch immer gleich, Du vergleichst da anscheinend einen Eintrag immer mit sich selbst und da die Schleife aufhört, wenn count <> 5, wird bei 5 Einträgen nur der erste gelöscht, da danach ja nur noch 4 vorhanden sind, änderst Du
Delphi-Quellcode:
auf
until (listbox0.Items.Count <> 5) or (o = 5);
Delphi-Quellcode:
werden entsprechend mehr Einträge gelöscht. Willst Du zwei hintereinanderliegende Einträge miteinander vergleichen, so sollte p um eins größer als o sein.
until (listbox0.Items.Count <> 3) or (o = 3);
Versuchs mal damit:
Delphi-Quellcode:
p ist dann überflüssig.
if listbox0.Items.Count = 5 then
begin o:=1; repeat if (listbox0.Items[o][5] + listbox0.Items[o][7] + listbox0.Items[o][9]) = (listbox0.Items[o - 1][5] + listbox0.Items[o - 1][7] + listbox0.Items[o - 1][9]) then listbox0.Items.Delete(o); Inc(o); until (listbox0.Items.Count <> 5) or (o = 5); end; |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Hallo danke für die schnellen Antworten, also es klappt mit deiner Lösung fast, allerdings nur wenn ich 'o'
auf 4 ändere
Delphi-Quellcode:
ansonsten bringt er mir nen Exception, das liegt aber denk ich mal daran, dass bei der Listbox der 'Index' bei 0
if listbox0.Items.Count = 5 then
begin o:=1; repeat if (listbox0.Items[o][5] + listbox0.Items[o][7] + listbox0.Items[o][9]) = (listbox0.Items[o - 1][5] + listbox0.Items[o - 1][7] + listbox0.Items[o - 1][9]) then listbox0.Items.Delete(o); Inc(o); until (listbox0.Items.Count <> 5) or (o = 4); end; anfängt und der 'Count' normal bei 1. Also 'o' ist ja die Indexnummer und bei 4 müsste der 'Count' auf 5 stehen, damit kein Fehler kommt, wenn ich mich nicht täusche. Jedenfalls das Problem ist, dass der erste, der zweite und der letzte Wert nicht verglichen werden also nur wenn wenn Idex[2] und Index[3] gleich sind wird eins gelöscht... |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Hallo,
nein, Deine Annahme stimmt nicht. Mit jedem Löschen eines Eintrages ändert sich automatisch count, so dass die Abfrage auf o = 4 nur dann stimmt, wenn Du vorher 5 Einträge hast und davon einen löschst. Das von Dir gewählte Konstrukt ist so hochgefährlich, wenn es funktioniert, dann nur unter ganz bestimmten Bedingungen, jede noch so kleine Abweichung führt zu einem Programmfehler. Hinterfrag bitte mal, ob die Abfrage or o = 4 oder wie auch immer überhaupt erforderlich ist. Und auch die Abfrage auf count <> 5 ist gefährlich. Dass erste Löschen eines Eintrages führt ja schon dazu, dass Count <> 5 ist. In dem Falle dürfte die Abfrage auf o überflüssig sein. Eventuell wäre da ein Count <= o die sinnvollere Alternative. |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Mal so eine Idee:
Delphi-Quellcode:
procedure DeleteDoubleItems(const sl: TStrings; MaxIndex: integer = -1);
var i: integer; begin sl.BeginUpdate; try if (MaxIndex < 0) or (MaxIndex >= sl.Count) then MaxIndex := Pred(sl.Count); for i := MaxIndex downto 1 do if sl.IndexOf(sl[i]) < i then sl.Delete(i); finally sl.EndUpdate; end; end; procedure TForm1.Button1Click(Sender: TObject); begin DeleteDoubleItems(ListBox1.Items); end; |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
also
Delphi-Quellcode:
klappt auch aber er frägt nur die Werte zwischen dem ersten und letzten Index ab.
until listbox0.Items.Count <= o;
Die Äußeren werden nicht beachtet. |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Hui DeddyH da blick ich jetzt als Anfänger noch gar nicht durch aber ich werd mich mal veruchen mit
zu beschäftigen, Danke dir trotzdem. |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Hallo,
das wird mir zu kompliziert:
Delphi-Quellcode:
Damit solltest Du doppelte Einträge wegbekommen. Mir ist bisher nicht klar geworden, wofür die Abfrage auf 5 oder sonstwieviele Einträge gut sein soll, sollen mindestens 5 Einträge in der Listbox überbleiben, auch wenn sie doppelt sind? Warum werden Doppelte nur entfernt, wenn mehr als 5 Einträge vorhanden sind?
if listbox0.Items.Count = 5 then begin
for o := listbox0.Items.Count - 1 DownTo 1 do begin if (listbox0.Items[o][5] + listbox0.Items[o][7] + listbox0.Items[o][9]) = (listbox0.Items[o - 1][5] + listbox0.Items[o - 1][7] + listbox0.Items[o - 1][9]) then listbox0.Items.Delete(o); end; end; |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Also wenn ein Eintrag gelöscht worden ist, soll die Suche beendet werden, deshalb habe ich die Beschränkung auf 5 gemacht, ansonsten sucht er ja weiter wenn er einen gelöscht hat und es sind nur noch 4 Werte da und es wird ein Fehler verursacht, weil auch an der 5ten stelle wieder gesucht wird, die aber jetzt leer ist.
Aber wie ich sehe klappt es auch mit deiner 'for' Schleife nur werden hier auch nicht alle Werte abgefagt. |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Zitat:
|
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Ohne mich selbst loben zu wollen finde ich meine Methode am Einfachsten ;)
|
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Ja das klappt aber es sollen auch der letzte mit dem ersten, der letzte mit dem zweiten usw verglichen
werden. Also wenn jetzt zum Beispiel an Stelle 1 (0 0 0) steht und an Stelle 5 (0 0 0) dann soll die erste stelle gelöscht werden oder wenn nicht anders möglich die 5te. |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Zitat:
Grundsätzlich wäre es auch (vielleicht) sinnvoller, die Doubletten gar nicht erst in die Listbox aufzunehmen. Also z.B. mit
Delphi-Quellcode:
zu gewährleisten dass keine doppelten Einträge hinein kommen.
with ListBox1.Items do
if IndexOf(~~)<0 then Add(~~ |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Das geht aber einfacher mit Sorted auf true und Duplicates auf dupIgnore.
[edit] Kommando zurück, das gilt nur für TStringlist. [/edit] |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Hallo,
Zitat:
Deine Methode berücksichtig bisher noch nicht, dass beim Vergleich nur das 5. ,7. und 9. Zeichen der Einträge berücksichtigt werden sollen. :( |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Hallo,
Zitat:
Du möchtest jeden Eintrag mit jedem Eintrag vergleichen und alle die löschen, bei denen die 5., 7. und 9. Stelle übereinstimmen. Hab' ich's jetzt verstanden :?: |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Unter "doppeltem Eintrag" verstehe ich aber etwas anderes :?
|
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Ja genau also die Einträge sind nur an den bestimmten Stellen gleich.
also es sieht zB ein gleicher Eintrag so aus: 1) 0 1 1 4) 0 1 1 aber sollte es zu kompliziert sein werde ich es vielleicht erstmal versuchen es vor dem Eintrag abzufangen, wobei das sicher auch nicht viel einfacher geht. |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Zitat:
Delphi-Quellcode:
var
sl:TStriglist; begin sl:=TStriglist.create; sl.duplicates:=dupIgnore; sl.assign(sllistbox0.Items); sllistbox0.Items.assign(sl); sl.free; end; Edit: Bei mir auch komando zurück. Habe den ersten Post zu schnell überflogen. ;-) |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
bernau das berücksichtigt aber nicht das die ersten beiden Stellen unterschiedlich sein können oder ?
Ah sehe 'edit' auch zurück |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
OK. Anderer Versuch. Ich würde mit einer Hilfsstrinliste arbeiten
Delphi-Quellcode:
var sl:TStringlist; stri:String; begin sl:=TStringlist.create; // downto verwenden, da items zwischendurch gelöscht werden können for a:=sllistbox0.Items.count-1 downto 0 do begin stri:=listbox0.Items[a][5] + listbox0.Items[a][7] + listbox0.Items[a][9]; if sl.indexof(stri)>=0 then listbox0.items.delete(a) else sl.add(stri); end; sl.free; end; Einfach so runtergetippt und nicht getestet |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Hallo,
so, letzter Versuch :P
Delphi-Quellcode:
for i := listbox0.items.count - 1 DownTo 0 Do begin
for k := i - 1 DownTo 0 Do begin if (i < listbox0.items.count - 1) and (k < listbox0.items.count - 1) then begin if listbox0.items[i][5] + listbox0.items[i][7] + listbox0.items[i][9] = listbox0.items[k][5] + listbox0.items[k][7] + listbox0.items[k][9] then begin listbox0.items.Delete(k); end; end; end; end; |
Re: Listbox Einträge vergl., bei Doppelbelegung einen Lösche
Nach einer kleinen Änderung klappt es nun danke dir nahpets!:thumb:
Delphi-Quellcode:
vorher wurde der letzte Eintrag nicht berücksichtigt.
for i := listbox0.items.count DownTo 0 Do begin
for k := i - 1 DownTo 0 Do begin if (i < listbox0.items.count) and (k < listbox0.items.count) then begin if listbox0.items[i][5] + listbox0.items[i][7] + listbox0.items[i][9] = listbox0.items[k][5] + listbox0.items[k][7] + listbox0.items[k][9] then begin listbox0.items.Delete(k); end; end; bernau deine Methode hab ich jetzt noch nicht getestet aber, trotzdem danke. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:00 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