Office Forum
www.Office-Loesung.de
Access :: Excel :: Outlook :: PowerPoint :: Word :: Office :: Wieder Online ---> provisorisches Office Forum <-
Textbox wie Combobox zum Suchen von Datensätzen verwenden
zurück: Events - Objekte entkoppeln, passive Ausführung von Code weiter: Transparente Bilder auf Buttons Unbeantwortete Beiträge anzeigen
Neues Thema eröffnen   Neue Antwort erstellen     Status: Tutorial Facebook-Likes Diese Seite Freunden empfehlen
Zu Browser-Favoriten hinzufügen
Autor Nachricht
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
07. Jul 2009, 15:05
Rufname:

Textbox wie Combobox zum Suchen von Datensätzen verwenden - Textbox wie Combobox zum Suchen von Datensätzen verwenden

Nach oben
       Version: Office 2007

Hallo zusammen,

in den meisten Datenbanken benötigt man irgendwann eine Suchfunktion, die in einem bestimmten Feld nach einem Inhalt suchen soll. Die Combobox ist mit dem AutoExpand eine praktische Sache, weil sie in einer Liste von Einträgen, die man der RowSource zuweist, nach einem Text suchen kann und ein Ergebnis zeigt, sobald man zu tippen beginnt.
Hat man etwa "Mei" getippt und in der Liste ist ein "Meier", wird der Text "Meier" bereits im Eingabefeld angezeigt, bevor man fertig getippt hat.

Die Combobox hat aber auch den Nachteil, daß sie eben den kompletten Datenbestand, der zur Suche notwendig ist, beim Öffnen der Form einladen muß, was bei einer Reihe solcher Elemente mit unterschiedlichen RowSources durchaus stark bremsen kann.
Erschwerend kommt hinzu, daß Access von sich aus nicht die kompletten Daten der RowSource lädt, sondern nur einen ersten Teil und den Rest dann in aller Gemütlichkeit nachlädt, nachdem die Form bereits geöffnet ist. Damit öffnet sich die Form zwar performanter, führt aber zu häßlichen Nebeneffekten, etwa, daß man den Scrollbalken der Combobox nicht vollständig nach unten ziehen kann - eben weil die Daten noch nicht vollständig geladen sind.
Das kann man zwar mit einem MoveLast forcieren - aber dann werden eben doch wieder die gesamten Daten der Liste sofort geladen.

Bei kurzen Listen ist das alles kein Problem, bei sehr großen Tabellen, eventuell auch noch aus mehreren Spalten bestehend, kann das schnell zum Performancekiller werden.
Außerdem gibt es noch einen Nebeneffekt bei Verwendung von z.B. MS SQL Server: Wird die Liste NICHT mit MoveLast komplett geladen, blockiert Access die Tabelle durch das langsame Nachladen so sehr, daß es zu TimeOut-Fehlern bei anderen Benutzern der gleichen Tabelle kommen kann (alle genannten Dinge in der Praxis ausprobiert und vorgekommen).

