Registerkarten für verschiedene Datensätze

Normalerweise verwendet man verschiedene Registerkarten, um unterschiedliche Daten anzuzeigen – beispielsweise auf dem Hauptformular die Basis-Daten zu einem Kunden wie Kundennummer und Name und auf den Registerkarten Informationen wie die Lieferanschrift, die Rechnungsanschrift und weitere Daten. Wir wollen in diesem Beitrag einmal zeigen, wie Sie verschiedene Datensätze der gleichen Tabelle auf Registerseiten anzeigen – beispielsweise, um die letzten zehn angezeigten Kunden immer schnell aufschlagen zu können.

Damit wäre auch schon die Anzahl der zu verwendenden Registerseiten festgelegt – nämlich zehn. Irgendwann würde es nämlich mit steigender Anzahl von Registerreitern etwas unübersichtlich.

Wir wollen also ein Hauptformular erstellen, das hauptsächlich ein Registersteuerelement enthält, das auf seinen zehn Registerseiten jeweils das gleiche Unterformular mit Daten aus der Tabelle tblKunden der Beispieldatenbank anzeigt.

Da wäre nun noch zu klären, wie wir dafür sorgen, dass überhaupt ein Kundendatensatz dorthin gelangt. Am einfachsten wäre es, eine kleine Suchfunktion samt Ergebnisliste in Form eines Listenfeldes im Hauptformular unterzubringen. Per Doppelklick auf einen der Einträge im Listenfeld soll der gewählte Kunde dann auf der Registerseite ganz links erscheinen. Die übrigen Kunden im Registersteuerelement sollen dann, sofern bereits vorhanden, auf die Registerseiten rechts davon verschoben werden.

Sobald ein neuer Kunde ausgewählt wird, soll bei komplett gefüllten Registerseiten also der letzte Kunde rechts rausfallen. Die vollständige Lösung sieht dann später wie in Bild 1 aus.

Die fertige Lösung

Bild 1: Die fertige Lösung

Unterformular erstellen

Das Unterformular der Lösung soll sfmKunden heißen und die Tabelle tblKunden als Datenherkunft nutzen. Ziehen Sie alle Felder der Datenherkunft aus der Feldliste in den Detailbereich des Formulars und teilen Sie diese etwa wie in Bild 2 auf. Stellen Sie die Eigenschaften Bildlaufleisten, Navigationsschaltflächen, Datensatzmarkierer und Trennlinien auf den Wert Nein ein.

Das Unterformular sfmKunden

Bild 2: Das Unterformular sfmKunden

Kunden auswählen

Die Auswahl der Kunden soll per Doppelklick auf die Einträge eines Listenfeldes erfolgen. Dieses soll wiederum nach der Eingabe in ein einfaches Suchfeld gefiltert werden.

Dazu fügen Sie dem Hauptformular namens frmKundenregister zunächst ein Textfeld namens txtSuche und ein Listenfeld namens lstKunden zu.

Die Eigenschaften Datensatzmarkierer, Navigationsschaltflächen, Trennlinien und Bildlaufleisten des Formulars sollten den Wert Nein enthalten.

Für das Listenfeld hinterlegen Sie ebenfalls die Tabelle tblKunden als Datenherkunft. Das Listenfeld soll die ersten vier Felder der Datensatzherkunft enthalten, daher stellen Sie die Eigenschaft Spaltenanzahl auf den Wert 4 ein. Die Spaltenbreiten sind mit 0cm;2cm;6cm;6cm vernünftig ausgelegt. Die erste Spalte enthält ja nur das Primärschlüsselfeld, das als gebundene Spalte dienen soll – dieses braucht nicht sichtbar zu sein.

Bis hierhin sieht das Hauptformular im Entwurf wie in Bild 3 aus. Damit das Listenfeld nur solche Einträge anzeigt, die in einem der drei Felder Kundencode, Firma oder Kontaktperson den im Suchfeld txtSuche eingegebenen Ausdruck enthalten, legen wir für das Ereignis Bei änderung des Textfeldes eine entsprechende VBA-Prozedur an.

Das Hauptformular mit Such- und Listenfeld

Bild 3: Das Hauptformular mit Such- und Listenfeld

Diese sieht wie in Listing 1 aus und stellt zunächst einen geeigneten Suchausdruck in Form einer SELECT-Anweisung zusammen. Diese wird dann der Eigenschaft RowSource des Listenfeldes zugewiesen.

Private Sub txtSuche_Change()
     Dim strSuche As String
     Dim strSQL As String
     strSuche = txtSuche.Text
     strSQL = "SELECT * FROM tblKunden WHERE KundenCode Like ''*" & strSuche _
         & "*'' OR Firma LIKE ''*" & strSuche _
         & "*'' OR Kontaktperson LIKE ''*" & strSuche & "*''"
     Me!lstKunden.RowSource = strSQL
