![]() |
ListBox - AutoComplete und Sorted
Hallo,
habe folgendes Problem: Ich lese Einträge aus einer SQLite-Datenbank in ein Array ein, und füge sie anschließend in eine ListBox ein. Das sieht etwa so aus:
Delphi-Quellcode:
Bisher sind das knapp 3000 Einträge.
[...]
for i := 0 to High(Eintrag) do begin Eintrag[i].Vorname := database.Results[i][0]; Eintrag[i].Strasse := database.Results[i][1]; [...] Form1.ListBox1.Items.Add(Eintrag[i].Vorname); end; [...] Das nette an der ListBox finde ich die AutoComplete-Eigenschaft. Wenn ich also 'chris' tippe, springt die ListBox gleich zum Eintrag 'Christoph'. Etwas erstaunlich ist nur, dass die AutoComplete-Eigenschaft nur dann funktioniert, wenn ich die ListBox-Eigenschaft 'Sorted' auf 'true' setze. Die Eigenschaft 'AutoComplete' scheint ohne 'Sorted:=true' keine Funktion zu besitzen. Das wäre mir ja eigentlich egal, aber nun habe ich Schwierigkeiten mit der Sortierreihenfolge der Listbox. Denn diese sortiert anders als meine SQLite-Datenbank (auch wenn ich diese vor Einlesen in das Array mit 'order by Name' sortiere). Wenn ich nun einen Eintrag in der ListBox anwähle
Delphi-Quellcode:
dann stimmen ItemIndex und die Nummer des Eintrags im Array nicht überein (aber genau das sollen sie tun).
Form1.RichEdit2.Text:=Eintrag[Form1.ListBox1.ItemIndex].Vorname;
Dünne ich meine Ergebnismenge aus, soll wieder in das Array geschrieben werden. Die ListBox (sowie das Array) enthält also immer die Ergebnismenge der aktuellen Datenbankabfrage. Mir würde es ausreichen, wenn die Eigenschaft 'AutoComplete' das tun würde was sie soll - tut sie aber nicht (ohne Sorted:=true). Als Umgehung könnte ich alle Daten aus der Datenbankabfrage zunächst in eine StringList lesen, diese nach Name sortieren und danach dann in das array einlesen - aber das kann es doch wohl nicht sein (würden den Einleseprozess sehr verlangsamen, ich habe über 70 Spalten in der Tabelle...). Die StringList müsste ausserdem als csv-Datei angelegt werden, (Name;Vorname;Strasse...); Problem dabei ist, dass auch Hochkommata und Anführungszeichen in den Einträgen verwendet werden. Der Einleseprozess wäre vorsichtig gesagt etwas umständlich. Was kann ich tun? Vielen Dank im Voraus, Christoph P.S.: Ich habe in diesen Bereich geposted, weil es sich mE. um ein Problem mit den Eigenschaften der Komponente ListBox handelt. |
Re: ListBox - AutoComplete und Sorted
Vielleicht wärst du auf der sicheren Seite, wenn du die Autocomplete einfach selbst programmieren würdest.
Du fragst die eingegeben Keys ab und suchst im Hintergrund per "Locate-Methode" in deiner (sortierten) Tabelle. Wenn die Listbox zuvor die sortierten Daten der Tabelle erhalten hat und nicht erneut sortiert wurde, kannst du dann ja einfach von der RecNo des aktuell gefundenen Datensatzes direkt auf den Index der Liste zugreifen (da diese ja identisch sind). Dort setzt du halt die Selected-Eigenschaft des Eintrags und du hast deine gewünschte Autocomplete-Funktion. Vielleicht ist die "Locate"-Methode gerade bei großen Datenmegen ja sogar effizienter als die Find-Methode der Listbox. Gruß Pfoto |
Re: ListBox - AutoComplete und Sorted
Hi,
danke für Deinen post - das übersteigt leider meine Programmier-Fähigkeiten. Kannst Du mir mit code weiterhelfen? Vielen Dank, Christoph |
Re: ListBox - AutoComplete und Sorted
Ich werde morgen mal etwas Code posten, vorher muss ich ihn aber noch bei mir ausprobieren, ob's denn überhaupt so funktioniert, wie ich in Gedanken meinte... :gruebel:
Gruß Pfoto |
Re: ListBox - AutoComplete und Sorted
autocomplete geht nur bei sorted weil es bei unsortierten Listen ewig dauern würde.
Wenn du das Array in deine Stringlist übeträgst könntest du doch den Arrayindex im Object-Property mit sichern. Damit weißt du nach dem sortieren noch welches der Originalindex ist. |
Re: ListBox - AutoComplete und Sorted
So, ich hab mal das folgende Beispiel geschrieben -- also bei mir funktioniert es... :-D
Delphi-Quellcode:
// Zuerst die betreffende Tabelle nach Deinen Wünschen sortieren
// Dann diese Methode einmalig bzw. bei Änderung der Einträge aufrufen procedure TForm_Main.DoInitListBox; begin ListBox1.Items.Clear; with DeineTabelle do while not EOF do begin ListBox1.Items.Add(FieldByName('Title').AsString); // Listbox mit Einträgen der Tabelle füllen Next; end; end; // KeyPress-Event der Listbox procedure TForm_Main.ListBox1KeyPress(Sender: TObject; var Key: Char); var Name: String; begin If (Key = Chr(VK_Escape)) or (Key = Chr(VK_RETURN)) then Suchwort:= ''; If (Key in ['A'..'Z']) or (Key in ['a'..'z']) or (Key in ['0'..'9']) or (Key = ' ') or (Key = '.') or // bei Bedarf die erlaubten Zeichen hinzufügen (Key = Chr(vk_Back)) then begin If (Key = Chr(vk_Back)) then // Wenn Taste Backspace, dann letztes Zeichen löschen Suchwort:= copy(Suchwort, 0, length(Suchwort)-1) else Suchwort:= Suchwort + Key; // Suchwort um den getippten Buchstaben erweitern with DeineTabelle, Sender As TListBox do // Suche erstes Vorkommen des Suchwortes in Spalte "Title" if Locate('Title', Suchwort, [loCaseInsensitive, loPartialKey]) then ItemIndex:= RecNo-1 // Aktuellen Cursor (also der, der mit "Locate" gesetzt wurde) übergeben else ItemIndex:= -1; // Sonst nichts in der Listbox markieren end; end; Für "DeineTabelle" und "Title" natürlich deine Bezeichner einsetzen. Hoffe, du kannst was draus verwenden Gruß Pfoto |
Re: ListBox - AutoComplete und Sorted
und besser ist es einfach in der Listbox zu sortieren da es bedutend schneller geht.
Delphi-Quellcode:
und anschließend die Listbox sortieren. Über
//schleife
ListBox.Items.AddObject(FieldByName('Title').AsString, TObject(DeinArrayIndexAlsInteger));
Delphi-Quellcode:
bekommst du dann wieder den originalen Index
MeinIndex := Integer(ListBox.Items.Objects[ListboxIndex]);
|
Re: ListBox - AutoComplete und Sorted
Hallo,
zunächst einmal ganz herzlichen Dank für Eure schnellen und freundlichen Anworten. Diverse Fragen (bitte um Nachsicht falls dumm): Kann es sein, dass ich 'FieldByName' gar nicht mit Delphi 6 Personal verwenden kann, weil die Datenbankfunktionalität fehlt? Ich nutze die freie Komponente libsql um auf eine SQLite-DB (externes file 'database.sdb') zuzugreifen. Sieht so aus:
Delphi-Quellcode:
Mit ist nicht klar, welche Tabelle gemeint ist - die existiert ja nur in der SQLite-Datenbank.
procedure LoadInformation;
var db: TLiteDB; i: integer; begin try db := TLiteDB.Create(Form1); db.Use('database.sdb'); db.Query('SELECT * FROM TableName ORDER BY Name'); // Arraygröße der Einträge auf Anzahl der Datensätze setzen SetLength(Eintrag, db.RowCount); // Einlesen der Daten aus der Datenbank in das array 'Eintrag' for i := 0 to High(Eintrag) do begin Eintrag[i].Vorname := db.Results[i][0]; Eintrag[i].Nachname := db.Results[i][1]; // Eintrage des Namens in die Listbox Form1.ListBox1.Items.Add(Eintrag[i].Nachname); [...] end; finally db.Free; end; end; Danke und Gruß, Christoph |
Re: ListBox - AutoComplete und Sorted
Hallo Christoph,
du kannst alles weiter so machen, wie bisher. Vergiss die Table und FieldByName und schau nochmal auf den Beitrag von SirThornberry:
Delphi-Quellcode:
so hast du den Index deines Datensatzes im Array immer parat und kannst deine Listbox unabhängig von der sqlite collation order sortieren.
...
// Eintrage des Namens in die Listbox Form1.ListBox1.Items.AddObject(Eintrag[i].Nachname, Pointer(i)); ... Grüße vom marabu |
Re: ListBox - AutoComplete und Sorted
Hallo,
ich kann es kaum glauben, es funktioniert! Wie viele Stunden habe ich schon versucht, diese Lösung hinzubekommen. Ganz herzlichen Dank an alle, die mir hier weitergeholfen haben. Und großes Lob dafür, dass Ihr Eure Hilfe so freundlich 'rübergebracht habt. Das habe ich in anderen Foren leider auch schon ganz anders erfahren. Hier noch kurz meine Lösung (falls jemand ein ähnliches Problem hat):
Delphi-Quellcode:
Grüße und nochmals danke,
procedure TForm1.ListBox1Click(Sender: TObject);
var // arrayindex (ai) ist der 'richtige' index aus dem Array, nicht der aus der ListBox ai: integer; begin ai := Integer(ListBox1.Items.Objects[Form1.ListBox1.ItemIndex]); Form1.RichEdit1.Text := Eintrag[ai].Nachname; Form1.RichEdit2.Text := Eintrag[ai].Vorname; end; Christoph |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:27 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 by Thomas Breitkreuz