Ab Access 2010 können Sie mit den Datenmakros auf eine triggerähnliche Technik zugreifen. Damit definieren Sie direkt in der Tabelle, was beim Hinzufügen, ändern oder Löschen von Daten geschehen soll – unabhängig davon, ob diese änderung direkt in der Tabelle, über ein Formular, per Aktionsabfrage oder auch per VBA angestoßen wurde. Dieser Beitrag zeigt, wie Sie die Datenmakros nutzen können.
Die Grundlagen zu Datenmakros haben wir bereits im Beitrag Datenmakros in Access 2010 (www.access-im-unternehmen.de/760) besprochen. Im vorliegenden Beitrag schauen wir uns einige praktische Aspekte an und nehmen dabei das Thema Restriktionen in den Fokus.
Bereits in früheren Versionen bietet Access ein paar Möglichkeiten, Daten mit Restriktionen zu versehen: beispielsweise mit eindeutigen Indizes, Primärschlüsselfeldern, Gültigkeitsregeln oder der Definition referentieller Integrität für Beziehungen und damit die Einschränkung der Werte für Fremdschlüsselfelder.
Mit Datenmakros legen Sie praktisch beliebige Restriktionen fest und kombinieren Makros dabei nach Wunsch mit VBA-Funktionen.
Da es hier um Restriktionen geht, kümmern wir uns in diesem Beitrag ausschließlich um die beiden Datenmakros Vor änderung und Vor Löschung. Beide werden ausgelöst, bevor eine änderung eines Datensatzes gespeichert beziehungsweise dieser endgültig gelöscht wird – es gibt also noch Gelegenheit, den Vorgang zu unterbrechen.
Bearbeitung komplett unterbinden
Dies kann eine grundsätzliche Option sein: Mit den Datenmakros Vor änderung und Vor Löschung lassen sich durchaus Regeln wie die folgenden festlegen:
- Einer Tabelle darf kein Datensatz hinzugefügt werden.
- Die Datensätze einer Tabelle dürfen nicht verändert werden.
- Es darf kein Datensatz aus der Tabelle gelöscht werden.
Differenzierte Restriktionen
Es gibt jedoch auch die Möglichkeit, eine oder mehrere Regeln festzulegen, nach denen der Benutzer einen Datensatz hinzufügen, ändern oder löschen darf. Damit können Sie die oben beschriebenen Restriktionen etwas lockern – zum Beispiel, indem Sie das Hinzufügen von Datensätzen zu einer Tabelle grundsätzlich erlauben. Ein ändern oder Löschen hingegen soll nur in den ersten 15 Minuten nach dem Anlegen möglich sein – danach bleibt der Datensatz, wo und wie er ist.
Zusammenspiel mit VBA
Die für diese und komplizierte Restriktionen notwendigen Regeln können Sie direkt per Makro-Programmierung definieren. Sie können jedoch von Datenmakros aus auch VBA-Funktionen aufrufen, um komplexere Prüfungen in der gewohnten Umgebung abzubilden.
Außerdem zeigen wir Ihnen, wie Sie von VBA aus mit Datenmakros interagieren können, die etwa durch das Bearbeiten der betroffenen Datensätze per VBA ausgelöst wurden.
Datensätze einer Tabelle schützen
Als Beispiel dient eine einfache Tabelle namens tblAnreden. Diese enthält in der Regel zwei bis drei Datensätze und sollte normalerweise nicht verändert werden (s. Bild 1).
Bild 2: Anlegen von Datenmakros in der Datenblattansicht einer Tabelle
Bis Access 2003 ließ sich dies mithilfe des Sicherheitssystems von Access regulieren, ab Access 2010 erledigen Sie dies mit Datenmakros. Schauen wir uns an, wie dies aussieht.
Am schnellsten prüfen lassen sich die änderungen an Datenmakros, wenn Sie diese öffnen, während die Tabelle in der Datenblattansicht angezeigt wird. Sie können die Wirkung dann direkt nach dem Schließen des Makro-Editors ausprobieren. Ein neues Datenmakro namens Vor änderung oder Vor Löschung legen Sie wie in Bild 2 an.
Bild 3: Dieses Makro löst einen Fehler aus, wenn der Benutzer einen Datensatz löschen will.
Voraussetzung hierfür ist allerdings, dass Sie in den Access-Optionen den Eintrag Aktuelle Datenbank|Anwendungsoptionen|Entwurfsänderungen für Tabellen in der Datenblattansicht aktivieren angehakt haben.
Löschen verhindern
Wenn Sie verhindern möchten, dass ein Datensatz gelöscht wird, fügen Sie ein neues Datenmakro Vor Löschung zur Tabelle hinzu. Darin legen Sie eine einzige Aktion namens AuslösenFehler an. Als Parameter geben Sie dabei die Fehlernummer (hier 1) sowie die Fehlerbeschreibung an, in diesem Fall Löschen nicht möglich (s. Bild 3).
Bild 1: Beispieltabelle, deren Daten geschützt werden sollen
Dies bewirkt, dass Access beim Versuch, einen der Datensätze der Tabelle tblAnreden zu löschen, eine Meldung wie in Bild 4 einblendet.
Bild 4: Meldung beim Versuch, einen Datensatz zu löschen
Die Fehlermeldung wird nicht angezeigt – vielleicht erscheint diese aber, wenn Sie versuchen, einen Datensatz per VBA zu löschen Probieren wir es aus, indem wir schnell eine entsprechende Anweisung zusammenstellen und diese im Direktfenster des VBA-Editors absetzen:
CurrentDB.Execute "DELETE FROM tblAnreden WHERE AnredeID = 3"
Das Ergebnis überrascht ein wenig und sieht wie in Bild 5 aus. Als Fehlernummer kommt hier 3939 zum Einsatz, was – um es vorwegzunehmen – scheinbar die Standardnummer für Fehler ist, die durch Datenmakros ausgelöst werden. Immerhin zeigt Access aber die angegebene Fehlermeldung an.
Bild 5: Beim Löschen per VBA erscheint eine völlig andere Fehlernummer.
Begnügen wir uns doch zunächst mit der Erkenntnis, dass wir in der Datenblattansicht und beim Löschen per Execute-Anweisung eine entsprechende Meldung provozieren und das Löschen verhindern können.
ändern von Daten verhindern
Wie sieht es bei der änderung eines Datensatzes aus Eigentlich genau wie beim Löschen. Wenn ein Datensatz nicht geändert werden darf, legen Sie das Datenmakro Vor änderung an.
Fügen Sie diesem die Aktion AuslösenFehler hinzu und hinterlegen Sie eine entsprechende Meldung (s. Bild 6). Beim Versuch, einen Datensatz der Tabelle zu ändern, liefert Access die angegebene Meldung und verwirft die änderung.
Bild 6: Dieses Makro verhindert änderungen am Datensatz.
Hinzufügen von Daten verhindern
Probieren Sie nun einmal, der mit dem oben beschriebenen Datenmakro Vor änderung ausgestatteten Tabelle einen neuen Datensatz hinzuzufügen.
Auch dies wird unterbunden, denn Access interpretiert das Hinzufügen eines neuen Datensatzes hier als änderung.
Was aber, wenn Sie eine spezifische Meldung ausgeben möchten, wenn der Benutzer unerlaubterweise versucht, einen Datensatz anzulegen Dann benötigen Sie eine Wenn-Bedingung, die prüft, ob der Benutzer einen neuen Datensatz angelegt oder nur einen bestehenden Datensatz geändert hat.
Wie auch bei Triggern üblich, erlaubt Access in den beiden Makro-Aktionen Vor änderung und Vor Löschung den Zugriff auf zwei verschiedene Zustände des aktuell bearbeiteten Datensatzes: erstens auf den Datensatz vor der änderung und zweitens auf den Datensatz nach der änderung. Den geänderten Datensatz referenzieren Sie dabei mit dem Tabellennamen. Der Ausdruck [tblAnreden].[AnredeID] liefert also den neuen Primärschlüsselwert des Datensatzes. Wenn Sie den Primärschlüsselwert des Datensatzes vor der änderung ermitteln möchten, nutzen Sie den Ausdruck [Alt].[AnredeID].
Dies gelingt nicht nur mit vorhandenen Datensätzen, sondern auch mit neuen. Und logischerweise sind die Werte der Felder eines Datensatzes vor dem Anlegen alle leer.
Auf einen neuen Datensatz prüfen
Um im Makro Vor änderung zu prüfen, ob ein neuer Datensatz angelegt oder ein bestehender Datensatz geändert wurde, brauchen Sie nur den Inhalt eines Feldes zu prüfen, von dem Sie genau wissen, dass es nach dem Anlegen gefüllt ist.
Dies ist bei einem Primärschlüsselfeld, das als Autowertfeld ausgelegt ist, der Fall. Also prüfen wir den Ausdruck IstNull([Alt].[AnredeID]). Ist dieser wahr, handelt es sich um einen neuen Datensatz, sonst um einen bestehenden Datensatz (s. Bild 7). Dementsprechend liefert Access beim Anlegen eines neuen Datensatzes die Meldung Sie dürfen dieser Tabelle keine Daten hinzufügen.
Bild 7: Fallunterscheidung beim ändern eines Datensatzes: Neu oder geändert
Datensätze nur 15 Minuten nach dem Anlegen ändern
Damit haben Sie bereits ein Beispiel für eine Bedingung kennengelernt. Schauen wir uns ein weiteres Beispiel an: Dabei soll der Benutzer einer Tabelle zwar beliebig neue Datensätze hinzufügen, diese aber nur innerhalb von 15 Minuten nach dem Anlegen wieder löschen oder ändern können.
Dazu verwenden wir eine Tabelle namens tblTaetigkeiten mit den Feldern TaetigkeitID, Taetigkeit und AngelegtAm (s. Bild 8).
Bild 8: Tabelle mit Zeitstempel
Den Wert des Feldes können Sie auf gewohnte Weise mit der Standardwert-Eigenschaft des Feldes festlegen. Sie können natürlich auch einen Befehl im Datenmakro Vor änderung unterbringen. Der Befehl heißt FestlegenFeld. Für die Parameter Name und Feld legen Sie dabei die beiden Ausdrücke AngelegtAm und Jetzt() fest.
Dies soll geschehen, wenn soeben ein neuer Datensatz angelegt wurde. Damit das Makro das Anlegedatum nur in diesem Fall einträgt, prüft es vorher, ob das Primärschlüsselfeld TaetigkeitID den Wert Null enthält – und dies ist nur bei einem neuen Datensatz der Fall.
Wenn der Datensatz nicht frisch angelegt wurde, soll eine weitere Prüfung erfolgen – nämlich die, ob das Anlegen des Datensatzes bereits vor mehr als 15 Minuten geschehen ist. In diesem Fall soll die änderung unter Angabe einer entsprechenden Meldung unterbunden werden. Der Ausdruck, der den zeitlichen Abstand zum Erstellungszeitpunkt prüft, lautet folgendermaßen:
Jetzt()-[Alt].[AngelegtAm]>1/96
Dies liest sich so: Wenn die Differenz aus der aktuellen Zeit und dem Erstellungszeitpunkt größer als 1/96 ist, soll ein Fehler ausgelöst und eine Meldung ausgegeben werden.
Datumsangaben werden ja intern als Double-Zahlen gespeichert, wobei die Zahl vor dem Komma dem Datum und die Zahl hinter dem Komma der Uhrzeit entspricht. 1/96 liefert den entsprechenden Bruchteil eines Tages, nämlich eine Viertelstunde. Das komplette Makro zeigt Bild 9.
Bild 9: Bei neuen Datensätzen Anlegedatum eintragen, sonst prüfen, ob der Datensatz bereits älter als 15 Minuten ist und dann änderungen unterbinden
Einfachere Variante
Wenn Sie das Eintragen des Anlegedatums per Standardwert des Feldes AngelegtAm durchführen, kann das Datenmakro vereinfacht werden (siehe Beispieltabelle tblTaetigkeiten_1).
Sie brauchen dort nicht vorab zu prüfen, ob ein neuer Datensatz angelegt wurde – dies geschieht impliziert im folgenden Ausdruck:
Jetzt()-[Alt].[AngelegtAm]>1/96
Wurde der Datensatz soeben angelegt, aber noch nicht gespeichert, liefert [Alt].[AngelegtAm] den Wert NULL zurück. Der Ausdruck Jetzt() – NULL liefert wiederum NULL, und NULL > 1/96 ebenfalls.
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