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.
Mehrere Datensätze pro Spalte in Formularen
Üblicherweise landen in einem Access-Formular entweder die Details eines Datensatzes oder mehrere Datensätze. Erstere können über das Formular verteilt werden, Letztere erscheinen untereinander in der Datenblattansicht oder der Endlosansicht. Mit einigen Unterformular-Steuerelementen lassen sich jedoch auch mehrere Datensätze nebeneinander anzeigen. Dieser Beitrag zeigt die Grundlagen zur Anzeige mehrerer Datensätze in einer Matrix von Unterformularen.
Grundlage für die Anzeige mehrerer Datensätze nebeneinander ist, dass Sie für jeden Datensatz ein Unterformular anlegen und diese dann nebeneinander anordnen. Die Datenherkünfte der Unterformulare müssen Sie dann noch so gestalten, dass diese jeweils den gewünschten Datensatz anzeigen. Wenn Sie also beispielsweise drei Kundendatensätze nebeneinander anzeigen wollen, müssten Sie dem ersten Unterformular den ersten Datensatz der Datenherkunft , dem zweiten den zweiten Datensatz und so weiter zuweisen.
Das Blättern in solchen Daten ist natürlich nicht mehr über die Bildlaufleiste möglich – dazu müssten Sie sich mit eigenen Steuerelementen wie etwa einer Nach oben- oder Nach unten-Schaltfläche behelfen. Natürlich könnte man auch die herkömmliche Bildlaufleiste nutzen, aber dann müsste das Formular so viele Unterformulare enthalten, dass alle Datensätze der Datenherkunft angezeigt werden können.
Mit steigender Datensatzanzahl sinkt hier die Performance, und auch die Anzahl der Unterformularsteuerelemente ist natürlich begrenzt. Also wollen wir es lieber bei einer vordefinierten Anzahl belassen und eigene Schaltflächen zum Blättern zwischen den Datensätzen verwenden. Das Ergebnis soll in der Rohfassung wie in Bild 1 aussehen. Das Hauptformular legen Sie als einfaches Formular mit der Bezeichnung frmKundenNebeneinander an und speichern dieses.
Bild 1: Unterformulare in mehreren Spalten zur Anzeige von Daten
Unterformulare hinzufügen
Im folgenden Beispiel wollen wir zwölf Unterformulare in drei Spalten und vier Zeilen anordnen. Die Unterformulare sollen die Bezeichnungen sfm01, smf02 und so weiter erhalten. Damit die Unterformulare korrekt positioniert und mit den richtigen Abmessungen ausgestattet werden, wollen wir diese mit einem kleinen Skript zum Hauptformular hinzufügen.
Dieses sieht wie in Listing 1 aus und ist in der Beispieldatenbank im Modul mdlTools zu finden. Die Prozedur erwartet einige Parameter, welche den Namen des mit Unterformularen auszustattenden Formulars sowie die Abmessungen für die Unterformularsteuerelemente enthalten. Dabei liefern intX und intY zunächst die Anzahl der anzulegenden Unterformulare je Zeile und Spalte. lngBreite und lngHoehe enthalten die Abmessungen, lngAbstandX und lngAbstandY den Abstand der Unterformulare untereinander und zum linken und oberen Rand des Formulars. Schließlich legen Sie mit strSubform, soweit gewünscht, noch den Wert der Eigenschaft Herkunftsobjekt (VBA: SourceObject) fest.
Public Sub UnterformulareAnlegen(strForm As String, intX As Integer, intY As Integer, lngBreite As Long, _
lngHoehe As Long, lngAbstandX As Long, lngAbstandY As Long, Optional strSubform As String)
Dim frm As Form
Dim ctl As Control
Dim i As Integer
Dim x As Integer
Dim y As Integer
On Error Resume Next
DoCmd.Close acForm, strForm
On Error GoTo 0
DoCmd.OpenForm strForm, acDesign
Set frm = Forms(strForm)
For i = frm.Controls.Count - 1 To 0 Step -1
Set ctl = frm.Controls(i)
Select Case ctl.ControlType
Case acLabel, acSubform
DeleteControl frm.Name, ctl.Name
End Select
Next i
i = 0
For y = 1 To intY
For x = 1 To intX
i = i + 1
Set ctl = CreateControl(frm.Name, acSubform, acDetail, , , lngAbstandX + (lngAbstandX + lngBreite) _
* (x - 1), lngAbstandY + (lngAbstandX + lngHoehe) * (y - 1), lngBreite, lngHoehe)
ctl.Name = "sfm" & Format(i, "00")
If Len(strSubform) > 0 Then
ctl.SourceObject = strSubform
End If
Next x
Next y
End Sub
Listing 1: Hinzufügen der Unterformulare zum Hauptformular
Für die Konstellation in der Beispieldatenbank haben wir den folgenden Aufruf der Prozedur zusammengestellt:
UnterformulareAnlegen "frmKundenNebeneinander", 3, 4, 4000, 3000, 100, 100, "sfmKundenNebeneinander"
Damit legt diese 3 x 4 Unterformularsteuerelemente an und füllt diese gleich mit dem Unterformular sfmKundenNebeneinander. Die Prozedur schließt zunächst das mit strForm übergebene Formular, sofern dieses noch geöffnet ist, und öffnet es erneut, diesmal in der Entwurfsansicht. Dann speichert es einen Verweis auf das Formular in der Variablen frm.
In einer For...Next-Schleife über alle im Formular enthaltenen Steuerelemente löscht sie dann alle bereits vorhandenen Unterformulare. Sie sollten die Routine also nicht für Formulare nutzen, die bereits für andere Zwecke vorgesehene Unterformulare enthalten, oder aber eine Prüfung einbauen, welche nur die in vorherigen Aufrufen angelegte Unterformularsteuerelemente löscht. Zum Löschen der Steuerelemente verwendet die Routine die DeleteControl-Methode, die den Namen des Formulars und des zu löschenden Steuerelements enthält.
Danach durchläuft die Prozedur zwei verschachtelte For...Next-Schleifen über die Werte von 1 bis intY beziehungsweise 1 bis intX. In der Schleife erhöht sie den Wert der Variablen i, die zuvor auf 0 eingestellt wurde, um 1. i soll die Nummer für den Steuerelementnamen (sfm01, sfm02 und so weiter) liefern. Nun folgt die Methode CreateControl, welche das eigentliche Steuerelement erstellt. Sie erwartet den Namen des Zielformulars, den Typ des zu erstellenden Steuerelements, den Zielbereich (hier den Detailbereich) sowie die Koordinaten und Abmessungen.
Die Abmessungen entnimmt die Routine den Parametern intHoehe und intBreite, die Koordinaten werden für jedes Steuerelement neu berechnet. Der Abstand vom linken Formularrand stammt dabei aus der Formel lngAbstandX + (lngAbstandX + lngBreite) * (x - 1). Im ersten Durchlauf ist x = 0, also ist der Abstand der mit lngAbstandX übergebene Wert. Für die folgenden Elemente, die natürlich rechts neben dem jeweils zuvor platzierten Element landen sollen, ermittelt die Routine die Position aus dem Abstand des ersten Elements vom linken Rand plus dem Produkt der Breite eines Elements plus dem einfachen Abstand und dem Index des Steuerelements. Auf die gleiche Art berechnet die Routine den Abstand vom oberen Formularrand.
Die Variable ctl speichert den Verweis auf das soeben erstellte Steuerelement. Damit weist die Routine noch den Namen für das Steuerelement zu. Wenn strSubform den Namen des Unterformulars enthält, der im Unterformularsteuerelement angezeigt werden soll, weist die Prozedur diesen der Eigenschaft SourceObject des Unterformularsteuerelements zu. Diesen Vorgang wiederholt die Prozedur, bis alle Zeilen und Spalten in den For...Next-Schleifen durchlaufen wurden. Das Ergebnis sieht zu diesem Zeitpunkt etwa wie in Bild 2 aus.
Bild 2: Frisch angelegte Unterformulare in der EntwurfsansichtUnterformular anlegen
Schließlich benötigen wir auch noch das Unterformular, das in den Unterformularsteuerelementen des Hauptformulars erscheinen und die verschiedenen Datensätze anzeigen soll. Die Herkunftstabelle heißt tblKunden und liefert einige Felder, die wir wie in Bild 3 im Unterformular sfmKundenNebeneinander anorden. Außerdem legen wir dort schon einmal eine Schaltfläche namens cmdLoeschen an, die später das Löschen des im Unterformular angezeigten Datensatzes erlauben soll.
Bild 3: Das Unterformular der BeispielanwendungWenn Sie nun das Hauptformular in der Formularansicht öffnen, zeigt dieses für jedes Unterformular den gleichen Datensatz an (s. Bild 4). Kein Wunder: Das Unterformular ist ja in allen Fällen genau gleich aufgebaut und zeigt dementsprechend auch die gleichen Daten an – zumindest, bis wir gleich mit einigen Zeilen Code eingreifen.
Bild 4: Gleicher Datensatz in allen Unterformularen
Unterformulare mit verschiedenen Datensätzen füllen
Die Unterformulare füllen wir gleich beim Öffnen des Hauptformulars, und zwar in der Ereignisprozedur, die durch das Ereignis Beim Laden ausgelöst wird (s. Listing 2). Diese Prozedur verwendet bereits einige Variablen, die wir modulweit im Kopf des Klassenmoduls Form_frmKundenNebeneinander deklarieren:
Private Sub Form_Load()
Dim intElemente As Integer
Dim j As Integer
Set db = CurrentDb
Set rst = db.OpenRecordset("SELECT * FROM tblKunden", dbOpenDynaset)
intStartdatensatz = 1
UnterformulareFuellen intElemente
Me!cmdNachUnten.Enabled = Not (intStartdatensatz + intElemente - 1 >= rst.RecordCount)
Me!cmdNachOben.Enabled = Not intStartdatensatz = 1
End Sub
Listing 2: Füllen der Unterformulare mit den gewünschten Datensätzen
Dim db As DAO.Database
Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.