Eine Lösung, um die praktische Funktion der ComboBox (das automatische Vervollständigen) nachzubilden, soll die folgende Demo zeigen:
Code:
'---------------------------------------------------------------------------------------
' Autor     : Christian Coppes
' Version   : 1.0
' Prozedur  : Text0_KeyUp
' Zweck     : Ersatz der ComboBox mit einer TextBox
'---------------------------------------------------------------------------------------
Private Sub Text0_KeyUp(KeyCode As Integer, Shift As Integer)
    Dim strSearch As String
    Dim strFound As String
    Dim lngStart As Long
       
    With Me!Text0
        Select Case KeyCode
          ' BS, Del, Tab
          Case 8, 46, 16, 9
            Exit Sub
          ' Pos1, End
          Case 36, 35
            If Shift = 0 Then
                Me.Text0.SelLength = 0
            End If
            Exit Sub
          ' Cursor Left, Right
          Case 37, 39
            If Shift = 0 Then
                Me.Text0.SelLength = 0
            End If
            Exit Sub
          Case Else
        End Select
        ' Textfeld ist leer, dann nichts tun
        If Nz(.Text) = "" Then Exit Sub
        ' Cursorposition speichern
        lngStart = .SelStart
        ' Steht der Cursor irgendwo im Text?
        If .SelLength = 0 And .SelStart < Len(.Text) Then
            ' dann gesamten Text zur Suche verwenden
            strSearch = .Text
          Else
            ' ansonsten nur den nicht markierten Teil
            strSearch = Left(.Text, .SelStart)
        End If
        ' Suche durchführen
        strFound = DFirst("Feldname", "SuchTabelle", _
                          "Left$(Feldname," & Len(strSearch) & _
                                                      ")='" & strSearch & "'")
        ' Wurde etwas gefunden?
        If strFound <> "" Then
            ' Ist die Länge des gefundenen Textes größer als
            ' die Länge des Suchtextes?
            If Len(strFound) > Len(strSearch) Then
                ' nur dann den gefundenen Text in die Textbox kopieren
                .Text = strFound
            End If
            ' den Cursor wieder an die Position setzen, an der er stand
            .SelStart = lngStart
            ' nur den letzten Teil des Textes (den man nicht eingegeben hat)
            ' markieren
            If Len(strFound) >= lngStart Then
                .SelLength = Len(strFound) - lngStart
              Else
                .SelLength = Len(strFound)
            End If
        End If
    End With
End Sub
Hier wird der KeyUp-Event dazu verwendet, eine individuelle Suche zu starten, sobald der Benutzer eine Taste gedrückt und wieder losgelassen hat. Dabei wurde versucht, das exakte Verhalten der Combobox nachzubilden.

Der deutliche Performancevorteil in der Praxis: Wird die Form geladen, wird nichts anderes als die Form geladen, denn die TextBox kennt keine RowSource. Wird nichts eingegeben, entstehen auch keine Anfragen an den Server. Die Anfrage (hier als Beispiel mit DFirst gelöst) kann natürlich genauso mit ADO durchgeführt werden.
Der Text "FeldName" und "SuchTabelle" muß entsprechend ausgetauscht werden gegen die entsprechenden eigenen Tabellen- und Feldnamenbezeichnungen. "Text0" ist der Name der Textbox und muß natürlich auch entsprechend angepaßt werden. Die Funktion ist auf die Eingabe von Textfeldern zugeschnitten und wurde nicht mit Zahlenwerten getestet, sollte aber durch vorherige Umwandlung des Suchfeldes in einen Text (innerhalb der Suche mit DFirst) ebenso funktionieren.

Um das Verhalten der ComboBox komplett nachzubilden, müßte man noch einen LostFocus-Event ergänzen, der die letzte Eingabe noch einmal in der Datenbank sucht und im Feld einstellt, wenn der Eingabetext genau einem Suchergebnis entspricht. Aber das sollte sicherlich kein Problem sein.

Der TextBox kann natürlich eine ControlSource hinzugefügt werden, in die der Wert gespeichert wird, oder man erstellt einen AfterUpdate-Event, der den eingegebenen Wert anderweitig in der Form verwendet.
Was die TextBox-Lösung natürlich nicht unterstützt (die ComboBox aber kann) ist die interne Zuweisung der zugrundeliegenden ID einer Tabelle und die Speicherung dieser ID im Eingabefeld.

Aber auch das kann man auf diese Weise lösen: Man liest zusätzlich zum Suchfeld die ID mit aus und speichert sie in einem versteckten Feld, dem man die richtige ControlSource zuweist. Dabei muß man lediglich überprüfen, ob die Sucheingabe wirklich einem Eintrag in der Liste entspricht und wenn nicht, dem versteckten Feld beispielsweise einen Null-Wert zuweist, wenn nur die ID gespeichert werden soll - oder den handeingegebenen Text in einem Freitextfeld, falls gewünscht. Für eine solche Suche ist allerdings DFirst ungeeignet, da müßte man dann auf ein Recordset zurückgreifen.

