Nach Daten im Unterformular suchen

Wenn Sie ein Abonnement des Magazins 'Access im Unternehmen' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

Nach Daten im Unterformular suchen

Die Konstellation von Haupt- und Unterformular zur Darstellung von Daten aus 1:n- beziehungsweise m:n-Beziehungen ist bekannt. Einen Datensatz im Hauptformular zu suchen ist auch kein Hexenwerk. Aber wie sieht es aus, wenn wir das Hauptformular nach den Datensätzen filtern wollen, deren verknüpfte Tabelle einen Datensatz mit einem bestimmten Kriterium enthält? Und wenn wir dann noch einen Schritt weitergehen und noch den ersten passenden Datensatz im Unterformular markieren wollen? Wie dies gelingt, zeigt der vorliegende Beitrag.

Die Tabellen der Beispieldatenbank rekrutieren sich wieder eimal aus der Südsturm-Datenbank, unserer angepassten Nordwind-Variante. Im ersten Beispiel schauen wir uns die Kategorien im Hauptformular an und die Artikel einer jeden Kategorie im Unterformular.

Mit einem Suchfeld im Hauptformular wollen wir nach Artikeln filtern. Außerdem soll es zwei Schaltflächen geben, mit denen wir zwischen den Ergebnissen hin- und herblättern können. Das Formular soll dann wie in Bild 1 aussehen.

Formular mit Filter nach Artikelname, Variante I

Bild 1: Formular mit Filter nach Artikelname, Variante I

Aufbau des Formulars

Das Hauptformular verwendet die Tabelle tblKategorien als Datenherkunft und zeigt die beiden Felder KategorieID und Kategoriename an. Das Unterformular steuert die Daten der Tabelle tblArtikel bei, und zwar in der Daten­blatt­ansicht. Damit es jeweils nur die Datensätze anzeigt, die mit dem aktuellen Datensatz der Tabelle tblKategorien im Hauptformular verknüpft sind, erhalten die Eigenschaften Verknüpfen von und Verknüpfen nach des Unterformular-Steuerelements jeweils den Wert KategorieID.

Steuerelemente

Die zusätzlichen Steuerelemente im Formular heißen txtSuchbegriff, cmdVorheriger und cmdNaechster. Wenn der Benutzer einen Begriff in das Textfeld txtSuchbegriff eingibt, soll die erste Kombination aus Kategorie und Artikel gefunden werden, deren Artikelname dem im Suchfeld eingegebenen Ausdruck entspricht (Platzhalter wie das Sternchen (*) sind dabei erlaubt).

Die beiden Schaltflächen cmdVorheriger und cmdNaechster sind beim Laden des Formulars noch deaktiviert. Erst, wenn der Benutzer einen Suchbegriff eingibt, wird geprüft, ob eine der Schaltflächen aktiviert werden soll – oder auch beide. Zeigt das Formular den ersten Treffer an und gibt es noch einen weiteren, soll die Schaltfläche cmdNaechster aktiviert werden. Blättert der Benutzer damit zum folgenden Treffer, soll auch die Schaltfläche cmdVorheriger aktiviert werden. Die Schaltfläche cmdNaechster bleibt dabei verfügbar, bis der Benutzer zum letzten Ergebnis weitergeklickt hat.

Programmierung der Suche

Die Suchfunktion erfordert einen etwas anderen Ansatz als übliche Suchfunktionen. Direkt nach der Eingabe des Suchbegriffs erstellen wir ein Recordset, das die Tabelle tblArtikel aufnimmt – mit dem eingegebenen Suchbegriff als Vergleichswert für das Feld Artikelname. Die Tabelle liefert für jedes Suchergebnis sowohl die ArtikelID also auch die KategorieID aus dem entsprechenden Fremdschlüsselfeld. Damit können wir dann also sowohl den gesuchten Datensatz im Unterformular einstellen als auch die dazu passende Kategorie im Hauptformular.

Schaltflächen deaktivieren

Beim Laden des Formulars sollen die beiden Schaltflächen cmdVorheriger und cmdNaechster zunächst deaktiviert sein. Dazu legen wir für das Ereignis Beim Laden die folgende Ereignisprozedur an:

Private Sub Form_Load()
     Me!cmdVorheriger.Enabled = False
     Me!cmdNaechster.Enabled = False
End Sub

