{"id":55000760,"date":"2011-02-01T00:00:00","date_gmt":"2020-05-22T22:01:24","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=760"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Datenmakros_in_Access_2010","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/","title":{"rendered":"Datenmakros in Access 2010"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg01.met.vgwort.de\/na\/9d85cd8e79734321be369c0fca6e98e2\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Seit Jahren w&uuml;nscht die Access-Entwicklergemeinde sich Trigger. Damit legt man gleich im Tabellenentwurf fest, was geschieht, wenn ein Benutzer Datens&auml;tze anlegt, bearbeitet oder l&ouml;scht. Doch diese n&uuml;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&uuml;r Access verf&uuml;gbar machen. Wir schauen uns an, was dabei herausgekommen ist.<\/b><\/p>\n<p><b>Sinn und Zweck von Datenmakros<\/b><\/p>\n<p>Genau wie Trigger in anderen Datenbankmanagementsystemen sollen Datenmakros ausgel&ouml;st werden, wenn der Benutzer eine der folgenden Aktionen durchf&uuml;hrt:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Nach dem Anlegen eines Datensatzes<\/li>\n<li class=\"aufz-hlung\">Vor dem &auml;ndern eines oder mehrerer Felder eines Datensatzes<\/li>\n<li class=\"aufz-hlung\">Nach dem &auml;ndern eines Datensatzes<\/li>\n<li class=\"aufz-hlung\">Vor dem L&ouml;schen eines Datensatzes<\/li>\n<li class=\"aufz-hlung\">Nach dem L&ouml;schen eines Datensatzes<\/li>\n<\/ul>\n<p>Nun wissen wir zwar, wann Datenmakros ausgel&ouml;st werden, aber wof&uuml;r kann man diese Objekte denn nun gebrauchen Der einfachste Anwendungsfall ist wohl das Protokollieren von &auml;nderungen an den Daten einer Tabelle. Sicher kennen Sie Varianten von Tabellen, die Felder wie <b>ErstelltAm<\/b>, <b>ErstelltDurch<\/b>, <b>GeaendertAm<\/b>, <b>GeaendertDurch<\/b>, <b>GeloeschtAm <\/b>und <b>GeloeschtDurch <\/b>enthalten.<\/p>\n<p>Deren Inhalte k&ouml;nnen nat&uuml;rlich nur dann automatisch ge&auml;ndert werden, wenn die &auml;nderungen selbst ein entsprechendes Ereignis ausl&ouml;sen. Bislang hat man sich dabei damit beholfen, dass man davon ausging, dass Benutzer die Daten einer Tabelle nur &uuml;ber ein Formular &auml;ndern und niemals direkt auf die Tabelle zugreifen.<\/p>\n<p>In Formularen gibt es schlie&szlig;lich Ereigniseigenschaften, welche entsprechende Prozeduren ausl&ouml;sen k&ouml;nnen. Dort bringt man dann Code unter, der daf&uuml;r sorgt, dass die Felder zur &auml;nderungsprotokollierung auf dem aktuellsten Stand gehalten werden.<\/p>\n<p>Das Problem dabei ist nur, dass es sehr viele M&ouml;glichkeiten gibt, den Inhalt einer Tabelle zu &auml;ndern. Der Benutzer kann dies direkt &uuml;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&ouml;sen.<\/p>\n<p>Schlie&szlig;lich gibt es auch noch Aktionsabfragen, die Datens&auml;tze anlegen, &auml;ndern oder l&ouml;schen k&ouml;nnen. Dies alles macht deutlich, dass der Entwickler an einer ganzen Reihe von Stellen daf&uuml;r sorgen muss, dass &auml;nderungen auch wirklich protokolliert werden.<\/p>\n<p>Wenn Sie die Tabellen beispielsweise in einer SQL Server- oder MySQL-Datenbank speichern, ist dies viel einfacher: Sie k&ouml;nnen dort Trigger anlegen, die bei jeder Daten&auml;nderung ausgel&ouml;st werden. F&uuml;r jeden Trigger definieren Sie, was dieser erledigen soll &#8211; in diesem Fall die &auml;nderungsinformationen in die Tabelle eintragen.<\/p>\n<p>Nun aber sollen die sogenannten Datenmakros die Aufgabe der Trigger auch in Access-Tabellen &uuml;bernehmen. Schauen wir uns also an, wie dies funktioniert.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Datenmakros verwalten<\/p>\n<p>Die Datenmakros von Access 2010 bearbeiten Sie in der Entwurfsansicht der jeweiligen Tabelle. Die notwendigen Befehle finden Sie im Ribbon-Bereich <b>Entwurf|Feld-, Datensatz- und Tabellenereignisse<\/b>. Dort lassen sich Datenmakros erstellen sowie l&ouml;schen oder umbenennen (s. Bild 1).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic001.png\" alt=\"pic001.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Datenmakros legen Sie in der Entwurfsansicht einer Tabelle an.<\/span><\/b><\/p>\n<p>Wir wollen zun&auml;chst f&uuml;r alle m&ouml;glichen Aktionen ein Datenmakro anlegen, das einfach nur mitteilt, durch welche Aktion es jeweils ausgel&ouml;st wurde. F&uuml;r das Datenmakro <b>Nach Einf&uuml;gung <\/b>soll so beispielsweise ein Meldungsfenster erscheinen, das uns informiert, dass soeben ein Datensatz eingef&uuml;gt wurde. &auml;hnliche Datenmakros legen wir f&uuml;r alle f&uuml;nf verf&uuml;gbaren Datenaktionen an.<\/p>\n<p><b>Definition von Datenmakros<\/b><\/p>\n<p>Datenmakros haben genau die gleiche Syntax wie herk&ouml;mmliche Makros. Diese wurden unter Access 2010 deutlich &uuml;berarbeitet. Die Neuerungen bez&uuml;glich dieses Objekttyps finden Sie im Detail im Beitrag <b>Makros in Access 2010 <\/b>(<b>www.access-im-unternehmen.de\/759<\/b>).<\/p>\n<p>Trotz der gleichen Syntax verwenden Datenmakros nur ganz wenige der in herk&ouml;mmlichen Makros vorkommenden Aktionen. Daf&uuml;r gibt es eine ganze Reihe spezieller Aktionen wie <b>Ausl&ouml;senFehler<\/b>, <b>DatensatzBearbeiten <\/b>oder <b>ProtokollierenEreignis<\/b> (s. Bild 2).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic002.png\" alt=\"pic002.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: F&uuml;r Datenmakros stehen andere Aktionen zur Verf&uuml;gung als f&uuml;r normale Makros.<\/span><\/b><\/p>\n<p>Unser Plan, beim Anlegen eines Datensatzes eine Meldung auszugeben, f&auml;llt somit ins Wasser: Das Ausgeben von Meldungen ist in Datenmakros nicht vorgesehen. Daf&uuml;r gibt es eine Aktion namens <b>ProtokollierenEreignis <\/b>&#8211; mal sehen, was wir damit anstellen k&ouml;nnen. Wir legen also ein erstes Datenmakro an, das beim Anlegen eines Datensatzes in der Tabelle <b>tblKunden<\/b> ein Ereignis protokolliert.<\/p>\n<p>Dort tragen wir den folgenden Ausdruck ein (s. Bild 3):<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic003.png\" alt=\"pic003.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3: Dieser Ausdruck soll beim Anlegen eines neuen Datensatzes protokolliert werden.<\/span><\/b><\/p>\n<pre>=&quot;Datensatz angelegt am &quot; &amp; Datum()<\/pre>\n<p>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, &auml;ndern oder L&ouml;schen eines Datensatzes immer darauf hingewiesen werden, was er soeben getan hat. <\/p>\n<p>Wenn man sich nicht drum k&uuml;mmert, st&ouml;&szlig;t man vielleicht beim n&auml;chsten Besuch des <b>Datei<\/b>-Tabs auf die neue Schaltfl&auml;che <b>Anwendungsprotokolltabelle anzeigen <\/b>(s. Bild 4).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic004.png\" alt=\"pic004.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 4: Das Anwendungsprotokoll lassen Sie sich &uuml;ber diesen Men&uuml;punkt im Backstage-Bereich anzeigen.<\/span><\/b><\/p>\n<p>Ein Klick auf diese Schaltfl&auml;che &ouml;ffnet die Tabelle <b>USysApplicationLog<\/b> &#8211; eine Art Systemtabelle, die beim ersten Protokollieren eines Datenmakros angelegt wird und im Datenbankfenster nur angezeigt wird, wenn die Option <b>Systemtabellen anzeigen <\/b>aktiviert ist.Im Gegensatz zu den &uuml;brigen Systemtabellen k&ouml;nnen Sie aber die enthaltenen Daten &auml;ndern und sogar die komplette Tabelle l&ouml;schen, wenn Sie die gespeicherten Daten nicht mehr ben&ouml;tigen.<\/p>\n<p>Diese Tabelle zeigt beispielsweise an, welches Objekt den Eintrag verursacht hat (hier das <b>AfterInsert<\/b>-Datenmakro der Tabelle <b>tblKunden<\/b>), ob es einen Fehler gab und wann der Eintrag stattfand. Au&szlig;erdem finden wir unseren Protokolltext wieder, und zwar im Feld <b>Description<\/b>.<\/p>\n<p>Wenn ein Datenmakro einen Fehler ausl&ouml;st, wird dieser &uuml;brigens auch in dieser Tabelle gespeichert; in diesem Fall landet der Fehlertext im Feld <b>Description<\/b> (s. Bild 5).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic005.png\" alt=\"pic005.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 5: Diese Tabelle speichert bei der Durchf&uuml;hrung von Datenmakros anfallende Meldungen.<\/span><\/b><\/p>\n<p><b>Makros in der Datenblattansicht &auml;ndern<\/b><\/p>\n<p>Wenn Sie die Option <b>Aktuelle Datenbank|Anwendungsoptionen|Entwurfs&auml;nderungen f&uuml;r Tabellen in der Datenblattansicht aktivieren <\/b>eingeschaltet haben, k&ouml;nnen Sie Datenmakros sogar in der Datenblattansicht von Tabellen &auml;ndern.<\/p>\n<p>Auch wenn wir normalerweise gegen das &auml;ndern des Tabellenentwurfs in der Datenblattansicht sind, spart das Bearbeiten der Datenmakros in dieser Ansicht doch das l&auml;stige Hin- und Herschalten zwischen Entwurf und Datenblatt.<\/p>\n<p>Sie finden die entsprechenden Schaltfl&auml;chen zum Anlegen beziehungsweise Bearbeiten der Datenmakros im Ribbon-Tab <b>Tabelle <\/b>(s. Bild 6).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic006.png\" alt=\"pic006.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 6: Wenn bereits ein Datenmakro f&uuml;r eine Tabelle hinterlegt ist, wird die Schaltfl&auml;che zum Aufrufen dieses Makros farblich hervorgehoben.<\/span><\/b><\/p>\n<p>Dort werden bereits vorhandene Datenmakros &uuml;brigens farbig hervorgehoben.<\/p>\n<p><b>Die Aktionen der Datenmakros<\/b><\/p>\n<p>Werfen wir nun einen Blick auf die verschiedenen Aktionen der Datenmakros. Die Aktion <b>ProtokollierenEreignis <\/b>haben wir ja bereits ansatzweise kennengelernt. Interessant sind hier noch die verschiedenen Parameter.<\/p>\n<p>Wenn Sie wie in Bild 7 die Liste der m&ouml;glichen Elemente mit der Tastenkombination <b>Strg + Leertaste <\/b>aufklappen, finden Sie beispielsweise s&auml;mtliche Feldnamen der aktuellen Tabelle, aber auch die VBA-Funktionen in der jeweiligen Landessprache vor. Zus&auml;tzlich gibt es ein paar datenmakro-spezifische Elemente, von denen zun&auml;chst die folgenden beiden interessant sind:<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic007.png\" alt=\"pic007.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 7: &Uuml;ber die Feldnamen greifen Sie auf die Werte des aktuellen Datensatzes zu.<\/span><\/b><\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>Alt<\/b>: Erlaubt den Zugriff auf die vor der &auml;nderung g&uuml;ltigen Feldwerte, Beispiel: <b>Alt.KundeID<\/b>. Nur sinnvoll in den Datenmakros <b>Nach Aktualisierung <\/b>und <b>Nach L&ouml;schung<\/b>.<\/li>\n<li class=\"aufz-hlung\"><b>MacroError<\/b>: Liefert Informationen &uuml;ber eventuell aufgetretene Fehler.<\/li>\n<\/ul>\n<p><b>Datenbl&ouml;cke<\/b><\/p>\n<p>Neben diesen Elementen gibt es einige sogenannte Datenbl&ouml;cke. Diese repr&auml;sentieren einige Standardabl&auml;ufe, die normalerweise mit DAO oder ADODB programmiert werden. Die vier Datenbl&ouml;cke lauten (englische Bezeichnungen in Klammern, falls Sie mit der englischen Version von Access arbeiten sollten):<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>DatensatzBearbeiten<\/b> (<b>EditRecord<\/b>): Entspricht dem &Ouml;ffnen eines Datensatzes zur Bearbeitung unter Angabe der zu &auml;ndernden Felder.<\/li>\n<li class=\"aufz-hlung\"><b>DatensatzErstellen<\/b> (<b>CreateRecord<\/b>): Entspricht dem Anlegen eines neuen Datensatzes mit <b>AddNew <\/b>und dem anschlie&szlig;enden Zuweisen von Feldwerten.<\/li>\n<li class=\"aufz-hlung\"><b>F&uuml;rJedenDatensatz<\/b> (<b>ForEachRecord<\/b>): Repr&auml;sentiert die <b>Do While<\/b>-Schleife f&uuml;r das Durchlaufen eines <b>Recordset<\/b>-Objekts.<\/li>\n<li class=\"aufz-hlung\"><b>NachschlagenDatensatz<\/b> (<b>LookupRecord<\/b>): Ermittelt einen einzigen Datensatz, dessen Feldinhalte im Anschluss etwa mit <b>DatensatzBearbeiten <\/b>ge&auml;ndert werden k&ouml;nnen.<\/li>\n<\/ul>\n<p><b>Datenaktionen<\/b><\/p>\n<p>Den gr&ouml;&szlig;ten Teil der Elemente machen die Datenaktionen aus. Einige von ihnen k&ouml;nnen immer ausgef&uuml;hrt werden, andere nur in bestimmten Zusammenh&auml;ngen:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>AbbrechenDatensatz&auml;nderung<\/b> (<b>UndoRecord<\/b>): Kann nur in den Datenbl&ouml;cken <b>DatensatzErstellen <\/b>und <b>DatensatzBearbeiten <\/b>verwendet werden, um die aktuellen &auml;nderungen zu verwerfen.<\/li>\n<li class=\"aufz-hlung\"><b>Ausf&uuml;hrenDatenmakro<\/b> (<b>RunDataMacro<\/b>): F&uuml;hrt ein anderes Datenmakro aus.<\/li>\n<li class=\"aufz-hlung\"><b>Ausl&ouml;senFehler<\/b> (<b>RaiseError<\/b>): Dies l&ouml;st einen Fehler aus, der entweder in die Anzeige einer Fehlermeldung m&uuml;ndet oder aber etwa unter VBA entsprechend behandelt werden kann.<\/li>\n<li class=\"aufz-hlung\"><b>BeendenF&uuml;rJedenDatensatz<\/b> (<b>ExitForEachRecord<\/b>): Beendet eine <b>F&uuml;rJedenDatensatz<\/b>-Schleife.<\/li>\n<li class=\"aufz-hlung\"><b>BeiFehler<\/b> (<b>OnError<\/b>): Fehlerbehandlung. Gibt an, ob Fehler &uuml;bergangen oder behandelt werden sollen beziehungsweise welches Makro im Falle eines Fehlers aufgerufen werden soll.<\/li>\n<li class=\"aufz-hlung\"><b>DatensatzL&ouml;schen<\/b> (<b>DeleteRecord<\/b>): L&ouml;scht den aktuellen Datensatz.<\/li>\n<li class=\"aufz-hlung\"><b>FestlegenFeld<\/b> (<b>SetField<\/b>): Hiermit legen Sie einen Feldwert fest. Dabei verwenden Sie die beiden Parameter <b>Feldname <\/b>und <b>Feldwert<\/b>.<\/li>\n<li class=\"aufz-hlung\"><b>FestlegenLokaleVar<\/b> (<b>SetLocalVar<\/b>): 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&auml;ter auf diesen Datensatz zuzugreifen.<\/li>\n<li class=\"aufz-hlung\"><b>L&ouml;schenMakroFehler<\/b> (<b>ClearMacroError<\/b>): Leert das <b>MacroError<\/b>-Objekt, das Informationen zum zuletzt aufgetretenen Fehler enth&auml;lt.<\/li>\n<li class=\"aufz-hlung\"><b>SendenEMail<\/b> (<b>SendEmail<\/b>): Versendet eine E-Mail bei einem der Ereignisse <b>Nach Einf&uuml;gung<\/b>, <b>Nach Aktualisierung <\/b>oder <b>Nach L&ouml;schung<\/b>. Dies geschieht jedoch nicht standardm&auml;&szlig;ig im stillen K&auml;mmerlein, sondern es erscheint eine Meldung, die auf einen eventuellen Missbrauch von Outlook hinweist.<\/li>\n<li class=\"aufz-hlung\"><b>StoppAlleMakros<\/b> (<b>StopAllMacros<\/b>): Beendet alle laufenden Makros.<\/li>\n<li class=\"aufz-hlung\"><b>StoppMakro<\/b> (<b>StopMacro<\/b>): Beendet das aktuelle Makro.<\/li>\n<\/ul>\n<p><!--30percent--><\/p>\n<p><b>Beispielanwendung: &auml;nderungshistorie<\/b><\/p>\n<p>F&uuml;r die Beispielanwendung erweitern wir die Tabelle <b>tblKunden <\/b>um die drei Felder <b>AngelegtAm<\/b>, <b>GeaendertAm <\/b>und <b>GeloeschtAm<\/b>. Je nach &auml;nderung soll hier das entsprechende Datum eingetragen werden.<\/p>\n<p>Beginnen wir gleich mit dem Anlegen eines neuen Datensatzes. Dies erledigt das Makro aus Bild 8.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic008.png\" alt=\"pic008.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 8: Dieses Makro f&uuml;gt einem neuen Datensatz das Anlegedatum hinzu.<\/span><\/b><\/p>\n<p>Die erste Aktion dient lediglich demonstrativen Zwecken: Sie schreibt einen Kommentar mit der ID des neuen Datensatzes in die Systemtabelle <b>USysApplicationLog<\/b>.<\/p>\n<p>Danach geht es richtig los: Wir erstellen zun&auml;chst eine Referenz auf den neu angelegten Datensatz. Dazu verwenden wir die Aktion <b>NachschlagenDatensatz <\/b>und verwenden als Bedingung den Ausdruck <b>[tblKunden].[KundeID] = [KundeID]<\/b>.<\/p>\n<p>Wir haben nun im Prinzip eine Datensatzgruppe erzeugt, die genau den neu angelegten Datensatz enth&auml;lt. Sie k&ouml;nnten dieser Datensatzgruppe nun noch einen Namen geben, indem Sie den Parameter <b>Alias <\/b>mit einem Wert wie <b>rstNeu <\/b>f&uuml;llen. Da wir aber hier nur mit einem einzigen Datensatz arbeiten, ist dies nicht n&ouml;tig. Damit die folgende <b>DatensatzBearbeiten<\/b>-Aktion jedoch wei&szlig;, dass sie sich auf den soeben ermittelten Datensatz beziehen soll, legen wir die <b>DatensatzBearbeiten<\/b>-Aktion in der Hierarchie unterhalb der <b>NachschlagenDatensatz<\/b>-Aktion an. Im Screenshot erkennen Sie dies durch die leichte Einr&uuml;ckung.<\/p>\n<p>Der Grund ist, dass Access sich den gefundenen Datensatz so lange merkt, bis Sie die Struktur verlassen, in der Sie den Datensatz ermittelt haben.<\/p>\n<p>Sie k&ouml;nnen also so lange immer wieder auf die Felder des Datensatzes zugreifen und ihre Werte &auml;ndern, bis die n&auml;chste &auml;nderung auf der gleichen Ebene von <b>NachschlagenDatensatz <\/b>ausgel&ouml;st wird (der graue Hintergrund in Bild 8 verdeutlicht dies).<\/p>\n<p><b>Warum nicht einfacher<\/b><\/p>\n<p>Die Vorgehensweise k&ouml;nnte man sich einfacher vorstellen. Access erm&ouml;glicht, wie wir gesehen haben, gleich nach dem Anlegen des neuen Datensatzes Zugriff auf seine Felder.<\/p>\n<p>So konnten wir gleich den Datensatz referenzieren, der den Prim&auml;rschl&uuml;sselwert des neu angelegten Datensatzes besitzt, und den Wert des Feldes <b>AngelegtAm <\/b>f&uuml;llen.<\/p>\n<p>Wenn wir den neuen Prim&auml;rschl&uuml;sselwert gleich nach dem Anlegen lesen k&ouml;nnen, haben wir doch offensichtlich Zugriff auf den neuen Datensatz &#8211; warum also k&ouml;nnen wir das Feld <b>AngelegtAm <\/b>nicht gleich f&uuml;llen Die Antwort ist einfach: Alle Datenmakros stellen einen Datensatz mit dem aktuellen Stand bereit, aber dieser ist schlicht schreibgesch&uuml;tzt.<\/p>\n<p><b>Datensatz&auml;nderungen speichern<\/b><\/p>\n<p>Bei &auml;nderungen am Datensatz sieht es ganz &auml;hnlich aus. Wenn wir beim &auml;ndern mindestens eines Feldes eines Datensatzes das &auml;nderungsdatum in ein Feld namens <b>GeaendertAm <\/b>eintragen m&ouml;chten, verwenden wir das Datenmakro <b>Nach Aktualisierung<\/b>.<\/p>\n<p>Dieses f&uuml;llen wir wie in Bild 9. Das Makro ist genau so wie das f&uuml;r das Anlegen aufgebaut &#8211; es wird lediglich ein anderes Feld ge&auml;ndert.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic009.png\" alt=\"pic009.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 9: Dieses Makro tr&auml;gt das &auml;nderungsdatum eines Datensatzes ein.<\/span><\/b><\/p>\n<p>Wenn Sie einen Datensatz &auml;ndern, wird dieses Makro die erw&uuml;nschte Wirkung erzielen.<\/p>\n<p>Was aber, wenn Sie einen neuen Datensatz anlegen Logischerweise l&ouml;st auch das Anlegen eines Datensatzes gleich das Datenmakro <b>Nach Aktualisierung <\/b>mit aus.<\/p>\n<p>Das hei&szlig;t, dass beim Anlegen eines Datensatzes nicht nur das Feld <b>AngelegtAm<\/b>, sondern auch <b>GeaendertAm <\/b>mit dem aktuellen Datum gef&uuml;llt wird.<\/p>\n<p>Ist das ein Problem Nein, eigentlich nicht, denn letztlich entspricht das Anlegen eines Datensatzes ja dem &auml;ndern mindestens eines seiner Felder. Wir belassen dieses Verhalten also wie gehabt.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Detaillierte &auml;nderungshistorie<\/p>\n<p>Vielleicht m&ouml;chten Sie nicht nur festhalten, wann ein Datensatz ge&auml;ndert wurde, sondern welche &auml;nderungen genau erfolgt sind. In diesem Fall m&uuml;ssen wir das Datenmakro, das beim &auml;ndern ausgel&ouml;st wird, etwas erweitern.<\/p>\n<p>Zus&auml;tzlich ben&ouml;tigen wir eine weitere Tabelle, die folgende Daten speichert:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Zeitpunkt der &auml;nderung<\/li>\n<li class=\"aufz-hlung\">Ge&auml;nderte Tabelle<\/li>\n<li class=\"aufz-hlung\">Prim&auml;rschl&uuml;sselwert des Datensatzes<\/li>\n<li class=\"aufz-hlung\">Ge&auml;ndertes Feld<\/li>\n<li class=\"aufz-hlung\">Alter Wert<\/li>\n<li class=\"aufz-hlung\">Neuer Wert<\/li>\n<\/ul>\n<p>Den Benutzer, der die &auml;nderung durchf&uuml;hrt, lassen wir weiterhin au&szlig;en vor. Die Tabelle zum Speichern der ge&auml;nderten Daten sieht wie in Bild 10 aus.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic010.png\" alt=\"pic010.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 10: Diese Tabelle speichert die &auml;nderungshistorie.<\/span><\/b><\/p>\n<p>Das Makro schlie&szlig;lich wird etwas umfangreicher als die bisherigen Makros. Der Grund ist, dass wir die &auml;nderungen jedes einzelnen Feldes separat pr&uuml;fen m&ouml;chten. Wir wissen ja nicht, welches der Felder des Datensatzes ge&auml;ndert wurde und somit das Datenmakro ausgel&ouml;st hat &#8211; es kann ein einziges Feld sein, der Benutzer kann aber auch mehrere Felder ge&auml;ndert haben.<\/p>\n<p>Da wir aber ohnehin die &auml;nderungen an jedem einzelnen Feld speichern m&ouml;chten, m&uuml;ssen wir auch alle Felder pr&uuml;fen. Das Makro aus Bild 11 beginnt mit einer <b>Wenn<\/b>-Bedingung, die pr&uuml;ft, ob der alte Inhalt des Feldes <b>Kunde <\/b>mit dem neuen &uuml;bereinstimmt.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic011.png\" alt=\"pic011.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 11: Speichern der &auml;nderungen im Feld Kunde der Tabelle tblKunden<\/span><\/b><\/p>\n<p>Den Inhalt des alten Feldes erhalten wir &uuml;ber ein spezielles Tabellen-Alias, n&auml;mlich <b>Alt <\/b>(in englischen Versionen: <b>Old<\/b>). Den Wert des Feldes <b>Kunden <\/b>in der neuen Version des Datensatzes k&ouml;nnen wir direkt &uuml;ber den Feldnamen abgreifen &#8211; ohne eine Tabelle oder ein Alias angeben zu m&uuml;ssen (dazu sp&auml;ter mehr).<\/p>\n<p>Wir k&ouml;nnten also mit der Bedingung <b>Wenn Nicht ([Alt].[Kunde]=[Kunde]) Dann <\/b>pr&uuml;fen, ob der Feldwert sich ge&auml;ndert hat.<\/p>\n<p>Access bietet aber speziell f&uuml;r diesen Fall eine eigene Funktion an, n&auml;mlich <b>Aktualisiert(&lt;Feldname&gt;)<\/b>. Diese macht das Zusammenstellen der Wenn-Bedingung nat&uuml;rlich noch einfacher. <\/p>\n<p>Wurde der Name des Kunden ge&auml;ndert, werden die nachfolgenden Aktionen ausgef&uuml;hrt. Diese sind wiederum verschachtelt: Die &auml;u&szlig;ere Aktion legt einen neuen Datensatz in der Tabelle <b>tblAenderungshistorie <\/b>an (dies entspricht dem Erzeugen einer Datensatzgruppe und dem Anlegen eines neuen Datensatzes mit <b>AddNew <\/b>unter DAO oder ADODB).<\/p>\n<p>Darin verschachtelt befinden sich einige Aktionen, welche die einzelnen Felder dieses neuen Datensatzes f&uuml;llen. Wichtig ist dabei, dass Sie die Anf&uuml;hrungszeichen an den richtigen Stellen setzen:<\/p>\n<p>Die Angabe von <b>&quot;tblKunden&quot; <\/b>f&uuml;r das Feld <b>GeaenderteTabelle <\/b>tr&auml;gt tats&auml;chlich diesen Ausdruck dort ein, w&auml;hrend <b>tblKunden <\/b>ohne Anf&uuml;hrungszeichen zu einem Fehler f&uuml;hrt: Access versucht dann auf ein Feld namens <b>tblKunden <\/b>zuzugreifen, was aber nicht gelingt.<\/p>\n<p>Wichtig ist auch, dass Sie beim Hinzuf&uuml;gen des neuen Wertes des Felds <b>Kunde <\/b>nicht mehr ohne Angabe des Tabellennamens oder Alias auf dieses Feld des neu angelegten Datensatzes der Tabelle <b>tblKunden <\/b>zugreifen k&ouml;nnen, sondern das Pr&auml;fix <b>tblKunden <\/b>voranstellen m&uuml;ssen &#8211; mehr dazu im folgenden Abschnitt.<\/p>\n<p>Um das vorliegende Makro zu testen, &auml;ndern Sie einen bestehenden Datensatz und tragen dort einen neuen Wert f&uuml;r das Feld <b>Kunde <\/b>ein. Anschlie&szlig;end finden Sie in der Tabelle <b>tblAenderungshistorie <\/b>einen entsprechenden neuen Datensatz vor.<\/p>\n<p><b>Greifbare Daten<\/b><\/p>\n<p>Die ersten beiden Beispiele zeigen sehr sch&ouml;n, wie wir auf die Felder der einzelnen Tabellen zugreifen k&ouml;nnen. Allerdings sind dabei auch einige Punkte aufgetaucht, die genauer untersucht werden m&uuml;ssen.<\/p>\n<p>Wenn Sie auf einen Wert eines neu angelegten oder ge&auml;nderten Datensatzes zugreifen m&ouml;chten, gelingt dies durch einfache Angabe des Feldnamens ohne f&uuml;hrenden Tabellennamen. Beim &auml;ndern eines Datensatzes greifen Sie durch Voranstellen von <b>Alt <\/b>beziehungsweise <b>Old <\/b>auf die alten Feldwerte zu, also beispielsweise <b>Alt.Kunde<\/b>.<\/p>\n<p>Andererseits lassen sich von einem Datenmakro aus keine &auml;nderungen an einem Feld durchf&uuml;hren, indem Sie es einfach per Feldname referenzieren &#8211; es ist schlicht schreibgesch&uuml;tzt.<\/p>\n<p>Wenn Sie dann mit der <b>NachschlagenDatensatz<\/b>-Aktion auf diesen Datensatz zugreifen, k&ouml;nnen Sie wiederum nicht mehr direkt auf Feldnamen wie <b>[Kunde] <\/b>zugreifen &#8211; Sie m&uuml;ssen den Tabellennamen voranstellen (<b>[tblKunden.Kunde]<\/b>).<\/p>\n<p>Dies gilt f&uuml;r alle Aktionen, mit denen Sie einen neuen Datensatz referenzieren &#8211; ob mit <b>DatensatzBearbeiten<\/b>, <b>DatensatzErstellen<\/b>, <b>F&uuml;rJedenDatensatz <\/b>oder <b>NachschlagenDatensatz<\/b>. Der Kontext liegt nun auf dem neuen Datensatz und Sie k&ouml;nnen nun nicht mehr ohne Angabe eines Tabellennamens oder eines Alias auf die Felder einer Tabelle zugreifen.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Benannte Makros<\/p>\n<p>Benannte Makros sind etwa mit Prozeduren oder Funktionen unter VBA vergleichbar. Sie k&ouml;nnen f&uuml;r benannte Makros Parameter festlegen und beim Aufruf entsprechende Werte &uuml;bergeben, die im benannten Makro weiterverarbeitet werden k&ouml;nnen. <\/p>\n<p>Die &auml;nderungshistorie ist ein prima Beispiel f&uuml;r solche benannten Makros, da wir prinzipiell f&uuml;r alle Felder der Tabelle pr&uuml;fen m&uuml;ssen, ob der Feldinhalt im Vergleich zum vorherigen Stand ge&auml;ndert wurde, und dementsprechend einen Eintrag in die Tabelle <b>tblAenderungshistorie<\/b> vornehmen m&uuml;ssen. <\/p>\n<p>Wir k&ouml;nnen nun also ein benanntes Makro erstellen, das f&uuml;r uns pr&uuml;ft, ob der alte Wert dem neuen entspricht und gegebenenfalls die &auml;nderung dokumentiert.<\/p>\n<p>Bild 12 zeigt das benannte Makro mit seinen Parametern. Benannte Makros k&ouml;nnen wie die Datenmakros nur in Zusammenhang mit einer Tabelle erstellen, es gibt keine globalen benannten Makros, die Sie von verschiedenen Tabellen aus aufrufen k&ouml;nnen.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic012.png\" alt=\"pic012.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 12: Ein benanntes Makro, das von anderen Datenmakros aus aufgerufen werden kann.<\/span><\/b><\/p>\n<p>Das Makro aus Bild 13 besitzt f&uuml;nf Parameter, f&uuml;r die wir im Makro lediglich den Namen und, falls gew&uuml;nscht, eine Beschreibung hinterlegen k&ouml;nnen. Auf die Parameter k&ouml;nnen wir in den folgenden Aktionen direkt zugreifen.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic013.png\" alt=\"pic013.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 13: Benanntes Makro mit seinen Parametern<\/span><\/b><\/p>\n<p>Der Aufruf eines solchen Makros erfolgt &uuml;ber die Aktion <b>Ausf&uuml;hrenDatenmakro<\/b>. Nach der Auswahl des benannten Makros, das bereits vorliegen muss, blendet Access die Parameter dieses Makros ein. Hier tragen Sie nun die Werte ein, die an das Makro &uuml;bergeben werden sollen.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic014.png\" alt=\"pic014.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 14: Aufruf eines benannten Makros mit seinen Parametern<\/span><\/b><\/p>\n<p>Zusammen f&uuml;hren Datenmakro und benanntes Makro nun die Funktion durch, die zuvor allein im Datenmakro aus Bild 11 untergebracht war. Nun brauchen Sie zum Speichern der &auml;nderungen nur noch f&uuml;r jedes Feld einmal den Aufruf des benannten Makros zu kopieren und einzuf&uuml;gen und anschlie&szlig;end die Parameter im Aufruf entsprechend dem zu pr&uuml;fenden Feld anzupassen.<\/p>\n<p><b>Achtung, Rekursion!<\/b><\/p>\n<p>Wenn Sie dem Datenmakro <b>Nach Aktualisierung <\/b>Aktionen zuweisen, die den Inhalt der ge&auml;nderten Tabelle selbst &auml;ndern (beispielsweise durch das Eintragen eines &auml;nderungsdatums), geraten Sie in eine Endlos-Schleife: Durch das erneute &auml;ndern des Datensatzes wird das Datenmakro <b>Nach Aktualisierung <\/b>erneut ausgel&ouml;st, schreibt wieder das &auml;nderungsdatum in das entsprechende Feld und so weiter.<\/p>\n<p>Irgendwann erkennt Access dies, bricht die Operation ab und tr&auml;gt eine entsprechende Meldung in die Tabelle <b>USysApplicationLog <\/b>ein.<\/p>\n<p>Wir m&ouml;chten das Datenmakro zum Eintragen der &auml;nderungshistorie nun um einen Befehl erweitern, der den Zeitpunkt der letzten &auml;nderung in das Feld <b>GeaendertAm <\/b>der Tabelle <b>tblKunden <\/b>selbst eintr&auml;gt.<\/p>\n<p>Diese Aktion geschieht im Anschluss an die verschiedenen Aufrufe des benannten Makros zum Speichern der &auml;nderungen der einzelnen Felder in der Tabelle <b>tblAenderungshistorie<\/b>. Die Vorgehensweise entspricht genau der beim Eintragen des Anlegedatums eines Datensatzes. <\/p>\n<p>Viel interessanter ist es, die drohende Rekursion zu verhindern, denn durch das Eintragen des &auml;nderungsdatums wird ja wiederum das Datenmakro <b>Nach Aktualisierung <\/b>ausgel&ouml;st.<\/p>\n<p>Wir m&uuml;ssen also gleich zu Beginn des Makros pr&uuml;fen, ob sich der Inhalt des Feldes <b>GeaendertAm <\/b>ge&auml;ndert hat. Falls ja, sollen keine weiteren Aktionen folgen, falls nein, wurde die &auml;nderung vermutlich durch eine andere Aktion ausgel&ouml;st. <\/p>\n<p><b>L&ouml;schvorgang dokumentieren<\/b><\/p>\n<p>Das Dokumentieren des L&ouml;schens von Datens&auml;tzen ist eine interessante Sache: Wenn Sie einen Datensatz l&ouml;schen, wohin sollen Sie dann sein L&ouml;schdatum schreiben<\/p>\n<p>Ungeachtet der anderen M&ouml;glichkeiten gehen wir f&uuml;r diesen Fall davon aus, dass wir den Datensatz nicht wirklich l&ouml;schen, sondern nur sein L&ouml;schdatum eintragen.<\/p>\n<p>Das bedeutet nat&uuml;rlich, dass die Formulare und andere Objekte, die auf die Daten dieser Tabelle zugreifen, die Datenherkunft nach dem L&ouml;schdatum filtern m&uuml;ssen, um keine bereits gel&ouml;schten Daten mehr anzuzeigen.<\/p>\n<p>Das ist wiederum eine interessante Anforderung, wenn es um das entsprechende Datenmakro geht: Dieses soll ja nun beim L&ouml;schen des Datensatzes nicht nur ein L&ouml;schdatum eintragen, sondern gleichzeitig auch noch daf&uuml;r sorgen, dass der Datensatz gar nicht gel&ouml;scht wird.<\/p>\n<p>Beides ist problematisch. Sie k&ouml;nnen das L&ouml;schen nur im <b>Vor L&ouml;schung<\/b>-Ereignis verhindern, indem Sie dort einen Fehler ausl&ouml;sen. Dieser zeigt jedoch standardm&auml;&szlig;ig eine Fehlermeldung an.<\/p>\n<p>Sie k&ouml;nnen allerdings etwa in Formularen oder unter VBA auf diesen Fehler reagieren und die Anzeige der entsprechenden Fehlermeldung verhindern.<\/p>\n<p>Leider l&ouml;st dies nicht das zweite Problem: Sie k&ouml;nnen im <b>Vor L&ouml;schung<\/b>-Datenmakro definitiv keine &auml;nderung von Daten ausf&uuml;hren. Das hei&szlig;t, dass wir kein L&ouml;schdatum in die Tabelle eintragen k&ouml;nnen.<\/p>\n<p>Wer also gel&ouml;schte Datens&auml;tze in der Tabelle belassen m&ouml;chte, kommt auf diesem Wege nicht weiter. Aber es gibt eine Alternative: Wir verwenden einfach das <b>Nach L&ouml;schung<\/b>-Datenmakro. Darin k&ouml;nnen wir noch auf alle Daten des gel&ouml;schten Datensatzes zugreifen und diesen somit rekonstruieren &#8211; nat&uuml;rlich nicht, ohne das L&ouml;schdatum entsprechend einzutragen. Dieses Makro sieht wie in Bild 15 aus.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_01\/Datenmakros-web-images\/pic015.png\" alt=\"pic015.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 15: Kopieren statt L&ouml;schen<\/span><\/b><\/p>\n<p><b>Vor Aktualisierung<\/b><\/p>\n<p>Warum verwenden wir eigentlich das <b>Nach Aktualisierung<\/b>-Datenmakro zum Schreiben der &auml;nderungshistorie und nicht das Makro <b>Vor &auml;nderung<\/b> Vermutlich, weil wir sicher sein wollen, dass die Daten auch nicht mehr ge&auml;ndert werden, bevor wir die Historie anpassen.<\/p>\n<p>Auch wenn wir in diesem Beitrag kein Beispiel mehr dazu liefern, wollen wir doch eine Eigenschaft dokumentieren, die nur im <b>Vor &auml;nderung<\/b>-Datenmakro verf&uuml;gbar ist: Sie hei&szlig;t <b>IstEingef&uuml;gt<\/b> (englisch: <b>IsInserted<\/b>) und gibt an, ob die aktuelle &auml;nderung durch das Neuanlegen eines Datensatzes ausgel&ouml;st wurde oder ob es sich um eine an einem bestehenden Datensatz durchgef&uuml;hrte &auml;nderung handelt.<\/p>\n<p>Dies ist deshalb wichtig, weil das Makro <b>Vor &auml;nderung <\/b>sowohl beim Anlegen eines neuen Datensatzes als auch bei &auml;nderungen an einem bestehenden Datensatz ausgel&ouml;st wird.<\/p>\n<p>Das Makro <b>Vor &auml;nderung <\/b>hat jedoch gegen&uuml;ber den beiden Makros <b>Nach Einf&uuml;gen <\/b>und <b>Nach Aktualisierung <\/b>einen deutlich eingeschr&auml;nkten Befehlsumfang. So k&ouml;nnen Sie von dort beispielsweise keine Eintr&auml;ge in der Tabelle <b>USysApplicationLog <\/b>speichern.<\/p>\n<p><b>Verwendung der Alias-Eigenschaft<\/b><\/p>\n<p>Sicher ist Ihnen in verschiedenen Makro-Aktionen die Alias-Eigenschaft aufgefallen, die wir bisher ignoriert haben. Diese Eigenschaft hat prinzipiell die gleiche Funktion wie unter SQL.<\/p>\n<p>Immer, wenn Sie ein Alias festlegen k&ouml;nnen, greifen Sie auf eine Datensatzgruppe mit einem oder mehreren Datens&auml;tzen zu.<\/p>\n<p>Sie k&ouml;nnen dieser Datensatzgruppe dann statt des Tabellennamens ein Alias wie beispielsweise <b>T1<\/b>, <b>T2 <\/b>oder <b>T3 <\/b>zuweisen. In den folgenden Aktionen greifen Sie dann auf diese Alias-Bezeichnungen zu, was erstens oft Schreibarbeit spart und zweitens meist &uuml;bersichtlicher ist.<\/p>\n<p>Drittens kann es ja sein, dass Sie einmal einen Tabellennamen &auml;ndern (auch wenn das nur in fr&uuml;hen Phasen der Entwicklung einer Anwendung geschehen sollte).<\/p>\n<p>Dann brauchen Sie den Tabellennamen nicht an jeder Stelle zu &auml;ndern, sondern nur dort, wo Sie das Alias eingetragen haben.<\/p>\n<p><b>Debuggen<\/b><\/p>\n<p>Ein Debuggen wie unter VBA ist beim Programmieren von Datenmakros nicht m&ouml;glich. Ein n&uuml;tzliches Hilfsmittel ist jedoch die <b>ProtokollierenEreignis<\/b>-Aktion, mit der Sie zu fast jeder Gelegenheit Ausdr&uuml;cke in die Tabelle <b>USysApplicationLog <\/b>schreiben k&ouml;nnen.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Test der Datenmakros <\/p>\n<p>Datenmakros wirken wirklich universell: Egal, ob Sie gleich in der Tabelle &auml;nderungen an den Daten vornehmen, ob Sie dies &uuml;ber eine Abfrage oder ein Formular erledigen oder gar eine der daf&uuml;r vorgesehenen VBA-Techniken verwenden: Datenmakros werden immer ausgef&uuml;hrt.<\/p>\n<p><b>Verschachtelte Daten anlegen<\/b><\/p>\n<p>Wenn Sie als Reaktion auf das Anlegen, &auml;ndern oder L&ouml;schen eines Datenmakros einen Datensatz in einer Tabelle anlegen m&ouml;chten und anschlie&szlig;end auf den Prim&auml;rschl&uuml;sselwert dieses Datensatzes zugreifen m&ouml;chten, k&ouml;nnen Sie diesen mit der Funktion <b>LetztesErstellenDatensatzID <\/b>abrufen.<\/p>\n<p>Diese Funktion arbeitet nur f&uuml;r solche Datens&auml;tze, die tats&auml;chlich mit der Aktion <b>DatensatzErstellen <\/b>(englisch: <b>CreateEntry<\/b>) erstellt wurden.<\/p>\n<p><b>Datenmakros kommen im XML-Format<\/b><\/p>\n<p>M&ouml;glicherweise machen Sie sich Gedanken, wie Sie beispielsweise allen Tabellen Ihrer Datenbank Makros zum Speichern der &auml;nderungshistorie hinzuf&uuml;gen sollen &#8211; immerhin ist der Makro-Editor zwar gegen&uuml;ber fr&uuml;her verbessert, aber Sie k&ouml;nnen beispielsweise nicht per VBA darauf zugreifen (zumindest nicht offensichtlich).<\/p>\n<p>F&uuml;r das Hinzuf&uuml;gen vieler &auml;hnlicher Datenmakros, die sich auf die Felder der Tabelle beziehen, k&ouml;nnen Sie aber per VBA-Code zumindest den entsprechenden XML-Code erstellen und brauchen diesen einfach nur noch in das Datenmakro einzuf&uuml;gen.<\/p>\n<p>Datenmakros werden n&auml;mlich vollst&auml;ndig im XML-Format gespeichert. Sie k&ouml;nnen dies leicht nachvollziehen, indem Sie den Inhalt oder einen Teil des Inhalts eines Datenmakros kopieren und in einen Texteditor oder auch ins VBA-Fenster einf&uuml;gen. Dort erkennen Sie den Aufbau des Makros im XML-Format. Dies gilt &uuml;brigens f&uuml;r alle Makros unter Access 2010.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Datenmakros sind ein faszinierendes Werkzeug. Endlich k&ouml;nnen auch Access-Entwickler von einem Trigger-&auml;hnlichen Konstrukt profitieren, das in der Welt der SQL-Server l&auml;ngst gang und g&auml;be ist.<\/p>\n<p>Zu verdanken haben wir dies wohl der Tatsache, dass das Access-Entwicklerteam seit der Version 2007 von Access mit einer eigenen Version der Jet Engine arbeitet, der sogenannten ACE. So konnte man dort endlich Features integrieren, ohne R&uuml;cksicht auf die zahlreichen anderen Anwendungen zu nehmen, welche die Jet Engine verwenden.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>Datenmakros.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{406DF130-03EE-4F7C-AF57-24AF95E1A987}\/aiu_760.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Seit Jahren w&uuml;nscht die Access-Entwicklergemeinde sich Trigger. Damit legt man gleich im Tabellenentwurf fest, was geschieht, wenn ein Benutzer Datens&auml;tze anlegt, bearbeitet oder l&ouml;scht. Doch diese n&uuml;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&uuml;r Access verf&uuml;gbar machen. Wir schauen uns an, was dabei herausgekommen ist.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66012011,662011,44000025],"tags":[],"class_list":["post-55000760","post","type-post","status-publish","format-standard","hentry","category-66012011","category-662011","category-VBA_und_Programmiertechniken"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Datenmakros in Access 2010 - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Datenmakros in Access 2010\" \/>\n<meta property=\"og:description\" content=\"Seit Jahren w&uuml;nscht die Access-Entwicklergemeinde sich Trigger. Damit legt man gleich im Tabellenentwurf fest, was geschieht, wenn ein Benutzer Datens&auml;tze anlegt, bearbeitet oder l&ouml;scht. Doch diese n&uuml;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&uuml;r Access verf&uuml;gbar machen. Wir schauen uns an, was dabei herausgekommen ist.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T22:01:24+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg01.met.vgwort.de\/na\/9d85cd8e79734321be369c0fca6e98e2\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"23\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Datenmakros in Access 2010\",\"datePublished\":\"2020-05-22T22:01:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/\"},\"wordCount\":4669,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/9d85cd8e79734321be369c0fca6e98e2\",\"articleSection\":[\"1\\\/2011\",\"2011\",\"VBA und Programmiertechniken\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/\",\"name\":\"Datenmakros in Access 2010 - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/9d85cd8e79734321be369c0fca6e98e2\",\"datePublished\":\"2020-05-22T22:01:24+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/9d85cd8e79734321be369c0fca6e98e2\",\"contentUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/9d85cd8e79734321be369c0fca6e98e2\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datenmakros_in_Access_2010\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Datenmakros in Access 2010\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Datenmakros in Access 2010 - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/","og_locale":"de_DE","og_type":"article","og_title":"Datenmakros in Access 2010","og_description":"Seit Jahren w&uuml;nscht die Access-Entwicklergemeinde sich Trigger. Damit legt man gleich im Tabellenentwurf fest, was geschieht, wenn ein Benutzer Datens&auml;tze anlegt, bearbeitet oder l&ouml;scht. Doch diese n&uuml;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&uuml;r Access verf&uuml;gbar machen. Wir schauen uns an, was dabei herausgekommen ist.","og_url":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T22:01:24+00:00","og_image":[{"url":"http:\/\/vg01.met.vgwort.de\/na\/9d85cd8e79734321be369c0fca6e98e2","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"23\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Datenmakros in Access 2010","datePublished":"2020-05-22T22:01:24+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/"},"wordCount":4669,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/9d85cd8e79734321be369c0fca6e98e2","articleSection":["1\/2011","2011","VBA und Programmiertechniken"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/","url":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/","name":"Datenmakros in Access 2010 - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/9d85cd8e79734321be369c0fca6e98e2","datePublished":"2020-05-22T22:01:24+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/#primaryimage","url":"http:\/\/vg01.met.vgwort.de\/na\/9d85cd8e79734321be369c0fca6e98e2","contentUrl":"http:\/\/vg01.met.vgwort.de\/na\/9d85cd8e79734321be369c0fca6e98e2"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Datenmakros_in_Access_2010\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Datenmakros in Access 2010"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000760","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55000760"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000760\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000760"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000760"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000760"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}