Die Funktion der Combobox kann man darüber hinaus ebenfalls nachstellen, indem man rechts neben der Textbox einen einfachen Button erstellt, der statt eine Combobox aufzuklappen ein komplettes Formular öffnet (durch entsprechende Einstellungen kann dieses auch ohne Ränder dargestellt werden) und dort eine komfortable Suche und/oder Editierung der Liste zuläßt (was die Combobox nicht in der Form kann). Beim Öffnen eines Formulars wird eine Tabelle deutlich performanter geladen als bei einer ComboBox, so daß die oben beschriebenen Probleme hier nicht auftreten, außerdem kann man selbst nach Belieben optimieren (was bei einer ComboBox auch nicht geht). Darüber hinaus wird das Extraformular natürlich erst mit dem Datenladen anfangen, wenn man das erste Mal auf den oben beschriebenen Button klickt. Wenn man also 20 solcher ComboBox-Imitationen auf einer Form hat und programmtechnisch dafür sorgt, daß immer nur ein Formular aufklappt, wenn das vorherige geschlossen wurde, kann es nie zu Performanceproblemen kommen, ganz gleich, wieviele Felder dieser Art man erzeugt.
Und ein weiterer Vorteil ist, daß man solche Aufklapp-Formulare auch in anderen Formen verwenden kann, ohne sie ändern zu müssen. Ändert man das Formular, ändert es sich für alle "ComboBoxen" in allen Formularen.

Viel Spaß beim Experimentieren...

Christian

(getestet mit Access 2007, englische Version, sollte aber auch in den meisten älteren Versionen funktionieren)
jens05
Moderator


Verfasst am:
08. Jul 2009, 19:47
Rufname:
Wohnort: ~~~~~


AW: Textbox wie Combobox zum Suchen von Datensätzen verwende - AW: Textbox wie Combobox zum Suchen von Datensätzen verwende

Nach oben
       Version: Office 2007

Hallo,
schöne Lösung, aber ich würde die Findfirst-Methode so anpassen.
Code:
        strFound = Nz(DFirst("Feldname", "SuchTabelle", _
                             "Left(Feldname," & Len(strSearch) & _
                                          ")='" & strSearch & "'"), strSearch)
Damit wird kein LZF erzeugt, wenn der Suchtext in der Tab nicht vorhanden ist.

Ich habe das auch mal mit DLookup anstatt DFirst versucht, und denke das dies etwas schneller ging. ;) (rein subjektiv)

_________________
mfg jens05 Wink
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
08. Jul 2009, 21:51
Rufname:

AW: Textbox wie Combobox zum Suchen von Datensätzen verwende - AW: Textbox wie Combobox zum Suchen von Datensätzen verwende

Nach oben
       Version: Office 2007

Hallo Jens,

ich persönlich verwende die Dxxx-Funktionen eigentlich überhaupt nicht, weil sie in den meisten Fällen zu langsam sind. Anstelle dessen verwende ich an gleicher Stelle eine Funktion, die per ADO die Suche auf dem Server durchführt. Diese fängt leere Ergebnisse selbst ab, von daher war mir das nicht aufgefallen.

Aber Deine Idee mit Nz(...,strSearch) ist nicht schlecht.

Gruß

Christian
RebeccaLiDe
Einsteiger


Verfasst am:
23. Jan 2011, 13:57
Rufname: Becky
Wohnort: Fürth

AW: Textbox wie Combobox zum Suchen von Datensätzen verwende - AW: Textbox wie Combobox zum Suchen von Datensätzen verwende

Nach oben
       Version: Office 2007