End Sub

Listing 1: Filtern des Listenfeldes nach dem im Suchfeld eingegebenen Ausdruck

Bild 4 zeigt die Suchfunktion mit dem entsprechenden Suchergebnis im Listenfeld.

Die Suchfunktion des Beispielformulars

Bild 4: Die Suchfunktion des Beispielformulars

Registersteuerelement anlegen

Damit kommen wir zum interessanten Teil und fügen zunächst ein neues Registersteuerelement zum Formular frmKundenregister hinzu. Dieses soll natürlich unter dem Listenfeld landen und die gleiche Breite wie dieses einnehmen. Das Registersteuerelement soll den Namen regKunden erhalten.

Nach dem Hinzufügen des Registersteuer-elements kommt das erste Unterformular an die Reihe. Genau genommen fügen wir dort zunächst einmal ein Unterformular-Steuerelement ein. Dazu klicken Sie auf den linken Registerreiter, dann auf die Schaltfläche zum Hinzufügen eines Unterformular-Steuerelements und fügen dieses dann schließlich in die erste Seite des Registersteuerelements ein.

Die Registerseite sollte dabei wie in Bild 5 schwarz hinterlegt erscheinen. Entfernen Sie dann das Bezeichnungsfeld und stellen Sie die Eigenschaft Name auf den Wert sfm01 ein (später werden wir noch weitere solcher Unterformulare einfügen). Anschließend ändern Sie die Eigenschaft Rahmenart des Unterformular-Steuerelements auf den Wert Transparent (s. Bild 6).

Hinzufügen des Unterformulars zur ersten Registerkarte

Bild 5: Hinzufügen des Unterformulars zur ersten Registerkarte

Der Rahmen des Unterformulars soll transparent erscheinen.

Bild 6: Der Rahmen des Unterformulars soll transparent erscheinen.

Kundendaten auf Registerseite anzeigen

Nun können wir uns um die Füllung des Unterformulars mit den Daten für den ersten im Listenfeld doppelt angeklickten Kunden-Datensatz kümmern. Legen Sie also für das Listenfeld eine Ereignisprozedur an, die durch das Ereignis Beim Doppelklicken ausgelöst wird.

Diese Prozedur sieht wie in Listing 2 aus und stellt zunächst die Beschriftung der ersten Registerseite des Registersteuerelements auf den Wert der Listenfeldspalte mit dem Index 2 ein, also der dritten Spalte. Diese liefert den Wert des Feldes Firma der Tabelle tblKunden.

Private Sub lstKunden_DblClick(Cancel As Integer)
     Me!regKunden.Pages(0).Caption = Me!lstKunden.Column(2)
     With Me!sfm01
         .SourceObject = "sfmKunden"
         .Form.RecordSource = "SELECT * FROM tblKunden WHERE KundeID = " & Me!lstKunden
     End With
End Sub

Listing 2: Anzeigen des angeklickten Kunden im Registersteuerelement

Danach folgen zwei Anweisungen, die sich mit dem Unterformular-Steuerelement beschäftigen: Die erste legt das Formular sfmKunden als das im Unterformular-Steuerelement anzuzeigende Objekt fest. Die zweite stellt die Datenherkunft für das Unterformular ein.

Dabei handelt es sich um eine SQL-Abfrage, die genau den Datensatz der Tabelle tblKunden liefert, den der Benutzer soeben im Listenfeld lstKunden doppelt angeklickt hat. Das Ergebnis sieht aktuell wie in Bild 7 aus.

Anzeige des soeben doppelt angeklickten Kunden-Datensatzes

Bild 7: Anzeige des soeben doppelt angeklickten Kunden-Datensatzes

Weitere Registerseiten füllen

Nun haben wir die erste Registerseite gefüllt. Dies funktioniert auch, wenn Sie danach andere Einträge des Listenfeldes anklicken. Allerdings fehlt noch die entscheidende Funktion: Nämlich das Verschieben des aktuell auf der ersten Registerseite angezeigten Kunden auf die zweite Seite, wenn die erste Seite einen neuen Kunden anzeigen soll.

Dazu wollen wir zunächst die Vorarbeiten erledigen – nämlich das Anlegen der übrigen neun Registerseiten samt Unterformular-Steuerelementen. Diese fügen Sie jeweils in die übrigen Registerseiten ein und benennen diese durchlaufend mit sfm02, sfm03 und so weiter bis sfm10.

Nachdem Sie geprüft haben, dass die Unterformular-Steuerelemente alle gleich ausgerichtet sind und die gleiche Größe haben, kümmern wir uns um den Code.

Hier ist zunächst zu beachten, dass das Registersteuerelement im Startzustand, also wenn der Benutzer noch keinerlei Kunden-Datensätze darin angezeigt hat, auch keine Daten anzeigen soll. Genau genommen wäre es praktisch, wenn der Benutzer per Bezeichnungsfeld darauf aufmerksam gemacht wird, dass er per Doppelklick einen Kunden im Unterformular anzeigen kann.

