Datenmakros in Access 2010

Seit Jahren wünscht die Access-Entwicklergemeinde sich Trigger. Damit legt man gleich im Tabellenentwurf fest, was geschieht, wenn ein Benutzer Datensätze anlegt, bearbeitet oder löscht. Doch diese nützlichen Helferlein blieben den Entwicklern von Systemen wie SQL Server, MySQL und Co. vorbehalten. Mit Access 2010 tut sich jedoch etwas in diesem Bereich: Mit den Datenmakros will Microsoft Trigger auch für Access verfügbar machen. Wir schauen uns an, was dabei herausgekommen ist.

Sinn und Zweck von Datenmakros

Genau wie Trigger in anderen Datenbankmanagementsystemen sollen Datenmakros ausgelöst werden, wenn der Benutzer eine der folgenden Aktionen durchführt:

  • Nach dem Anlegen eines Datensatzes
  • Vor dem ändern eines oder mehrerer Felder eines Datensatzes
  • Nach dem ändern eines Datensatzes
  • Vor dem Löschen eines Datensatzes
  • Nach dem Löschen eines Datensatzes

Nun wissen wir zwar, wann Datenmakros ausgelöst werden, aber wofür kann man diese Objekte denn nun gebrauchen Der einfachste Anwendungsfall ist wohl das Protokollieren von änderungen an den Daten einer Tabelle. Sicher kennen Sie Varianten von Tabellen, die Felder wie ErstelltAm, ErstelltDurch, GeaendertAm, GeaendertDurch, GeloeschtAm und GeloeschtDurch enthalten.

Deren Inhalte können natürlich nur dann automatisch geändert werden, wenn die änderungen selbst ein entsprechendes Ereignis auslösen. Bislang hat man sich dabei damit beholfen, dass man davon ausging, dass Benutzer die Daten einer Tabelle nur über ein Formular ändern und niemals direkt auf die Tabelle zugreifen.

In Formularen gibt es schließlich Ereigniseigenschaften, welche entsprechende Prozeduren auslösen können. Dort bringt man dann Code unter, der dafür sorgt, dass die Felder zur änderungsprotokollierung auf dem aktuellsten Stand gehalten werden.

Das Problem dabei ist nur, dass es sehr viele Möglichkeiten gibt, den Inhalt einer Tabelle zu ändern. Der Benutzer kann dies direkt über ein an die Tabelle gebundenes Formular erledigen oder ein Ereignis kann Code zum Aktualisieren der Tabelle via DAO, ADODB oder direkt per SQL-Anweisung auslösen.

Schließlich gibt es auch noch Aktionsabfragen, die Datensätze anlegen, ändern oder löschen können. Dies alles macht deutlich, dass der Entwickler an einer ganzen Reihe von Stellen dafür sorgen muss, dass änderungen auch wirklich protokolliert werden.

Wenn Sie die Tabellen beispielsweise in einer SQL Server- oder MySQL-Datenbank speichern, ist dies viel einfacher: Sie können dort Trigger anlegen, die bei jeder Datenänderung ausgelöst werden. Für jeden Trigger definieren Sie, was dieser erledigen soll – in diesem Fall die änderungsinformationen in die Tabelle eintragen.

Nun aber sollen die sogenannten Datenmakros die Aufgabe der Trigger auch in Access-Tabellen übernehmen. Schauen wir uns also an, wie dies funktioniert.

Datenmakros verwalten

Die Datenmakros von Access 2010 bearbeiten Sie in der Entwurfsansicht der jeweiligen Tabelle. Die notwendigen Befehle finden Sie im Ribbon-Bereich Entwurf|Feld-, Datensatz- und Tabellenereignisse. Dort lassen sich Datenmakros erstellen sowie löschen oder umbenennen (s. Bild 1).

pic001.png

Bild 1: Datenmakros legen Sie in der Entwurfsansicht einer Tabelle an.

Wir wollen zunächst für alle möglichen Aktionen ein Datenmakro anlegen, das einfach nur mitteilt, durch welche Aktion es jeweils ausgelöst wurde. Für das Datenmakro Nach Einfügung soll so beispielsweise ein Meldungsfenster erscheinen, das uns informiert, dass soeben ein Datensatz eingefügt wurde. ähnliche Datenmakros legen wir für alle fünf verfügbaren Datenaktionen an.

Definition von Datenmakros

Datenmakros haben genau die gleiche Syntax wie herkömmliche Makros. Diese wurden unter Access 2010 deutlich überarbeitet. Die Neuerungen bezüglich dieses Objekttyps finden Sie im Detail im Beitrag Makros in Access 2010 (www.access-im-unternehmen.de/759).