Hallo super genau sowas habe ich gesucht, oder sagen wir so: ich glaube das ich sowas gesucht habe. Razz
Nachdem ich aber echt noch sehr unerfahren bin meine Frage, oder Bitte hat jemand von Euch da draußen sowas schonmal gemacht? Wenn ja gibt es dazu evtl. eine Test DB von wo ich mir das mal anschauen kann. Ich weiß ist viel verlangt, aber mit den blanken Codes kann ich soviel nicht anfangen. Ich lerne besser an Beispielen.
Also es wäre echt klasse.
Ganz liebe Grüße
RebeccaLiDe
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
02. Feb 2011, 17:21
Rufname:

AW: Textbox wie Combobox zum Suchen von Datensätzen verwende - AW: Textbox wie Combobox zum Suchen von Datensätzen verwende

Nach oben
       Version: Office 2007

Hallo,

habe Deine Nachricht nicht gesehen, da hat das Forum mal wieder keine Mail verschickt...Smile

Hier ist eine Variante, die diese Technik verwendet, in einer neuen Version, die das ganze als universell verwendbare Funktion kapselt, so daß der Code im Formular so gering wie möglich gehalten wird.

Das Beispiel zeigt die Suchergebnisse aus einer Ländertabelle an, man kann das Land entweder in Englisch oder in Deutsch eingeben und AutoComplete besorgt den Rest. Dabei werden auch noch andere Felder des Formulars mit Suchergebnissen aus der Ländertabelle befüllt.

Da bei einer Combobox meistens ein Text gesucht, aber ein ID-Wert gespeichert werden soll, wird von der Funktion der gefundene ID-Wert zurückgegeben, den man dann z.B. in einem gebundenen (versteckten) Feld speichern kann. Alternativ kann man natürlich auch den zurückgegebenen Textwert in ein entsprechendes gebundenes Textfeld speichern, falls das in der Datenbank Sinn macht (eher seltener).

Die Anzeige der Zusatzfelder zeigt, daß man auch andere Felder mit dem gefundenen ID-Wert mit entsprechenden Feldern füllen kann, eine andere Variante wäre etwa, ein UFO einzubinden mit RecordSource auf die Suchtabelle und das UFO mit dem versteckten ID-Feld zu verlinken. So könnte man auch gleich einen kompletten Datensatz anzeigen, ohne einzeln mühsam DLookup zu verwenden. Oder man könnte mit dem ID-Wert ein entsprechendes Recordset öffnen und die Feldwerte komplett dort auslesen, statt für jedes Feld ein einzelnes DLookup zu verwenden, was besser wäre, ich mir aber hier gespart habe - usw., alles eine Frage dessen, was man damit machen möchte.

Gruß

Christian

PS: Bitte Nachfragen zu diesem Thema im Forum Access Programmierung / VBA
beim Thema Textbox wie Combo zum Suchen von DS verwenden (Nachgefragt) stellen.



TextboxAutocomplete.zip
 Beschreibung:
Demo im Format Access 2000 für die Autocomplete-Funktion für Textboxen.

Download
 Dateiname:  TextboxAutocomplete.zip
 Dateigröße:  42.8 KB
 Heruntergeladen:  229 mal

Gast



Verfasst am:
21. Apr 2012, 13:58
Rufname:

AW: Textbox wie Combobox zum Suchen von Datensätzen verwende - AW: Textbox wie Combobox zum Suchen von Datensätzen verwende

Nach oben
       Version: Office 2007

Danke in die Runde,
die Textbox ist super.
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
22. Apr 2012, 01:02
Rufname:


AW: Textbox wie Combobox zum Suchen von Datensätzen verwende - AW: Textbox wie Combobox zum Suchen von Datensätzen verwende

Nach oben
       Version: Office 2007

Hallo zusammen,

