AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

ListBox - AutoComplete und Sorted

Ein Thema von Christoph · begonnen am 12. Okt 2005 · letzter Beitrag vom 13. Okt 2005
Antwort Antwort
Benutzerbild von Christoph
Christoph

Registriert seit: 23. Jan 2004
Ort: Heidelberg
48 Beiträge
 
Delphi 6 Personal
 
#1

ListBox - AutoComplete und Sorted

  Alt 12. Okt 2005, 13:18
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:
[...]
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;

[...]
Bisher sind das knapp 3000 Einträge.
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

Form1.RichEdit2.Text:=Eintrag[Form1.ListBox1.ItemIndex].Vorname; dann stimmen ItemIndex und die Nummer des Eintrags im Array nicht überein (aber genau das sollen sie tun).
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.
'Bist 900 Jahre alt wirst aussehen Du nicht gut!'
  Mit Zitat antworten Zitat
Pfoto

Registriert seit: 26. Aug 2005
Ort: Daun
541 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: ListBox - AutoComplete und Sorted

  Alt 12. Okt 2005, 14:56
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
Jürgen Höfs
  Mit Zitat antworten Zitat
Benutzerbild von Christoph
Christoph

Registriert seit: 23. Jan 2004
Ort: Heidelberg
48 Beiträge
 
Delphi 6 Personal
 
#3

Re: ListBox - AutoComplete und Sorted

  Alt 12. Okt 2005, 19:28
Hi,

danke für Deinen post - das übersteigt leider meine Programmier-Fähigkeiten.
Kannst Du mir mit code weiterhelfen?

Vielen Dank,
Christoph
'Bist 900 Jahre alt wirst aussehen Du nicht gut!'
  Mit Zitat antworten Zitat
Pfoto

Registriert seit: 26. Aug 2005
Ort: Daun
541 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: ListBox - AutoComplete und Sorted

  Alt 12. Okt 2005, 20:20
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...

Gruß
Pfoto
Jürgen Höfs
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#5

Re: ListBox - AutoComplete und Sorted

  Alt 12. Okt 2005, 20:45
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.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Pfoto

Registriert seit: 26. Aug 2005
Ort: Daun
541 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: ListBox - AutoComplete und Sorted

  Alt 12. Okt 2005, 22:32
So, ich hab mal das folgende Beispiel geschrieben -- also bei mir funktioniert es...



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
Jürgen Höfs
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#7

Re: ListBox - AutoComplete und Sorted

  Alt 13. Okt 2005, 05:40
und besser ist es einfach in der Listbox zu sortieren da es bedutend schneller geht.
Delphi-Quellcode:
//schleife
ListBox.Items.AddObject(FieldByName('Title').AsString, TObject(DeinArrayIndexAlsInteger));
und anschließend die Listbox sortieren. Über
MeinIndex := Integer(ListBox.Items.Objects[ListboxIndex]); bekommst du dann wieder den originalen Index
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von Christoph
Christoph

Registriert seit: 23. Jan 2004
Ort: Heidelberg
48 Beiträge
 
Delphi 6 Personal
 
#8

Re: ListBox - AutoComplete und Sorted

  Alt 13. Okt 2005, 12:57
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:
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;
Mit ist nicht klar, welche Tabelle gemeint ist - die existiert ja nur in der SQLite-Datenbank.

Danke und Gruß,
Christoph
'Bist 900 Jahre alt wirst aussehen Du nicht gut!'
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#9

Re: ListBox - AutoComplete und Sorted

  Alt 13. Okt 2005, 13:29
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:
...
// Eintrage des Namens in die Listbox
Form1.ListBox1.Items.AddObject(Eintrag[i].Nachname, Pointer(i));
...
so hast du den Index deines Datensatzes im Array immer parat und kannst deine Listbox unabhängig von der sqlite collation order sortieren.

Grüße vom marabu
  Mit Zitat antworten Zitat
Benutzerbild von Christoph
Christoph

Registriert seit: 23. Jan 2004
Ort: Heidelberg
48 Beiträge
 
Delphi 6 Personal
 
#10

Re: ListBox - AutoComplete und Sorted

  Alt 13. Okt 2005, 13:54
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:
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;
Grüße und nochmals danke,
Christoph
'Bist 900 Jahre alt wirst aussehen Du nicht gut!'
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:31 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