![]() |
ComboBox mit mehreren Spalten?
Hallo Leute,
leider bin ich noch blutiger Delphi-Anfänger und deshalb habe ich eine Frage an die Fachleute. :warn: :coder: Ist es eigentlich möglich, in der Standard-ComboBox mehrere Spalten darzustellen und wenn ja, wie macht man so etwas. Ich möchte meine Access-Frontend Datenbank als Delphi-Programm umschreiben und bei meiner Access-Datenbank benutze ich sehr häufig die ComboBox mit mehreren Spalten. Folgendes Beispiel: Ich möchte eine Benutzerauswahl über eine ComboBox machen. 1. Spalte = Personalnummer (nicht sichtbar z.B. Spaltenbreite 0cm!) 2. Spalte = Name (soll angezeigt werden!) Es soll aber nur der Name angezeigt werden, die Personalnummer soll nicht sichtbar sein und dient nur zur eindeutigen Identifikation des Benutzers - sozusagen als Rückgabewert den ich dann für weitere Abfragen weiterverwenden kann. Kann ich so etwas auch mit Delphi6 Personal-Edition machen? :gruebel: Für die Datenbank-Verbindung benutze ich KaDao (Freeware). Ich hoffe, dass mir evtl. jemand weiterhelfen kann ansonsten brauche ich erst gar nicht anfangen. Danke im Voraus! MfG Stefan H. |
Re: ComboBox mit mehreren Spalten?
Wenn du eh nur eine sehen willst, dann benutze die Methode AddObject von Item ->
![]() |
Re: ComboBox mit mehreren Spalten?
Vielleicht hilft dir sonst auch das hier:
![]() Oder habe ich dich falsch verstanden? |
Re: ComboBox mit mehreren Spalten?
so Legt man ein (bzw. 3) Item(s) mit dazugehöriger PersonalNummer an
Delphi-Quellcode:
Uns so lässt du dir die personalnummer von dem ausgewählten Item anzeigen
var LPersonalnummer: String;
begin LPersonalnummer := 'Personalnummer 3094d'; Combobox1.Items.AddObject('Hansmüller', TObject(LPersonalnummer)); LPersonalnummer := 'Personalnummer 394d0'; Combobox1.Items.AddObject('Fritz walter', TObject(LPersonalnummer)); LPersonalnummer := 'Personalnummer 08173'; Combobox1.Items.AddObject('Max mustermann', TObject(LPersonalnummer));
Delphi-Quellcode:
showmessage(String(Combobox1.Items.Objects[ComboBox1.ItemIndex]));
|
Re: ComboBox mit mehreren Spalten?
@SirThornberry: Habe ich alles in der Code-Lib erklärt. ;)
|
Re: ComboBox mit mehreren Spalten?
@Luckie: jetzt wo du es sagst seh ichs *g* hab den link nicht angeschaut. Aber da er ja nur eine personalnummer haben will ist mein beispiel denk ich einfacher zu verstehen. Das "new" und "dispose" verwirrt ihn vielleicht nur - ansonsten wenn er mehr als nur nen string speichern will dann ist dein beitrag aus der codelib eindeutig besser :thuimb:
|
Re: ComboBox mit mehreren Spalten?
Hallo!
Vielen, vielen Dank nochmals für die schnellen Antworten. :thuimb: Ich werde das mit dem AddObject mal ausprobieren. Wünsche allen noch ein schönes Wochenende!!! MfG Stefan H. |
Re: ComboBox mit mehreren Spalten?
Zitat:
Ich habe in meinem D5-Programm eine TComboBox-Komponente, die mehrere Items (Personennamen) enthält. Damit ich in der dahinterliegenden Datenbank (Firebird 2.0) nur eine ID speichere (z.B. "LPersonalnummer), habe ich diese ID in der ComboBox dem jeweiligen Item, wie von Dir beschrieben, mit AddObjects hinzugefügt. Soweit so gut, nun zum Problem: Ich möchte, wenn ich in einem TDBGrid durch die Datenmenge scrolle, die jeweilige Personalnummer aus der Datenbank holen und über diese ID das Item in der ComboBox ermitteln, dessen Personalnummer der ID des Datensatzes entspricht. Denn Ziel ist es, das zugehörige Item in der ComboBox auszuwählen und den Personennamen anzuzeigen. Ich hoffe, jemand kann mir einen guten und performanten Tip geben. Grüsse, Carsten |
Re: ComboBox mit mehreren Spalten?
Hallo Carsten,
du hast eine Combo mit den Paaren ID, Personalname und eine Tabelle mit einem ID-Feld? Wenn du über die Tabelle scrollst, suchst du mit dem ID-Feld der Tabelle in der Combo, stimmt das soweit? Nehmen wir an du suchst über einen Integer (Code so aus dem Kopf)
Delphi-Quellcode:
Ist deine ID ein String, dann musst du den Code eben schnell auf String-Werte anpassen. Du kannst in den Beiträgen weiter oben nachschauen.procedure <DeineForm>.SearchInCombo(Value:integer); var i: integer; begin for i := 0 to <ComboBox>.Items.Count-1 do begin if (integer(<ComboBox>.Items.Objects[i])=Value) then begin <ComboBox>.ItemIndex := i; Break; end; end; end; Jedoch hast du für diese Lösung immer noch das Problem, das für nicht gefundene IS-Werte, zumindest der letzte Wert angezeigt wird. Sollte dies nicht gewünscht sein, so musst du anstatt dem Break ein Exit verwenden und am Ende der Schleife den ItemIndex auf -1 setzen.
Delphi-Quellcode:
BTW: Warum nimmst du nicht zwei Tabellen (die Tabelle mit dem ID-Feld hast du schon, fehlt noch die 2. Tabelle mit den Werten für ID und Personalname), einen Query zur Suche in der 2. Tabelle und einer Ausgabe über ein Label oder ein ReadOnly-Editfeld. Dies könnte viel schneller sein, natürlich abhängig von der Anzahl der Daten.procedure <DeineForm>.SearchInCombo(Value:integer); var i: integer; begin for i := 0 to <ComboBox>.Items.Count-1 do begin if (integer(<ComboBox>.Items.Objects[i])=Value) then begin <ComboBox>.ItemIndex := i; Exit; end; end; <ComboBox>.ItemIndex := -1; end; |
Re: ComboBox mit mehreren Spalten?
Hi Gremlin,
Vielen Dank für Dein ausführliches Beispiel. Meine Daten haben am Anfang ungefähr eine Größe von ca. 3.000 Datensätzen, später evtl. 30.000. Das mit der FOR-Schleife habe ich mir auch schon überlegt. Ein Vorteil ist, daß die Berechnungen im Hauptspeicher ausgeführt werden, jedoch kann es auch lange dauern, wenn diese Schleife bis zu einige tausend Male aufgerufen wird. Das mit der Query zur Suche in der 2. Tabelle ist unter diesen Umständen vielleicht doch günstiger. Die Ausgabe würde ich weiterhin in der ComboBox belassen, da man über die Funktion "ComboBox.Items.IndexOf" relativ schnell das zugehörige Item ermitteln kann. Oder gibt es weitere Argumente für ein Label oder ein Readonly-Editfeld ? Mir fällt noch eine dritte Möglichkeit ein, die ich hier kurz skizzieren möchte: Parallel zum Füllen der ComboBox erzeuge ich eine StringList mit KeyValue-Werten (Bezeichner=Wert). Bezeichner würde in diesem Fall die ID sein und Wert würde der jeweils dazugehörige Name sein. Nur wie stelle ich es da an, mit dem Wert der ID direkt auf den Wert zuzugreifen ? |
Re: ComboBox mit mehreren Spalten?
Wenn du 30.000 Datensätze hast, dann darfst du den Initialisierungsvorgang für die Combo bzw. StringListe nicht vergessen. Ein Scrollen über einen Datensatz und ein anschliessendes Suchen in deiner 2. Datenmenge würde evtl. gleich schnell sein.
Du könntest beispielsweise über die Eigenschaft Values der Klasse TStringliste zugreifen und darüber die korr. Werte ermitteln.
Delphi-Quellcode:
ShowMessage('Der Wert für 4711=Test: '+Liste.Values['4711']);
Ich kann nicht beurteilen, woher die Werte für die ComboBox resp. die StringListe kommen. Wenn diese aus einer anderen Tabelle wie deine erste Tabelle kommen würden und der Grid ist nur zum blättern/scrollen verwendet, dann würde sich ein Query anbieten mit einem Join von Tabelle1 zu Tabelle2 über die ID-Nummer:
Delphi-Quellcode:
[...]
// FQuery ist beispielsweise ein im Formular angegebener Query a la FQuery : TQuery; // Dann könnte eine für die Initialisierung in etwa so aussehen with FQuery do begin Close; SQL.Clear; SQL.Add('Select Tabelle1.ID, Tabelle2.Personalname'); SQL.Add('from Tabelle1'); SQL.Add(' join Tabelle2 on (Tabelle2.ID=Tabelle1.ID)'); // wenn es nicht notwendigerweise einen Personalnamen zum Hauptdatensatz gibt, // diesen 2. Teil verwenden // SQL.Add(' left join Tabelle2 on (Tabelle2.ID=Tabelle1.ID)'); try Open; except // Eventuelles Fehlerhandling hier einbauen end; end; |
Re: ComboBox mit mehreren Spalten?
Hi Gremlin,
Vielen Dank für deine konstruktive Unterstützung. Ich hätte heute fast angefangen, eine der weiter oben beschriebenen Lösungen umzusetzen. Jedoch habe ich über ein anderes Forum, wo ich ebenfalls aktiv bin, genau die Lösung erhalten, die ich suche. Und zwar kann man auf die Objekte der in einer ComboBox enthaltenen Items ebenfalls ganz einfach zugreifen. Man muß nur wissen wie, die Lösung des Problems lautet: ComboBox1.Items.IndexOfObject(TObject(iID)) Ist das nicht eine geile Lösung ? Man kann sofort und ohne Umwege über die in der Tabelle enthaltene ID das zugehörige Item der ComboBox ausfindig machen. Der Umweg über eine Stringliste ist somit definitiv nicht nötig. Die Werte meiner ComboBox werden übrigens während der Intialisierung des Formulars über eine 2. Tabelle gefüllt. Grüsse, Carsten |
Re: ComboBox mit mehreren Spalten?
Hi Carsten,
jo, kannst du auch über die Combo machen, es gibt doch mehrere Lösungen. :thumb: Nur solltest du dir überlegen, ob es sinnvoll ist, die Werte von der Tabelle2 in die Combo zu schreiben und beim Scrollen von Tabelle1 in der Combo zu suchen, anstatt über einen Query beide Tabellen auf einmal zu kombinieren. Ich kann das für dich nicht entscheiden. :-D Fang doch einfach mal mit einer ersten Lösung an und wenn sie dir nicht gefällt machst du es eben anders. Wenn dann noch Fragen auftauchen melde dich einfach nochmal. :wink: Viel Erfolg. |
AW: ComboBox mit mehreren Spalten?
Hallo Zusammen,
der Threat ist zwar schon älter, aber vielleicht kann mir trotzdem jemand einen Tip geben. Ich habe es folgendermaßen umgesetzt:
Delphi-Quellcode:
Im OnChange Procedure wollte ich den Wert dann in ein Editfeld schreiben und habe es so versucht:
while not Query.Eof do begin
if not Query.FieldByName(Spalte_sichtbar).IsNull then begin Wert:=Query.FieldByName(Spalte_Unsichtbar).AsString; ComboBox.Items.AddObject(Query.FieldByName(Spalte_sichtbar).AsString, TObject(Wert)); end; Query.Next; end;
Delphi-Quellcode:
Edit_Abteilung_ID.Text:=String(Combo_Abteilung.Items.Objects[Combo_Abteilung.ItemIndex]);
Leider wird dann nur so ein komisches Zeichen in das Editfeld geschrieben (wie ein L falschherung, Schenkel zeigt nach links). Wenn ich es debuggere, dann bekomme ich immer den Wert #4. Kann mir jemand sagen, was ich falsch mache? Vielen Dank Patrick |
AW: ComboBox mit mehreren Spalten?
Du kannst nicht einen String als TObject interpretieren um ihn entsprechend anzuhängen.
Bei Strings gibt es automatische Referenzzählung. Wenn zur Laufzeit gemeint wird das der String nicht mehr verwendet wird, wird er aufgeräumt. Und nach einiger Zeit ist an dieser Speicheradresse irgendwas zu finden. |
AW: ComboBox mit mehreren Spalten?
Das verstehe ich nicht. Habe ich diesen Thread falsch verstanden? Ich dachte es ginge genau darum, einem String eine Zusatz-Info mitzugeben, die ich dann später wieder abrufen kann.
Wenn das so nicht geht, hast Du eine andere Idee, wie ich das lösen kann? Vielen Dank Patrick |
AW: ComboBox mit mehreren Spalten?
Ja, da hast etwas völlig falsch verstanden.
Diese "tolle" Lösung (mehr ein Gewurschtel oder auch Krücke) misbraucht den Objekt-Parameter um einen Integer Wert dort abzulegen. Das funktioniert irgendwie, ist aber nicht der Sack der Zwerge. Wenn du eine Information dort ablegen willst, dann lege dort auch eine Information ab. Nehmen wir an, dort soll eine Person abgelegt werden mit einem string ID Wert, dann mach das dich richtig:
Delphi-Quellcode:
Aus der Abfrage erzeugst du dir die Instanzen und fügst diese dann zu den ComboBox Items hinzu
TPerson = class
public constructor Create( const ID, FirstName, LastName : string ); function ToString : string; override; property ID : string read FID; property FirstName : string read FFirstName; property LastName : string read FLastName; end; function TPerson.ToString: string; begin Result := FLastName + ', ' + FFirstName; end;
Delphi-Quellcode:
Du musst jetzt nur wegen der Freigabe schauen, ob die ComboBox Items das OwnsObjects unterstützen.
LPerson := TPerson.Create( ... );
ComboBox.Items.AddObject( LPerson.ToString, LPerson ); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:41 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