die oben vorgestellte Methode für AutoComplete mit einer Textbox funktioniert schon ziemlich gut, hat aber den Nachteil, daß der Code ein wenig "verstreut" ist und der Code, den man in das Formular einsetzen muß, um AutoComplete zu aktivieren, doch noch recht umfangreich ist - mit entsprechend vielen Fehlermöglichkeiten.

Die angehängte Demodatenbank enthält nun eine neue Variante, diesmal als Klassenmodul. Um die AutoComplete-Funktion in eigene Datenbanken einzufügen, muß man als erstes die Klasse "clsCCTextboxAutocomplete.cls" in die Datenbank importieren.

Danach setzt man für jedes Textfeld, mit dem man AutoComplete verwenden möchte, eine Objektvariable auf diese Klasse auf Modulebene in den Formularcode, z.B.:
Code:
Private objAutoCompleteMeinTextfeld As clsCCTextAutocomplete
Danach muß man nur noch im Form_Load-Event folgenden Code einfügen:
Code:
    Set objAutoCompleteMeinTextfeld = New clsCCTextAutocomplete

    With objAutoCompleteMeinTextfeld
        .InitAutoComplete Me.MeinTextfeld, "Tabellenname oder Abfragename", _
                          "ID-Feldname", "Textfeldname"
    End With
"MeinTextfeld" ist der Name der Textbox, für die AutoComplete aktiviert werden soll.
"ID-Feldname" ist der Name des Feldes in der Tabelle/Abfrage, das den ID-Wert repräsentiert (wie die ausgeblendete Spalte einer Combobox).
"Textfeldname" ist der Name des Feldes in der Tabelle/Abfrage, das beim AutoComplete verwendet werden soll (wie die Spalte 2 einer Combobox).

Das war's für den einfachsten Fall.

Zwei weitere Parameter für die "InitAutoComplete"-Sub sind, daß man zum einen eine weitere Textbox angeben kann, in die die ID kopiert wird (z.B. für ein verstecktes ID-Feld) sowie ein WHERE-String, der wie ein Filter-String aufgebaut sein muß, also eine WHERE-Klausel ohne das Wort "WHERE". Diese Bedingung wird zusätzlich an den SQL-String angehängt, der den AutoComplete-Text in der Tabelle/Abfrage sucht. Es wird immer automatisch nach der Spalte sortiert, nach der in der AutoComplete-Textbox gesucht wird.

Außerdem hat die Klasse noch eine Sub namens "AddTextbox". Damit kann man weitere Textbox-Controls angeben, die mit dem Inhalt des Feldes gefüllt wird, das man als zweiten Parameter in dieser Sub angeben muß. Der Feldname muß in der Tabelle/Abfrage enthalten sein, die man in der AutoComplete-Textbox angegeben hat. Das Vorhandensein sowohl der Tabelle/Abfrage wie auch der einzelnen Feldnamen wird geprüft und eine Fehlermeldung in Deutsch oder Englisch ausgegeben, je nach eingestellter Sprache. Defaultsprache ist Englisch. Ändern kann man die Sprache mit der Eigenschaft "Language"-

Mit Hilfe der Sub "AddTextbox" kann man also neben dem ID-Feld auch weitere Spalten der gleichen Tabelle in weitere Textboxen übertragen. Die Demodatenbank zeigt ein Beispiel, in dem zwei Textboxen verwendet werden, die einmal die Eingabe eines Landesnamens auf Deutsch und einmal auf Englisch ermöglichen. Beide erhalten wechselseitig per "AddTextbox" das jeweils andere Textfeld zugeordnet, so daß man sich aussuchen kann, über welche Textbox man nach dem Land sucht. Zusätzlich wird das Landeskürzel und die ID in der Tabelle in zwei weiteren Textboxen ausgegeben.

Die Textboxen können gebunden oder ungebunden sein.

Das Format der angehängten Demodatenbank ist A2000.

