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

Aus DBWiki
Wechseln zu: Navigation, Suche

Aufgabenstellung

  1. Nach Ä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 das 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: http://www.dbwiki.net/
 
   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
   ElseIf lngret = vbCancel Then  'wenn "Abbrechen" gedrückt wird, Speichern verhindern
      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: http://www.dbwiki.net/
 
   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: http://www.dbwiki.net/
 
   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:
'Quelle: http://www.dbwiki.net/
 
Option Compare Database
Option Explicit
 
'Variable auf Formularebene deklarieren
Private 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()
 
   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.


Weblinks