{"id":55000399,"date":"2006-10-01T00:00:00","date_gmt":"2021-02-11T21:06:17","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=399"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"MDBComparer","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/MDBComparer\/","title":{"rendered":"MDB-Comparer"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg06.met.vgwort.de\/na\/2019e9909edb4a92b86addb80023f78a\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<h3>Zusammenfassung<\/h3>\n<p>Bauen Sie sich ein Tool zum Vergleichen des Datenmodells verschiedener Versionen einer Datenbank.<\/p>\n<h3>Techniken<\/h3>\n<p>Tabellen, VBA<\/p>\n<h3>Voraussetzungen<\/h3>\n<p>Access 2000 und h&ouml;her<\/p>\n<h3>Beispieldatenbank<\/h3>\n<p>MDBComparer.mdb<\/p>\n<h3><\/h3>\n<p><b>Andr&eacute; Minhorst, Duisburg<\/b><\/p>\n<p><b>&#8222;Mmmh&#8230; irgendwas stimmt nicht. Die Anwendung, die mir der Kunde gerade zur&uuml;ckgeschickt hat, lief doch eben noch Und jetzt &#8211; fehlende Parameter, nicht vorhandene Tabellen&#8220; &#8211; Nun, so oder &auml;hnlich sieht das aus, wenn der Anwender im Datenmodell wirkt und dann der Code nicht mehr passt. &#8222;Nicht, dass das Debugging allein schon nervend w&auml;re &#8211; dann muss ich auch noch die kompletten Tabellen nach &auml;nderungen durchsuchen!&#8220; Aber nicht mehr lange &#8211; ab jetzt vergleichen Sie die Tabellen und Felder zweier Datenbankversionen vollautomatisch!<\/b><\/p>\n<p>Im vorliegenden Beitrag lernen Sie ein Tool kennen, mit dem Sie die Unterschiede der Tabellen und Felder zweier Versionen einer Datenbank ermitteln k&ouml;nnen.<\/p>\n<p>Der MDB-Comparer soll helfen, die Datenstruktur zweier Access-Datenbanken zu vergleichen. Dazu geh&ouml;ren in dieser ersten Version die Tabellen und die enthaltenen Felder samt wichtigen Eigenschaften wie Datentypen und Feldgr&ouml;&szlig;en. Um weitere wichtige Informationen wie Verkn&uuml;pfungen zwischen den einzelnen Tabellen oder Indizes soll sich eine erweiterte Fassung der hier vorgestellten L&ouml;sung in einer der folgenden Ausgaben von Access im Unternehmen k&uuml;mmern.<\/p>\n<h3>Vergleich der Datenstruktur &#8211; wozu<\/h3>\n<p>Gerade noch liegt dem Autor eine Datenbank auf dem Tisch, deren Funktionen nicht mehr wie gew&uuml;nscht arbeiten, weil der Besitzer die zugrunde liegenden Tabellen ge&auml;ndert hat. Was nun Am einfachsten w&auml;re es wohl, einfach den durch die &auml;nderungen nicht mehr funktionierenden VBA-Code einfach einmal laufen zu lassen und diesen zu &uuml;berarbeiten. Mit ein wenig Gl&uuml;ck h&auml;ngt es nur an einer Stelle; anderenfalls kann dies aber auch zu einem lang andauernden Hinterherfixen f&uuml;hren.<\/p>\n<p>Die Analyse der &auml;nderungen am Datenmodell macht auf jeden Fall Sinn: Vielleicht muss man ja gar nicht an den VBA-Code heran, sondern kann das Problem auf andere Weise umgehen Wenn die Daten wie im vorliegenden Fall aus verkn&uuml;pften Tabellen stammen, kann man das Problem viel eleganter l&ouml;sen: Man benennt einfach die Verkn&uuml;pfungen um &#8211; etwa durch Anh&auml;ngen eines Zeichens wie dem Unterstrich (_) &#8211; und erstellt eine Abfrage, die auf der ge&auml;nderten Tabelle beruht und genauso hei&szlig;t. Formulare, Berichte und VBA-Code merken es in den meisten F&auml;llen nicht, wenn man diesen statt einer Tabelle eine Abfrage mit dem Namen der eigentlich verwendeten Tabelle pr&auml;sentiert. Man muss nur den Aufbau der verwendeten Abfragen auf das der urspr&uuml;nglich verwendeten Tabelle anpassen &#8211; im einfachsten Fall durch das Umbenennen von Tabellen- und\/oder Feldnamen.<\/p>\n<p><IMG height=\"118\" src=\"..\/fileadmin\/_temp_\/{1E265FCC-EA90-4466-A3C7-8596E9D018DF}\/pic001.png\" width=\"500\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1:  Die komplette Benutzeroberfl&auml;che des MDB-Comparers<\/span><\/b><\/p>\n<p>Und um zu erkennen, ob dies Sinn macht, muss man zuvor die &auml;nderungen an der Datenstruktur identifizieren.<\/p>\n<h3>Das Hauptformular der Anwendung<\/h3>\n<p>Die Benutzeroberfl&auml;che der Anwendung besteht aus einem einzigen Formular. Dort gibt der Benutzer die Namen der beiden zu untersuchenden Datenbanken ein und klickt auf die Schaltfl&auml;che Vergleichen &#8211; fertig! Das Tool schreibt nun eine Textdatei auf die Festplatte und &ouml;ffnet diese direkt im Anschluss mit Notepad.<\/p>\n<p>Die Optionen des Formulars sind schnell erkl&auml;rt: Das Kontrollk&auml;stchen &#8222;gleiches Verzeichnis wie oben&#8220; sorgt daf&uuml;r, dass beim &ouml;ffnen des Datei &ouml;ffnen-Dialogs direkt das Verzeichnis angezeigt wird, aus dem auch die erste Version der Datenbank stammt, und mit der Option Systemtabellen einbeziehen entscheidet man, ob man selbige ebenfalls vergleichen m&ouml;chte.<\/p>\n<p>Auch f&uuml;r den Bau einer scheinbar einfachen Anwendung wie dem MDB-Comparer sind einige sorgf&auml;ltige Planungen notwendig. Sonst programmiert man einfach los und stellt irgendwann fest, dass man etwa eine Menge VBA-Code geschrieben hat, aber dieser so aussieht, dass man ihn nicht  sinnvoll von einem Formular aus steuern und dessen Ergebnisse nicht  in diesem darstellen kann.<\/p>\n<p>Daher stellt man sich zun&auml;chst einen Plan zusammen, welche Aufgaben die Anwendung erledigen soll, welche Eingangswerte daf&uuml;r erforderlich und welches Ergebnis die Anwendung liefern soll. Die Eingangswerte stehen schon fest: Dabei handelt es sich um die beiden zu vergleichenden Datenbanken. Zur Eingabe eigenen sich zwei Textfelder, gegebenenfalls um zwei Schaltfl&auml;chen zum Aufrufen eines Datei &ouml;ffnen-Dialogs erg&auml;nzt.<\/p>\n<p>Bei den Ergebnissen sieht das schon anders aus: Wie sollen denn die Unterschiede in den Datenmodellen der beiden Datenbanken ausgegeben werden Sollen alle enthaltenen Informationen gegen&uuml;bergestellt und die Unterschiede markiert werden, oder soll das Ergebnis nur die Unterschiede liefern Welche Unterschiede sind denn eigentlich zu erwarten Und wo soll das Ergebnis ausgegeben werden In einem Textfeld im gleichen Formular, das die Eingabe der zu vergleichenden Datenbanken erm&ouml;glicht Nun, wenn viele Unterschiede vorhanden sind, ist das in Abh&auml;ngigkeit von der geplanten Gr&ouml;&szlig;e des Formulars gegebenenfalls etwas unkomfortabel. Vielleicht kann man die Ergebnisse einfach in eine Textdatei schreiben, wie es auch Versionierungstools beim Vergleichen verschiedener Dateien tun Die Textdateien kann sich der Benutzer dann im Texteditor seiner Wahl ansehen und dessen M&ouml;glichkeiten wie etwa zum Durchsuchen der Datei voll aussch&ouml;pfen.<\/p>\n<h3>Ausgabe der Unterschiede<\/h3>\n<p>Wo Sie die Unterschiede ausgeben, spielt letzten Endes keine Rolle &#8211; die unterschiedlichen Techniken unterscheiden sich nur durch wenige Handgriffe voneinander.<\/p>\n<p>Aber welche Unterschiede soll die Anwendung nun ausgeben und wie ermittelt man diese<\/p>\n<p>Beginnen wir mit einer Liste der m&ouml;glichen Unterschiede. Die Anwendung soll<\/p>\n<li>hinzugef&uuml;gte Tabellen und alle enthaltenen Felder und Eigenschaften mit dem Vermerk &#8222;Hinzugef&uuml;gt:&#8220;,<\/li>\n<li>gel&ouml;schte Tabellen und alle enthaltenen Felder und Eigenschaften mit dem Vermerk &#8222;Gel&ouml;scht:&#8220;,<\/li>\n<li>hinzugef&uuml;gte Felder inklusive Angabe der Tabellen und Eigenschaften mit dem Vermerk &#8222;Hinzugef&uuml;gt:&#8220;,<\/li>\n<li>gel&ouml;schte Felder inklusive Angabe der Tabellen und Eigenschaften mit dem Vermerk &#8222;Gel&ouml;scht:&#8220; und<\/li>\n<li>ge&auml;nderte Feldeigenschaften unter Angabe der Tabelle, des Feldes und der ge&auml;nderten Eigenschaft in der alten und der neuen Version mit den Vermerken &#8222;Alt:&#8220; und &#8222;Neu:&#8220;<\/li>\n<p>ausgeben.<\/p>\n<p>Dabei sollte man noch kl&auml;ren, inwieweit man versucht, Tabellen mit ge&auml;nderten Tabellennamen oder Felder mit ge&auml;nderten Feldnamen zu identifizieren oder ob man die jeweiligen Elemente als gel&ouml;scht und wieder hinzugef&uuml;gt deklariert.<\/p>\n<p>Hier spielen dann auch die zur Verf&uuml;gung stehenden Techniken eine Rolle: Sicher sollte man f&uuml;r ein Tool wie dieses darauf verzichten, einen Algorithmus zu entwickeln, der pr&uuml;ft, ob eine Tabelle mit ge&auml;ndertem Namen neu ist oder nur eine neue Fassung einer bestehenden Tabelle &#8211; wer viel Zeit hat, kann sich sicher einmal mit diesem Thema befassen, aber an dieser Stelle soll mit wenig Aufwand ein brauchbares Tool zum Erkennen der Unterschiede zweier Versionen einer Datenbank her.<\/p>\n<p>Unvermeidlich scheint, dass man zun&auml;chst die Elemente der einen Version der Datenbank durchl&auml;uft und schaut, ob die passenden Elemente in der zweiten Version der Datenbank ebenfalls enthalten sind und dies anschlie&szlig;end f&uuml;r die Elemente der zweiten Version wiederholt. Und wie das genau passiert, zeigt das folgende Kapitel.<\/p>\n<p>Als Beispiel kommt wieder mal die Nordwind-Datenbank zum Zuge &#8211; wenn auch diesmal in zweifacher und vor allem unterschiedlicher Ausf&uuml;hrung.<\/p>\n<p>Die beiden Beispieldatenbanken hei&szlig;en Nordwind_Alt.mdb und Nordwind_Neu.mdb, wobei die erstgenannte die Tabellen im Originalzustand enth&auml;lt.<\/p>\n<p>Die neuere Version enth&auml;lt folgende &auml;nderungen, die der MDB-Comparer erkennen soll:<\/p>\n<li>eine neue Tabelle namens tblBeispiel mit zwei Feldern,<\/li>\n<li>in der Tabelle Bestellungen fehlt das Feld Versand&uuml;ber,<\/li>\n<li>die Tabelle Versandfirmen f&auml;llt weg,<\/li>\n<li>die Tabelle Personal wird in Mitarbeiter umbenannt,<\/li>\n<li>das Feld Personal-Nr der neuen Tabelle Mitarbeiter wird in MitarbeiterID umbenannt, ebenso das gleichnamige Feld der Tabelle Bestellungen,<\/li>\n<li>die Tabelle Artikel wird in Produkte umbenannt,<\/li>\n<li>die Tabelle Bestellungen erh&auml;lt ein neues Feld namens Rechnungsdatum,<\/li>\n<li>und das Feld Beschreibung der Tabelle Kategorien erh&auml;lt den Datentyp Text mit einer Feldgr&ouml;&szlig;e von 255 statt des Datentyps Memo.<\/li>\n<p><IMG height=\"253\" src=\"..\/fileadmin\/_temp_\/{1E265FCC-EA90-4466-A3C7-8596E9D018DF}\/pic002.png\" width=\"500\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2:  Das Datenmodell der Beispieldatenbank<\/span><\/b><\/p>\n<p>Das Datenmodell besteht aus zwei Tabellen, die die einzelnen Tabellen sowie die Felder und deren Eigenschaften speichern (siehe Bild 2). Zus&auml;tzlich dazu bekommt jede Tabelle zwei Felder, die angeben, in welcher der beiden Datenbankversionen die Tabelle beziehungsweise das Feld enthalten ist.<\/p>\n<p>Die Tabellen speichern nicht das endg&uuml;ltige Ergebnis der Untersuchung, sondern lediglich die beim Untersuchen vorgefundenen Tabellen, Felder und deren Eigenschaften. Die Auswertung &uuml;bernehmen die im n&auml;chsten Kapitel beschriebenen VBA-Prozeduren.<\/p>\n<p>Die beiden Tabellen sind &uuml;ber das Fremdschl&uuml;sselfeld TabelleID miteinander verkn&uuml;pft; f&uuml;r die Verkn&uuml;pfung ist referentielle Integrit&auml;t festgelegt. Au&szlig;erdem stellt die Aktivierung der L&ouml;schweitergabe sicher, dass beim L&ouml;schen der Eintr&auml;ge der Tabelle tblTabellen auch die passenden Eintr&auml;ge der Tabelle tblFelder gel&ouml;scht werden.<\/p>\n<p><IMG height=\"249\" src=\"..\/fileadmin\/_temp_\/{1E265FCC-EA90-4466-A3C7-8596E9D018DF}\/pic003.png\" width=\"391\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3:  Ein aus mehreren Feldern zusammengesetzter eindeutiger Schl&uuml;ssel<\/span><\/b><\/p>\n<p>Damit die nachfolgend beschriebenen Routinen bereits vorhandene Elemente beim Einf&uuml;gen identifizieren k&ouml;nnen, stellen Sie die Eigenschaft Indiziert des Feldes Tabellenname der Tabelle tblTabellen auf Ja (Ohne Duplikate) ein.<\/p>\n<p><!--30percent--><\/p>\n<p>F&uuml;r die Tabelle tblFelder erzeugen Sie einen zusammengesetzten eindeutigen Schl&uuml;ssel wie in Bild 3. Auf diese Weise markiert das Tool nur solche Felder als in beiden Versionen vorhanden, die wirklich exakt gleich sind. Wie dies genau ermittelt wird, erfahren Sie weiter unten.<\/p>\n<p>Das Formular frmVergleichen dient als Benutzerschnittstelle zu den im Modul mdlCompare enthaltenen Funktionen. Hier gibt man die zu vergleichenden Datenbanken sowie zwei weitere Optionen ein und startet den Vorgang mit der passenden Schaltfl&auml;che.<\/p>\n<p>Da der Schwerpunkt dieses Tools auf dem Vorgang zum Vergleichen der Tabellen und Felder zweier Datenbanken liegt, sollen die wenigen Funktionen des Formulars nicht in aller L&auml;nge beschrieben werden.<\/p>\n<p>Wichtig ist allein, dass die Prozedur, die durch einen Klick auf die Schaltfl&auml;che cmdVergleichen ausgel&ouml;st wird, erst die in den Tabellen des MDB-Comparers enthaltenen Daten l&ouml;scht, diese dann &uuml;ber die Routine Einlesen mit den aus den angegebenen Datenbanken gewonnen Informationen f&uuml;llt und den Inhalt der Tabellen dann mit der Prozedur Auswertung analysiert und die Ergebnis in einer Textdatei speichert.<\/p>\n<p>Die Untersuchung erfolgt in zwei Schritten: Im ersten Schritt liest der MDB-Comparer die ben&ouml;tigten Informationen &uuml;ber Tabellen und Felder der beiden Datenbanken ein und schreibt diese in die Datenbank, im zweiten Schritt analysiert das Tool die gewonnen Daten und gibt ein Ergebnis aus.<\/p>\n<p><b>Quellcode 1: Modulkopf und die Steuerroutine f&uuml;r das Einlesen der Tabellen- und Feldinformationen der zu vergleichenden Datenbanken<\/b><\/p>\n<pre>Option Compare Database\r\nOption Explicit\r\nDim db As DAO.Database\r\nDim rstFelder As DAO.Recordset\r\nConst cstrLine = \"------------------------------------------\"\r\nPublic Function Einlesen(strDatenbankAlt As String, _    strDatenbankNeu As String, bolSystemtabellen As Boolean) _    As String\r\n    Dim dbAlt As DAO.Database\r\n    Dim dbNeu As DAO.Database\r\n    Set db = CurrentDb\r\n    Set dbAlt = DBEngine.OpenDatabase(strDatenbankAlt)\r\n    Set dbNeu = DBEngine.OpenDatabase(strDatenbankNeu)\r\n    TabellenErfassen dbAlt, bolSystemtabellen, 1\r\n    TabellenErfassen dbNeu, bolSystemtabellen, 2\r\n    Set db = Nothing\r\n    Set dbAlt = Nothing\r\n    Set dbNeu = Nothing\r\nEnd Function<\/pre>\n<p><b>Einlesen der Tabellen und Felder<\/b><\/p>\n<p>Das Speichern der Tabellen und Felder samt Informationen in den zwei beschriebenen Tabellen erleichtert die anschlie&szlig;ende Auswertung &#8211; erstens kostet das Einlesen von Informationen aus externen Datenbanken Zeit, die man m&ouml;glichst nur einmal aufwenden sollte, und zweitens bereiten die nachfolgenden Routinen gleichzeitig die Daten f&uuml;r eine einfachere Untersuchung vor.<\/p>\n<p>Quellcode 1 enth&auml;lt den Kopf des Standardmoduls mdlCompare, das alle f&uuml;r das Vergleichen ben&ouml;tigten Routinen enth&auml;lt, sowie die erste Routine namens Einlesen.<\/p>\n<p>Diese Routine erzeugt Objektverweise des Typs Database auf die beiden zu vergleichenden Datenbanken und ruft die Routine TabellenAuflisten einmal f&uuml;r die alte und einmal f&uuml;r die neue Version der zu vergleichenden Datenbank auf.<\/p>\n<p>Die Routine TabellenErfassen durchl&auml;uft alle Tabellen der per Parameter &uuml;bergebenen Datenbank und schreibt diese in die Tabelle tblTabellen. Dazu durchl&auml;uft sie in einer For Each-Schleife alle TableDef-Objekte der zu erfassenden Datenbank und pr&uuml;ft dort zun&auml;chst, welchen Wert der Parameter bolSystemtabellen hat &#8211; ist dieser gleich False, dann soll die Routine die Systemtabellen nicht erfassen.<\/p>\n<p>Innerhalb der Schleife versucht die Routine zun&auml;chst, einfach den Tabellennamen in die Tabelle tblTabellen zu schreiben und je nach der aktuell untersuchten Version das Feld Version_1 oder Version_2 auf den Wert True zu setzen. Damit markiert das Tool jeden Tabelleneintrag so, dass man bereits aus der Tabelle tblTabellen erkennen kann, ob eine Tabelle in der ersten, der zweiten oder gar beiden Versionen enthalten ist (siehe Bild 4).<\/p>\n<p>Wenn eine Tabelle in der ersten und in der zweiten Version der Datenbank enthalten ist, wird die Routine TabellenErfassen f&uuml;r diese Tabelle zweimal durchlaufen: Beim ersten Mal legt die Routine einen Datensatz f&uuml;r diese Tabelle an, beim zweiten Durchlauf verursacht der Versuch, den Datensatz anzulegen, einen Fehler, weil schon ein Datensatz mit dem gleichen Tabellennamen vorhanden ist und das Feld mit den Tabellennamen keine Duplikate enthalten darf. Diesen Fehler fangen die folgenden Zeilen ab, die einfach eine UPDATE-Anweisung verwenden, um in dem bereits vorhandenen Datensatz den Wert des Feldes Version_2 auf True zu setzen.<\/p>\n<p>Jeweils im Anschluss an das Anlegen oder Anpassen eines Datensatzes ruft die Routine die Prozedur auf, die alle Felder dieser Tabelle erfassen soll &#8211; dazu weiter unten mehr. F&uuml;r die &uuml;brigen Zeilen der Routine TabellenErfassen ist nun nur wichtig, dass die Tabelle tblFelder die Felder der soeben untersuchten Tabelle enth&auml;lt. Aus den Felddatens&auml;tzen einer Tabelle erzeugt die Routine n&auml;mlich nun eine Art Schl&uuml;ssel: Sie durchl&auml;uft die Felder in alphabetischer Reihenfolge und h&auml;ngt alle Informationen wie Name, Datentyp, Feldgr&ouml;&szlig;e und Standardwert hintereinander an eine Zeichenkette an, die dann als zus&auml;tzlicher Wert zu jeder Tabelle gespeichert wird.<\/p>\n<p><IMG height=\"180\" src=\"..\/fileadmin\/_temp_\/{1E265FCC-EA90-4466-A3C7-8596E9D018DF}\/pic004.png\" width=\"500\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 4:  Die Tabelle tblTabellen speichert Informationen &uuml;ber die in den zu vergleichenden Datenbanken enthaltenen Tabellen.<\/span><\/b><\/p>\n<p><b>Quellcode 2: Erfassen der Tabellen der zu vergleichenden Datenbanken<\/b><\/p>\n<pre>Private Sub TabellenErfassen(dbExtern As DAO.Database, bolSystemtabellen As Boolean, _    intVersion As Integer)\r\n    Dim tdf As DAO.TableDef\r\n    Dim lngTabelleID As Long\r\n    Dim strIdentifier As String\r\n    For Each tdf In dbExtern.TableDefs\r\n        If Not (bolSystemtabellen = False And (tdf.Attributes And dbSystemObject) &lt;&gt; 0) Then\r\n            On Error Resume Next\r\n            db.Execute \"INSERT INTO tblTabellen(Tabellenname, Version_\" & intVersion _                & \") VALUES (''\" & tdf.Name & \"'', True)\", dbFailOnError\r\n            If Err.Number = 3022 Then\r\n                db.Execute \"UPDATE tblTabellen SET Version_\" & intVersion _                    & \" = True WHERE Tabellenname = ''\" & tdf.Name & \"''\", dbFailOnError\r\n            End If\r\n            On Error GoTo 0\r\n            lngTabelleID = DLookup(\"TabelleID\", \"tblTabellen\", \"Tabellenname = ''\" _                & tdf.Name & \"''\")\r\n            FelderErfassen tdf, intVersion, lngTabelleID\r\n            Set rstFelder = db.OpenRecordset(\"SELECT * FROM tblFelder WHERE TabelleID = \" _                & lngTabelleID & \" ORDER BY Feld\", dbOpenDynaset)\r\n            strIdentifier = \"\"\r\n            Do While Not rstFelder.EOF\r\n                strIdentifier = strIdentifier & rstFelder!Feld & \"|\" & rstFelder!Datentyp _                    & \"|\" & rstFelder!Feldgroesse & \"|\" & rstFelder!Standardwert & \"|\"\r\n                rstFelder.MoveNext\r\n            Loop\r\n            db.Execute \"UPDATE tblTabellen SET Identifier = ''\" & strIdentifier _                & \"'' WHERE Tabellenname = ''\" & tdf.Name & \"''\", dbFailOnError\r\n        End If\r\n    Next tdf\r\nEnd Sub<\/pre>\n<p>Wozu dies dient Nun, es kann ja sein, dass ein Benutzer eine Tabelle einfach nur umbenannt hat. In erster Instanz erkennt das Tool dann die alte Tabelle und die neue, umbenannte Version als zwei verschiedene Tabellen an, geht also davon aus, dass die alte Tabelle gel&ouml;scht und eine neue erzeugt wurde. Wenn aber alle Felder und sonstigen Informationen gleich sind, soll das Tool die &auml;nderung einfach als Umbenennung der Tabelle erkennen, was hiermit m&ouml;glich ist.<\/p>\n<p>Prinzipiell genauso wie die vorherige Routine funktioniert die Prozedur FelderErfassen (s. Quellcode 3). Sie schreibt zwar einige Infomationen mehr in die hier verwendete Tabelle tblFelder, aber auch hier sorgt eine Fehlerbehandlung daf&uuml;r, dass beim Anf&uuml;gen bereits vorhandener Felder kein neuer Datensatz, sondern nur ein passender Eintrag im Feld Version_2 vorgenommen wird. Verantwortlich ist daf&uuml;r der oben erw&auml;hnte zusammengesetzte eindeutige Schl&uuml;ssel. Das Ergebnis sieht etwa wie in Bild 5 aus.<\/p>\n<p><IMG height=\"243\" src=\"..\/fileadmin\/_temp_\/{1E265FCC-EA90-4466-A3C7-8596E9D018DF}\/pic005.png\" width=\"500\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 5:  Erfassung der Felder einer Tabelle &#8211; hier mit je zwei entfernten und zwei neuen Feldern<\/span><\/b><\/p>\n<p><IMG height=\"361\" src=\"..\/fileadmin\/_temp_\/{1E265FCC-EA90-4466-A3C7-8596E9D018DF}\/pic006.png\" width=\"500\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 6:  Das Ergebnis eines Datenbankvergleichs<\/span><\/b><\/p>\n<p><b>Quellcode 3: Erfassen der Felder der alten und der neuen Datenbankversion<\/b><\/p>\n<pre>Private Sub FelderErfassen(tdf As DAO.TableDef, intVersion As Integer, lngTabelleID As Long)\r\n    Dim fld As DAO.Field\r\n    For Each fld In tdf.Fields\r\n        On Error Resume Next\r\n        db.Execute \"INSERT INTO tblFelder(TabelleID, Feld, Datentyp, Feldgroesse, \" _            & \"Standardwert, Version_\" & intVersion & \") VALUES(\" & lngTabelleID & \", ''\" _            & fld.Name & \"'', \" & fld.Type & \", \" & fld.Size & \", ''\" & fld.DefaultValue _            & \"'', True)\", dbFailOnError\r\n        If Err.Number = 3022 Then\r\n            db.Execute \"UPDATE tblFelder SET Version_\" & intVersion _                & \" = True WHERE TabelleID = \" & lngTabelleID & \" AND Feld = ''\" & fld.Name _                & \"''\", dbFailOnError\r\n        End If\r\n        On Error GoTo 0\r\n    Next fld\r\nEnd Sub<\/pre>\n<p><b>Ermitteln der Unterschiede<\/b><\/p>\n<p>Trotz guter Vorbereitung erfordert das Ermitteln und Ausgeben der Unterschiede immer noch eine Menge VBA-Code. Damit Sie selbst &auml;nderungen daran vornehmen k&ouml;nnen, drucken wie diesen dennoch komplett ab und beschreiben die Funktionsweise. Die Routine schreibt alle Ergebnisse in eine Textdatei namens Unterschiede.txt. Den Kopf bilden die Dateinamen der untersuchten Versionen inklusive Pfad.<\/p>\n<p>Die vorangestellten Gr&ouml;&szlig;er(&gt;)- und Kleiner(&lt;)-Zeichen dienen der Zuordnung der nachfolgenden Ergebnisse zu den beiden Datenbankversionen.<\/p>\n<p><b>Quellcode 4: Die Routine &#8222;Auswertung&#8220; ermittelt die Unterschiede zwischen den Tabellen zweier Datenbanken auf Basis der zuvor erzeugten Tabellen (erster Teil).<\/b><\/p>\n<pre>Public Sub Auswertung(strDateiAlt As String, strDateiNeu As String)\r\n    Dim intCount As Integer\r\n    Dim rstT As DAO.Recordset\r\n    Dim rstT1 As DAO.Recordset\r\n    Dim rstT2 As DAO.Recordset\r\n    Dim rstF As DAO.Recordset\r\n    Dim rstF1 As DAO.Recordset\r\n    Dim rstF2 As DAO.Recordset\r\n    Dim bolLine As Boolean\r\n    Dim i As Integer\r\n    Dim bolUmbenannt As Boolean\r\n    Open CurrentProject.Path & \"\\Unterschiede.txt\" For Output As #1\r\n    Print #1, \"&gt; Alte Datenbank: \" & strDateiAlt\r\n    Print #1, \"&lt; Neue Datenbank: \" & strDateiNeu\r\n    Print #1, cstrLine\r\n    Set db = CurrentDb\r\n[1] Set rstT = db.OpenRecordset(\"SELECT * FROM tblTabellen WHERE Version_1 = True \" _        & \"AND Version_2 = True\", dbOpenDynaset)\r\n    Do While Not rstT.EOF\r\n        ''Felder durchsuchen, die nicht in beiden Versionen enthalten sind\r\n[2]     Set rstF = db.OpenRecordset(\"SELECT * FROM tblFelder WHERE TabelleID = \" _            & rstT!TabelleID & \" AND (Version_1 = False OR Version_2 = False) \" _            & \"ORDER BY Feld, Version_1\", dbOpenDynaset)\r\n        If Not rstF.EOF Then\r\n            Print #1, \"Tabelle: \" & rstT!Tabellenname\r\n            Print #1, cstrLine\r\n        End If\r\n[3]     Do While Not rstF.EOF\r\n            intCount = DCount(\"Feld\", \"tblFelder\", \"TabelleID = \" & rstT!TabelleID _            & \" AND Feld = ''\" & rstF!Feld & \"''\")\r\n[4]         If intCount = 2 Then\r\n                Print #1, \"&gt;    Feld: \" & rstF!Feld, GetDatentyp(rstF!Datentyp), _                    rstF!Feldgroesse, rstF!Standardwert\r\n                rstF.MoveNext\r\n                Print #1, \"&lt;    Feld: \" & rstF!Feld, GetDatentyp(rstF!Datentyp), _                    rstF!Feldgroesse, rstF!Standardwert\r\n            Else\r\n[5]             If rstF!Version_1 = True Then\r\n                    Print #1, \"&gt;    Feld: \" & rstF!Feld, GetDatentyp(rstF!Datentyp), _                        rstF!Feldgroesse, rstF!Standardwert\r\n                    Print #1, \"&lt;    Feld: .\/.\"\r\n                Else\r\n                    Print #1, \"&gt;    Feld: .\/.\"\r\n                    Print #1, \"&lt;    Feld: \" & rstF!Feld, GetDatentyp(rstF!Datentyp), _                        rstF!Feldgroesse, rstF!Standardwert\r\n                End If\r\n            End If\r\n            Print #1, cstrLine\r\n            rstF.MoveNext\r\n        Loop\r\n        rstT.MoveNext\r\n    Loop<\/pre>\n<p>Damit Sie eine Vorstellung davon bekommen, was die Routine &uuml;berhaupt tut, betrachten Sie einfach Abb. 6. Nach der Ausgabe der beteiligten Datenbanken folgen die Unterschiede zwischen den beteiligten Tabellen:<\/p>\n<p>Zun&auml;chst diejenigen, bei denen sich nur einzelne Felder innerhalb einer Tabelle ge&auml;ndert haben, dann Tabellen, deren Namen sich ge&auml;ndert hat und schlie&szlig;lich komplett entfernte und hinzugef&uuml;gte Tabellen.<\/p>\n<p>An der mit [1] markierten Stelle beginnt im Quellcode 4 die Untersuchung der Tabellen, die in beiden Versionen enthalten sind. Die folgende Do While-Schleife durchl&auml;uft alle Tabellen, f&uuml;r die dies der Fall ist. In [2] &ouml;ffnet die Routine eine Datensatzgruppe, die alle Felder dieser Tabelle enth&auml;lt, die entweder in der einen oder der anderen Tabelle fehlen. Ist die Datensatzgruppe nicht leer, ist klar: Hier gibt es &auml;nderungen, also kann man den Tabellennamen in die Textdatei mit den Ergebnissen drucken. Fehlen also nur noch die eigentlichen Unterschiede. <\/p>\n<p><b>Quellcode 5: Fortsetzung der Prozedur &#8222;Auswertung&#8220;<\/b><\/p>\n<pre>    ''Tabellen durchsuchen, die nur in der ersten Version enthalten sind\r\n    Set rstT1 = db.OpenRecordset(\"SELECT * FROM tblTabellen WHERE Version_1 = True \" _        & \"AND Version_2 = False\", dbOpenDynaset)\r\n    Set rstT2 = db.OpenRecordset(\"SELECT * FROM tblTabellen WHERE Version_1 = False \" _        & \"AND Version_2 = True\", dbOpenDynaset)\r\n    Do While Not rstT1.EOF\r\n        bolUmbenannt = False\r\n        If rstT2.EOF Then\r\n            Print #1, \"Tabelle: \" & rstT1!Tabellenname & \" entfernt\"\r\n            Print #1, cstrLine\r\n        Else\r\n            Do While Not rstT2.EOF\r\n                If rstT1!Identifier = rstT2!Identifier Then\r\n                    Print #1, \"Tabelle: \" & rstT1!Tabellenname & \" umbenannt in \" _                        & rstT2!Tabellenname\r\n                    db.Execute \"UPDATE tblTabellen SET Umbenannt = True WHERE TabelleID = \" _                        & rstT2!TabelleID, dbFailOnError\r\n                    Print #1, cstrLine\r\n                    bolUmbenannt = True\r\n                End If\r\n                rstT2.MoveNext\r\n            Loop\r\n            If bolUmbenannt = False Then\r\n                Print #1, \"Tabelle: \" & rstT1!Tabellenname & \" entfernt\"\r\n                Print #1, cstrLine\r\n            End If\r\n            rstT2.MoveFirst\r\n        End If\r\n        rstT1.MoveNext\r\n    Loop\r\n    ''Tabellen durchsuchen, die nur in der zweiten Version enthalten sind\r\n    rstT2.MoveFirst\r\n    Do While Not rstT2.EOF\r\n        rstT1.MoveFirst\r\n        If rstT1.EOF Or (Not rstT1.EOF And rstT2!Umbenannt = False) Then\r\n            Print #1, \"Tabelle: \" & rstT2!Tabellenname & \" hinzugef&uuml;gt\"\r\n            Print #1, cstrLine\r\n        End If\r\n        rstT2.MoveNext\r\n    Loop\r\n    Close #1\r\nEnd Sub<\/pre>\n<p>Um die k&uuml;mmern sich dann die in der unter  [3] zu findenden Do While-Schleife. Die Variable intCount wird mit der Anzahl der Datens&auml;tze der Tabelle tblFelder gef&uuml;llt, die das Feld mit dem aktuellen Namen enthalten &#8211; ist dieser Wert 2, dann gibt es f&uuml;r jede Version der Datenbank einen Eintrag und damit einen Unterschied bez&uuml;glich der Eigenschaften dieses Feldes [4].<\/p>\n<p>Also gibt die Routine das Feld und dessen Eigenschaften aus der ersten Version und dann die passenden Informationen f&uuml;r die zweite Version aus. Dazu springt sie mit .MoveNext einfach einen Datensatz weiter.<\/p>\n<p>Die Sortierung nach dem Feldnamen und der Version in [2] sorgt daf&uuml;r, dass dabei auch der passende, zweite Datensatz angesprungen wird.<\/p>\n<p>Gibt es keine zwei Versionen des gleichen Feldnamens in der Tabelle, ist das Feld entweder gel&ouml;scht oder hinzugef&uuml;gt worden: Dies ermittelt man &uuml;ber den Wert des Feldes Version_1 der Datensatzgruppe. Ist dieser True, stammt das Feld aus der ersten Version und ist in der zweiten Version nicht mehr enthalten, ansonsten andersherum [5].<\/p>\n<p>Auf diese Weise durchl&auml;uft die Routine alle Felddatens&auml;tze aller Tabellen und schreibt Ungereimtheiten in den Bericht.<\/p>\n<p>Quellcode 5 zeigt den zweiten Teil dieser Prozedur. Der hier enthaltene Code untersucht noch die Tabellen, die nur in der ersten Version der Datenbank enthalten sind.<\/p>\n<p>Ziel dieser Untersuchung ist es, herauszufinden, ob es m&ouml;glicherweise zwei Tabellen unterschiedlichen Namens in den beiden Versionen der Datenbank gibt, die aber genau die gleichen Felder enthalten und damit gegebenenfalls nur umbenannt wurden.<\/p>\n<p>Die Routine &ouml;ffnet zun&auml;chst zwei Datensatzgruppen, von denen die erste alle Tabellen-Datens&auml;tze enth&auml;lt, die nur in der ersten Version vorkommen, und die zweite nur diejenigen, die nur in der zweiten Version enthalten sind.<\/p>\n<p>Dann vergleicht Sie jeden Datensatz der ersten mit jedem Datensatz der zweiten Tabelle und pr&uuml;ft, ob der Inhalt des Feldes Identifier gleich ist. Ist das der Fall, sind die Felder der Tabelle identisch und die Tabelle somit nur umbenannt worden. Anderenfalls scheint die Tabelle in der zweiten Version nicht mehr vorhanden zu sein. Beide F&auml;lle ziehen einen entsprechenden Eintrag in der Ausgabedatei nach sich.<\/p>\n<p>Zuletzt untersucht die Routine alle Tabellen, die nur in der zweiten, aber nicht in der ersten Version enthalten sind.<\/p>\n<p>Damit die Tabellen, die bereits vorher als &#8222;umbenannt&#8220; erkannt wurden, nicht erneut untersucht werden m&uuml;ssen, erhalten diese in der Tabelle tblTabellen den Wert True f&uuml;r das Feld Umbenannt.<\/p>\n<p>Wenn die Ausf&uuml;hrung des Codes einer neuen Version einer Datenbank einmal hakt, nachdem jemand &auml;nderungen an den zugrunde liegenden Tabellen vorgenommen hat, kann man die erfolgten &auml;nderungen mit dem hier vorgestellten Tool leicht entdecken.<\/p>\n<p>Erweiterungspotential gibt es genug: Beim Vergleich der Felder betrachtet das Tool derzeit nur, ob ein Feld gleichen Namens sowohl in der ersten als auch in der zweiten Version der Datenbank enthalten ist, und schlie&szlig;t gegebenenfalls auf ein Entfernen oder Hinzuf&uuml;gen dieses Feldes.<\/p>\n<p>Man k&ouml;nnte zus&auml;tzlich noch pr&uuml;fen, ob Felder, die nur in einer Version vorkommen, zumindest gleiche Eigenschaften haben und dementsprechend einfach nur umbenannt worden sein k&ouml;nnen.<\/p>\n<p>Schlie&szlig;lich k&ouml;nnte man den Vergleich auf die Verkn&uuml;pfungen und Indizes ausdehnen, und auch die &uuml;brigen Datenbankobjekte k&ouml;nnte man dabei direkt mit untersuchen.<\/p>\n<p>F&uuml;r viele Anwendungen ist auch das Einbeziehen der MDW-Dateien wichtig &#8211; anderenfalls h&auml;tte das Tool keinen Zugriff auf gesch&uuml;tzte Dateien. Sie sehen schon &#8211; die Geschichte ist noch nicht ausgestanden: Fortsetzung folgt!<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>MDBComparer.mdb<\/p>\n<p>Nordwind_Alt.mdb<\/p>\n<p>Nordwind_Neu.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/F5926DBF-EB9B-4D15-A36F-6995ADA6C67A\/aiu_399.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8222;Mmmh&#8230; irgendwas stimmt nicht. Die Anwendung, die mir der Kunde gerade zur&uuml;ckgeschickt hat, lief doch eben noch Und jetzt &#8211; fehlende Parameter, nicht vorhandene Tabellen&#8220; &#8211; Nun, so oder &auml;hnlich sieht das aus, wenn der Anwender im Datenmodell wirkt und dann der Code nicht mehr passt. &#8222;Nicht, dass das Debugging allein schon nervend w&auml;re &#8211; dann muss ich auch noch die kompletten Tabellen nach &Auml;nderungen durchsuchen!&#8220; Aber nicht mehr lange &#8211; ab jetzt vergleichen Sie die Tabellen und Felder zweier Datenbankversionen vollautomatisch!<\/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":[662006,66052006,44000027,44000021],"tags":[],"class_list":["post-55000399","post","type-post","status-publish","format-standard","hentry","category-662006","category-66052006","category-Loesungen","category-Tabellen_und_Datenmodellierung"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>MDB-Comparer - 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\/MDBComparer\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MDB-Comparer\" \/>\n<meta property=\"og:description\" content=\"&quot;Mmmh... irgendwas stimmt nicht. Die Anwendung, die mir der Kunde gerade zur&uuml;ckgeschickt hat, lief doch eben noch Und jetzt - fehlende Parameter, nicht vorhandene Tabellen&quot; - Nun, so oder &auml;hnlich sieht das aus, wenn der Anwender im Datenmodell wirkt und dann der Code nicht mehr passt. &quot;Nicht, dass das Debugging allein schon nervend w&auml;re - dann muss ich auch noch die kompletten Tabellen nach &Auml;nderungen durchsuchen!&quot; Aber nicht mehr lange - ab jetzt vergleichen Sie die Tabellen und Felder zweier Datenbankversionen vollautomatisch!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/MDBComparer\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2021-02-11T21:06:17+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg06.met.vgwort.de\/na\/2019e9909edb4a92b86addb80023f78a\" \/>\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=\"20\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"MDB-Comparer\",\"datePublished\":\"2021-02-11T21:06:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/\"},\"wordCount\":3330,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/2019e9909edb4a92b86addb80023f78a\",\"articleSection\":[\"2006\",\"5\\\/2006\",\"L\u00f6sungen\",\"Tabellen und Datenmodellierung\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/\",\"name\":\"MDB-Comparer - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/2019e9909edb4a92b86addb80023f78a\",\"datePublished\":\"2021-02-11T21:06:17+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/2019e9909edb4a92b86addb80023f78a\",\"contentUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/2019e9909edb4a92b86addb80023f78a\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/MDBComparer\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"MDB-Comparer\"}]},{\"@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":"MDB-Comparer - 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\/MDBComparer\/","og_locale":"de_DE","og_type":"article","og_title":"MDB-Comparer","og_description":"\"Mmmh... irgendwas stimmt nicht. Die Anwendung, die mir der Kunde gerade zur&uuml;ckgeschickt hat, lief doch eben noch Und jetzt - fehlende Parameter, nicht vorhandene Tabellen\" - Nun, so oder &auml;hnlich sieht das aus, wenn der Anwender im Datenmodell wirkt und dann der Code nicht mehr passt. \"Nicht, dass das Debugging allein schon nervend w&auml;re - dann muss ich auch noch die kompletten Tabellen nach &Auml;nderungen durchsuchen!\" Aber nicht mehr lange - ab jetzt vergleichen Sie die Tabellen und Felder zweier Datenbankversionen vollautomatisch!","og_url":"https:\/\/access-im-unternehmen.de\/MDBComparer\/","og_site_name":"Access im Unternehmen","article_published_time":"2021-02-11T21:06:17+00:00","og_image":[{"url":"http:\/\/vg06.met.vgwort.de\/na\/2019e9909edb4a92b86addb80023f78a","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"20\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/MDBComparer\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/MDBComparer\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"MDB-Comparer","datePublished":"2021-02-11T21:06:17+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/MDBComparer\/"},"wordCount":3330,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/MDBComparer\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/2019e9909edb4a92b86addb80023f78a","articleSection":["2006","5\/2006","L\u00f6sungen","Tabellen und Datenmodellierung"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/MDBComparer\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/MDBComparer\/","url":"https:\/\/access-im-unternehmen.de\/MDBComparer\/","name":"MDB-Comparer - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/MDBComparer\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/MDBComparer\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/2019e9909edb4a92b86addb80023f78a","datePublished":"2021-02-11T21:06:17+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/MDBComparer\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/MDBComparer\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/MDBComparer\/#primaryimage","url":"http:\/\/vg06.met.vgwort.de\/na\/2019e9909edb4a92b86addb80023f78a","contentUrl":"http:\/\/vg06.met.vgwort.de\/na\/2019e9909edb4a92b86addb80023f78a"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/MDBComparer\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"MDB-Comparer"}]},{"@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\/55000399","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=55000399"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000399\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000399"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000399"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000399"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}