Das Formular "frmTestClass" zeigt ein kleines Beispiel, wie man ein Mini-"Test Driven Development" mit Access auch ohne großes Framework hinbekommen kann. Damit wurden die verschiedenen falschen Parameterübergaben während der Entwicklung getestet.

Viel Spaß damit

Christian



TextboxAutoCompleteClassV1_0.zip
 Beschreibung:
Verbesserte Textbox-AutoComplete-Funktion als Klassenmodul. Format: A2000, enthält die Klasse auch als Textdatei.

Download
 Dateiname:  TextboxAutoCompleteClassV1_0.zip
 Dateigröße:  109.58 KB
 Heruntergeladen:  78 mal

Neues Thema eröffnen   Neue Antwort erstellen Alle Zeiten sind
GMT + 1 Stunde

Diese Seite Freunden empfehlen

Seite 1 von 1
Gehe zu:  
Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum nicht posten
Du kannst Dateien in diesem Forum herunterladen

Verwandte Themen
Forum / Themen   Antworten   Autor   Aufrufe   Letzter Beitrag 
Keine neuen Beiträge Access Tabellen & Abfragen: Duplikate suchen 1 erwing 805 21. Jan 2006, 13:35
Wollibär Duplikate suchen
Keine neuen Beiträge Access Tabellen & Abfragen: Warengruppen suchen 0 umbroboy 581 07. Nov 2005, 18:03
umbroboy Warengruppen suchen
Keine neuen Beiträge Access Tabellen & Abfragen: Differenzen zwischen einzelnen Datensätzen 8 Kirk 927 21. Okt 2005, 15:29
Kirk Differenzen zwischen einzelnen Datensätzen
Keine neuen Beiträge Access Tabellen & Abfragen: Filtern nach den letzten xy Datensätzen 1 BML77 507 25. Jun 2005, 20:03
jens05 Filtern nach den letzten xy Datensätzen
Keine neuen Beiträge Access Tabellen & Abfragen: Datensatz über Formular suchen 3 Sandnet 2166 10. Jun 2005, 10:52
Dalmatinchen Datensatz über Formular suchen
Keine neuen Beiträge Access Tabellen & Abfragen: Mailadressen aus verschiedenen Datensätzen zusammenfassen 4 Florus 609 25. Mai 2005, 09:51
Florus Mailadressen aus verschiedenen Datensätzen zusammenfassen
Dieses Thema ist gesperrt, du kannst keine Beiträge editieren oder beantworten. Access Tabellen & Abfragen: Fehler beim Filtern von unterschiedlich langen Datensätzen! 1 SteffenL 515 20. Apr 2005, 15:15
Willi Wipp Fehler beim Filtern von unterschiedlich langen Datensätzen!
Keine neuen Beiträge Access Tabellen & Abfragen: Unternummern von Artikeln suchen/verwalten 4 umbroboy 502 22. Nov 2004, 17:49
Gast Unternummern von Artikeln suchen/verwalten
Keine neuen Beiträge Access Tabellen & Abfragen: Selektierten Datensätzen den selben Wert zuweisen 3 studio 712 14. Okt 2004, 14:40
Willi Wipp Selektierten Datensätzen den selben Wert zuweisen
Keine neuen Beiträge Access Tabellen & Abfragen: Datum abfragen bericht anzeigen // Artikel usw. suchen 2 mr@ 1259 10. Okt 2004, 20:03
mr@ Datum abfragen bericht anzeigen // Artikel usw. suchen
Keine neuen Beiträge Access Tabellen & Abfragen: Probleme mit Datensätzen in Tabellen 0 Jörg O 403 14. Sep 2004, 12:20
Jörg O Probleme mit Datensätzen in Tabellen
Keine neuen Beiträge Access Tabellen & Abfragen: datensätze suchen 13 mr@ 1514 13. Sep 2004, 10:21
meyster datensätze suchen
 

----> Diese Seite Freunden empfehlen <------ Impressum - Besuchen Sie auch: Microsoft-Excel Diagramme