VBA Tipp: Schließen des Formulars im Before-Update-Ereignis vermeiden

Aus DBWiki
Wechseln zu: Navigation, Suche

Aufgabenstellung

  1. Nach der Änderung von Daten in einem Formular soll der Benutzer dazu aufgefordert werden, zu entscheiden, ob er die Daten speichern oder verwerfen will, oder die Eingabe der Daten fortsetzen will. Dazu wird das Before-Update-Ereignis des Formulars verwendet.
  2. Erst nach dem Ausfüllen aller Pflichtfelder soll ein Formular geschlossen werden können. Dazu wird das Before-Update-Ereignis des Formulars in Verbindung mit einer eigenen "Schließen"-Schaltfläche verwendet.


Das Before-Update-Ereignis des Formulars wird ausgelöst, wenn ein geänderter Datensatz aktualisiert wird.
Das geschieht

  • beim Versuch, den Datensatz zu speichern, z.B. durch Klick auf den Datensatzmarkierer
  • beim Versuch, zu einem anderen Datensatz zu wechseln


Lösung 1: Überprüfung auf geänderte Daten

  • Im Before-Update-Ereignis des Formulars wird überprüft, ob Daten geändert wurden.
  • Der Benutzer wird über eine MsgBox gefragt, ob er die Änderungen speichern will.
    Folgende Antworten sind möglich:
    • Ja                 (geänderte Daten werden gespeichert)
    • Nein             (Änderungen werden rückgängig gemacht)
    • Abbrechen   (Dateneingabe wird fortgesetzt)
Private Sub Form_BeforeUpdate(Cancel As Integer)
 
 'Quelle: www.dbwiki.net oder www.dbwiki.de
 
 Dim lngret As Long
 
 lngret = MsgBox("Änderungen speichern?", vbYesNoCancel)
 
 'wenn "Nein" gedrückt wird, Änderungen rückgängig machen
 If lngret = vbNo Then
   Me.Undo
 'wenn "Abbrechen" gedrückt wird, Speichern verhindern
 ElseIf lngret = vbCancel Then
   Cancel = True
 End If
 
End Sub


Lösung 2: Überprüfung auf ausgefüllte Pflichtfelder

1. Im Before-Update-Ereignis des Formulars wird überprüft, ob alle Pflichtfelder ausgefüllt sind. Die Namen der Pflichtfelder werden - durch Komma getrennt - in ein Array eingelesen.

Private Sub Form_BeforeUpdate(Cancel As Integer)
 
 'Quelle: www.dbwiki.net oder www.dbwiki.de
 
 Dim strLeerfelder As String
 Dim strMeldung As String
 Dim Feldnamen() As Variant
 Dim varElement As Variant
 
 'Feldnamen (nicht Steuerelementinhalte) der Pflichtfelder in ein Array einlesen
 Feldnamen() = Array("Bestelldatum", "Lieferdatum", "Versanddatum")
 
 'Pflichtfelder auf Wert prüfen, und leere Felder auflisten
 For Each varElement In Feldnamen()
   If IsNull(Me(varElement).Value) Then
     strLeerfelder = strLeerfelder & "• " & varElement & vbCrLf
   End If
 Next
 
 If Not strLeerfelder = "" Then
   strMeldung = "Bitte folgende Pflichtfelder ausfüllen:" & vbCrLf
   strMeldung = strMeldung & strLeerfelder
   strMeldung = strMeldung & "oder alle Eingaben mit 'Abbrechen' verwerfen."
 
   If MsgBox(strMeldung, vbExclamation + vbOKCancel) = vbCancel Then
     Me.Undo
   Else
     Cancel = True
   End If
 
 End If
 
End Sub

2. Verwendung einer eigenen "Schließen"-Schaltfläche
Im Klick-Ereignis der eigenen "Schließen"-Schaltfläche wird folgender Code eingetragen.

