Datenblätter liefern ausreichende Möglichkeiten zum Durchsuchen und Filtern ihrer Inhalte. Leider sind diese meist versteckt, sodass Otto Normalverbraucher üblicherweise erst mit der Nase darauf gestoßen werden muss. Viel schöner wäre es doch, wenn das Datenblatt über jeder Spalte ein entsprechendes Steuerelement zur Eingabe der gesuchten Werte enthielte. Schauen wir uns also an, welche Möglichkeiten es hier gibt und wie wir die auftretenden Klippen umschiffen.
Die Aufgabe, ein Datenblatt mit einer integrierten Leiste mit Suchfeldern zu erweitern, scheitert zuerst einmal an der Natur von Formularen, die Daten in der Datenblattansicht anzeigen: Sie zeigen nämlich außer dem reinen Datenblatt gar nichts an. Die gewünschte Suchleiste müsste also, zusammen mit dem Formular in der Datenblattansicht, in einem weiteren übergeordneten Formular angezeigt werden.
Schnellanleitung
Mit unserer Lösung aus diesem Beitrag realisieren Sie dies aber ganz schnell und flexibel. Und so geht es:
- Fügen Sie die Objekte frmSearchbar, clsDatasheetSearch und clsDatasheetSearchControl zur Zieldatenbank hinzu.
- Öffnen Sie das Formular mit dem Unterformular in der Datenblattansicht und fügen Sie darüber ein weiteres, flaches Unterformular-Steuerelement ein. Stellen Sie seine Eigenschaft Herkunftsobjekt auf frmSearchbar ein.
- Fügen Sie dem Hauptformular eine Prozedur hinzu, die durch das Ereignis Beim Laden ausgelöst wird und ändern Sie diese wie in Listing 1.
- Ersetzen Sie dabei <Unterformular> durch den Namen des Unterformular-Steuerelements mit dem Formular in der Datenblattansicht.
- Ersetzen Sie außerdem <Suchformular> durch den Namen des Unterformular-Steuerelements, dem Sie das Formular frmSearchbar zugewiesen haben. Achtung: Der Name des Unterformular-Steuerelements entspricht nicht zwangsläufig dem darin angezeigten Unterformular!
Listing 1: Mehr als dieser Code ist für den Betrieb der Suchleiste nicht notwendig.
Dim objDatasheetSearch As clsDatasheetSearch Private Sub Form_Load() Set objDatasheetSearch = New clsDatasheetSearch With objDatasheetSearch Set .DatasheetControl = Me!<Unterformular> Set .SearchformControl = Me!<Suchformular> End With End Sub
Such-Steuerelemente
Sie müssten also normalerweise die benötigten Steuerelemente – Textfelder, Kombinationsfelder und Kontrollkästchen – oberhalb des Unterformular-Steuerelements mit dem Unterformular in der Datenblattansicht einfügen. Diese werden dann in der entsprechenden Breite angelegt.
Die Suchfelder für normale Textfelder bleiben zunächst leer, die Suchfelder für Werte aus Kombinationsfeldern sollen ebenfalls als Kombinationsfelder ausgeführt werden. So kann der Benutzer einen der Einträge auswählen und damit die Datensätze des Unterformulars nach diesem Eintrag filtern (s. Bild 1).
Bild 1: Unterformular mit darüber liegenden Suchfeldern
Bei Kontrollkästchen im Unterformular müssen wir uns etwas einfallen lassen: Ein solches zeigt ja standardmäßig nur die Werte Wahr und Falsch an. Wir möchten aber auch die Möglichkeit bieten, sowohl Datensätze mit dem Feldinhalt Wahr als auch Falsch anzuzeigen.
Wenn dann als Suchsteuerelement ebenfalls ein Kontrollkästchen zum Einsatz kommt, ist dies nicht möglich. Also verwenden wir ein Kombinationsfeld, mit dem der Benutzer die drei Werte Alle, Wahr und Falsch auswählen kann.
Dementsprechend müssten auch die Steuerelemente zum Filtern von Datensätzen nach dem Inhalt von Kombinationsfeldern einen Eintrag namens <Alle> enthalten. Anderenfalls müsste der Benutzer das Kombinationsfeld von Hand leeren, was wenig intuitiv erscheint.
Datenblatt und fixe Suchfelder
Nun würden wir also ein Datenblatt aufbauen, es als Unterformular in ein anderes Formular integrieren und die gewünschten Suchsteuerelemente über den jeweiligen Spalten anordnen. Dies könnte wie in Bild 2 aussehen. Dann funktioniert die Suche aber auch nur solange, bis der Benutzer eine der folgenden Aktionen durchführt:
Bild 2: Zwei Unterformular für Suchfelder und Datenblatt
- Verändern der Spaltenbreite eines Feldes
- Vertauschen zweier Felder
- Ein-/Ausblenden von Feldern
- Scrollen des Datenblatts, wenn die Felder nicht gleichzeitig dargestellt werden können
All dies führt dazu, dass die Suchsteuerelemente nicht mehr richtig über den entsprechenden Feldern stehen. Fazit: Starr eingebaute Steuerelemente eignen sich nur für die Suche in Datenblattansichten, deren Layout nicht durch den Benutzer verändert werden kann.
Sprich: Für den Moment wirklich etwas zu langweilig. Wir wollen mehr!
Flexibles Such-Unterformular
Und zwar eine variabel einsetzbare Lösung, die nicht nur für ein einziges Datenblatt funktioniert, sondern möglichst für alle möglichen. Daher zunächst folgende Ideen:
- Die Steuerelemente zum Eingeben von Such-/Filterbegriffen sollen in einem eigenen Unterformular liegen, damit diese in verschiedenen Formularen eingesetzt werden können.
- Es sollen ausreichend Steuerelemente vorliegen, um auch breite Datenblatt-Unterformulare mit Suchfeldern ausstatten zu können. Also legen wir uns auf 20 fest, was auch breite Datenblätter abdecken sollte. Gegebenenfalls kann man dies auch erweitern.
- Dummerweise weiß man vorher nie, wieviele Textfelder, Kombinationsfelder und Kontrollkästchen das Datenblatt enthält. Also legen wir diese flexibel an: Je ein Textfeld, Kombinationsfeld und Kontrollkästchen für jedes Feld des Datenblatts, für 20 Spalten also immerhin 60 Steuerelemente. Wir blenden ein, was für das jeweilige Feld des Datenblatts benötigt wird.
- Beim Öffnen des Formulars soll Code das Datenblatt-Unterformular untersuchen und die entsprechenden Steuerelemente im Such-Unterformular ein-/ausblenden, auf die richtige Breite anpassen und gegebenenfalls mit Daten füllen (gilt nur für Kombinationsfelder und Kontrollkästchen).
- Wenn der Benutzer die Datenblatt-Konfiguration ändert, also etwa Spaltenbreiten anpasst, Spalten vertauscht, ein- oder ausblendet oder scrollt, müssen die Steuerelemente im Such-Unterformular angepasst werden. Wann und wie dies geschieht, erfahren Sie weiter unten im Detail.
Grundlage: Ausreichend Steuerelemente!
Das Unterformular mit den Such-Steuerelementen soll frmSearchbar heißen. Der Rest, also das Hauptformular und das Unterformular mit der Datenblattansicht, können nach Wunsch benannt werden – das Suchformular soll ohnehin dynamisch daran angepasst werden.
Bevor wir überhaupt mit der eigentlichen Programmierung der Lösung beginnen, statten wir das Unterformular mit den oben erwähnten 60 Steuerelementen für die Eingabe der Suchkriterien aus.
Erfreulicherweise brauchen Sie nicht einen Handschlag selbst durchzuführen, denn wir haben eine kleine Routine programmiert, die diese Aufgabe für uns erledigt.
Die Prozedur SuchleistenformularErstellen aus Listing 2 löscht zunächst ein eventuell vorhandenes Formular gleichen Namens und erstellt dann mit der CreateForm-Methode ein neues Formular. Dieses referenziert es dann mit der Objektvariablen frm und öffnet es in der Entwurfsansicht.
Listing 2: Anlegen des Suchformulars
Public Sub SuchleistenformularErstellen() ... On Error Resume Next DoCmd.DeleteObject acForm, "frmSearchbar" On Error GoTo 0 Set frm = Application.CreateForm strForm = frm.Name DoCmd.OpenForm frm.Name, acDesign For i = 1 To 20 Set txt = Application.CreateControl(frm.Name, acTextBox, acDetail) With txt .Name = "txt" & Format(i, "00") .Visible = False End With Set cbo = Application.CreateControl(frm.Name, acComboBox, acDetail) With cbo .Name = "cbo" & Format(i, "00") .Visible = False End With Set chk = Application.CreateControl(frm.Name, acComboBox, acDetail) With chk .Name = "chk" & Format(i, "00") .Visible = False .RowSourceType = "Value List" .RowSource = "''Alle'';''Wahr'';''Falsch''" End With Next i With frm .NavigationButtons = False .RecordSelectors = False .ScrollBars = False .DividingLines = False .HasModule = True End With DoCmd.Close acForm, frm.Name, acSaveYes DoCmd.Rename "frmSearchbar", acForm, strForm End Sub
Die Hauptarbeit führt dann eine Schleife mit 20 Durchläufen aus: Sie legt jeweils ein Steuerelement zum Eingeben von Filterkriterien für Textbox-, ComboBox– und Checkbox-Steuerelemente an und weist diesen durchnummerierte Namen wie txt01, cbo01 oder chk01 zu.
Die mit chk… benannten Steuerelemente sind jedoch, wie oben bereits beschrieben, keine Kontrollkästchen, sondern Kombinationsfelder, die lediglich zur Auswahl der Werte Alle, Wahr und Falsch dienen.
Alle Steuerelemente werden zunächst mit der Eigenschaft Visible auf Unsichtbar eingestellt. Nach dem Anlegen der Steuerelemente legt die Prozedur noch einige Eigenschaften für das Unterformular fest. So werden die Datensatzmarkierer, die Navigationsleiste, Bildlaufleisten und Trennlinien ausgeschaltet.
Außerdem wird mit HasModule = True ein Klassenmodul zum Formular hinzugefügt. Schließlich speichert die Routine das neue Formular und benennt es in frmSearchbar um.
Probieren Sie es aus – Formularerstellung per Mausklick! Die Steuerelemente würden, sorgfältig ausgerichtet, wie in Bild 3 aussehen.
Bild 3: Alle Steuerelemente des Formulars frmSearchbar
Klasseneinsatz
Den größten Teil des Codes dieser Lösung könnte man im Unterformular frmSearchbar unterbringen. Allerdings müssen auch die 60 Steuerelemente dieses Formulars Ereignisprozeduren besitzen, die etwa nach Eingabe oder änderung von Suchbegriffen ausgelöst werden.
Da zumindest jeweils 20 Steuerelemente identische Anweisungen aufrufen dürften, wollen wir aus Gründen der Wartbarkeit zwei Klassenmodule einführen.
Das erste heißt clsDatasheetSearch und enthält die wesentlichen Elemente der Steuerung des Suchformulars. Es greift auch durch das Datenblatt-Formular ausgelöste Aktionen – wie etwa das ändern der Spaltenbreiten oder -anordnung – auf und reagiert entsprechend darauf.
Die zweite Klasse heißt clsDatasheetSearchControl und wird für jedes der 60 Steuerelemente einmal instanziert. Diese Klasse enthält im Wesentlichen Ereignisprozeduren, die beim ändern der Suchbegriffe durch den Benutzer ausgelöst werden und in der Folge die angezeigten Datensätze im Datenblatt-Unterformular filtern sollen.
Black Box
Eigentlich können Sie die beiden Klassen als Black Box betrachten. Damit die Suchleiste funktioniert, brauchen Sie nämlich nur ganz wenige Aufgaben zu erledigen.
Sie fügen das Formular frmSearchbar zum Hauptformular hinzu, fügen darunter in der gleichen Breite das Formular mit der Datenblattansicht hinzu und legen einige Zeilen Code an.
Zunächst brauchen Sie eine Zeile, die eine Objektvariable für eine Instanz der Klasse clsDatasheetSearch aufnehmen kann:
Dim objDatasheetSearch As clsDatasheetSearch
Außerdem legen Sie für das Hauptformular eine Ereignisprozedur an, die durch das Ereignis Beim Laden ausgelöst wird und wie folgt aussieht:
Private Sub Form_Load() Set objDatasheetSearch = New clsDatasheetSearch With objDatasheetSearch Set .DatasheetControl = Me!sfmDatasheet Set .SearchformControl = Me!sfmSearchform End With End Sub
Diese instanziert das Objekt und stellt zwei seiner Eigenschaften ein. Der Eigenschaft DatasheetControl weisen Sie einen Verweis auf das Unterformularsteuerelement zur Anzeige der Datenblattansicht zu und der Eigenschaft SearchformControl einen Verweis auf das Unterformularsteuerelement mit dem Unterformular frmSearchbar.
Für beides ermitteln Sie zunächst den Namen des jeweiligen Unterformular-Steuerelements, etwa sfmDatasheet oder sfmSearchform, und weisen diese den Eigenschaften des Objekts objDatasheetSearch zu.
Innereien der Klasse clsDatasheetSearch
Natürlich wollen wir Ihnen an dieser Stelle die Funktionsweise der Klasse nicht vorenthalten – dies ist unabdingbar, wenn Sie eigene Feineinstellungen vornehmen möchten.