Trotz der gleichen Syntax verwenden Datenmakros nur ganz wenige der in herkömmlichen Makros vorkommenden Aktionen. Dafür gibt es eine ganze Reihe spezieller Aktionen wie AuslösenFehler, DatensatzBearbeiten oder ProtokollierenEreignis (s. Bild 2).

pic002.png

Bild 2: Für Datenmakros stehen andere Aktionen zur Verfügung als für normale Makros.

Unser Plan, beim Anlegen eines Datensatzes eine Meldung auszugeben, fällt somit ins Wasser: Das Ausgeben von Meldungen ist in Datenmakros nicht vorgesehen. Dafür gibt es eine Aktion namens ProtokollierenEreignis – mal sehen, was wir damit anstellen können. Wir legen also ein erstes Datenmakro an, das beim Anlegen eines Datensatzes in der Tabelle tblKunden ein Ereignis protokolliert.

Dort tragen wir den folgenden Ausdruck ein (s. Bild 3):

pic003.png

Bild 3: Dieser Ausdruck soll beim Anlegen eines neuen Datensatzes protokolliert werden.

="Datensatz angelegt am " & Datum()

Nach dem Wechsel in die Datenblattansicht und dem Anlegen eines neuen Datensatzes geschieht nichts. Der Datensatz wird wie gewohnt angelegt, aber wenn dies protokolliert wird, erfolgt dies in aller Heimlichkeit. Das ist aber auch gut so: Wer will schon beim Anlegen, ändern oder Löschen eines Datensatzes immer darauf hingewiesen werden, was er soeben getan hat.

Wenn man sich nicht drum kümmert, stößt man vielleicht beim nächsten Besuch des Datei-Tabs auf die neue Schaltfläche Anwendungsprotokolltabelle anzeigen (s. Bild 4).

pic004.png

Bild 4: Das Anwendungsprotokoll lassen Sie sich über diesen Menüpunkt im Backstage-Bereich anzeigen.

Ein Klick auf diese Schaltfläche öffnet die Tabelle USysApplicationLog – eine Art Systemtabelle, die beim ersten Protokollieren eines Datenmakros angelegt wird und im Datenbankfenster nur angezeigt wird, wenn die Option Systemtabellen anzeigen aktiviert ist.Im Gegensatz zu den übrigen Systemtabellen können Sie aber die enthaltenen Daten ändern und sogar die komplette Tabelle löschen, wenn Sie die gespeicherten Daten nicht mehr benötigen.

Diese Tabelle zeigt beispielsweise an, welches Objekt den Eintrag verursacht hat (hier das AfterInsert-Datenmakro der Tabelle tblKunden), ob es einen Fehler gab und wann der Eintrag stattfand. Außerdem finden wir unseren Protokolltext wieder, und zwar im Feld Description.

Wenn ein Datenmakro einen Fehler auslöst, wird dieser übrigens auch in dieser Tabelle gespeichert; in diesem Fall landet der Fehlertext im Feld Description (s. Bild 5).

pic005.png

Bild 5: Diese Tabelle speichert bei der Durchführung von Datenmakros anfallende Meldungen.

Makros in der Datenblattansicht ändern

Wenn Sie die Option Aktuelle Datenbank|Anwendungsoptionen|Entwurfsänderungen für Tabellen in der Datenblattansicht aktivieren eingeschaltet haben, können Sie Datenmakros sogar in der Datenblattansicht von Tabellen ändern.

Auch wenn wir normalerweise gegen das ändern des Tabellenentwurfs in der Datenblattansicht sind, spart das Bearbeiten der Datenmakros in dieser Ansicht doch das lästige Hin- und Herschalten zwischen Entwurf und Datenblatt.

Sie finden die entsprechenden Schaltflächen zum Anlegen beziehungsweise Bearbeiten der Datenmakros im Ribbon-Tab Tabelle (s. Bild 6).

pic006.png

Bild 6: Wenn bereits ein Datenmakro für eine Tabelle hinterlegt ist, wird die Schaltfläche zum Aufrufen dieses Makros farblich hervorgehoben.

Dort werden bereits vorhandene Datenmakros übrigens farbig hervorgehoben.

Die Aktionen der Datenmakros

Werfen wir nun einen Blick auf die verschiedenen Aktionen der Datenmakros. Die Aktion ProtokollierenEreignis haben wir ja bereits ansatzweise kennengelernt. Interessant sind hier noch die verschiedenen Parameter.