Private Sub Schaltfläche_Schließen_Click()
 
 'Quelle: www.dbwiki.net oder www.dbwiki.de
 
 On Error GoTo Err_Schaltfläche_Schließen_Click
 
 ' Speicherversuch, wenn Daten geändert wurden. Löst das Before-Update-Ereignis aus.
 If Me.Dirty Then
   ' Wenn im Before-Update-Ereignis Cancel auf True steht (OK gedrückt),
   ' läuft der Speicher-Versuch in den Fehler 2501,
   ' und das Schließen des Formulars wird dadurch umgangen.
   DoCmd.RunCommand acCmdSaveRecord
 End If
 
 'Wenn im Before-Update-Ereignis Cancel auf False steht,
 '(alle Pflichtfelder wurden ausgefüllt, oder "Abbrechen" wurde gedrückt)
 'oder wenn das Before-Update-Ereignis gar nicht ausgelöst wurde,
 'wird das Formular geschlossen.
 DoCmd.Close
 
Exit_Schaltfläche_Schließen_Click:
 Exit Sub
 
Err_Schaltfläche_Schließen_Click:
 
 'Fehler 2501 - "Die Aktion RunCommand wurde abgebrochen"
 If Not Err.Number = 2501 Then
   MsgBox "Laufzeitfehler '" & Err.Number & "':" & vbCrLf & vbCrLf & Err.Description
 End If
 
 Resume Exit_Schaltfläche_Schließen_Click
 
End Sub


Erweiterte Möglichkeiten

  • Um das Schließen des Formulars über die systemeigene "Schließen"-Schaltfläche (x-Symbol) in der Menüleiste zu verhindern, kann man die Formulareigenschaft "Schließen Schaltfläche" auf 'Nein' stellen, so dass die systemeigene "Schließen"-Schaltfläche (x-Symbol) deaktiviert wird.
  • Um das Schließen des Formulars zusätzlich über die Tastenkombination Alt+F4 zu verhindern, muss obiger Code für die eigene "Schließen"-Schaltfläche folgendermaßen erweitert werden:
Option Compare Database
Option Explicit
 
'Variable auf Formularebene deklarieren
Dim bolSchließenErlaubt As Boolean
 
Private Sub Form_Unload(Cancel As Integer)
 
 If bolSchließenErlaubt = False Then
   Cancel = True
 End If
 
End Sub
 
Private Sub Schaltfläche_Schließen_Click()
 
 'Quelle: www.dbwiki.net oder www.dbwiki.de
 
 On Error GoTo Err_Schaltfläche_Schließen_Click
 
 ' Speicherversuch, wenn Daten geändert wurden. Löst das Before-Update-Ereignis aus.
 If Me.Dirty Then
   ' Wenn im Before-Update-Ereignis Cancel auf True steht,
   ' läuft der Speicher-Versuch in den Fehler 2501,
   ' und das Schließen des Formulars wird dadurch umgangen.
   DoCmd.RunCommand acCmdSaveRecord
 End If
 
 'Wenn im Before-Update-Ereignis Cancel auf False steht,
 '(alle Pflichtfelder wurden ausgefüllt, oder "Abbrechen" wurde gedrückt)
 'oder wenn das Before-Update-Ereignis gar nicht ausgelöst wurde,
 'wird das Formular geschlossen.
 bolSchließenErlaubt = True
 DoCmd.Close
 
Exit_Schaltfläche_Schließen_Click:
 Exit Sub
 
Err_Schaltfläche_Schließen_Click:
 
 'Fehler 2501 - "Die Aktion RunCommand wurde abgebrochen"
 If Not Err.Number = 2501 Then
   MsgBox "Laufzeitfehler '" & Err.Number & "':" & vbCrLf & vbCrLf & Err.Description
 End If
 
 Resume Exit_Schaltfläche_Schließen_Click
 
End Sub
Wiki hinweis.png

Hinweis zur erweiterten Lösung:

  • Da bei der erweiterten Lösung das Formular nur noch über die "Schließen"-Schaltfläche geschlossen werden kann, ist auch ein Wechsel von der Formularansicht in die Entwurfsansicht nicht mehr möglich.
  • Um in die Entwurfsansicht zu gelangen, muss das Formular aus dem Navigationsbereich (Datenbankfenster) in der Entwurfsansicht geöffnet werden.


Wiki hinweis.png

Allgemeiner Hinweis:

Um das unbeabsichtigte Verlassen eines Datensatzes mittels der TAB- oder ENTER-Taste zu verhindern, kann auch die Formulareigenschaft Zyklus auf Aktueller Datensatz eingestellt werden.


Web-Links