Zur Hauptseite ... Zum Onlinearchiv ... Zum Abonnement ... Zum Newsletter ... Zu den Tools ... Zum Impressum ... Zum Login ...

Achtung: Dies ist nicht der vollständige Artikel, sondern nur ein paar Seiten davon. Wenn Sie hier nicht erfahren, was Sie wissen möchten, finden Sie am Ende Informationen darüber, wie Sie den ganzen Artikel lesen können.

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 5/2010.

Unser Angebot für Sie!

Lesen Sie diesen Beitrag und 500 andere sofort im Onlinearchiv, und erhalten Sie alle zwei Monate brandheißes Access-Know-how auf 72 gedruckten Seiten! Plus attraktive Präsente, zum Beispiel das bald erscheinende Buch 'Access 2010 - Das Grundlagenbuch für Entwickler'!

Diesen Beitrag twittern

Zusammenfassung

Erfahren Sie, wie Sie Detailformulare aufrufen und zum Anlegen und Bearbeiten von Daten nutzen.

Techniken

Formulare, VBA

Voraussetzungen

Access 2000 und höher

Beispieldateien

UnterformularSteuern.mdb

Shortlink

www.access-im-unternehmen.de/742

Daten in Detailformularen anzeigen und bearbeiten

André Minhorst, Duisburg

Viele Anwendungen zeigen Daten in Haupt- und Unterformularen an, wobei das Unterformular Daten einfacher Tabellen enthält (etwa Adressen) oder Haupt- und Unterformular verknüpfte Daten darstellen (zum Beispiel Kunden und Projekte). Die Daten im Unterformular können dann zwar möglicherweise direkt an Ort und Stelle bearbeitet werden, aber wenn das im Unterformular dargestellte Objekt viele Felder enthält, sollten Sie dafür ein spezielles Detailformular bereitstellen. Mit diesem kann der Benutzer dann neue Datensätze anlegen und bestehende bearbeiten. In diesem Beitrag erfahren Sie, wie Sie ein solches Detailformular aufbauen und es für die verschiedenen Bearbeitungsarten einsetzen.

Das Zusammenspiel eines Formulars zur Anzeige der Übersicht der Datensätze einer Tabelle und eines weiteren Formulars zum Anlegen eines neuen Datensatzes oder zum Bearbeiten des jeweils in der Liste ausgewählten Datensatzes liefert eine Menge Herausforderungen:

  • Wie öffne ich das Detailformular?
  • Wie bringe ich es dazu, einen neuen Datensatz anzuzeigen?
  • Wie zeigt es gleich nach dem Öffnen einen Datensatz an, der im aufrufenden Formular markiert ist?
  • Wie sorge ich dafür, dass die Daten im aufrufenden Formular nach dem Schließen des Detailformulars aktualisiert werden?
  • Wie teile ich dem Detailformular den Wert des Fremdschlüsselfeldes mit, wenn ich einen neuen Datensatz anlegen möchte, der mit dem aktuell im Hauptformular angezeigten Datensatz verknüpft ist?

Diese und weitere Fragen beantwortet der vorliegende Beitrag.

Beispiele dieses Beitrags

In diesem Beitrag werden wir zwei verschiedene Beispiele betrachten: Im ersten zeigen Haupt- und Unterformular lediglich Adressdaten im Unterformular an, aber keine Daten im Hauptformular. Im zweiten Beispiel enthält das Hauptformular ebenfalls Daten, die per 1:n-Beziehung mit denen im Unterformular verknüpft sind. In diesem Fall kommt das gute, alte Beispiel der Projekte eines Kunden zum Einsatz: Das Hauptformular zeigt die Daten eines Kunden an, das Unterformular die der zu diesem Kunden gehörenden Projekte.

Die grundsätzliche Technik ist bei beiden Varianten gleich, bei der Version mit 1:n-Beziehung und Daten im Hauptformular kommt noch eine Feinheit hinzu.

Haupt- und Unterformular des ersten Beispiels heißen frmAdressenMitDetailformular und sfmAdressenMitDetailformular und sehen wie in Abb. 1 aus. Das Unterformular zeigt alle Felder der Tabelle tblAdressen in der Datenblattansicht an. Das Detailformular heißt frmAdresseDetails und basiert ebenfalls auf der Tabelle tblAdressen. Es sieht wie in Abb. 2 aus und bringt eine Kopfzeile im Kopfbereich sowie die Schaltflächen cmdOK und cmdAbbrechen im Fußbereich des Formulars unter.

pic001.png

Abb. 1: Übersicht der Adressen, die per Detailformular neu angelegt und bearbeitet werden sollen

pic002.png

Abb. 2: Formular zum Anlegen oder Bearbeiten einer Adresse

Später werden die Eigenschaften Trennlinien, Datensatzmarkierer, Navigationsschaltflächen und Bildlaufleisten sämtlich auf den Wert Nein eingestellt, vorerst benötigen wir jedoch zumindest noch die Navigationsschaltflächen, um Informationen über den beziehungsweise die aktuell angezeigten Datensätze zu erhalten.

Das Bezeichnungsfeld im Formularkopf heißt lblTitel und zeigt aktuell den Text Adresse bearbeiten an. Warum erhält ein Bezeichnungsfeld einen richtigen Namen? Normalerweise ändern wir diesen nie, weil wir kaum einmal per VBA auf Bezeichnungsfelder zugreifen. In diesem Fall soll das Bezeichnungsfeld jedoch je nach Art der Datenbearbeitung entweder den Titel Neue Adresse oder Adresse bearbeiten anzeigen.

Öffnen des Detailformulars zum Anlegen eines neuen Datensatzes

Wenn Sie einen neuen Datensatz anlegen möchten, klicken Sie im Formular frmAdressenMitDetailformular auf die Schaltfläche cmdNeu mit der Beschriftung Neue Adresse.

Die Schaltfläche soll nun das Formular frmAdresseDetail aufrufen und einen leeren, neuen Datensatz anzeigen. Dazu statten wir die Prozedur cmdNeu_Click, die wir durch Auswählen des Wertes [Ereignisprozedur] für die Eigenschaft Beim Klicken und anschließendes Anklicken der Schaltfläche mit den drei Punkten erzeugen, wie folgt mit einer einzigen Anweisung aus:

Private Sub cmdNeu_Click()

    DoCmd.OpenForm "frmAdresseDetail",

    WindowMode:=acDialog, DataMode:=acFormAdd

End Sub

Normalerweise würde die Anweisung DoCmd.OpenForm "frmAdresseDetail" ausreichen, um das Formular zu öffnen. In diesem Fall brauchen wir jedoch zwei weitere Parameter:

  • WindowMode:=acDialog legt fest, dass die Anweisung das Formular als modalen Dialog öffnet. Das bedeutet, dass der aufrufende Code nicht weiterläuft, bevor das aufgerufene Formular geschlossen oder unsichtbar gemacht wird. Wir werden später Code hinzufügen, der nach dem Schließen des Detailformulars die Adressenliste im aufrufenden Formular aktualisiert.
  • DataMode:=acFormAdd sorgt dafür, dass das Formular gleich nach dem Öffnen einen neuen, leeren Datensatz anzeigt. Gleichzeitig wird ein Filter gesetzt, damit in der aktuellen Ansicht tatsächlich nur ein neuer Datensatz angelegt und kein bestehender Datensatz bearbeitet werden kann.

Abb. 3 zeigt, wie dies aussieht. Der Datensatzmarkierer bestätigt, dass das Formular neben dem neuen, leeren Datensatz keine weiteren Datensätze enthält.

pic003.png

Abb. 3: Anlegen eines neuen Datensatzes über das Detailformular frmAdresseDetail

Sie können damit nun einen neuen Datensatz eingeben, aber was geschieht dann? Wir müssen zunächst die beiden Schaltflächen cmdOK und cmdAbbrechen mit Ereignisprozeduren ausstatten. Dies ist normalerweise sehr einfach. Die OK-Schaltfläche soll nur das Formular schließen, was die folgende Prozedur erledigt:

Private Sub cmdOK_Click()

    DoCmd.Close acForm, Me.Name

End Sub

Unter normalen Umständen wird der neue Datensatz, sofern einer angelegt wurde, nun gespeichert und das Formular geschlossen.

Die Abbrechen-Schaltfläche hingegen soll die Änderungen verwerfen und das Formular daraufhin schließen. Das Verwerfen der Änderungen erledigt die Undo-Methode des Formulars:

Private Sub cmdAbbrechen_Click()

    Me.Undo

    DoCmd.Close acForm, Me.Name

End Sub

Dummerweise kann man Änderungen nach dem erstmaligen Speichern des Datensatzes nicht mehr rückgängig machen - mehr dazu erfahren Sie gleich.

Beobachtungen im Detailformular

Wenn Sie das Detailformular über die Schaltfläche Neue Adresse geöffnet haben, zeigt die Navigationsleiste 1 von 1 an und die Schaltfläche zum Neuanlegen eines weiteren Datensatzes ist deaktiviert. Sofort nach dem Eingeben des ersten Zeichens in eines der Felder des Formulars ändert sich dies: Die Schaltfläche zum Anlegen eines neuen Datensatzes wird aktiviert. Sie können also nun einen neuen Datensatz anlegen, obwohl Sie den ersten noch gar nicht abgeschlossen haben.

Man sollte meinen, dass man dies durch Einstellen der Eigenschaft Anfügen zulassen des Formulars frmAdresseDetail auf den Wert Nein verhindern kann. Dies gelingt jedoch nur, wenn Sie das Formular ohne das Argument DataMode öffnen oder durch einen Doppelklick auf seinen Namen im Datenbankfenster beziehungsweise im Navigationsbereich. DataMode:=acFormAdd stellt diese Eigenschaft automatisch auf Ja ein, was auch logisch ist.

Wie aber können wir verhindern, dass der Benutzer mehr als einen Datensatz gleichzeitig eingibt, ohne das Formular erneut öffnen zu müssen? Wir nehmen ihm einfach die Möglichkeit, zu einem neuen Datensatz zu springen, indem wir die Navigationsleiste durch Einstellen der entsprechenden Eigenschaft auf den Wert Nein ausblenden.

Nun kann der Benutzer aber immer noch durch wiederholtes Betätigen der Tab- oder Eingabetaste durch die Steuerelemente navigieren. Wenn er sich auf dem letzten Steuerelement der Aktivierungsreihenfolge befindet und nochmals die Tab- oder Eingabetaste betätigt, landet er ebenfalls in einem neuen Datensatz. Aber auch dies können Sie verhindern: Dazu stellen Sie einfach die Eigenschaft Zyklus des Formulars auf Aktueller Datensatz ein. Der Fokus landet dann zwar auch wieder beim ersten Steuerelement der Aktivierreihenfolge, jedoch ohne den Datensatz zu wechseln. Sie können dies am besten beobachten, wenn Sie die Navigationsschaltflächen aktivieren und einmal alle Steuerelemente durchlaufen.

Anzeige der richtigen Überschrift

Eine weitere Beobachtung ist, dass das Formular frmAdresseDetail nun natürlich den Text Adresse bearbeiten als Beschriftung des Bezeichnungsfeldes lblTitle anzeigt, obwohl Sie ja gerade einen neuen Datensatz anlegen. Wir müssen also herausfinden, ob die DoCmd.OpenForm-Methode den Wert acFormAdd oder acFormEdit für den Parameter DataMode verwendet hat.

Es gibt sicher ein paar Workarounds, den direkten Weg liefert aber eine nicht dokumentierte und verborgene Eigenschaft namens DefaultEditing. Diese enthält in direkter Abhängigkeit vom Wert des Parameters DataMode einen der folgenden beiden Werte (es gibt noch weitere, die aber in diesem Zusammenhang irrelevant sind):

  • 1: Das Formular wurde mit DataMode:=acFormAdd geöffnet.
  • 2: Das Formular wurde mit DataMode:=acFormEdit geöffnet.

Im Code können wir uns dies in einer Ereignisprozedur zunutze machen, die durch das Ereignis Beim Laden des Formulars ausgelöst wird. Diese wertet die Eigenschaft DefaultEditing aus und weist der Caption-Eigenschaft von lblTitle den entsprechenden Wert zu:

Private Sub Form_Load()

    Select Case Me.DefaultEditing

        Case 1

            Me!lblTitel.Caption = "Neue Adresse anlegen"

        Case 2

            Me!lblTitel.Caption = "Adresse bearbeiten"

    End Select

End Sub

Gespeicherte Änderungen abbrechen?

Schließlich fällt uns beim spielerischen Ausprobieren des Formulars noch auf, dass die Abbrechen-Schaltfläche spätestens dann keinen Sinn mehr macht, wenn der Benutzer einen neu angelegten Datensatz erstmalig gespeichert hat, was er normalerweise mit einem Klick auf den Datensatzmarkierer oder durch den Wechseln zu einem anderen Datensatz erledigen kann. Ersteres gelingt nicht, wenn wir den Datensatzmarkierer mit der entsprechenden Eigenschaft ausblenden, das Zweite unterbinden wir mit der Zyklus-Eigenschaft.

Es bleibt allerdings noch die Möglichkeit, den Datensatz mit Strg + S zu speichern - da dies eine in vielen Anwendungen verbreitete Tastenkombination zum Speichern ist, werden manche Benutzer sie vielleicht automatisch hin und wieder einsetzen (der Autor spricht aus Erfahrung). Beim Speichern werden aber die beiden Ereignisse Vor Aktualisierung und Nach Aktualisierung ausgelöst. Hier könnten Sie schlicht dafür sorgen, dass die Abbrechen-Schaltfläche deaktiviert wird:

Private Sub Form_AfterUpdate()

    Me!cmdAbbrechen.Enabled = False

End Sub

Möglicherweise wird der Benutzer nicht verstehen, warum die Abbrechen-Schaltfläche plötzlich inaktiv ist. Daher sollten Sie beim Ereignis Vor Aktualisierung eine entsprechende Meldung anzeigen (s. Abb. 4):

pic004.png

Abb. 4: Diese Meldung erscheint beim Versuch, einen Datensatz zu speichern.

Private Sub Form_BeforeUpdate(Cancel As Integer)

    If MsgBox("Änderungen können nach dem Speichern nicht mehr mit Abbrechen oder " _

            & "Escape verworfen werden. Fortsetzen?", vbOKCancel + vbExclamation, _

            "Datensatz wird gespeichert") = vbCancel Then

        Cancel = True

    End If

End Sub

Wenn der Benutzer nun die Tastenkombination Strg + S betätigt, erscheint die Meldung. Beim Klicken auf OK wird der Datensatz gespeichert und in der Folge die Abbrechen-Schaltfläche des Formulars deaktiviert. Klickt der Benutzer auf die Abbrechen-Schaltfläche des Meldungsfensters, wird der Speichervorgang abgebrochen.

Beim reinen Einsatz eines Formulars zum Anlegen neuer Datensätze wäre es auch denkbar, dass man den Datensatz, wenn dieser bereits gespeichert wurde, beim Anklicken der Abbrechen-Schaltfläche einfach wieder löscht. In diesem Falle brauchte man die Abbrechen-Schaltfläche nach dem vorzeitigen Speichern des neuen Datensatzes auch nicht zu deaktivieren, da sie ja die erwartete Aufgabe erfüllt. Die Abbrechen-Schaltfläche müsste dann etwa folgende Prozedur ausführen (die Ereignisprozeduren für Vor Aktualisierung und Nach Aktualisierung müssten Sie dann verwerfen):

Private Sub cmdAbbrechen_Click()

    Select Case Me.DefaultEditing

        Case 1 'Neuer Datensatz

            If Me.Dirty Then

                Me.Undo

            Else

                Me.Recordset.Delete

            End If

        Case 2 'Datensatz bearbeiten

            Me.Undo

    End Select

    DoCmd.Close acForm, Me.Name

Sie haben das Ende des frei verfügbaren Teils des Artikels erreicht. Lesen Sie weiter, um zu erfahren, wie Sie den vollständigen Artikel lesen und auf viele hundert weitere Artikel zugreifen können.

Sind Sie Abonnent?Jetzt einloggen ...
 

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

© 2003-2015 André Minhorst Alle Rechte vorbehalten.