Vorher müssen wir uns allerdings noch überlegen, wie wir die zuletzt aufgerufenen Kundendatensätze überhaupt speichern, um diese später wiederherstellen zu können. Da diese Information sitzungsübergreifend verfügbar sein soll, speichern wir diese also einfach in einer Tabelle namens tblLetzteKunden. Diese Tabelle sieht im Entwurf wie in Bild 8 aus. Sie speichert neben dem Primärschlüsselwert, der benötigt wird, um die Reihenfolge des Anlegens zu dokumentieren, nur den Primärschlüsselwert des jeweiligen Datensatzes der Tabelle tblKunden. Damit jeder Kundendatensatz hier nur einmal vermerkt wird, stellen wir für das Feld LetzterKunde noch den Wert Ja (Ohne Duplikate) für die Eigenschaft Indiziert ein.

Tabelle zum Speichern der zuletzt angezeigten Kunden

Bild 8: Tabelle zum Speichern der zuletzt angezeigten Kunden

Damit eventuell gelöschte Datensätze aus der Tabelle tblKunden auch aus der Tabelle tblLetzteKunden entfernt werden, legen wir noch eine Beziehung zwischen den beiden Tabellen an und versehen diese mit referenzieller Integrität und Löschweitergabe (s. Bild 9).

Einrichten einer Löschweitergabe für die Kundentabellen

Bild 9: Einrichten einer Löschweitergabe für die Kundentabellen

Kunden über die Registerseiten verteilen

Damit begeben wir uns an eine neue Version der Ereignisprozedur lstKunden_DblClick (s. Listing 3). Diese speichert zunächst den Wert des Feldes Kunde-ID aus dem Listenfeld in der Variablen lngKundeID zwischen.

Private Sub lstKunden_DblClick(Cancel As Integer)
     Dim lngKundeID As Long
     Dim db As DAO.Database
     Dim rstLetzteKunden As DAO.Recordset
     Dim i As Integer
     Dim intGefuellt As Integer
     Set db = CurrentDb
     lngKundeID = Me!lstKunden
     db.Execute "DELETE FROM tblLetzteKunden WHERE LetzterKunde = " & lngKundeID, _
         dbFailOnError
     db.Execute "INSERT INTO tblLetzteKunden(LetzterKunde) VALUES(" & lngKundeID & ")", _
         dbFailOnError
     Set rstLetzteKunden = db.OpenRecordset("SELECT TOP 10 LetzterKunde " _
         "FROM tblLetzteKunden ORDER BY LetzterKundeID DESC", _
         dbOpenDynaset)
     Do While Not rstLetzteKunden.EOF
         Me!regKunden.Pages(intGefuellt).Visible = True
         Me!regKunden.Pages(intGefuellt).Caption = DLookup("Firma", "tblKunden", _
             "KundeID = " & rstLetzteKunden!LetzterKunde)
         intGefuellt = intGefuellt + 1
         With Me("sfm" & Format(intGefuellt, "00"))
             .SourceObject = "sfmKunden"
             .Form.RecordSource = "SELECT * FROM tblKunden WHERE KundeID = " _
                 & rstLetzteKunden!LetzterKunde
         End With
         rstLetzteKunden.MoveNext
     Loop
     For i = intGefuellt To 9
         Me!regKunden.Pages(i).Visible = False
         With Me("sfm" & Format(i + 1, "00"))
             .SourceObject = ""
         End With
     Next i
End Sub

Listing 3: Anzeigen der zuletzt gewählten Kunden auf verschiedenen Registerseiten

Dann löscht sie einen eventuell bereits vorhandenen Datensatz in der Tabelle tblLetzteKunden, da dieser im nächsten Schritt neu angelegt wird. Warum nicht einfach prüfen, ob ein solcher Datensatz vorhanden ist und diesen beibehalten Weil der zuletzt per Doppelklick ausgewählte Datensatz ja als aktuellster Datensatz gespeichert und ganz links im Registersteuerelement angezeigt werden soll. Dies erreichen wir am einfachsten über den Autowert-Primärschlüssel der Tabelle tblLetzteKunden: Ein neuer Datensatz erhält ja automatisch den höchsten Wert und wird so über die Sortierung nach dem Primärschlüsselwert als zuletzt gewählter Eintrag erkannt.

Danach erstellt die Prozedur ein Recordset auf Basis der Tabelle tblLetzteKunden, wobei sie die Daten absteigend nach dem Feld LetzterKundeID sortiert und nur zehn Datensätze liefert – mehr benötigen wir ja nicht, um die zehn Datensätze für die zehn Registerseiten zu ermitteln.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar