Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi KillDuplicates gibt Fehler mit CoolTrayIcon? (https://www.delphipraxis.net/58006-killduplicates-gibt-fehler-mit-cooltrayicon.html)

lucius 29. Nov 2005 22:41


KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Hallo Leute etwas seltsames ist mir passiert und ich weiss nicht weiter.
Ich benutze ein CoolTrayIcon fuer mein Programm.
Jetzt wollte ich ueber der Function KillDuplicates doppelte Eintraege aus einer TStringListe entfernen aber dabei gibt das CoolTrayIcon einen Fehler aus.
Delphi-Quellcode:
procedure TDemoForm.SpeedButton1Click(Sender: TObject);
Var Sl:Tstringlist;
    i,Anzahl:integer;
    Listitem:Tlistitem;
begin
  Screen.Cursor := crHourGlass;
  Listview.Items.BeginUpdate;
  Listview.clear;
  sl:=TStringList.Create;
  try
    sl.LoadFromFile(label2.caption +  '\torrents.db');
    //anzahl lesen
    anzahl:=strtoint(sl[0]);
    KillDuplicates(sl); <----------------------
    for i:=0 to anzahl do
      begin
        listitem:=listview.Items.add;
        //caption des items lesen
        listitem.Caption := sl[i*2+1];
        //alle subitems des items mit einmal lesen
        listitem.SubItems.CommaText := sl[i*2+2];
      end;
  finally
   Groupbox2.Caption := 'Aantal torrents: ' + IntTostr(Listview.Items.count);
    sl.free;
    Listview.Items.EndUpdate;
  end;
Screen.Cursor := crDefault;
end;
Der Fehler:
Zitat:

EStringListError List index out of Bounds(813);
Dan fragt er um die.pas file vom Cooltrayicon.
Kan mir bitte einer helfen?
Danke im voraus.

dahead 29. Nov 2005 23:08

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Hallo,

bevor ich dir auf eine egtl. Frage antworten kann, muss ich selbst ein paar Dinge wissen:

was liest du mit "anzahl:=strtoint(sl[0]);" aus? bzw. bist du sicher, dass die auswertung stimmt.

du gehst mit "for i:=0 to anzahl do " eine Schleife durch. Bist du sicher, dass da kein - 1 hin kommt?

Das verstehe ich nicht:

Zitat:

Dan fragt er um die.pas file vom Cooltrayicon.
meinst du, er markiert die CoolTrayIcon.pas?

an welcher code-stelle tritt der Out-Of-Bounds Fehler auf?

lucius 29. Nov 2005 23:21

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Hi dahead,
Zitat:

was liest du mit "anzahl:=strtoint(sl[0]);" aus?
Damit lese ich die Anzahl der Zeilen in de TStringListe(sl) aus., und die Auswertung stimmt(810).
Bei der schleife kommt keine -1 for.
Zitat:

an welcher code-stelle tritt der Out-Of-Bounds Fehler auf?
An der Stelle mit dem Pfeil.
Aber der Sinn der Sache ist eigentlich um doppelte Eintraege ob nun in der TStringListe oder direct aus der Listview zu entfernen.

dahead 29. Nov 2005 23:48

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
ahja, dann nehme ich mal an, dass killduplicates die menge der einträge kürzt. du aber mit der variable anzahl noch auf die alte menge zugreifst.

du musst also entweder die variable neu zuweisen (anzahl := SL.Count-1) oder aber in der for schleife for I := 0 to SL.Count - 1 verwenden.

lucius 29. Nov 2005 23:56

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Hmmm dahead funzt nicht richtig, bekomme immer noch out of bounds.
Gibt es denn ne Function womit man doppelte Eintraege aus der Listview loeschen kann?
Meine Listview hat 4 Spalten und das ich dann zum Beispiel nach der 3en Spalte gucke ob da doppelte Eintraege vorhanden sind.

dahead 30. Nov 2005 00:05

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
also ich kenne keine direkte funktion. du könntest dir eine selber basteln (z.b. zwei for-schleifen, die den text der stringliste vergleichen und bei gleichheit löschen. das könntest du mit "for I := SL.Count - 1 downto 0 do for F := SL.Count - 1 downto 0 do ..." lösen).

aber ich denke, dass deine killdupes funktion/routine das schon macht, oder? wie sieht die denn aus, bzw. was passiert, wenn du diese ausklammerst, geht dann alles reibungslos?

lucius 30. Nov 2005 08:41

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Morgen dahead, so sieht die Killduplicates aus.
Delphi-Quellcode:
procedure KillDuplicates(s: TStrings);
var
  iLow, iHigh: integer;
begin
  for iLow := 0 to s.Count - 2 do
    for iHigh := Pred(s.Count) downto Succ(iLow) do
      if s[iLow] = s[iHigh] then
        s.Delete(iHigh);
Gruss Lucius.

RavenIV 30. Nov 2005 08:45

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
da liegt der Fehler:
du löschst in KillDuplicates ein Element aus der Liste.
beim Durchgehen der Liste beachtest du dies aber nicht und läufst bis zur Original-Länge der Liste.

=> Du muss also nach dem Duplikat-Löschen noch mal die Länfe ermitteln (anzahl := ...)

mumu 30. Nov 2005 08:47

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
das müsste funktionieren:

Delphi-Quellcode:
procedure KillDuplicates(s: TStrings);
var
  iLow, iHigh: integer;
begin
  for iLow := s.Count-1 downto 0 do
    for iHigh := s.Count-1 downto 0 do
      if s[iLow] = s[iHigh] then
      begin
        s.Delete(iLow);
        break;
      end;

lucius 30. Nov 2005 09:16

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Leider mumu, funzt auch nicht richtig.
List index out of Bounds(1).
Dann wieder die Message zum oeffnen van der CoolTrayIcon.pas was ich getan habe da gibt er an:
Delphi-Quellcode:
// Pass the message on
Msg.Result := CallWindowProc(OldWndProc, (Owner as TWinControl).Handle, <------- Zeile wird markiert
              Msg.Msg, Msg.wParam, Msg.lParam);
Ich raff es auch nicht mehr.
Irgendwas stoert CoolTrayIcon an den KillDublicates.

RavenIV 30. Nov 2005 09:31

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Zitat:

Zitat von lucius
List index out of Bounds(1).

Da hast du doch die Fehlermeldung.
was ist da so schwer zu verstehen?

Zitat:

Zitat von lucius
Dann wieder die Message zum oeffnen van der CoolTrayIcon.pas was ich getan habe da gibt er an:

Delphi-Fehler sind nicht immer verlässlich.
Oft liegt der Fehler auch einige Anweisungen vorher.

Beachte doch mal mein letztes Posting und versuch's dann nochmal.

*** liesst denn keiner meine Postings? ***

lucius 30. Nov 2005 09:49

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
RavenIV, ich habe die Anzahl neu gesetzt nachdem Killduplicates ausgefuehrt wurde, aber das will auch nicht so.
Wenn ich jetzt Killdublicates weg lasse, laeuft alles wunderbar ausser das wenn ich jetzt die Listview neu laden moechte mit
Delphi-Quellcode:
Var Sl:Tstringlist;
    i,Anzahl:integer;
    Listitem:Tlistitem;
begin
  //speedbutton1.Visible := false;
  Screen.Cursor := crHourGlass;
  Listview.Items.BeginUpdate;
  Listview.items.clear;
  sl:=TStringList.Create;
  try
    sl.LoadFromFile(label2.caption +  '\torrents.db'); <---- hierdrin koennen doppelte sitzen
    //anzahl lesen
    anzahl:=strtoint(sl[0]);
    for i:=0 to anzahl do
      begin
        listitem:=listview.Items.add;
        //caption des items lesen
        listitem.Caption := sl[i*2+1];
        //alle subitems des items mit einmal lesen
        listitem.SubItems.CommaText := sl[i*2+2];
      end;
  finally
  Groupbox2.Caption := 'Anzahl torrents: ' + IntTostr(Listview.Items.count);
    sl.free;
    Listview.Items.EndUpdate;
  end;
Screen.Cursor := crDefault;
end;
Dan werden die (doppelte) Eintraege mit in der Listview angezeigt und das moechte ich beheben.
Zitat:

Da hast du doch die Fehlermeldung.
was ist da so schwer zu verstehen?
Weil egal was ich mache ich jedesmal Index out of bounds bekomme, wenn ich Killdublicates in den oberen Code setze.

mumu 30. Nov 2005 09:52

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
warum debuggst du das ganze nicht einfach mal durch. irgendwo in der KillDuplicates Funktion wird wohl was irgendwas über den index hinauslaufen...

RavenIV 30. Nov 2005 09:58

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Zitat:

for i:=0 to anzahl do
lass doch mal bis "anzahl - 1" laufen...
daher, dass du bei "0" anfängst, laufst du einmal zuviel durch.

marabu 30. Nov 2005 10:10

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Moin Lucius,

wie hast du denn deine Datei torrents.db aufgebaut? Ist das eine CSV-Datei?

Code:
Datum,Category
2005-11-28,Muziek
oder ist es eine folded CSV-Datei?

Code:
Datum=2005-11-28,Category=Muziek
oder ist es ein ganz anderes Format? Steht wirklich eine Anzahl in der ersten Zeile?

Die Prozedur KillDuplicates() hatte ich ursprünglich für etwas anderes entworfen. Wenn du sie in deinem Projekt verwendest, dann musst du sie verstehen und an deine Bedürfnisse anpassen. Sie funktioniert unverändert, wenn du eine folded CSV-Datei verwendest, aber sie stellt die Gleichheit anhand aller Spaltenwerte fest und nicht aufgrund der Übereinstimmung nur eines bestimmten Spaltenwertes.

Grüße vom marabu

lucius 30. Nov 2005 10:17

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
RaveIV, leider, ich habe deine Variante probiert, downto etc.
Ich denke ich muss schon die TStringList in Ruhe lassen in der LoadFunction, das bringt so nichts, habe gestern bis 03.00 dran gessen und bin noch keinen Schritt weiter.
Gibt es denn eine Function die doppelte Eintraege in einer Listview loescht?
Dann gehe ich eben die Listview an den Kragen.
Ich moechte dan in einer bestimmten Spalte gucken ob da doppelte drin stehen und dan loeschen.
In etwa so?
Delphi-Quellcode:
for i := Listview.Items.Count -1 downto 0 do
   if Listview.Items[i].SubItems[2] = ... then
      Listview.Items[i].Delete..
Hi marabu die Datei ist so aufgebaut:
Zitat:

2005-11-28,"Films - DVDr","End of Days","4.36 GB", ........

dahead 30. Nov 2005 10:50

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Hi Lucius!

so müsste es hoffentlich funktionieren:

Delphi-Quellcode:
procedure KillDuplicates(SL: TStringList);
var
  I, F: integer;
begin
  for I := SL.Count - 1 downto 0 do
  for F := SL.Count - 1 downto 0 do
  if I <> F then
  if SL[I] = SL[F] then
   begin
    SL.Delete(F);
    Break;
   end;
end;
Edit: Alternativ könntest du auch beim Hinzufügen der Einträge zu deiner Stringliste die Eigenschaft Duplicates := dupIgnore setzen. Damit werden gleiche Items nicht mehr Hinzugefügt, und du sparst dir das KillDuplicates mit den zwei Schleifen.

Edit2:
Zitat:

Gibt es denn eine Function die doppelte Eintraege in einer Listview loescht?
Das halte ich pers. nicht für sinnvoll, du solltest die Daten (wie du es ja bereits machst) vor dem Anzeigen in der Listview auf Duplikate prüfen und ggf. löschen. Außerdem nicht sich das von der Funktion her egtl. nicht viel, sei es ListView oder StringList.

Da ich annehme, dass du die Torrents in einer Listview dem Benutzer anzeigen willst, plädiere ich für die erste Version (also vorher Duplikate raus, dann anzeigen), da es den Benutzer ja nicht zu interessieren braucht, ob da Duplikate drin sind oder waren. Außerdem dürfte es schneller gehen.

marabu 30. Nov 2005 10:57

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Mein Vorschlag wäre:

Delphi-Quellcode:
procedure KillDuplicatesEx(s: TStrings; index: integer);
var
  iLow, iHigh: integer;
  sLow, sHigh: TStringList;
begin
  sLow := TStringList.Create;
  sHigh := TStringList.Create;
  for iLow := 0 to s.Count - 2 do
    for iHigh := Pred(s.Count) downto Succ(iLow) do
    begin
      sLow.CommaText := s[iLow];
      sHigh.CommaText := s[iHigh];
      if sLow[index] = sHigh[index] then
        s.Delete(iHigh);
    end;
  sLow.Free;
  sHigh.Free;
end;
marabu

lucius 30. Nov 2005 11:08

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Hi marabu,
Delphi-Quellcode:
procedure KillDuplicatesEx(s: TStrings; index: integer);
was soll ich denn den Indexwert uebergeben?

MFG, Lucius.

marabu 30. Nov 2005 11:13

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Hi Lucius,

du musst 2 übergeben, wenn du die Gleichheit anhand des Wertes im dritten Feld der CSV-Datei feststellen möchtest.

marabu

lucius 30. Nov 2005 11:29

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Marabu, list index out of bounds(2)

wobei ich die Anzahl neu definieren muss denke ich mal? dan ist das Problem geloesst, hoffe ich, oder?
Delphi-Quellcode:
try
    sl.LoadFromFile(label2.caption +  '\torrents.db');
    //anzahl lesen
    KillDuplicatesEx(sl, 2);
    anzahl:=strtoint(sl[0]); <---- list index out of bounds(2)
    for i:=0 to anzahl do
      begin
        listitem:=listview.Items.add;
        //caption des items lesen
        listitem.Caption := sl[i*2+1];
        //alle subitems des items mit einmal lesen
        listitem.SubItems.CommaText := sl[i*2+2];
      end;
  finally
MFG, Lucius.

marabu 30. Nov 2005 11:46

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Lucius, du hast doch gar keine Anzahl in der ersten Zeile von torrents.db stehen - oder? Und deine Indexberechnung in der Schleife kann nicht funktionieren. Wenn der Aufbau der Datei so ist, wie du es weiter oben behauptest, dann musst du es so probieren:

Delphi-Quellcode:
var
  FieldList: TStringList;
begin
  FieldList := TStringList.Create;
  // ...
  try
    sl.LoadFromFile(label2.caption +  '\torrents.db');
    KillDuplicatesEx(sl, 2);
    for i := 0 to Pred(sl.Count) do
    begin
      FieldList.CommaText := sl[i];
      with ListView.Items.Add do
      begin
        Caption := FieldList[0];
        FieldList.Delete(0);
        SubItems.Assign(FieldList);
      end;
    end;
  finally
    FieldList.Free;
    // ...
  end;
  // ...
end;
Hoffentlich habe ich mich nicht zu oft verschrieben...

marabu

lucius 30. Nov 2005 12:00

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
So ich werde mich erstmal ein Sueppchen essen und dann deine Function ausprobieren marabu, denn ich brauche erstmal ne kleine Pauze mir kwalmt schon der Kopf. :wall:

MFG, Lucius.

lucius 30. Nov 2005 12:35

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
So marabu, habe deine Function ausprobiert aber nog immer Listindex out of Bounds(2).
Delphi-Quellcode:
try
    sl.LoadFromFile(label2.caption +  '\torrents.db');
    //anzahl lesen
    KillDuplicatesEx(sl, 2);
    for i := 0 to Pred(sl.Count) do <------ out of bounds(2)
    begin
      FieldList.CommaText := sl[i];
      with ListView.Items.Add do
      begin
        Caption := FieldList[0];
        FieldList.Delete(0);
        SubItems.Assign(FieldList);
      end;
    end;
  finally
    FieldList.Free;
So sieht die torrents.db vor dem laden aus.
Zitat:

2005-11-30,"Muziek - Album","Rene Froger - Pure Christmas (2005)","102.91 MB","7 seeders and 20 leechers","172.12 kB/s",http://www.liquidtorrent.org/details.php?id=8607&hit=1,"http://www.liquidtorrent.org/download.php/8607/Rene Froger - Pure Christmas.torrent" ////Doppelt muesste also raus////

2005-11-30,"Muziek - Album","Rene Froger - Pure Christmas (2005)","102.91 MB","7 seeders and 20 leechers","172.12 kB/s",http://www.liquidtorrent.org/details.php?id=8607&hit=1,"http://www.liquidtorrent.org/download.php/8607/Rene Froger - Pure Christmas.torrent"

2005-11-30,"Apps - PC","Driver Genius Professional Edition 2005, Version:6.0.1882","5.66 MB","22 seeders and no leecher","22.43 kB/s",http://www.liquidtorrent.org/details.php?id=8606&hit=1,"http://www.liquidtorrent.org/download.php/8606/Driver Genius Professional Edition 2005.rar.torrent"

2005-11-30,"Films - DVDr","End of Days","4.51 GB","no seeders and 11 leechers","51.91 kB/s",http://www.liquidtorrent.org/details.php?id=8605&hit=1,"http://www.liquidtorrent.org/download.php/8605/end of days.torrent"
Ich wuesste nicht was ich noch alles probieren muesste?

MFG, Lucius.

marabu 30. Nov 2005 12:47

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Jetzt wo du satt bist, solltest du mal nachsehen, ob da Leerzeilen zwischen den Datenzeilen in der Textdatei sind.

marabu

lucius 30. Nov 2005 12:48

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Ja es gibt Leerzeilen in der Datei, siehe Zitat.

marabu 30. Nov 2005 12:50

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Raus damit. Wofür sollen die gut sein?

marabu

lucius 30. Nov 2005 12:52

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Das ist die Speicher Function die verursacht die Leerzeilen.
Delphi-Quellcode:
Var Sl:Tstringlist;
    i:integer;
begin
  sl:=TStringList.Create;
  try
    //anzahl schreiben
    sl.Add(inttostr(ListView.Items.count-1));
    for i:=0 to ListView.Items.count-1 do
      begin
        //caption des items schreiben
        sl.Add(ListView.Items[i].Caption);
        //alle subitems des items mit einmal reinschreiben
        sl.Add(ListView.Items[i].SubItems.CommaText)
      end;
    sl.SaveToFile(label2.caption +  '\torrents.db');
  finally
    sl.free;
  end;

marabu 30. Nov 2005 13:06

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Lucius, du darfst die Anzahl nicht mit rausschreiben - es ist dann keine CSV-Datei mehr und du bekommst die Zahl ja später problemlos wieder, wenn du die Datei mit LoadFromFile() einliest. Außerdem müssen alle Spaltenwerte in einer Zeile stehen, damit der Code zum Einlesen funktioniert, den ich dir weiter oben (#22) gegeben habe.

Delphi-Quellcode:
var
  slLines, slFields: TStringList;
  i: integer;
begin
  slFields := TStringList.Create;
  slLines := TStringList.Create;
  try
    with ListView do
      for i := 0 to Pred(Items.Count) do
      begin
        slFieldsl.Assign(Items[i].SubItems);
        slFields.Insert(0, Items[i].Caption);
        slLines.Add(sfFields.CommaText);
        slFields.Clear;
      end;
    slLines.SaveToFile(label2.caption +  '\torrents.db');
  finally
    slLines.Free;
    slFields.Free;
  end;
end;
marabu

lucius 30. Nov 2005 13:31

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Na marabu,

Nachdem ich alles eingebaut habe wie du es sagtest funktioniert es, aber er laedt die Daten nicht mehr so schnell dan die andere Function in der Listview, eigentlich Schade.
Das war ne schwere Geburt aber es klappt.
Herzlichen Dank an alle die geholfen haben insbesondere marabu.

MFG, Lucius.

marabu 30. Nov 2005 18:13

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Hi Lucius,

Zitat:

Zitat von lucius
aber er laedt die Daten nicht mehr so schnell dan die andere Function in der Listview

du hast doch vor dem Laden der Items (#22) bestimmt die ListView mit Items.Clear geleer. Hast du auch Items.BeginUpdate und Items.EndUpdate verwendet? Das würde alles etwas schneller machen. Und wenn es das nicht ist, dann müssen wir die Zeiten einmal messen.

marabu

lucius 1. Dez 2005 00:06

Re: KillDuplicates gibt Fehler mit CoolTrayIcon?
 
Hi marabu ja ich verwende Items.BeginUpdate und Items.EndUpdate, die Liste wird auch vorher geleert.
Delphi-Quellcode:
var
  FieldList: TStringList;
begin
  Listview.Items.BeginUpdate; <------------
  Listview.Clear; <------------
  FieldList := TStringList.Create;
  // ...
  try
    sl.LoadFromFile(label2.caption +  '\torrents.db');
    KillDuplicatesEx(sl, 2);
    for i := 0 to Pred(sl.Count) do
    begin
      FieldList.CommaText := sl[i];
      with ListView.Items.Add do
      begin
        Caption := FieldList[0];
        FieldList.Delete(0);
        SubItems.Assign(FieldList);
      end;
    end;
  finally
  Listview.Items.EndUpdate; <--------------
    FieldList.Free;
    // ...
  end;
  // ...
end;


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