{"id":55000929,"date":"2014-04-01T00:00:00","date_gmt":"2020-05-22T21:19:55","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=929"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Wiederherstellungspunkt_fuer_Daten","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/","title":{"rendered":"Wiederherstellungspunkt f&uuml;r Daten"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg07.met.vgwort.de\/na\/8c7397683f2e4260bd86b0f405774d0e\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>W&auml;hrend Sie eine Datenbank entwickeln, geben Sie Beispieldaten ein, testen die neu hinzugef&uuml;gten Formulare und VBA-Prozeduren anhand dieser Daten, pr&uuml;fen das Ergebnis und stellen die Beispieldaten gegebenenfalls wieder her, um weitere Tests mit ge&auml;nderten Prozeduren durchzuf&uuml;hren. Bei komplizierteren Prozeduren kann dies einige Iterationen in Anspruch nehmen und das manuelle Bereitstellen der Testdaten wird zu einer hinderlichen und zeitraubenden Prozedur. Zu diesem Zweck stellen wir im vorliegenden Beitrag Techniken vor, mit denen Sie per Knopfdruck alle Daten aus definierten Tabellen sichern und diese mit einem weiteren Knopfdruck wiederherstellen.<\/b><\/p>\n<p>Wenn Sie eine neue Datenbank entwickeln, stehen Sie ohnehin zun&auml;chst einmal vor dem Problem, dass Sie schnell Beispieldaten f&uuml;r ein oder mehrere Tabellen erstellen m&uuml;ssen. F&uuml;r diesen Fall empfiehlt sich immer noch die Nutzung des Tools aus dem Beitrag <b>Der Beispieldaten-Assistent <\/b>(<b>www.access-im-unternehmen.de\/745<\/b>).<\/p>\n<p>Wenn Sie aber damit einmal brauchbare Beispieldaten entworfen haben, m&ouml;chten Sie diesen Assistenten vermutlich nicht nach jeder &auml;nderung der Daten erneut heranziehen &#8211; zumal dieser immer nur eine Tabelle gleichzeitig f&uuml;llen kann und dies bei mehreren Tabellen doch aufwendig wird.<\/p>\n<p><b>Tests &auml;ndern Daten<\/b><\/p>\n<p>Nun haben Sie aber vielleicht eine Datenbank mit einem Datenmodell entworfen, das mehrere verkn&uuml;pfte Tabellen enth&auml;lt, die Sie mehr oder weniger m&uuml;hsam mit Testdaten gef&uuml;llt haben. Dann f&uuml;hren Sie ein paar Tests mit frisch erstellten Formularen oder neu programmierten Routinen durch und &auml;ndern die Daten dabei &#8211; Sie &auml;ndern Feldinhalte, f&uuml;gen neue Datens&auml;tze hinzu oder l&ouml;schen vorhandene Datens&auml;tze. Wenn die zu testenden Aktionen nicht das gew&uuml;nschte Ergebnis bringen, m&ouml;chten Sie diese m&ouml;glichst mit den gleichen Testdaten erneut durchf&uuml;hren. Dazu m&uuml;ssen Sie aber die Testdaten wiederherstellen.<\/p>\n<p><b>Programmlogik und Daten als Backup<\/b><\/p>\n<p>Eine Methode w&auml;re es, vor dem Durchf&uuml;hren ein Backup der Datenbank herzustellen und nach missgl&uuml;cktem Test mit dem vorherigen Stand weiterzuarbeiten. Keine schlechte Idee, aber dadurch, dass Sie immer komplett auf eine vorherige Version zur&uuml;ckgreifen, verlieren Sie m&ouml;glicherweise auch &auml;nderungen, die Sie beim Testen etwa beim Debuggen des Codes durchgef&uuml;hrt haben.<\/p>\n<p><b>Tabellenbackup per Backend<\/b><\/p>\n<p>Die zweite Variante w&auml;re es, die Daten komplett in ein Backend auszulagern und dieses vor dem &auml;ndern der Daten zu kopieren und anschlie&szlig;end wiederherzustellen. Damit w&uuml;rden Sie auf jeden Fall die &auml;nderungen der Programmlogik beibehalten, da Sie das Frontend nicht austauschen m&uuml;ssen.<\/p>\n<p>Dies bedeutet allerdings auch, dass Sie die Datenbank gleich zu Beginn aufteilen m&uuml;ssen. Wenn allerdings auch das Datenmodell noch nicht komplett ausgereift ist, kommt weiterer Aufwand auf Sie zu:<\/p>\n<p>Sie m&uuml;ssen beispielsweise die Tabellen nach jeder &auml;nderung des Datenmodells neu mit dem Frontend verkn&uuml;pfen und m&uuml;ssen &uuml;berdies aufpassen, dass Sie keine &auml;nderungen am Backend vornehmen und dieses dann durch eine &auml;ltere Version des Backends ersetzen.<\/p>\n<p><b>Reines Datenbackup<\/b><\/p>\n<p>Es gibt noch eine dritte Methode, auf die wir in diesem Beitrag detaillierter eingehen. Diese soll es erlauben, per Knopfdruck eine Kopie aller aktuell in der Datenbank verwendeten Tabellen zu erstellen und die in den Kopien enthaltenen Daten ebenfalls per Knopfdruck in die Tabellen zur&uuml;ckzuschreiben.<\/p>\n<p>Das bedeutet, dass im ersten Schritt f&uuml;r jede Tabelle der Datenbank eine Kopie angelegt wird, deren Name beispielsweise aus dem Namen der Originaltabelle plus einem Zusatz besteht, sodass aus <b>tblKunden <\/b>beispielsweise <b>tblKunden_Backup <\/b>wird. Dieser Vorgang ist nicht besonders aufwendig: Mit einer <b>SELECT INTO<\/b>-Anweisung erstellen Sie schnell eine neue Tabelle auf Basis einer bestehenden Tabelle, welche genauso aufgebaut ist wie die Originaltabelle und auch gleich mit den identischen Daten gef&uuml;llt wird.<\/p>\n<p>Im zweiten Schritt m&uuml;ssen dann nur die ge&auml;nderten Inhalte der Originaltabellen gel&ouml;scht und durch die gespeicherten Inhalte ersetzt werden. Einfacher geht es doch nicht!<\/p>\n<p>Leider gibt es einen kleinen Haken: Wenn die Tabellen miteinander verkn&uuml;pft sind und f&uuml;r die Beziehungen referenzielle Integrit&auml;t definiert ist, dann k&ouml;nnen Sie die Daten nicht in beliebiger Reihenfolge anlegen. Angenommen, die Tabelle <b>tblKunden <\/b>enth&auml;lt ein Fremdschl&uuml;sselfeld namens <b>AnredeID<\/b>, das zur Auswahl der Datens&auml;tze der Tabelle <b>tblAnreden <\/b>dient, und es gibt eine Beziehung mit referenzieller Integrit&auml;t zwischen dem Feld <b>AnredeID <\/b>der Tabelle <b>tblKunden <\/b>und dem gleichnamigen Feld der Tabelle <b>tblAnreden<\/b>. Dann k&ouml;nnen Sie zwar erst die Datens&auml;tze der Tabelle <b>tblAnredeID <\/b>hinzuf&uuml;gen und dann die Datens&auml;tze der Tabelle <b>tblKunden<\/b>, aber nicht umgekehrt: Beim Hinzuf&uuml;gen eines Datensatzes zur Tabelle <b>tblKunden<\/b>, dessen Feld <b>AnredeID <\/b>einen Wert enth&auml;lt, der noch nicht in der Tabelle <b>tblAnreden <\/b>enthalten ist, erhalten Sie einen entsprechenden Fehler.<\/p>\n<p>Das bedeutet, dass wir vor dem Wiederherstellen der Tabellen dringend die richtige Reihenfolge zum Wiederherstellen ermitteln und die Wiederherstellung in dieser Reihenfolge durchf&uuml;hren m&uuml;ssen. Die Ermittlung der richtigen Reihenfolge ist der aufwendigere Teil der geplanten L&ouml;sung.<\/p>\n<p><b>Formular als Schaltzentrale<\/b><\/p>\n<p>Als Erstes wollen wir ein Formular erstellen, das als Schaltzentrale f&uuml;r die Funktionen zum Sichern und Wiederherstellen der Tabellen dient. Das Formular hei&szlig;t <b>frmSichernUndWiederherstellen <\/b>und soll zun&auml;chst zwei Schaltfl&auml;chen im Fu&szlig;bereich des Formulars enthalten. Die Schaltfl&auml;che <b>cmdSichern <\/b>soll zun&auml;chst alle in der Datenbank enthaltenen Tabellen kopieren. Die Schaltfl&auml;che <b>cmdWiederherstellen <\/b>soll die vorhandenen Tabellen mit den Daten aus den gesicherten Tabellen f&uuml;llen.<\/p>\n<p>Das Formular sieht im derzeitigen Zustand wie in Bild 1 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_02\/pic_929_001.png\" alt=\"Erster Entwurf des Formulars frmSichernUndWiederherstellen\" width=\"575\" height=\"373,2456\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Erster Entwurf des Formulars frmSichernUndWiederherstellen<\/span><\/b><\/p>\n<p><b>Tabellen sichern<\/b><\/p>\n<p>Um die Tabellen zu sichern, ben&ouml;tigen wir eine entsprechende Aktionsabfrage. Diese wollen wir per VBA dynamisch f&uuml;r alle in der Datenbank enthaltenen Tabellen zusammensetzen und ausf&uuml;hren.<\/p>\n<p>Wer unsicher in der Formulierung der entsprechenden SQL-Ausdr&uuml;cke ist, kann jederzeit die Entwurfsansicht f&uuml;r die Erstellung von Abfragen zuhilfe nehmen. In diesem Fall legen Sie eine neue Abfrage an, f&uuml;gen dieser etwa die Tabelle <b>tblKategorien <\/b>hinzu und ziehen alle Felder in das Entwurfsraster (alternativ reicht auch das Hinzuf&uuml;gen des Sternchens stellvertretend f&uuml;r alle Felder der Tabelle).<\/p>\n<p>Dann klicken Sie wie in Bild 2 auf die Schaltfl&auml;che <b>Ent-wurf|Ab-frage-typ|Ta-belle er-stellen<\/b>. Dies ruft die Anzeige des Dialogs aus Bild 3 hervor, mit dem Sie den Namen der zu erstellenden Tabelle angeben und gegebenenfalls eine andere Zieldatenbank festlegen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_02\/pic_929_003.png\" alt=\"Angabe des Namens der zu erstellenden Tabelle\" width=\"575\" height=\"296,933\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Angabe des Namens der zu erstellenden Tabelle<\/span><\/b><\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_02\/pic_929_002.png\" alt=\"&auml;ndern einer Auswahlabfrage in eine Tabellenerstellungsabfrage\" width=\"575\" height=\"326,2516\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: &auml;ndern einer Auswahlabfrage in eine Tabellenerstellungsabfrage<\/span><\/b><\/p>\n<p>Es tut sich zun&auml;chst nichts, aber wenn Sie nun in die SQL-Ansicht der soeben erstellten Abfrage wechseln, erhalten Sie einen SQL-Ausdruck, der mit <b>SELECT&#8230;INTO <\/b>beginnt und einer Tabellenerstellungsabfrage entspricht:<\/p>\n<pre>SELECT KategorieID, Kategoriename, \r\nBeschreibung, \r\nAbbildung \r\nINTO tblKategorien_Backup\r\nFROM tblKategorien;<\/pre>\n<p>Unter Verwendung des Sternchens ginge dies noch k&uuml;rzer:<\/p>\n<pre>SELECT * INTO tblKategorien_Backup\r\nFROM tblKategorien;<\/pre>\n<p><b>VBA-Prozedur zum Sichern der Tabellen<\/b><\/p>\n<p>Damit k&ouml;nnen wir nun bereits die VBA-Prozedur zum Erstellen der Tabellenkopien anlegen. Diese sieht im ersten Anlauf wie in Listing 1 aus. Die Prozedur durchl&auml;uft alle <b>TableDef<\/b>-Objekte der Datenbank und kopiert diese mit der <b>SELECT&#8230;INTO<\/b>-Anweisung in eine neue Tabelle, die mit dem Zusatz <b>_Backup <\/b>ausgestattet wird.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdSichern_Click()\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>tdf<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     For Each tdf In db.TableDefs\r\n         db.Execute \"SELECT * INTO \" & tdf.Name & \"_Backup FROM \" & tdf.Name\r\n     <span style=\"color:blue;\">Next<\/span> tdf\r\n     <span style=\"color:blue;\">Set<\/span> db = Nothing\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Prozedur zum Sichern aller Tabellen der Datenbank<\/span><\/b><\/p>\n<p>Der erste Test liefert gleich ein kleines Problem zutage, wie Bild 4 zeigt: Anscheinend enth&auml;lt eine der zu kopierenden Tabellen ein mehrwertiges Feld, was zu dem angezeigten Fehler f&uuml;hrt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_02\/pic_929_004.png\" alt=\"Fehler beim Kopieren einer Tabelle mit Mehrfachwertfeld\" width=\"400\" height=\"221,5385\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Fehler beim Kopieren einer Tabelle mit Mehrfachwertfeld<\/span><\/b><\/p>\n<p>Mehrwertige Felder sollte man nicht unbedingt nutzen, was aber dennoch nichts an der Frage &auml;ndert, in welcher Tabelle sich dieses Feld befindet. Ein Klick auf Debuggen und die Analyse des aktuellen Wertes von <b>tdf.Name <\/b>liefert die schuldige Tabelle: Es handelt sich um die Systemtabelle <b>MSysResources<\/b>.<\/p>\n<p>Bei dem Feld, das den Fehler ausl&ouml;st, handelt es sich genau genommen aber nicht um ein mehrwertiges Feld, sondern um ein Anlagefeld. Diese beiden Feldtypen lassen sich also nicht mit der <b>SELECT&#8230;INTO<\/b>-Anweisung kopieren.<\/p>\n<p>Ein weiterer Fehler kann auftreten, wenn  die Datenbank tempor&auml;re Tabellen enth&auml;lt, deren Name mit dem Tilde-Zeichen (<b>~<\/b>) beginnt (Fehlermeldung s. Bild 5). Beide schlie&szlig;en wir der Einfachheit halber zun&auml;chst aus, indem wir der Prozedur eine Bedingung hinzuf&uuml;gen, die nur noch solche Tabellen kopiert, die mit <b>tbl <\/b>beginnen (s. Listing 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_02\/pic_929_005.png\" alt=\"Fehler beim Kopieren einer tempor&auml;ren Tabelle\" width=\"400\" height=\"221,5385\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Fehler beim Kopieren einer tempor&auml;ren Tabelle<\/span><\/b><\/p>\n<p>Auf diese Weise schlie&szlig;en wir aktuell Tabellen aus, die entweder als Systemtabelle oder durch die Tilde (~) als erstes Zeichen als tempor&auml;re Tabelle gekennzeichnet sind.<\/p>\n<p>Nun haben wir zwar gesagt, dass man als professioneller Access-Entwickler keine mehrwertigen Felder verwendet (der Grund ist, dass diese Beziehungen in verborgenen Tabellen verwalten).<\/p>\n<p>Allerdings wird man bei Verwendung der neueren Access-Versionen (ab Access 2007) nicht um die Verwendung von Anlage-Feldern herumkommen.<\/p>\n<p>Und diese l&ouml;sen, wie oben gesehen, ebenfalls  Fehler aus, wenn Sie diese per <b>SELECT&#8230;INTO<\/b>-Anweisung in eine neue Tabelle kopieren m&ouml;chten.<\/p>\n<p>Eines vorweg: Wir haben zwar M&ouml;glichkeiten gefunden, die Inhalte von Anlagefeldern von einer in die andere Tabelle zu verschieben, aber das Erstellen von Anlagefeldern per Tabellenerstellungsabfrage scheint nicht m&ouml;glich zu sein. Deshalb gehen wir einen kleinen Umweg: Wir erstellen die neue Tabelle, die auch die Daten des Anlagefeldes aufnehmen soll, zwar mit <b>SELECT INTO<\/b>.<\/p>\n<p>Statt das Anlagefeld wie die &uuml;brigen Felder direkt zu kopieren, legen wir jedoch nur die in diesem Zusammenhang ben&ouml;tigten Felder der dem Anlagefeld untergeordneten Tabelle an &#8211; in diesem Fall <b>FileData <\/b>und <b>FileName<\/b>. Die entsprechende <b>SELECT INTO<\/b>-Abfrage soll dann wie folgt aussehen:<\/p>\n<pre>SELECT Data.FileData AS Data_FileData, \r\nData.FileName AS Data_FileName, \r\nExtension, Id, Name, Type \r\nINTO _tblResources_Backup \r\nFROM tblResources<\/pre>\n<p>Die Zielfelder haben wir mit dem Unterstrich statt mit dem Punkt ausgestattet, weil der Punkt nicht als Teil von Feldnamen verwendet werden darf. Aus <b>Data.FileData <\/b>wird so in der Backuptabelle <b>Data_FileData<\/b>. Nach dem Kopieren soll etwa die Tabelle <b>tblResources <\/b>(welche der Systemtabelle <b>MSysResources <\/b>entspricht, die wir zu Testzwecken in <b>tblResources <\/b>kopiert haben) so wie die Tabelle <b>_tblResources_Backup <\/b>aussehen (s. Bild 6).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_02\/pic_929_006.png\" alt=\"Tabellen mit Anlagefeld und die Backup-Tabelle mit den entsprechenden Feldern\" width=\"650\" height=\"356,8121\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Tabellen mit Anlagefeld und die Backup-Tabelle mit den entsprechenden Feldern<\/span><\/b><\/p>\n<p>Schauen wir uns nun die modifizierte Variante der Prozedur <b>cmdSichern_Click <\/b>an, die jetzt auch Anlagefelder sichert (s. Listing 3). Diese durchl&auml;uft wiederum per <b>For Each<\/b>-Schleife alle Tabellen der Datenbank und ber&uuml;cksichtigt darin alle Tabellen, die mit <b>tbl <\/b>beginnen. Die Variable <b>strFelder <\/b>soll die Liste aller zu ber&uuml;cksichtenden Felder aufnehmen. Mit einem Sternchen (*) f&uuml;r alle Felder ist es nicht getan, da wir ja den Feldern des Anlagefeldes eine Sonderbehandlung angedeihen lassen m&uuml;ssen.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdSichern_Click()\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>tdf<span style=\"color:blue;\"> As <\/span>DAO.TableDef\r\n     <span style=\"color:blue;\">Dim <\/span>fld<span style=\"color:blue;\"> As <\/span>DAO.Field\r\n     <span style=\"color:blue;\">Dim <\/span>strFelder<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strSQL<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     For Each tdf In db.TableDefs\r\n         <span style=\"color:blue;\">If <\/span>tdf.Name Like \"tbl*\"<span style=\"color:blue;\"> Then<\/span>\r\n             strFelder = \"\"\r\n             For Each fld In tdf.Fields\r\n                 Select Case fld.Type\r\n                     <span style=\"color:blue;\">Case <\/span>dbAttachment\r\n                         strFelder = strFelder & \", \" & fld.Name & \".FileData AS \" _\r\n                             & fld.Name & \"_FileData, \" & fld.Name & \".FileName AS \" _\r\n                             & fld.Name & \"_FileName, \" & fld.Name & \".FileType AS \" _\r\n                             & fld.Name & \"_FileType\" \r\n                     <span style=\"color:blue;\">Case <\/span>dbComplexByte, dbComplexDecimal, dbComplexDouble, dbComplexGUID, _\r\n                             dbComplexInteger, dbComplexLong, _\r\n                             dbComplexSingle, dbComplexText\r\n                         <span style=\"color:blue;\">MsgBox<\/span> \"Mehrwertige Felder werden nicht unterst&uuml;tzt.\"\r\n                     <span style=\"color:blue;\">Case Else<\/span>\r\n                         strFelder = strFelder & \", \" & fld.Name\r\n                 <span style=\"color:blue;\">End Select<\/span>\r\n             <span style=\"color:blue;\">Next<\/span> fld\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strFelder) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n                 strFelder = <span style=\"color:blue;\">Mid<\/span>(strFelder, 3)\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             strSQL = \"SELECT \" & strFelder & \" INTO _\" & tdf.Name & \"_Backup FROM \" & tdf.Name\r\n             On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n             db.Execute \"DROP TABLE _\" & tdf.Name & \"_Backup\", dbFailOnError\r\n             <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n             db.Execute strSQL, dbFailOnError\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> tdf\r\n     <span style=\"color:blue;\">Set<\/span> db = Nothing\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><!--30percent--><\/p>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Kopieren der Inhalte aller Tabellen inklusive Anlagefelder<\/span><\/b><\/p>\n<p>Die folgende <b>For Each<\/b>-Schleife durchl&auml;uft alle Felder des <b>TableDef<\/b>-Objekts f&uuml;r die aktuelle Tabelle.<\/p>\n<p>Dabei unterscheidet die Prozedur in einer <b>Select Case<\/b>-Bedingung nach dem Typ des Feldes. Lautet dieser <b>dbAttachment<\/b>, handelt es sich um ein Anlagefeld. F&uuml;r dieses f&uuml;gt die Prozedur einen Ausdruck wie den folgenden zur Variablen <b>strFelder <\/b>hinzu:<\/p>\n<pre>, Data.FileData AS Data_FileData\r\n, Data.FileName AS Data_FileName<\/pre>\n<p>F&uuml;r alle anderen Felddatentypen wird <b>strFelder <\/b>einfach nur um ein f&uuml;hrendes Komma und den Feldnamen erweitert. Mehrwertige Felder werden nicht ber&uuml;cksichtigt. Wenn eine Tabelle ein mehrwertiges Feld enth&auml;lt, zeigt die Prozedur lediglich einen entsprechenden Hinweis an.<\/p>\n<p>Wenn <b>strFelder<\/b> eine Zeichenkette mit einer L&auml;nge gr&ouml;&szlig;er als <b>0 <\/b>enth&auml;lt (was der Regelfall ist, aber sicher ist sicher), schneidet die Prozedur die ersten beiden Zeichen ab, welche dem f&uuml;hrenden Komma und einem Leerzeichen entsprechen.<\/p>\n<p>Dann f&uuml;gt die Prozedur die SQL-Anweisung zum Kopieren der Daten der aktuellen Tabelle in eine neue Tabelle zusammen und speichert das Ergebnis in der Variablen <b>strSQL<\/b>. Dabei verwendet die Prozedur als Namen der Zieltabelle den Namen der Quelltabelle mit f&uuml;hrendem Unterstrich und nachfolgendem <b>_Backup<\/b>. Wie die Anweisung f&uuml;r die Tabelle <b>tblResources <\/b>aussieht, haben wir bereits weiter oben dargestellt. Anschlie&szlig;end l&ouml;scht die Prozedur eine eventuell vorhandene Tabelle mit dem gleichen Namen wie die Backuptabelle und f&uuml;hrt die in <b>strSQL <\/b>gespeicherte <b>SELECT INTO<\/b>-Abfrage aus.<\/p>\n<p><b>Wiederherstellen der Daten<\/b><\/p>\n<p>Nun gehen wir davon aus, dass der Benutzer mit der <b>Sichern<\/b>-Schaltfl&auml;che eine Sicherung der Tabellen mit dem Pr&auml;fix <b>tbl<\/b> erstellt hat und dann die Daten der betroffenen Tabellen ordentlich durcheinandergebracht hat &#8211; genau so, dass er nun gern den vorherigen Stand wiederherstellen m&ouml;chte.<\/p>\n<p>Genau f&uuml;r diesen Zweck haben wir die Schaltfl&auml;che <b>cmdWiederherstellen <\/b>vorbereitet. Diese l&ouml;st die folgende Prozedur aus:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdWiederherstellen_Click()\r\n     TabellenLeeren\r\n     TabellenWiederherstellen\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die erste hier aufgerufene Prozedur soll die Inhalte der Originaltabellen l&ouml;schen, die zweite die Inhalte aus dem Backup wiederherstellen.<\/p>\n<p>Warum nicht einfach die Tabellen komplett l&ouml;schen und dann wiederherstellen Dies ginge auch, w&auml;re aber deutlich aufwendiger. Ein wichtiger Grund ist, dass wir mit den <b>SELECT INTO<\/b>-Anweisungen zum Erstellen der Backup-Tabellen tats&auml;chlich nur Tabellen mit den korrekten Felddatentypen und Inhalten erstellt haben &#8211; weitere Attribute wie etwa die Definition von Prim&auml;rschl&uuml;sseln, Fremdschl&uuml;sseln, Beziehungen et cetera wurden nicht gespeichert. Wir m&uuml;ssen also die Originaltabellen behalten, wenn wir den Vorgang auf eine einfache Weise abschlie&szlig;en m&ouml;chten.<\/p>\n<p>Schauen wir uns zun&auml;chst die Prozedur <b>TabellenLeeren <\/b>an. Im ersten Anlauf w&uuml;rde man diese Prozedur, die alle Tabellen mit dem Pr&auml;fix <b>tbl <\/b>leeren soll, vermutlich wie folgt definieren:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TabellenLeeren()\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>tdf<span style=\"color:blue;\"> As <\/span>DAO.TableDef\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     For Each tdf In db.TableDefs\r\n         <span style=\"color:blue;\">If <\/span>tdf.Name Like \"tbl*\"<span style=\"color:blue;\"> Then<\/span>\r\n             db.Execute \"DELETE FROM \" _\r\n                 & tdf.Name, dbFailOnError\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> tdf\r\n     <span style=\"color:blue;\">Set<\/span> db = Nothing\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Dies liefert aber dummerweise die Fehlermeldung aus Bild 7, wenn die Tabelle mit den zu l&ouml;schenden Daten die Mastertabelle einer mit referenzieller Integrit&auml;t ohne L&ouml;schweitergabe definierten Beziehung darstellt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_02\/pic_929_007.png\" alt=\"Fehler beim Versuch, Daten aus verkn&uuml;pften Tabellen zu l&ouml;schen\" width=\"450\" height=\"249,2307\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Fehler beim Versuch, Daten aus verkn&uuml;pften Tabellen zu l&ouml;schen<\/span><\/b><\/p>\n<p><b>Tabellen in der richtigen Reihenfolge leeren<\/b><\/p>\n<p>Wir m&uuml;ssen in diesem Fall zuerst die Daten der Detailtabelle dieser Beziehung l&ouml;schen und erst dann die Daten der Mastertabelle. Wie aber bestimmen wir die richtige Reihenfolge zum L&ouml;schen der Daten in den Tabellen Dazu haben wir im Beitrag <b>L&ouml;sch- und Kopierreihenfolge f&uuml;r Tabellen <\/b>(<b>www.access-im-unternehmen.de\/926<\/b>) eine entsprechende Funktion vorgestellt. Diese hei&szlig;t <b>TabellenreihenfolgeLoeschen <\/b>und liefert eine Collection mit den Tabellen in der richtigen Reihenfolge zur&uuml;ck, sodass Sie die enthaltenen Tabellen ohne Fehlermeldungen leeren k&ouml;nnen (Sie finden die Funktion im Modul <b>mdlTools <\/b>der Beispieldatenbank).<\/p>\n<p>Die neue Version der Prozedur <b>TabellenLeeren <\/b>sieht nun wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TabellenLeeren()\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>colTabellen<span style=\"color:blue;\"> As <\/span>Collection\r\n     <span style=\"color:blue;\">Dim <\/span>var<span style=\"color:blue;\"> As Variant<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     <span style=\"color:blue;\">Set<\/span> colTabellen = _\r\n         TabellenreihenfolgeLoeschen\r\n     For Each var In colTabellen\r\n         db.Execute \"DELETE FROM \" _\r\n             & var, dbFailOnError\r\n     <span style=\"color:blue;\">Next<\/span> var\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Prozedur f&uuml;llt das <b>Collection<\/b>-Objekt <b>colTabellen <\/b>mit den Tabellen in der f&uuml;r das L&ouml;schen der Daten richtigen Reihenfolge. Die folgende <b>For Each<\/b>-Schleife durchl&auml;uft alle Elemente der Collection.<\/p>\n<p>Innerhalb der <b>For Each<\/b>-Schleife l&ouml;scht eine <b>DELETE<\/b>-Abfrage jeweils alle Datens&auml;tze der aktuell in der Variablen <b>var <\/b>gespeicherten Tabelle. Damit w&auml;re der erste Schritt erledigt &#8211; die vermurksten Daten sind gel&ouml;scht.<\/p>\n<p><b>Daten wiederherstellen<\/b><\/p>\n<p>Damit wenden wir uns der zweiten, etwas aufwendigeren Aufgabe zu: dem Wiederherstellen der Daten aus den Backup-Tabellen.<\/p>\n<p>Hier gibt es zwei Probleme, deren L&ouml;sung wir in andere Beitr&auml;ge ausgelagert haben:<\/p>\n<ul>\n<li>Auch beim Hinzuf&uuml;gen von Datens&auml;tzen zu verkn&uuml;pften Tabellen m&uuml;ssen Sie eine bestimmte Reihenfolge einhalten. Das bedeutet, dass Sie zun&auml;chst die Daten der Mastertabellen anlegen und erst dann die Daten der damit verkn&uuml;pften Detailtabellen. Der bereits weiter oben erw&auml;hnte Beitrag <b>L&ouml;sch- und Kopierreihenfolge f&uuml;r Tabellen <\/b>(<b>www.access-im-unternehmen.de\/926<\/b>) liefert auch hierf&uuml;r eine passende Funktion, die alle Tabellen in der richtigen Reihenfolge zum Einf&uuml;gen der Daten ermittelt. Diese Funktion hei&szlig;t <b>TabellenreihenfolgeKopieren <\/b>(siehe Modul <b>mdlTools<\/b>).<\/li>\n<li>Das Kopieren von Daten per INSERT INTO-Abfrage in ein Anlagefeld kann nicht auf einfache Weise erledigt werden. Aus diesem Grund haben wir uns im Beitrag <b>Datens&auml;tze mit Anlagefeld kopieren <\/b>(<b>www.access-im-unternehmen.de\/930<\/b>) mit dem Kopieren von Datens&auml;tzen mit Anlagefeldern besch&auml;ftigt. Dieser Beitrag liefert unter anderem die Information, dass ein Anlagefeld mit einer separaten <b>INSERT INTO<\/b>-Abfrage kopiert werden muss.<\/li>\n<\/ul>\n<p>Die Prozedur <b>TabelleWiederherstellen<\/b> aus Listing 5 f&uuml;llt zun&auml;chst die Collection <b>colTabellen <\/b>mithilfe der Funktion <b>TabellenreihenfolgeKopieren<\/b>. In einer <b>For Each<\/b>-Schleife &uuml;ber diese Collection durchl&auml;uft die Prozedur dann die Tabelle in der f&uuml;r das Einf&uuml;gen von Datens&auml;tzen korrekten Reihenfolge.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TabellenWiederherstellen()\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>colTabellen<span style=\"color:blue;\"> As <\/span>Collection\r\n     <span style=\"color:blue;\">Dim <\/span>tdf<span style=\"color:blue;\"> As <\/span>DAO.TableDef\r\n     <span style=\"color:blue;\">Dim <\/span>fld<span style=\"color:blue;\"> As <\/span>DAO.Field\r\n     <span style=\"color:blue;\">Dim <\/span>strFelder<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strSQL<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intAnlagefelder<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strSQLAnlagefeld()<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strTabelle<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strPK<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>var<span style=\"color:blue;\"> As Variant<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     <span style=\"color:blue;\">Set<\/span> colTabellen = TabellenreihenfolgeKopieren\r\n     For Each var In colTabellen\r\n         strTabelle = var\r\n         strFelder = \"\"\r\n         intAnlagefelder = 0\r\n         strPK = PrimaerschluesselErmitteln(strTabelle)\r\n         <span style=\"color:blue;\">Set<\/span> tdf = db.TableDefs(strTabelle)\r\n         For Each fld In tdf.Fields\r\n             Select Case fld.Type\r\n                 <span style=\"color:blue;\">Case <\/span>dbAttachment\r\n                     ReDim Preserve strSQLAnlagefeld(intAnlagefelder)\r\n                     strSQLAnlagefeld(intAnlagefelder) = \"INSERT INTO \" & tdf.Name & \"(\" _\r\n                         & fld.Name & \".FileName, \" & fld.Name & \".FileData) SELECT T1.\" _\r\n                         & fld.Name & \"_FileName, T1.\" & fld.Name & \"_FileData FROM (SELECT \" _\r\n                         & fld.Name & \"_FileName, \" & fld.Name & \"_FileData, \" & strPK _\r\n                         & \" FROM _\" & var & \"_Backup) AS T1 WHERE \" & var & \".\" & strPK _\r\n                         & \" = T1.\" & strPK & \";\"\r\n                     intAnlagefelder = intAnlagefelder + 1\r\n                 <span style=\"color:blue;\">Case Else<\/span>\r\n                     strFelder = strFelder & \", \" & fld.Name\r\n             <span style=\"color:blue;\">End Select<\/span>\r\n         <span style=\"color:blue;\">Next<\/span> fld\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strFelder) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n             strFelder = <span style=\"color:blue;\">Mid<\/span>(strFelder, 3)\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         strSQL = \"INSERT INTO \" & tdf.Name & \" SELECT \" & strFelder & \" FROM _\" & tdf.Name & \"_Backup\"\r\n         db.Execute strSQL, dbFailOnError\r\n         <span style=\"color:blue;\">If <\/span>intAnlagefelder &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n             For i = <span style=\"color:blue;\">LBound<\/span>(strSQLAnlagefeld) To <span style=\"color:blue;\">UBound<\/span>(strSQLAnlagefeld)\r\n                 db.Execute strSQLAnlagefeld(i), dbFailOnError\r\n             <span style=\"color:blue;\">Next<\/span> i\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> var\r\n     <span style=\"color:blue;\">Set<\/span> db = Nothing\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Wiederherstellen der Inhalte aller Tabellen inklusive Anlagefelder<\/span><\/b><\/p>\n<p>Dabei wird der Name der Tabelle in der <b>Variant<\/b>-Variablen <b>var <\/b>gespeichert, von wo aus diese gleich an die Variable <b>strTabelle <\/b>&uuml;bergeben wird. Die Prozedur leert die Variable <b>strFelder<\/b>, welche f&uuml;r jede Tabelle die Feldliste der zu kopierenden Felder aufnimmt. Au&szlig;erdem gibt es eine Z&auml;hlervariable f&uuml;r eventuell enthaltene Anlagefelder namens <b>intAnlagefelder<\/b>. Diese stellt die Prozedur f&uuml;r jede neue Tabelle auf den Wert <b>0 <\/b>ein.<\/p>\n<p>Nun ben&ouml;tigen wir zum Zusammenstellen der Abfrage, welche die in einem m&ouml;glicherweise enthaltenen Anlagefeld enthaltenen Daten wiederherstellt, den Namen des Prim&auml;rschl&uuml;sselfeldes von Backup- und Zieltabelle, der gl&uuml;cklicherweise identisch ist.<\/p>\n<p>Diesen ermitteln wir mit der Hilfsfunktion <b>Primaerschl&uuml;ssel-Ermitteln <\/b>aus Listing 4. Diese Funktion durchl&auml;uft alle <b>Index<\/b>-Elemente der mit dem Parameter <b>strTabelle <\/b>&uuml;bergebenen Tabelle und pr&uuml;ft, ob ihre Eigenschaft <b>Primary <\/b>den Wert <b>True <\/b>hat.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>PrimaerschluesselErmitteln(strTabelle<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>tdf<span style=\"color:blue;\"> As <\/span>DAO.TableDef\r\n     <span style=\"color:blue;\">Dim <\/span>idx<span style=\"color:blue;\"> As <\/span>DAO.Index\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     <span style=\"color:blue;\">Set<\/span> tdf = db.TableDefs(strTabelle)\r\n     For Each idx In tdf.Indexes\r\n         <span style=\"color:blue;\">If <\/span>idx.Primary = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n             PrimaerschluesselErmitteln = idx.Fields(0).Name\r\n             <span style=\"color:blue;\">Exit Function<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> idx\r\n     <span style=\"color:blue;\">Set<\/span> db = Nothing\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Diese Prozedur ermittelt den Namen des Prim&auml;rschl&uuml;sselfeldes einer Tabelle.<\/span><\/b><\/p>\n<p>In diesem Fall ermittelt die Funktion den Namen des ersten Feldes, der an dem Index beteiligt ist, und gibt diesen an die aufrufende Routine zur&uuml;ck. Wir gehen an dieser Stelle davon aus, dass keine Tabellen mit mehr als einem Prim&auml;rschl&uuml;sselfeld verwendet werden.<\/p>\n<p>Der Name des Prim&auml;rschl&uuml;sselfeldes landet in der Variablen <b>strPK<\/b>.<\/p>\n<p>Die Prozedur referenziert nun das <b>TableDef<\/b>-Objekt auf Basis der mit <b>strTabelle <\/b>angegebenen Tabelle mit der Variablen <b>tdf <\/b>und durchl&auml;uft in einer <b>For Each<\/b>-Schleife alle Felder dieser Tabellendefinition.<\/p>\n<p>Eine <b>Select Case<\/b>-Bedingung pr&uuml;ft den Datentyp des aktuell mit <b>fld <\/b>referenzierten Feldes. Im Falle eines Anlagefeldes (<b>dbAttachment<\/b>) redimensioniert die Prozedur die Variable <b>strSQLAnlagefeld <\/b>auf die aktuell in <b>intAnlagefelder <\/b>gespeicherte Anzahl von Anlagefeldern, die bisher in dieser Tabelle entdeckt wurden.<\/p>\n<p>Dann weist die Prozedur dem String-Array <b>strSQLAnlagefeld<\/b>() einen Ausdruck hinzu, der die <b>SELECT INTO<\/b>-Anweisung mit der Sonderbehandlung f&uuml;r das Wiederherstellen der Daten des aktuell bearbeiteten Anlagefelds enth&auml;lt.<\/p>\n<p>Der resultierende Ausdruck kann beispielsweise wie folgt aussehen:<\/p>\n<pre>INSERT INTO tblResources(\r\n     Data.FileName, Data.FileData\r\n) SELECT \r\n     T1.Data_FileName, \r\n     T1.Data_FileData \r\nFROM (\r\n     SELECT Data_FileName, \r\n     Data_FileData, Id \r\n     FROM _tblResources_Backup\r\n) AS T1 WHERE tblResources.Id = T1.Id;<\/pre>\n<p>Informationen zur Zusammenstellung und Funktion einer solchen SQL-Anweisung finden Sie im Beitrag <b>Datens&auml;tze mit Anlagefeld kopieren <\/b>(<b>www.access-im-unternehmen.de\/930<\/b>).<\/p>\n<p>Wichtig ist an dieser Stelle, dass Sie wissen, dass diese Anweisung f&uuml;r jedes Anlagefeld erstellt wird und nach dem Kopieren der &uuml;brigen Felder per <b>INSERT INTO <\/b>in die Zieltabelle aufgerufen wird.<\/p>\n<p>Wenn das Feld kein Anlagefeld ist, sondern ein mehrwertiges Feld, weist die Prozedur mit einer entsprechenden Meldung darauf hin, das mehrwertige Felder nicht unterst&uuml;tzt werden.<\/p>\n<p>Schlie&szlig;lich folgt der <b>Case Else<\/b>-Zweig, der alle &uuml;brigen Felder abdeckt. Hier f&uuml;gt die Prozedur lediglich den Feldnamen samt f&uuml;hrendem Komma an die Variable <b>strFelder <\/b>an.<\/p>\n<p>Das f&uuml;hrende Komma der Feldliste wird im n&auml;chsten Schritt entfernt. Dann stellt die Prozedur die <b>INSERT INTO<\/b>-Anweisung f&uuml;r die Felder au&szlig;er den Anlagefeldern zusammen. Diese sieht etwa wie in folgendem Beispiel aus:<\/p>\n<pre>INSERT INTO tblVersandfirmen \r\nSELECT FirmaID, Firma, Telefon \r\nFROM _tblVersandfirmen_Backup<\/pre>\n<p>Dann f&uuml;hrt die Prozedur diese Anweisung f&uuml;r die aktuelle Tabelle aus. Sollte die Variable <b>intAnlagefelder <\/b>gr&ouml;&szlig;er als <b>0 <\/b>sein, was darauf hindeutet, dass die aktuelle Tabelle mindestens ein Anlagefeld enth&auml;lt, das einer Sonderbehandlung bedarf, f&uuml;hrt die Prozedur noch weitere Schritte aus. Da die Variable <b>strSQLAnlagefeld() <\/b>an dieser Stelle ein oder mehrere Elemente enthalten kann (eines f&uuml;r jedes Anlagefeld), durchl&auml;uft die Prozedur alle Elemente in einer <b>For&#8230;Next<\/b>-Schleife. Innerhalb dieser Schleife f&uuml;hrt die Prozedur jeweils die im Array gespeicherte <b>INSERT INTO<\/b>-Anweisung f&uuml;r je ein Anlagefeld aus.<\/p>\n<p>Wenn dieser Vorgang f&uuml;r alle Anlagefelder durchgef&uuml;hrt wurde, k&uuml;mmert die Prozedur sich um die anderen Tabellen, die in der Collection <b>colTabellen <\/b>gespeichert sind.<\/p>\n<p>Somit sind nun alle Tabellen, deren Pr&auml;fix auf <b>tbl <\/b>lautet, mit den in den Backuptabellen gespeicherten Daten gef&uuml;llt.<\/p>\n<p><b>Erweiterung: Tabellen ausw&auml;hlen<\/b><\/p>\n<p>Nun gibt es im Formular <b>frmSichernUndWiederherstellen <\/b>noch etwas freien Platz, den wir f&uuml;llen m&uuml;ssen. Diesen nutzen wir dazu, ein Listenfeld unterzubringen, das alle Tabellen anzeigt und dem Benutzer die M&ouml;glichkeit bietet, eine oder mehrere auszuw&auml;hlen und somit nur einen Teil des Datenmodells zu sichern oder wiedeherzustellen.<\/p>\n<p>Das Listenfeld soll schlicht <b>lstTabellen <\/b>hei&szlig;en und wird wie in Bild 8 in das Formular eingef&uuml;gt. Damit der Benutzer mehrere Eintr&auml;ge ausw&auml;hlen kann, stellen Sie die Eigenschaft <b>Mehrfachauswahl <\/b>auf <b>Einfach <\/b>ein.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_02\/pic_929_008.png\" alt=\"Listenfeld zur Auswahl der zu sichernden oder wiederherzustellenden Tabellen\" width=\"450\" height=\"310,7143\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Listenfeld zur Auswahl der zu sichernden oder wiederherzustellenden Tabellen<\/span><\/b><\/p>\n<p>Die Prozedur aus Listing 6 sorgt daf&uuml;r, dass die Tabellen in das Listenfeld eingetragen werden. Sie durchl&auml;uft alle Tabellen der Datenbank und f&uuml;gt diejenigen zur Variablen <b>strTabellen <\/b>hinzu, die mit dem Pr&auml;fix <b>tbl <\/b>ausgestattet sind. Diese Liste landet dann als Datensatzherkunft im Listenfeld. F&uuml;r dieses stellt die Prozedur zuvor die Eigenschaft <b>Herkunftsart <\/b>auf <b>Wertliste <\/b>ein.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>TabellenEinlesen()\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>dao.Database\r\n     <span style=\"color:blue;\">Dim <\/span>tdf<span style=\"color:blue;\"> As <\/span>dao.TableDef\r\n     <span style=\"color:blue;\">Dim <\/span>strTabellen<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     For Each tdf In db.TableDefs\r\n         <span style=\"color:blue;\">If <\/span>tdf.Name Like \"tbl*\"<span style=\"color:blue;\"> Then<\/span>\r\n             strTabellen = strTabellen & tdf.Name & \";\"\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> tdf\r\n     <span style=\"color:blue;\">With<\/span> Me!lstTabellen\r\n         <span style=\"color:blue;\">Debug.Print<\/span> .RowSourceType\r\n         .RowSourceType = \"Value List\"\r\n         .RowSource = strTabellen\r\n     End <span style=\"color:blue;\">With<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> db = Nothing\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Prozedur zum F&uuml;llen des Listenfeldes mit den Namen aller Tabellen<\/span><\/b><\/p>\n<p>Die Prozedur soll beim &ouml;ffnen des Formulars ausgef&uuml;hrt werden, was Sie durch die folgende Ereignisprozedur realisieren:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Load()\r\n     TabellenEinlesen\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Nun m&uuml;ssen wir noch die einzelnen Prozeduren anpassen, damit nur die markierten Tabellen beim Sichern und Wiederherstellen ber&uuml;cksichtigt werden. Dazu reicht eine zus&auml;tzliche <b>If&#8230;Then<\/b>-Bedingung, die Sie innerhalb der &auml;u&szlig;eren <b>For Each<\/b>-Schleife platzieren:<\/p>\n<pre><span style=\"color:blue;\">If <\/span>InListenfeldMarkiert(var)<span style=\"color:blue;\"> Then<\/span>\r\n     ...\r\n<span style=\"color:blue;\">End If<\/span><\/pre>\n<p>Die Funktion <b>InListenfeldMarkiert <\/b>seht wie in Listing 7 aus. Sie durchl&auml;uft alle selektierten Eintr&auml;ge des Listenfeldes und gibt den Wert <b>True <\/b>zur&uuml;ck, wenn die mit <b>var <\/b>&uuml;bergebene Tabelle in der Liste enthalten ist.<\/p>\n<pre><span style=\"color:blue;\">Private Function <\/span>InListenfeldMarkiert(var<span style=\"color:blue;\"> As Variant<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>varListe<span style=\"color:blue;\"> As Variant<\/span>\r\n     For Each varListe In Me!lstTabellen.ItemsSelected\r\n         <span style=\"color:blue;\">If <\/span>var = Me!lstTabellen.ItemData(varListe)<span style=\"color:blue;\"> Then<\/span>\r\n             InListenfeldMarkiert = <span style=\"color:blue;\">True<\/span>\r\n             <span style=\"color:blue;\">Exit Function<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> varListe\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 7: Test, ob eine Tabelle im Listenfeld markiert ist<\/span><\/b><\/p>\n<p>Die gleiche Bedingung haben wir auch in die Prozedur <b>cmdSichern_Click <\/b>eingebaut.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>In meiner t&auml;glichen Programmierpraxis kommt es sehr oft vor, dass ich bestimmte Daten in Tabellen eingebe, ein Formular oder eine VBA-Routine &auml;ndere und diese ausprobiere, wodurch ich die Daten der beteiligten Tabellen &auml;ndere.<\/p>\n<p>Wenn ich die neue Funktion erneut mit dem vorherigen Stand der Daten ausf&uuml;hren m&ouml;chte, muss ich diese von Hand wiederherstellen oder etwa die Tabellen aus einer gesicherten Version der Datenbank m&uuml;hsam neu importieren.<\/p>\n<p>Die hier vorgestellten Prozeduren erleichtern dies ungemein: Sie klicken eine Schaltfl&auml;che eines Formulars an, um ein Backup der Tabellen anzufertigen und stellen dieses mit einem Klick auf eine weitere Schaltfl&auml;che wieder her.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>WiederherstellungspunktFuerDaten.accdb<\/p>\n<p>WiederherstellungspunktFuerDaten2003.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{0B7AEC49-E67A-4505-863D-7D0D882916E8}\/aiu_929.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>W&auml;hrend Sie eine Datenbank entwickeln, geben Sie Beispieldaten ein, testen die neu hinzugef&uuml;gten Formulare und VBA-Prozeduren anhand dieser Daten, pr&uuml;fen das Ergebnis und stellen die Beispieldaten gegebenenfalls wieder her, um weitere Tests mit ge&auml;nderten Prozeduren durchzuf&uuml;hren. Bei komplizierteren Prozeduren kann dies einige Iterationen in Anspruch nehmen und das manuelle Bereitstellen der Testdaten wird zu einer hinderlichen und zeitraubenden Prozedur. Zu diesem Zweck stellen wir im vorliegenden Beitrag Techniken vor, mit denen Sie per Knopfdruck alle Daten aus definierten Tabellen sichern und diese mit einem weiteren Knopfdruck wiederherstellen.<\/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":[66022014,662014,44000021],"tags":[],"class_list":["post-55000929","post","type-post","status-publish","format-standard","hentry","category-66022014","category-662014","category-Tabellen_und_Datenmodellierung"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Wiederherstellungspunkt f&uuml;r Daten - 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\/Wiederherstellungspunkt_fuer_Daten\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Wiederherstellungspunkt f&uuml;r Daten\" \/>\n<meta property=\"og:description\" content=\"W&auml;hrend Sie eine Datenbank entwickeln, geben Sie Beispieldaten ein, testen die neu hinzugef&uuml;gten Formulare und VBA-Prozeduren anhand dieser Daten, pr&uuml;fen das Ergebnis und stellen die Beispieldaten gegebenenfalls wieder her, um weitere Tests mit ge&auml;nderten Prozeduren durchzuf&uuml;hren. Bei komplizierteren Prozeduren kann dies einige Iterationen in Anspruch nehmen und das manuelle Bereitstellen der Testdaten wird zu einer hinderlichen und zeitraubenden Prozedur. Zu diesem Zweck stellen wir im vorliegenden Beitrag Techniken vor, mit denen Sie per Knopfdruck alle Daten aus definierten Tabellen sichern und diese mit einem weiteren Knopfdruck wiederherstellen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T21:19:55+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg07.met.vgwort.de\/na\/8c7397683f2e4260bd86b0f405774d0e\" \/>\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\\\/Wiederherstellungspunkt_fuer_Daten\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Wiederherstellungspunkt f&uuml;r Daten\",\"datePublished\":\"2020-05-22T21:19:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/\"},\"wordCount\":3791,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/8c7397683f2e4260bd86b0f405774d0e\",\"articleSection\":[\"2\\\/2014\",\"2014\",\"Tabellen und Datenmodellierung\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/\",\"name\":\"Wiederherstellungspunkt f&uuml;r Daten - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/8c7397683f2e4260bd86b0f405774d0e\",\"datePublished\":\"2020-05-22T21:19:55+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/8c7397683f2e4260bd86b0f405774d0e\",\"contentUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/8c7397683f2e4260bd86b0f405774d0e\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Wiederherstellungspunkt_fuer_Daten\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Wiederherstellungspunkt f&uuml;r Daten\"}]},{\"@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":"Wiederherstellungspunkt f&uuml;r Daten - 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\/Wiederherstellungspunkt_fuer_Daten\/","og_locale":"de_DE","og_type":"article","og_title":"Wiederherstellungspunkt f&uuml;r Daten","og_description":"W&auml;hrend Sie eine Datenbank entwickeln, geben Sie Beispieldaten ein, testen die neu hinzugef&uuml;gten Formulare und VBA-Prozeduren anhand dieser Daten, pr&uuml;fen das Ergebnis und stellen die Beispieldaten gegebenenfalls wieder her, um weitere Tests mit ge&auml;nderten Prozeduren durchzuf&uuml;hren. Bei komplizierteren Prozeduren kann dies einige Iterationen in Anspruch nehmen und das manuelle Bereitstellen der Testdaten wird zu einer hinderlichen und zeitraubenden Prozedur. Zu diesem Zweck stellen wir im vorliegenden Beitrag Techniken vor, mit denen Sie per Knopfdruck alle Daten aus definierten Tabellen sichern und diese mit einem weiteren Knopfdruck wiederherstellen.","og_url":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T21:19:55+00:00","og_image":[{"url":"http:\/\/vg07.met.vgwort.de\/na\/8c7397683f2e4260bd86b0f405774d0e","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\/Wiederherstellungspunkt_fuer_Daten\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Wiederherstellungspunkt f&uuml;r Daten","datePublished":"2020-05-22T21:19:55+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/"},"wordCount":3791,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg07.met.vgwort.de\/na\/8c7397683f2e4260bd86b0f405774d0e","articleSection":["2\/2014","2014","Tabellen und Datenmodellierung"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/","url":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/","name":"Wiederherstellungspunkt f&uuml;r Daten - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg07.met.vgwort.de\/na\/8c7397683f2e4260bd86b0f405774d0e","datePublished":"2020-05-22T21:19:55+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/#primaryimage","url":"http:\/\/vg07.met.vgwort.de\/na\/8c7397683f2e4260bd86b0f405774d0e","contentUrl":"http:\/\/vg07.met.vgwort.de\/na\/8c7397683f2e4260bd86b0f405774d0e"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Wiederherstellungspunkt_fuer_Daten\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Wiederherstellungspunkt f&uuml;r Daten"}]},{"@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\/55000929","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=55000929"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000929\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000929"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000929"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000929"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}