Wenn Sie wie in Bild 7 die Liste der möglichen Elemente mit der Tastenkombination Strg + Leertaste aufklappen, finden Sie beispielsweise sämtliche Feldnamen der aktuellen Tabelle, aber auch die VBA-Funktionen in der jeweiligen Landessprache vor. Zusätzlich gibt es ein paar datenmakro-spezifische Elemente, von denen zunächst die folgenden beiden interessant sind:

pic007.png

Bild 7: Über die Feldnamen greifen Sie auf die Werte des aktuellen Datensatzes zu.

  • Alt: Erlaubt den Zugriff auf die vor der änderung gültigen Feldwerte, Beispiel: Alt.KundeID. Nur sinnvoll in den Datenmakros Nach Aktualisierung und Nach Löschung.
  • MacroError: Liefert Informationen über eventuell aufgetretene Fehler.

Datenblöcke

Neben diesen Elementen gibt es einige sogenannte Datenblöcke. Diese repräsentieren einige Standardabläufe, die normalerweise mit DAO oder ADODB programmiert werden. Die vier Datenblöcke lauten (englische Bezeichnungen in Klammern, falls Sie mit der englischen Version von Access arbeiten sollten):

  • DatensatzBearbeiten (EditRecord): Entspricht dem Öffnen eines Datensatzes zur Bearbeitung unter Angabe der zu ändernden Felder.
  • DatensatzErstellen (CreateRecord): Entspricht dem Anlegen eines neuen Datensatzes mit AddNew und dem anschließenden Zuweisen von Feldwerten.
  • FürJedenDatensatz (ForEachRecord): Repräsentiert die Do While-Schleife für das Durchlaufen eines Recordset-Objekts.
  • NachschlagenDatensatz (LookupRecord): Ermittelt einen einzigen Datensatz, dessen Feldinhalte im Anschluss etwa mit DatensatzBearbeiten geändert werden können.

Datenaktionen

Den größten Teil der Elemente machen die Datenaktionen aus. Einige von ihnen können immer ausgeführt werden, andere nur in bestimmten Zusammenhängen:

  • AbbrechenDatensatzänderung (UndoRecord): Kann nur in den Datenblöcken DatensatzErstellen und DatensatzBearbeiten verwendet werden, um die aktuellen änderungen zu verwerfen.
  • AusführenDatenmakro (RunDataMacro): Führt ein anderes Datenmakro aus.
  • AuslösenFehler (RaiseError): Dies löst einen Fehler aus, der entweder in die Anzeige einer Fehlermeldung mündet oder aber etwa unter VBA entsprechend behandelt werden kann.
  • BeendenFürJedenDatensatz (ExitForEachRecord): Beendet eine FürJedenDatensatz-Schleife.
  • BeiFehler (OnError): Fehlerbehandlung. Gibt an, ob Fehler übergangen oder behandelt werden sollen beziehungsweise welches Makro im Falle eines Fehlers aufgerufen werden soll.
  • DatensatzLöschen (DeleteRecord): Löscht den aktuellen Datensatz.
  • FestlegenFeld (SetField): Hiermit legen Sie einen Feldwert fest. Dabei verwenden Sie die beiden Parameter Feldname und Feldwert.
  • FestlegenLokaleVar (SetLocalVar): Hiermit legen Sie eine Variable fest, die innerhalb des aktuellen Makros weiterverwendet werden kann. Ein Beispiel ist das Merken der ID eines neu angelegten Datensatzes, um später auf diesen Datensatz zuzugreifen.
  • LöschenMakroFehler (ClearMacroError): Leert das MacroError-Objekt, das Informationen zum zuletzt aufgetretenen Fehler enthält.
  • SendenEMail (SendEmail): Versendet eine E-Mail bei einem der Ereignisse Nach Einfügung, Nach Aktualisierung oder Nach Löschung. Dies geschieht jedoch nicht standardmäßig im stillen Kämmerlein, sondern es erscheint eine Meldung, die auf einen eventuellen Missbrauch von Outlook hinweist.
  • StoppAlleMakros (StopAllMacros): Beendet alle laufenden Makros.
  • StoppMakro (StopMacro): Beendet das aktuelle Makro.

Beispielanwendung: änderungshistorie

Für die Beispielanwendung erweitern wir die Tabelle tblKunden um die drei Felder AngelegtAm, GeaendertAm und GeloeschtAm. Je nach änderung soll hier das entsprechende Datum eingetragen werden.

Beginnen wir gleich mit dem Anlegen eines neuen Datensatzes. Dies erledigt das Makro aus Bild 8.

pic008.png

Bild 8: Dieses Makro fügt einem neuen Datensatz das Anlegedatum hinzu.

Die erste Aktion dient lediglich demonstrativen Zwecken: Sie schreibt einen Kommentar mit der ID des neuen Datensatzes in die Systemtabelle USysApplicationLog.

Danach geht es richtig los: Wir erstellen zunächst eine Referenz auf den neu angelegten Datensatz. Dazu verwenden wir die Aktion NachschlagenDatensatz und verwenden als Bedingung den Ausdruck [tblKunden].[KundeID] = [KundeID].

Wir haben nun im Prinzip eine Datensatzgruppe erzeugt, die genau den neu angelegten Datensatz enthält. Sie könnten dieser Datensatzgruppe nun noch einen Namen geben, indem Sie den Parameter Alias mit einem Wert wie rstNeu füllen. Da wir aber hier nur mit einem einzigen Datensatz arbeiten, ist dies nicht nötig. Damit die folgende DatensatzBearbeiten-Aktion jedoch weiß, dass sie sich auf den soeben ermittelten Datensatz beziehen soll, legen wir die DatensatzBearbeiten-Aktion in der Hierarchie unterhalb der NachschlagenDatensatz-Aktion an. Im Screenshot erkennen Sie dies durch die leichte Einrückung.

Der Grund ist, dass Access sich den gefundenen Datensatz so lange merkt, bis Sie die Struktur verlassen, in der Sie den Datensatz ermittelt haben.

Sie können also so lange immer wieder auf die Felder des Datensatzes zugreifen und ihre Werte ändern, bis die nächste änderung auf der gleichen Ebene von NachschlagenDatensatz ausgelöst wird (der graue Hintergrund in Bild 8 verdeutlicht dies).

Warum nicht einfacher

Die Vorgehensweise könnte man sich einfacher vorstellen. Access ermöglicht, wie wir gesehen haben, gleich nach dem Anlegen des neuen Datensatzes Zugriff auf seine Felder.

So konnten wir gleich den Datensatz referenzieren, der den Primärschlüsselwert des neu angelegten Datensatzes besitzt, und den Wert des Feldes AngelegtAm füllen.

Wenn wir den neuen Primärschlüsselwert gleich nach dem Anlegen lesen können, haben wir doch offensichtlich Zugriff auf den neuen Datensatz – warum also können wir das Feld AngelegtAm nicht gleich füllen Die Antwort ist einfach: Alle Datenmakros stellen einen Datensatz mit dem aktuellen Stand bereit, aber dieser ist schlicht schreibgeschützt.

Datensatzänderungen speichern

Bei änderungen am Datensatz sieht es ganz ähnlich aus. Wenn wir beim ändern mindestens eines Feldes eines Datensatzes das änderungsdatum in ein Feld namens GeaendertAm eintragen möchten, verwenden wir das Datenmakro Nach Aktualisierung.

Dieses füllen wir wie in Bild 9. Das Makro ist genau so wie das für das Anlegen aufgebaut – es wird lediglich ein anderes Feld geändert.

pic009.png

Bild 9: Dieses Makro trägt das änderungsdatum eines Datensatzes ein.

Wenn Sie einen Datensatz ändern, wird dieses Makro die erwünschte Wirkung erzielen.

Was aber, wenn Sie einen neuen Datensatz anlegen Logischerweise löst auch das Anlegen eines Datensatzes gleich das Datenmakro Nach Aktualisierung mit aus.

Das heißt, dass beim Anlegen eines Datensatzes nicht nur das Feld AngelegtAm, sondern auch GeaendertAm mit dem aktuellen Datum gefüllt wird.

Ist das ein Problem Nein, eigentlich nicht, denn letztlich entspricht das Anlegen eines Datensatzes ja dem ändern mindestens eines seiner Felder. Wir belassen dieses Verhalten also wie gehabt.

Detaillierte änderungshistorie

Vielleicht möchten Sie nicht nur festhalten, wann ein Datensatz geändert wurde, sondern welche änderungen genau erfolgt sind. In diesem Fall müssen wir das Datenmakro, das beim ändern ausgelöst wird, etwas erweitern.

Zusätzlich benötigen wir eine weitere Tabelle, die folgende Daten speichert:

  • Zeitpunkt der änderung
  • Geänderte Tabelle
  • Primärschlüsselwert des Datensatzes
  • Geändertes Feld
  • Alter Wert
  • Neuer Wert

Den Benutzer, der die änderung durchführt, lassen wir weiterhin außen vor. Die Tabelle zum Speichern der geänderten Daten sieht wie in Bild 10 aus.

pic010.png

Bild 10: Diese Tabelle speichert die änderungshistorie.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar