Home > Artikel > Ausgabe 4/2013 > Änderungen protokollieren, Teil I

Änderungen protokollieren, Teil I

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Textfelder sind das Hauptwerkzeug zur Eingabe von Daten. Sie können diese an die Felder der Datenherkunft eines Formulars binden oder diese ungebunden einsetzen. So intuitiv Textfelder zu benutzen sind, soviele Möglichkeiten und Fallstricke bieten sie auch. Dieser Artikel zeigt, was alles bei der Eingabe von Daten mit Textfeldern geschieht und wann welche Texte wo gespeichert werden.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1304_AenderungenProtokollieren.mdb.

Warum protokollieren?

Änderungen an Datensätzen sind in der Regel unumkehrbar, wenn der Datensatz einmal gespeichert ist. Solange dies noch nicht geschehen ist und Sie einfach nur die Werte eines oder mehrerer Felder aktualisiert haben, lässt sich dies noch rückgängig machen – beispielsweise durch Betätigen der Escape-Taste.

Anderenfalls können Sie nach einer Fehleingabe nur hoffen, dass Sie den vorherigen Zustand des Datensatzes wiederherstellen können – oder dass eine Sicherungskopie noch den gewünschten Stand enthält. Wenn Sie dem vorbeugen möchten, können Sie die Änderungen an Datensätzen auch protokollieren. Dabei gibt es zwei Varianten:

  • Sie speichern die Änderung eines jeden Feldes als eigenen Datensatz in einer Tabelle, welche den Namen der betroffenen Tabelle und des Feldes, den alten und den neuen Wert, den betroffenen Datensatz sowie das Änderungsdatum und gegebenenfalls den ausführenden Benutzer speichert.
  • Sie legen für jede Tabelle, für die Sie Änderungen protokollieren möchten, eine Kopie an. Vor einer Änderung übertragen Sie den vorherigen Zustand in diese Tabelle – auch hier wieder mit dem Datum der Änderung und dem Namen der ausführenden Person.

In diesem Artikel schauen wir uns beide Varianten an.

Formularereignisse als Ausgangspunkt

Während es etwa unter dem SQL Server Trigger gibt, denen Sie Code zum Protokollieren von Änderungen zuweisen können, müssen Sie in reinen Access-Datenbanken (also solchen, die ihre Daten wiederum in einer Access-Datenbank speichern – egal, ob in einer einzigen Datei oder aufgeteilt in Frontend und Backend) entsprechende Ereignisprozeduren zu den Formularen hinzufügen, in welchen die Änderungen durchgeführt werden.

In den meisten Fällen werden Sie die Änderungen beim Speichern des Datensatzes protokollieren. Der richtige Zeitpunkt ist das Ereignis Vor Aktualisierung des Formulars. Es wird unmittelbar vor dem Speichern ausgelöst – und vor dem Ereignis Nach Aktualisierung.

Der Vorteil des Ereignisses Vor Aktualisierung ist: Sie können zu diesem Zeitpunkt sowohl auf den vorherigen als auch auf den aktuellen Wert eines Feldes der Datenherkunft zugreifen – und zwar über die Eigenschaften OldValue und Value (weitere Informationen hierzu finden Sie im Artikel Textfelder: Value, OldValue und Text.

Was soll protokolliert werden?

Die Protokollierung soll so erfolgen, dass alle zur Kontrolle und sogar zur Wiederherstellung der geänderten Daten notwendigen Informationen gespeichert weden. Dazu legen Sie eine Tabelle namens tblAenderungen an, die im Entwurf wie in Bild 1 aussieht.

Die Tabelle tblAenderungen in der Entwurfsansicht

Bild 1: Die Tabelle tblAenderungen in der Entwurfsansicht

Dabei kommen die folgenden Felder zum Einsatz:

  • AenderungID: Primärschlüsselfeld der Tabelle
  • Tabelle: Name der Tabelle, deren Datensatz geändert wurde
  • Aktion: Wir wollen nicht nur Änderungen, sondern auch das Anlegen oder Löschen von Datensätzen dokumentieren. Dieses Feld soll die Werte New, Edit und Delete aufnehmen.
  • Feld: Name des geänderten Feldes
  • PKName: Name des Primärschlüsselfeldes der betroffenen Tabelle
  • PKWert: Wert des Primärschlüsselfeldes des geänderten Datenatzes
  • Zeit: Datum und Uhrzeit der Änderung
  • Benutzer: Aktueller Benutzer zum Zeitpunkt der Änderung
  • AlterWert: Wert des Feldes vor der Änderung
  • NeuerWert: Wert des Feldes nach der Änderung

Diese Art der Protokollierung erzeugt natürlich eine Menge Daten: Es wird tatsächlich zu jedem geänderten Feld ein eigener Datensatz in der Tabelle tblAenderungen angelegt.

Wenn wir nun im Formular frmArtikel beispielsweise den Wert des Feldes Artikelname von Chai in Chai (Tee) ändern, soll die Tabelle einen Datensatz wie in Bild 2 erhalten.

Die Tabelle tblAenderungen mit einer ersten Änderung

Bild 2: Die Tabelle tblAenderungen mit einer ersten Änderung

Nun benötigen wir nur noch eine Ereignisprozedur, die genau dies erledigt.

Änderung in Tabelle schreiben

Wir gehen zunächst vereinfachend davon aus, dass wir nur Änderungen am Feld Artikelname in der Tabelle speichern möchten. Dazu legen Sie für das Ereignis Vor Aktualisierung des Formulars die folgende Ereignisprozedur an:

Private Sub Form_BeforeUpdate(Cancel As Integer)

     Dim db As DAO.Database

     Dim rst As DAO.Recordset

     Set db = CurrentDb

     Set rst = db.OpenRecordset("SELECT * FROM tblAenderungen WHERE 1 = 2", dbOpenDynaset)

     If Not Me!txtArtikelname.Value = _

             Me!txtArtikelname.OldValue Then

         rst.AddNew

         rst!Tabelle = "tblArtikel"

         rst!Aktion = "Edit"

         rst!Feld = "Artikelname"

         rst!PKName = "ArtikelID"

         rst!PKWert = Me!ArtikelID

         rst!Zeit = Now

         rst!Benutzer = CurrentUser

         rst!AlterWert = Me!txtArtikelname.OldValue

         rst!NeuerWert = Me!txtArtikelname.Value

         rst.Update

     End If

     Set db = Nothing

End Sub

Diese Ereignisprozedur erstellt ein Recordset auf Basis der Tabelle tblAenderungen, das allerdings wegen des Kriteriums (1=2) keinen einzigen Datensatz enthält. Dies ist auch nicht nötig, denn wir wollen ja nur einen neuen Datensatz hinzufügen.

Der Übersichtlichkeit halber legen wir diesen Datensatz zunächst mit der AddNew-Methode an und weisen alle Feldwerte einzeln zu. Die meisten Zuweisungen sind selbsterklärend. Die Zeit wird mit der Funktion Now ermittelt, der aktuelle Access-Benutzer mit CurrentUser (hier könnte man noch den aktuellen Windows-Benutzer referenzieren – zumindest da Access seit der Version 2007 das Sicherheitssystem nicht mehr unterstützt). Den alten und den neuen Wert des gebundenen Steuerelements erhalten wir mit den Eigenschaften OldValue und Value.

Alle Felder protokollieren

Steigen wir nun einen Schritt weiter in die Änderungsprotokollierung ein, indem wir nicht nur eines, sondern gleich alle Felder protokollieren, die das Formular frmArtikel anzeigt.

Dazu erweitern wir die Ereignisprozedur Form_BeforeUpdate wie folgt:

Private Sub Form_BeforeUpdate(Cancel As Integer)

     Dim db As DAO.Database

     Dim rst As DAO.Recordset

     Dim ctl As Control

     Dim strControlsource As String

     Set db = CurrentDb

     Set rst = db.OpenRecordset("SELECT * FROM tblAenderungen WHERE 1 = 2", dbOpenDynaset)

     For Each ctl In Me.Controls

         strControlsource = ""

         On Error Resume Next

         strControlsource = ctl.ControlSource

         On Error GoTo 0

         If Len(strControlsource) > 0 Then

             If Not ctl.Value = ctl.OldValue Then

                 rst.AddNew

                 rst!Tabelle = "tblArtikel"

                 rst!Aktion = "Edit"

                 rst!Feld = ctl.ControlSource

                 rst!PKName = "ArtikelID"

                 rst!PKWert = Me!ArtikelID

                 rst!Zeit = Now

                 rst!Benutzer = CurrentUser

                 rst!AlterWert = ctl.OldValue

                 rst!NeuerWert = ctl.Value

                 rst.Update

             End If

         End If

     Next ctl

     Set db = Nothing

End Sub

Die Prozedur erhält zunächst eine neue Variable namens ctl. Mit dieser Variablen können Sie sämtliche Access-Steuerelemente referenzieren. Nach dem Erstellen des Recordsets, dem die Prozedur die Änderungsinformationen hinzufügen soll, startet die Prozedur eine Schleife über alle Steuerelemente des Formulars.

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!