Nach der Eingabe eines Suchbegriffes und dem Auslösen des Ereignisses Nach Aktualisierung soll die Prozedur aus Listing 1 ausgelöst werden. Die Prozedur füllt die Variable db mit einem Verweis auf das Database-Objekt der aktuellen Datenbank. Dann liest sie den Suchbegriff aus dem Textfeld txtSuchbegriff in die Variable strSuchbegriff ein. Hat der Suchbegriff eine Länge von mehr als null Zeichen, erstellt die Prozedur ein neues Recordset, das alle Datensätze der Tabelle tblArtikel enthält, deren Feld Artikelname dem Suchbegriff entspricht. Dieses Recordset speichert die Prozedur in einer Variablen, die im Kopf des Klassenmoduls wie folgt deklariert wird und damit von allen Prozeduren des Moduls aus erreichbar ist:

Private Sub txtSuchbegriff_AfterUpdate()
     Dim db As DAO.Database
     Dim strSuchbegriff As String
     Set db = CurrentDb
     strSuchbegriff = Nz(Me!txtSuchbegriff, "")
     If Len(strSuchbegriff) > 0 Then
         Set rstErgebnis = db.OpenRecordset("SELECT ArtikelID, KategorieID FROM tblArtikel WHERE Artikelname LIKE '" _
             & strSuchbegriff & "' ORDER BY tblKategorien.KategorieID, tblArtikel.ArtikelID", dbOpenSnapshot)
         SteuerelementeAktualisieren
         Filtern
     Else
         FilterAufheben
     End If
End Sub

Listing 1: Prozedur für das Ereignis Nach Aktualisierung des Suchfeldes

Dim rstErgebnis As DAO.Recordset

Wir verwenden den Wert dbOpenSnapshot als Parameter, da dies direkt den Wert der Eigenschaft Recordcount des Recordsets verfügbar macht. Nachdem dies geschehen ist, ruft die Prozedur zwei weitere Routinen namens SteuerelementeAktualisieren und Filtern auf. Erstere aktiviert oder deaktiviert die beiden Schaltflächen cmdVorheriger und cmdNaechster in Abhängigkeit von der Datensatzposition, der zweite filtert die Daten in Haupt- und Unterformular nach dem aktuellen Datensatz des Recordsets rstErgebnis.

Sollte das Textfeld txtSuchbegriff keinen Wert enthalten, ruft die Prozedur die Routine FilterAufheben auf, was wieder alle Datensätze in Haupt- und Unterformular anzeigt.

Steuerelemente aktualisieren

Die Routine SteuerelementeAktualisieren kümmert sich um das Aktivieren und Deaktivieren der beiden Schaltflächen cmdVorheriger und cmdNaechster. Die erste If...Then-Bedingung dieser Routine prüft, ob die aktuelle Position des Datensatzzeigers von rstErgebnis kleiner als die Anzahl der Datensätze minus eins ist.

Minus eins deshalb, weil AbsolutePosition für den ersten Datensatz den Wert 0 liefert. In diesem Fall aktiviert die Routine die Schaltfläche cmdNaechster, anderenfalls wird sie deaktiert. Bei der Schaltfläche cmdVorheriger sieht es ähnlich aus: Die If...Then-Bedingung prüft, ob AbsolutePosition größer 0 ist. Falls ja, kann der Benutzer noch einen Datensatz nach vorn blättern und die Schaltfläche cmdVorheriger wird aktiviert:

Private Sub SteuerelementeAktualisieren()
     If rstErgebnis.AbsolutePosition _
             < rstErgebnis.RecordCount - 1 Then
         Me!cmdNaechster.Enabled = True
     Else
         Me!cmdNaechster.Enabled = False
     End If
     If rstErgebnis.AbsolutePosition > 0 Then
         Me!cmdVorheriger.Enabled = True
     Else
         Me!cmdVorheriger.Enabled = False
     End If
End Sub

Filtern der Artikel

Die Routine Filtern sorgt für die Anzeige des jeweils aktuellen Datensatzes des Recordsets rstErgebnis (s. Listing 2). Dabei prüft die Routine zunächst, ob das Recordset mindestens einen Datensatz enthält. Falls ja, stellt sie die Eigenschaft Filter des Hauptformulars auf einen Ausdruck ein, bei dem der Wert von KategorieID der Datenherkunft dem Wert dieses Feldes im aktuelle Datensatz des Recordsets entspricht und aktiviert den Filter durch Setzen von FilterOn auf True.

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Ich habe die Datenschutzbestimmungen zur Kenntnis genommen.