| |
|
|
| Hallo Frank,
ich hatte vor, in einem meiner Programme eine Windows Listbox durch ein Listview auszutauschen. In einem Testlauf werden ca. 20.000 Zeilen eingefügt wobei vor dem Einfügen jeder Zeile geprüft wird, ob diese schon vorhanden ist. Die Listbox-Version war in knapp 4 Minuten durch, die Listview Version habe ich nach 20 Minuten und 1/10 der Arbeit abgebrochen.
In der Listbox Frage ich dies so ab: exist& = SendMessage(box&,$01A2,-1,addr(edit$))
Ich suche nach der genauen Zeile
Bei dem Listview läuft das so: exist& = SearchText(box&,0, GetLines(box&),1,Addr(edit$),10,addr(exist2&))
Genauer String, Suche nur in der betreffenden Spalte. Schon bei 2.000 Zeilen verdammt langsam.
-Gibt es keine Vergleichbare Windows Message, die entweder du verwenden kannst oder du mir empfehlen kannst.
-Kannst du den Aufbau der Funktion noch mal überdenken, ich bin sicher, dass man das noch optimieren kann.
-Ich weiß nicht wie es geht aber ich würde es so machen: nur nach dem ersten Zeichen jeder Zeile Suchen, bei übereinstimmung auch das zweite abfragen usw.
-Habe ich einen vorhandenen Befehl übersehen?
-Sinnvoll wäre ein SearchText-Lite Variante, die darauf optimiert ist nur in einer Spalte zu suchen und bei der ersten Fundstelle gleich abbricht. Den Parameter für Fundstellen-Spalte könnte man hierbei auch weglassen.
Wenn du es schaffst, die Funktion doppelt so schnell zu machen kann ich noch nichts anfangen, erst wenn es zumindest halb so schnell wie in den Listboxes ist wäre es akzeptabel. Meinst du das ist machbar?
Gruß, Sven |
|
|
| |
|
|
|
| Habe folgendes in der Win32.hlp gefunden, konnte es jedoch nicht erfolgreich in eine Funktion oder Message umsetzen.
LVM_FINDITEM wParam = (WPARAM) (int) iStart; lParam = (LPARAM) (const LV_FINDINFO FAR *) plvfi;
// Corresponding macro int ListView_FindItem(HWND hwnd, int iStart, const LV_FINDINFO FAR* plvfi);
The LVM_FINDITEM message searches for a list view item with the specified c haracteristics. You can send this message explicitly or by using the ListVi ew_FindItem macro.
Parameters
hwnd
Handle to the list view control.
iStart
Index of the item to begin the search with or -1 to start from the beginnin g. The specified item is itself excluded from the search.
plvfi
Pointer to an LV_FINDINFO structure that contains information about what to search for. Return Value
Returns the index of the item if successful or -1 otherwise.
ich halte es für unwahrscheinlich aber vielleicht bremst auch der Befehl GetLines(box&) die ganze Sache? Liest der Befehl nur einen Wert aus oder muss er jedes mal die Zeilen von 0 bis Ende durchzählen? |
|
|
| |
|
|
|
| Hallo Sven,
ist mir nie aufgefallen, das der Befehl so langsam sein soll... Wahrscheinlich benötigt das System länger, Daten aus einem Listview zu lesen, als aus Listboxen. Hat ja im Regelfall auch mehrere Spalten.
Und das Listview strebt danach, beim löschen oder einfügen eines Eintrags das Listview zu aktualisieren. Das kostet enorm Zeit, kann aber leicht abgestellt werden
SendMessage(listview&,11,0,0) Neuaufbau des Listviews SendMessage(li stview&,11,1,0) Wiederaufbau des Listviews (standart).[/CODE
Ich glaube auch, du versuchst dein Problem verkehrt zu lösen. Ich würde es so machen, das ich die 20000 Zeilen einfügen würde und zum Sch luss erst mit DeleteDoubleItems() alle doppelten Einträge löschen würde. So :
[CODE]SendMessage(listview&,11,0,0) Neuaufbau des Listviews verhinde rn !
Whileloop GetColumns(listview&) DeleteDoubleItems(listview&,(&loop-1)) EndWhile
SendMessage(listview&,11,1,0) Wiederaufbau des Listviews (standart).
Teste mal... Gruß, Frank |
|
|
| |
|
|
|
| Nochmal...
Hallo Sven,
ist mir nie aufgefallen, das der Befehl so langsam sein soll... Wahrscheinlich benötigt das System länger, Daten aus einem Listview zu lesen, als aus Listboxen. Hat ja im Regelfall auch mehrere Spalten.
Und das Listview strebt danach, beim löschen oder einfügen eines Eintrags das Listview zu aktualisieren. Das kostet enorm Zeit, kann aber leicht abgestellt werden
SendMessage(listview&,11,0,0) Neuaufbau des Listviews SendMessage(listview&,11,1,0) Wiederaufbau des Listviews (standart).
Ich glaube auch, du versuchst dein Problem verkehrt zu lösen. Ich würde es so machen, das ich die 20000 Zeilen einfügen würde und zum Sch luss erst mit DeleteDoubleItems() alle doppelten Einträge löschen würde. So:
SendMessage(listview&,11,0,0) Neuaufbau des Listviews verhindern !
Whileloop GetColumns(listview&) DeleteDoubleItems(listview&,(&loop-1)) EndWhile
SendMessage(listview&,11,1,0) Wiederaufbau des Listviews (standart).
Teste mal... Gruß, Frank |
|
|
| |
|
|
|
| Hallo Frank, danke für die rasche Antwort.
Hat es etwas zu sagen, dass DeleteDoubleItems() in der Hilfe nicht dokumentiert ist? Beim Löschen doppeler Einträge soll nur eine Column berücksichtigt werden. Tauchen in Spalte 1 Doppelte Einträge auf so sollen Sie gelöscht werden, gleich was in den anderen Spalten ist.
Da über längere Zeit mal mehr und mal weniger Zeilen eingefügt werden, soll die Aktualisierung eigentlich immer sofort stattfinden und doppelte Zeilen zu keiner Zeit in der Liste sein. Es ist auch nicht die Aktualsierung, die lange braucht sondern nur das SearchText() Notfalls muss ich es eben doch am Ende über einen Double Befehl machen, und mich mit den doppelten Zeilen bis dahin abfinden. Falls der Befehl auch spaltenweise funktioniert - hast du dazu eine Idee?
Sven |
|
|
| |
|
|
|
| Hi,
> Hallo Frank, danke für die rasche Antwort. > > Hat es etwas zu sagen, dass DeleteDoubleItems() in der Hilfe nicht dokumentiert ist?
Hmm, in meiner Hilfe ist die Funktion erklärt... Hast du mal ein Update gemacht ?
> Beim Löschen doppeler Einträge soll > nur eine Column berücksichtigt werden. Tauchen in Spalte 1 Doppelte Einträge auf so sollen Sie gelöscht werden, gleich was > in den anderen Spalten ist.
Noch einfacher, dann kannst du die Whileloop-Schleife ja weglassen.
> > Da über längere Zeit mal mehr und mal weniger Zeilen eingefügt werden, soll die Aktualisierung eigentlich immer sofort stattfinden > und doppelte Zeilen zu keiner Zeit in der Liste sein.
Dann baust du DeleteDoubleItems eben häufiger ein. Anstatt zu prüfen, ob der Eintrag doppelt ist, benutzt du DeleteDoubleItems.
> Es ist auch nicht die Aktualsierung, die lange braucht sondern nur > das SearchText() Notfalls muss ich es eben doch am Ende über einen Double Befehl machen, und mich mit den doppelten Zeilen > bis dahin abfinden.
Wie gesagt, kontinuierlich einbauen...
> Falls der Befehl auch spaltenweise funktioniert - hast du dazu eine Idee?
Hab ich ja schon gesagt. Hier ist die Syntax:
DeleteDoubleItems(H,S)
Löscht alle doppelt oder mehrfach vorkommen Itemtexte in einer Spalte eines Listviews.
H : Long - Handle eines mit CreateListview() erstellten Listview Controls S : Long - Index der Spalte von H, deren mehrfach vorkommende Itemtexte gelöscht werden sollen (nullbasierend)
Eine schnelle und bequeme Methode, doppelte, bzw. mehrfache Einträge zu löschen. Um ein komplettes Listview damit zu bearbeiten, müssen alle Spalten durchlaufen werden, z.B. so:
SendMessage(listview&,11,0,0) Neuaufbau des Listviews verhindern !
Whileloop GetColumns(listview&) DeleteDoubleItems(listview&,(&loop-1)) EndWhile
SendMessage(listview&,11,1,0) Wiederaufbau des Listviews (standart).
Gruß, Frank |
|
|
| |
|
|
|
| Hallo Frank, ich denke ich habs kapiert. Ich mache es ohne SearchText und bin dabei noch 3mal schneller als mit der Listbox Version.
Listbox sofort auf doppelte Prüfen: 3:30 Minuten Listbox ohne Prüfung: < 1 Minute
ListView sofort auf doppelte Prüfen: > 20 Minuten Listbox ohne Prüfung: ca. 1 Minute
Damit kann ich leben!
Nur leider gibts den DeleteDouble Befehl in dem aktuellen Paket nicht. Ich bin auch recht verwirrt was die Version und Hilfe Dateien angeht.
Aktueller Download:
Version 1.5 Letzter Stand: 25.Nov.2003 Funktion unbekannt: DeleteDoubleItems
Hilfe im Web:
Version 1.6 Letzter Stand: 25.Nov.2003 DeleteDoubleItems() in Hilfe aufgeführt
Jetzt bin ich aber verwirrt! Wo bekomme ich die Version 1.6, was ist ausser dem DeleteDoubleItems noch dazu gekommen und warum ist der Entwicklungsstand auch 25.Nov.2003 wie bei der 1.5.
Gruß, Sven |
|
|
| |
|
|
|
| Hi,
ah, da hab ich wohl Mist gebaut. Ich werd dir die neue Dll-Version mal so zuschicken, per Mail. Das Update kommt dann, wenn noch einige Funktionen dazgekommen sind.
Gruß, Frank |
|
|
| |
|
|
|
| Wo gibt es denn die Version 1.6 ? Auf der Website finde ich nur die 1.5
Gruss Dirk |
|
|
| |
|
|
|
| Hi,
ja, 1.5 ist das letzte Update. 1.6 Beta ist der Arbeitstitel meiner Dll-Version, an der ich momentan sporadisch arbeite. Bisher habe ich es so gehalten, das ein neues Update erfolgt, sobald einige neue Funktionen dazugekommen sind. Und so wird es auch weiterhin bleiben. Wann genau das 1.6 Update jetzt erscheint, weiss ich noch nicht, sicherlich aber noch dieses Jahr.
Gruß, Frank |
|
|
| |
|
|