Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.
Unterformulare zeigen meist vom Hauptformular abhängige Daten in der Datenblattansicht an – beispielsweise die Projekte eines Kunden oder die Artikel einer Kategorie. Manchmal dient das Hauptformular aber auch nur der Steuerung des Zugriffs auf die Daten im Unterformular und liefert etwa eine Einfügen-, Detailansicht/Bearbeiten- oder Löschen-Schaltfläche für die Bearbeitung der im Unterformular angezeigten Datensätze. In diesem Beitrag zeigen wir, wie Sie ein solches Formular anlegen und die Steuerelemente zum Steuern des Unterformulars ausstatten.
Man kann nicht zwingend davon ausgehen, dass Benutzer wissen, wie sie mit den üblichen Navigationselementen eines Formulars in der Datenblattansicht umgehen müssen – also beispielsweise mit dem Datensatzmarkierer oder der Navigationsleiste. Manchmal macht man sich das Leben einfacher, wenn man lediglich entsprechende Schaltflächen bereitstellt, um etwa einen Datensatz zu löschen oder einen neuen anzulegen.
Was das Bearbeiten von Daten in der Datenblattansicht angeht, kommt es sehr auf die Art der Bearbeitung an: Wenn man wirklich schnell Zugriff auf ein paar Werte haben möchte, die über mehrere Datensätze verteilt sind, macht ein Bearbeiten in der Datenblattansicht durchaus Sinn.
Oftmals tut man dem Benutzer damit jedoch keinen Gefallen: Es kann nämlich schnell passieren, dass man gerade in sehr breiten Datenblattansichten einen Feldinhalt ändert, der zum falschen Datensatz gehört – dies geschieht umso öfter, je weiter das zu bearbeitende Feld am rechten Rand des Unterformulars liegt.
Was also tun Ganz einfach: Sie verwenden die Datenblattansicht einfach nur zum Betrachten, Durchsuchen und Sortieren der Daten und stellen für alle übrigen Aufgaben ein Detailformular zur Bearbeitung des jeweiligen Datensatzes zur Verfügung. Dieses zeigt immer nur einen Datensatz an und enthält eine OK– und eine Abbrechen-Schaltfläche, um änderungen im jeweils geöffneten Datensatz zu bestätigen oder zu verwerfen.
Um einen Datensatz der Datenblattansicht in diesem Detailformular anzuzeigen, fügen Sie dem Hauptformular eine Schaltfläche zum Anfügen eines neuen Datensatzes (dies öffnet das Detailformular mit einem leeren, neuen Datensatz) und eine zum Bearbeiten des aktuell markierten Datensatzes hinzu. Um das Angebot abzurunden, können Sie die beiden Schaltflächen noch um eine dritte ergänzen, die zum Löschen des aktuell markierten Datensatzes im Unterformular dient.
Damit offensichtlich ist, dass sich diese drei Schaltflächen auf die Daten im Unterformular beziehen, sollten Sie diese entsprechend positionieren. Nachdem Unterformulare meistens eher am unteren Rand des Hauptformulars landen und dieses noch darunter in der Regel die Schaltflächen zum Schließen des Hauptformulars selbst unterbringt, fällt dieser Ort weg. Sinnvoll ist daher beispielsweise die Anordnung der Schaltflächen zum Steuern des Unterformulars direkt über dem Unterformular.
Im ersten Beispiel verwenden wie eine ganz einfache Adresstabelle als Datenquelle für das Unterformular in der Datenblattansicht (s. Bild 1). AnredeID ist ein Fremdschlüsselfeld, das als Nachschlagefeld ausgelegt ist und die Daten der Tabelle tblAnreden anzeigt, die lediglich aus den beiden Feldern AnredeID und Anrede besteht.
Bild 1: Entwurf der Beispieltabelle tblAdressen
Haupt- und Unterformular erstellen
Als Erstes erstellen Sie ein Unterformular, das Sie unter dem Namen sfmAdressen speichern und dem Sie als Datenherkunft die Tabelle tblAdressen zuweisen.
Ziehen Sie dann alle Felder der Tabelle aus der Feldliste in den Detailbereich der Entwurfsansicht. Stellen Sie die Eigenschaft Standardansicht auf den Wert Datenblatt ein.
Schließen Sie das Unterformular und legen Sie das Hauptformular an. Dieses erhält den Namen frmAdressen. Ziehen Sie das Unterformular sfmAdressen in den Detailbereich der Entwurfsansicht des Formulars frmAdressen, sodass sich ein Bild wie in Bild 2 ergibt.
Bild 2: Entwurf des Hauptformulars mit eingebautem Unterformular
Stellen Sie außerdem die Eigenschaften Trennlinien, Datensatzmarkierer, Navigationsschaltflächen und Bildlaufleisten auf Nein sowie die Eigenschaft Automatisch zentrieren auf Ja ein – das Hauptformular zeigt ja keine eigenen Daten an, daher brauchen wir dafür auch keine Navigationselemente.
Neu und Löschen im Unterformular
Wir legen nun zunächst zwei Schaltflächen namens cmdNeu und cmdLoeschen mit den Beschriftungen Neue Adresse und Adresse löschen im Hauptformular gleich oberhalb des Unterformulars an.
Diese Schaltflächen sollen die angegebene Aktion gleich im Unterformular durchführen, also den Datensatzmarkierer entweder auf einem neuen, leeren Datensatz positionieren oder den aktuell markierten Datensatz löschen. Später schauen wir uns die Variante an, bei der das Anlegen und zusätzlich das Bearbeiten über ein Detailformular erfolgen.
Wenn der Benutzer auf die Schaltfläche Neue Adresse klickt, soll schlicht der Fokus auf einem neuen, leeren Datensatz landen. Legen Sie die folgende Ereignisprozedur für das Ereignis Beim Klicken der Schaltfläche cmdNeu an:
Private Sub cmdNeu_Click() Me!sfmAdressen.SetFocus DoCmd.GoToRecord Record:=acNewRec End Sub
Diese braucht zwei Schritte zum Erreichen des Ziels: Als Erstes setzt sie den Fokus auf das Unterformular-Steuerelement. Dies ist gleichbedeutend mit dem Setzen des Fokus auf das Formular im Unterformular-Steuerelement, was Sie mit dieser Anweisung erreichen würden (und was letztlich genauer ist):
Me!sfmAdressen.Form.SetFocus
Die zweite Anweisung springt zu einem neuen, leeren Datensatz – der Benutzer kann nun gleich mit dem Eingeben der Daten beginnen.
Beim Löschen eines Datensatzes ist das Prinzip ähnlich. Allerdings schalten wir hier noch eine Meldung vor, die sicherstellt, dass der Datensatz tatsächlich gelöscht werden soll. Falls ja, setzen wir ebenfalls den Fokus auf das Unterformular-Steuerelement und löschen den Datensatz dann mit der RunCommand-Methode des Application-Objekts unter Verwendung des Parameters acDeleteRecord:
Private Sub cmdLoeschen_Click() If MsgBox("Wirklich löschen", vbYesNo + vbExclamation, "Löschvorgang") = vbYes Then Me!sfmAdressen.SetFocus Application.RunCommand acCmdDeleteRecord End If End Sub
Sowohl beim Anlegen eines neuen als auch beim Löschen eines bestehenden Datensatzes kommen Methoden zum Einsatz, die das Betätigen bestimmter Elemente der Benutzeroberfläche durch den Benutzer nachbilden. SetFocus bildet den Mausklick des Benutzers in das Unterformular nach und GotoRecord und RunCommand DeleteRecord sind prinzipiell das VBA-Pendant entsprechender Menübefehle.
Wir wollen es etwas genauer machen und greifen nun direkt auf das Recordset-Objekt des Unterformulars zu. Die Prozedur zum Anlegen eines neuen Datensatzes sieht dann so aus:
Private Sub cmdNeu_Click() Me!sfmAdressen.Form.Recordset.AddNew End Sub
Das Recordset-Objekt enthält eine Referenz auf die Datensatzgruppe, die das Unterformular gerade anzeigt. Die AddNew-Methode springt zu einem neuen Datensatz dieser Datensatzgruppe.
Auch beim Löschen wollen wir den direkten Weg wählen:
Private Sub cmdLoeschen_Click() If MsgBox("Wirklich löschen", vbYesNo + vbExclamation, "Löschvorgang") = vbYes Then Me!sfmAdressen.Form.Recordset.Delete End If End Sub
Genau wie AddNew-Methode einen neuen Datensatz anlegt, löscht die Delete-Methode den aktuell markierten Datensatz.
Wir müssen hier noch eine kleine Sicherung einbauen, denn es kann passieren, dass der Benutzer erst einen neuen Datensatz anlegt und diesen dann gleich löschen möchte – ohne ihn vorher durch Wechseln zu einem anderen Datensatz, Betätigen von Strg + S oder eine andere Methode gespeichert zu haben.
In diesem Fall versucht er, einen physisch noch gar nicht vorhandenen Datensatz zu löschen, was zu einem Fehler führt. Wir prüfen also vor dem Löschen noch, ob überhaupt ein Datensatz markiert ist beziehungsweise ob der Datensatzzeiger sich gerade auf einem frisch angelegten, aber noch nicht gespeicherten Datensatz befindet. Diese Information liefert die NewRecord-Eigenschaft des Unterformulars:
Private Sub cmdLoeschen_Click() If Not Me!sfmAdressen.Form.NewRecord Then ''... Löschvorgang End If End Sub
Wenn der Benutzer nun auf die Löschen-Schaltfläche klickt, während er gerade einen neuen Datensatz anlegt, geschieht schlicht gar nichts.
Abhängige Löschen-Schaltfläche
Dies könnte den Benutzer irritieren: Immerhin ist die Schaltfläche aktiviert, löst aber keine Aktion aus. Besser wäre es, wenn eine Schaltfläche nur dann aktiviert ist, wenn sie auch etwas erledigt.
Wir müssen also eine Möglichkeit finden, die Löschen-Schaltfläche (und genau genommen auch die Neu-Schaltfläche) zu deaktivieren, wenn der Datensatzzeiger des Unterformulars auf einem neuen, noch nicht gespeicherten Datensatz steht.
Die einfachste Möglichkeit bietet das Ereignis Beim Anzeigen des Unterformulars, denn dieses wird immer dann ausgelöst, wenn der Datensatzzeiger zu einem anderen Datensatz springt.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
Testzugang
eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel
diesen und alle anderen Artikel mit dem Jahresabo