{"id":55001151,"date":"2018-10-01T00:00:00","date_gmt":"2020-05-13T21:11:54","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1151"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"ODBCDirect_durch_die_Hintertuer","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/","title":{"rendered":"ODBCDirect durch die Hintert&uuml;r"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg06.met.vgwort.de\/na\/c00450571e2d41e28eb42a54ae4a5a28\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Haben Sie Ihr Backend in ein DBMS ausgelagert, also die Tabellen auf einen SQL-Server migriert, so steht Ihnen ab Access 2007 nur noch die Schnittstelle ADODB zur Verf&uuml;gung, um unter VBA auf sie zuzugreifen, falls Sie sich nicht nur auf verkn&uuml;pfte Tabellen beschr&auml;nken m&ouml;chten. Denn die Technologie ODBCDirect, mit der man direkt eine Verbindung zum Server aufbauen konnte, wurde ersatzlos gestrichen. Mit einem Trick schlagen Sie Microsoft jedoch ein Schnippchen!<\/b><\/p>\n<h2>ODBCDirect<\/h2>\n<p>Es handelt sich dabei eine Datenschnittstelle, die in der Bibliothek <b>DAO<\/b> untergebracht ist. Dort finden Sie ein <b>Connection<\/b>-Objekt, welches allein f&uuml;r die Kommunikation mit einem SQL-Server &uuml;ber <b>ODBC<\/b> zust&auml;ndig ist (s. Bild 1). Doch offenbar enth&auml;lt die Bibliothek diese Klasse nur noch aus Kompatibilit&auml;tsgr&uuml;nden, denn jeglicher Methodenaufruf auf sie endet mit einer Fehlermeldung 3827: <b>ODBCDirect wird nicht mehr unterst&uuml;tzt. Schreiben Sie den Code so um, dass ADO anstelle von DAO verwendet wird<\/b>. Das k&ouml;nnen Sie tun, denn etwas anderes bleibt Ihnen nun auch nicht &uuml;brig. <\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_05\/Connection_Objektkatalog.png\" alt=\"Die ODBCDirect-Klasse Connection im Objektkatalog von VBA\" width=\"500\" height=\"534,3135\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Die ODBCDirect-Klasse Connection im Objektkatalog von VBA<\/span><\/b><\/p>\n<p>Der Sachverhalt stellt sich in der Praxis nicht selten ein. Haben Sie etwa eine &auml;ltere <b>Access 2003<\/b>-Datenbank im Einsatz, die <b>ODBCDirect<\/b> nutzt, und auf den Rechnern soll <b>Office 2010<\/b> installiert werden, so kommen Sie um Anpassungen leider nicht herum. Statt der <b>DAO-Connection<\/b> verwenden Sie nun &uuml;berall eine <b>ADODB-Connection<\/b>, deren Methoden aber deutlich abweichen! Hier ist einiges an Arbeit f&uuml;r die Migration angesagt. <\/p>\n<p>Warum Microsoft die Schnittstelle entfernte, ist nicht nachzuvollziehen. Einerseits wurden die sogenannten <b>Access-Projekte<\/b> (<b>ADP<\/b>) in welchen Sie Formulare unmittelbar an einen <b>MSSQL<\/b>-Server binden konnten, ab <b>Access 2007<\/b> komplett entfernt und stattdessen wurden ODBC-verkn&uuml;pfte Tabellen empfohlen. Gleichzeitig aber strich man <b>ODBCDirect<\/b>. Ich habe daf&uuml;r nur eine Erkl&auml;rung: Einst waren SQL-Server ziemlich teuer, weshalb sie h&auml;ufig f&uuml;r Low Budget-L&ouml;sungen mit Access nicht infrage kamen. Zudem scheuten viele Entwickler den Einsatz des SQL-Servers, weil hier eine Menge zus&auml;tzliches Knowhow zu erwerben war. In der Folge fanden Sie in den einschl&auml;gigen Foren und Newsgroups nur selten Fragen zum Thema <b>ODBCDirect<\/b>. F&uuml;r Microsoft offenbar Grund genug, sich dieser Schnittstelle zu entledigen.<\/p>\n<p>Inzwischen aber stellt nicht nur Microsoft selbst einen kostenlosen leistungsf&auml;higen Server (<b>SQL Server Express<\/b>) zur Verf&uuml;gung, sondern auch andere Gr&ouml;&szlig;en der Branche, wie <b>IBM<\/b> mit <b>DB2 Express<\/b> oder <b>Oracle<\/b> mit E<b>xpress 11g<\/b>, von den <b>OpenSource<\/b>-L&ouml;sungen <b>MySQL<\/b>, <b>MariaDB<\/b>, <b>Postgres<\/b> und <b>Firebird<\/b> ganz zu schweigen, sodass der Einsatz dieser <b>DBMS<\/b> als Backend, die der A<b>ccess Engine<\/b> klar den Rang ablaufen, naheliegt.<\/p>\n<p>Wollen Sie hier <b>ADODB<\/b> verwenden, so hat dies einen Haken: Viele der genannten <b>DBMS<\/b> stellen keinen <b>OLEDB-Provider<\/b> zur Verf&uuml;gung. Manche sind instabil oder wenig performant, bei manchen finden Sie gar keinen. Dann m&uuml;ssen Sie den <b>ODBC-Provider MSDASQL<\/b> nehmen, der aber eine zus&auml;tzliche Ebene einzieht und deshalb in der Performance das Nachsehen hat.<\/p>\n<p>Empfehlung: Voten Sie auf <b>access.uservoice<\/b> f&uuml;r die Wiederaufnahme von <b>ODBCDirect<\/b>! Dort nimmt Microsoft Vorschl&auml;ge zu zuk&uuml;nftigen Access-Versionen entgegen. Fr&uuml;her einmal gab es das <b>Connect<\/b>-Programm von Microsoft, wo vornehmlich <b>MVPs<\/b> ihre Vorschl&auml;ge einbrachten. Die wurden allerdings nicht wirklich ernst genommen. Offenbar hat sich dies ge&auml;ndert. Nach dem Debakel mit den <b>Access-WebServices<\/b>, die in der Zukunft deshalb eben entfallen sollen, wendet man sich nun anscheinend vermehrt den Anregungen der Community zu, wie etwa die Wiedergeburt der <b>dBase<\/b>-Schnittstelle zeigt.<\/p>\n<p>Die Programmierung der <b>ODBCDirect<\/b>-Schnittstelle ist fast so einfach, wie die von lokalen oder verlinkten Access-Tabellen:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>oWrk<span style=\"color:blue;\"> As <\/span>DAO.Workspace\r\n<span style=\"color:blue;\">Dim <\/span>oConx<span style=\"color:blue;\"> As <\/span>DAO.Connection\r\n<span style=\"color:blue;\">Dim <\/span>sConx<span style=\"color:blue;\"> As String<\/span>\r\n<span style=\"color:blue;\">Dim <\/span>rs<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n<span style=\"color:blue;\">Set<\/span> oWrk = oDbEng.CreateWorkspace(\"\", \"\", \"\", dbUseODBC)\r\nsConx = \"ODBC;Driver={Microsoft dBase Driver (*.dbf)}\" & _\r\n             \";DriverID=533\";Dbq=\" & CurrentProject.Path\r\n<span style=\"color:blue;\">Set<\/span> oConx = oWrk.OpenConnection(\"\", , , sConx)\r\n<span style=\"color:blue;\">Set<\/span> rs = oConx.OpenRecordset( _\r\n     \"SELECT * FROM KUNDENLI.DBF.DBF\", dbOpenDynaset)<\/pre>\n<p>Hier wird zun&auml;chst ein Workspace <b>oWrk<\/b> angelegt, welches von dem abweicht, das die <b>DBEngine<\/b> von <b>Access.Application<\/b> voreingestellt hat, weil die Konstante <b>dbUseODBC<\/b> angegeben ist. Der Normalfall w&auml;re <b>dbUseJet<\/b>. Dann wird in <b>sConx<\/b> der <b>Connect<\/b>-String zusammengebaut, der mit dem Tag <b>ODBC;<\/b> beginnen muss.<\/p>\n<p>Mit <b>Driver<\/b> geben Sie den Namen eines installierten ODBC-Treibers an, in unserem Fall den <b>dBase<\/b>-Treiber. Daran schlie&szlig;en sich treiberspezifische Optionen an. Hier ist es vor allem der Pfad, unter dem sich die <b>dBase<\/b>-Dateien befinden, im Schl&uuml;ssel <b>Dbq<\/b>.<\/p>\n<p>Mit diesem <b>Connect<\/b>-String &ouml;ffnen Sie das <b>Connection<\/b>-Objekt <b>oConx<\/b>. &auml;hnlich, wie bei einem <b>Database<\/b>-Objekt, k&ouml;nnen Sie nun ein <b>Recordset<\/b> &uuml;ber ein SQL-Statement auf die <b>Connection<\/b> &ouml;ffnen.<\/p>\n<h2>Aber das geht doch gar nicht mehr!<\/h2>\n<p>Korrekt. F&uuml;hren Sie den angef&uuml;hrten Code in einer <b>ACCDB<\/b> aus, so tritt die erw&auml;hnte Fehlermeldung auf.<\/p>\n<p>Sie k&ouml;nnten nun auf die Idee kommen, statt der <b>ACE<\/b>-Bibliothek die alte zu verwenden. L&ouml;schen Sie also den Verweis auf <b>DAO<\/b> und laden Sie einen auf <b>DAO.36<\/b> neu (<b>Microsoft DAO 3.6 Object Library<\/b>). Tats&auml;chlich &auml;ndert dies am Sachverhalt rein gar nichts. Denn der Verweis f&uuml;hrt nicht dazu, dass die alte Engine geladen w&uuml;rde.<\/p>\n<p>Da die alte, wie die neue, den Namen <b>DAO<\/b> tr&auml;gt, verwendet Access weiterhin die interne <b>ADEDAO.dll<\/b>, die bereits beim Start von Access geladen wird. Die Bibliothek selbst wird zwar von VBA genutzt, doch quasi nur als Tabelle f&uuml;r die Klassen, die unter beiden Bibliotheken an dieselben <b>GUIDs<\/b> und Methoden f&uuml;r die <b>Interfaces<\/b> gebunden sind.<\/p>\n<p>Der n&auml;chste Versuch w&auml;re, eine eigene <b>DBEngine<\/b> anzulegen, die auf die <b>dao360.dll<\/b> verweist. Das l&auml;sst sich &uuml;ber die Methode <b>CreateObject<\/b> erledigen:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>oDBEng<span style=\"color:blue;\"> As Object<\/span>\r\n<span style=\"color:blue;\">Dim <\/span>oWrk<span style=\"color:blue;\"> As Object<\/span>\r\n<span style=\"color:blue;\">Set<\/span> oDbEng = CreateObject(\"DAO.DBEngine.36\")\r\n<span style=\"color:blue;\">Set<\/span> oWrk = oDbEng.CreateWorkspace(\"\", \"\", \"\", dbUseODBC)<\/pre>\n<p>Verbl&uuml;ffend, auch dies zeitigt dieselbe Fehlermeldung in der letzten Zeile! Hier ist der Grund der, dass die Office-Installation in der Registry die ProgID- und CLSID-Schl&uuml;ssel so verbogen hat, dass sie ebenfalls auf die acedao.dll verweisen. Also scheinen wohl alle Wege verbaut zu sein.<\/p>\n<h2>Es geht doch!<\/h2>\n<p>In der letzten Ausgabe erfuhren Sie, wie Sie <b>COM-Objekte<\/b> instanziieren k&ouml;nnen, ohne dass jene im System registriert sein m&uuml;ssen (A<b>ctiveX und COM ohne Registrierung verwenden<\/b>). Dabei kommt ein Modul zum Einsatz (<b>mdlComLoaderASM<\/b>), das ziemlich komplex ist und auch vor <b>Assembler<\/b>-Teilen nicht Halt macht. Hier haben Sie nun eine n&uuml;tzliche Anwendung f&uuml;r die Routinen des Moduls: Wir versuchen, eine Instanz der alten <b>JET-Engine<\/b> &uuml;ber die Funktion <b>GetCOMInstance<\/b> zu erhalten. Das geht im Prinzip so:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>oDbEng<span style=\"color:blue;\"> As <\/span>DAO.DBEngine\r\n<span style=\"color:blue;\">Dim <\/span>oWrk<span style=\"color:blue;\"> As <\/span>DAO.Workspace\r\n<span style=\"color:blue;\">Set<\/span> oDbEng = GetCOMInstance(sFile, \"DBEngine\", <span style=\"color:blue;\">True<\/span>)\r\n<span style=\"color:blue;\">Set<\/span> oWrk = oDbEng.CreateWorkspace(\"\", \"\", \"\", dbUseODBC)<\/pre>\n<p>Und, siehe da, die Sache klappt, und wir haben Microsoft ausgetrickst! Nat&uuml;rlich muss in der Variablen <b>sFile<\/b> zuvor der Pfad zur dao360.dll stehen.<\/p>\n<p>Aber gibt es diese Datei &uuml;berhaupt auf dem Rechner mit <b>Office 2007<\/b> ff. Wir k&ouml;nnen das nicht f&uuml;r alle F&auml;lle versichern. Doch die<b> dao360.dll<\/b> wird auch von Windows selbst f&uuml;r seine Zwecke genutzt, weshalb die Datei nach unseren Beobachtungen mit diesem installiert wird. Auch der Pfad scheint immer derselbe zu sein. Sie k&ouml;nnen ihn vom Pfad der <b>ACEDAO<\/b> ableiten, wenn auf diese ein Verweis gesetzt ist:<\/p>\n<pre>sFile = References(\"DAO\").FullPath\r\nsFile = <span style=\"color:blue;\">Replace<\/span>(sFile, \"OFFICE14\\ACEDAO.DLL\", _\r\n                        \"DAO\\dao360.dll\")<\/pre>\n<p>Heraus kommt dabei der String<\/p>\n<pre>C:\\Program Files (x86)\\Common Files\\Microsoft Shared\\DAO\\dao360.dll<\/pre>\n<p>M&ouml;chten Sie also Ihre alte <b>Access 2003<\/b>-Datenbank, die <b>ODBCDirect<\/b> nutzt, nach <b>Access 2010<\/b> migrieren, so ersetzen Sie im Code einfach alle Aufrufe auf das <b>Connection<\/b>-Objekt etwa mit dieser Routine:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>oConx<span style=\"color:blue;\"> As <\/span>DAO.Connection\r\n<span style=\"color:blue;\">Dim <\/span>oDbEng<span style=\"color:blue;\"> As <\/span>DAO.DBEngine\r\n<span style=\"color:blue;\">Dim <\/span>oWrk<span style=\"color:blue;\"> As <\/span>DAO.Workspace\r\n<span style=\"color:blue;\">Function <\/span>Connection<span style=\"color:blue;\"> As <\/span>DAO.Connection\r\n<span style=\"color:blue;\">Dim <\/span>sFile<span style=\"color:blue;\"> As String<\/span>\r\n<span style=\"color:blue;\">If <\/span>oConx Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n   sFile = References(\"DAO\").FullPath\r\n   sFile = <span style=\"color:blue;\">Replace<\/span>(sFile, \"OFFICE14\\ACEDAO.DLL\", _\r\n                        \"DAO\\dao360.dll\")\r\n   <span style=\"color:blue;\">Set<\/span> oDbEng = GetCOMInstance(sFile, \"DBEngine\", <span style=\"color:blue;\">True<\/span>)\r\n   <span style=\"color:blue;\">Set<\/span> oWrk = oDbEng.CreateWorkspace(\"\", \"\", \"\", dbUseODBC)\r\n<span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">Set<\/span> Connection = oConx\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>Das <b>Connection<\/b>-Objekt steht damit generell im VBA-Projekt zur Verf&uuml;gung. Auf Umgestaltung nach <b>ADO<\/b> k&ouml;nnen Sie getrost verzichten. <\/p>\n<p>Ein Anwendungsbeispiel finden Sie in Listing 1. Wie zuvor ausgef&uuml;hrt erzeugt <b>GetCOMInstance<\/b> hier eine neue <b>DBEngine<\/b>. Statt der <b>ProgID<\/b> <b>DBEngine<\/b> allerdings ist die entsprechende <b>CLSID<\/b> f&uuml;r das Objekt der Begierde eingesetzt. <b>GetCOMInstance<\/b> muss n&auml;mlich sonst die <b>CLSID<\/b> aus der <b>ProgID<\/b> selbst ermitteln, was Sie der Prozedur abnehmen k&ouml;nnen.<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>ConnectMysqlODBCDirect()\r\n     <span style=\"color:blue;\">Dim <\/span>oDbEng<span style=\"color:blue;\"> As <\/span>DAO.DBEngine\r\n     <span style=\"color:blue;\">Dim <\/span>oWrk<span style=\"color:blue;\"> As <\/span>DAO.Workspace\r\n     <span style=\"color:blue;\">Dim <\/span>oConx<span style=\"color:blue;\"> As <\/span>DAO.Connection\r\n     <span style=\"color:blue;\">Dim <\/span>sConx<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>rs<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>sFile<span style=\"color:blue;\"> As String<\/span>\r\n     \r\n     sFile = <span style=\"color:blue;\">Replace<\/span>(References(\"DAO\").FullPath, \"OFFICE14\\ACEDAO.DLL\", \"DAO\\dao360.dll\")\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> oDbEng = GetCOMInstance(sFile, _\r\n                     \"{00000100-0000-0010-8000-00AA006D2EA4}\", <span style=\"color:blue;\">True<\/span>)\r\n     ''''oder statt CLSID: DBEngine ~ DAO.DBEngine.36\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> oWrk = oDbEng.CreateWorkspace(\"\", \"\", \"\", dbUseODBC)\r\n     sConx = \"ODBC;Driver={MySQL ODBC 5.3 ANSI Driver};\" & _\r\n         \"DATABASE=mysqlbackend;\" & _\r\n         \"SERVER=127.0.0.1;PORT=3306;\" & _\r\n         \"UID=root;PWD=aiupwd;OPTION=18475\"\r\n     <span style=\"color:blue;\">Set<\/span> oConx = oWrk.OpenConnection(\"\", dbDriverNoPrompt, , sConx)\r\n     ''''oder dbDriverCompleteRequired\r\n     <span style=\"color:blue;\">Set<\/span> rs = oConx.OpenRecordset( _\r\n       \"SELECT ID,Artikel FROM tblArtikel\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rs.EOF\r\n         <span style=\"color:blue;\">Debug.Print<\/span> rs(0).Value, rs(1).Value\r\n         rs.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     rs.Close\r\n     \r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     oWrk.Close\r\n     <span style=\"color:blue;\">Set<\/span> oWrk = Nothing\r\n     oConx.Close\r\n     <span style=\"color:blue;\">Set<\/span> oConx = Nothing\r\n     <span style=\"color:blue;\">Set<\/span> oDbEng = Nothing\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><!--30percent--><\/p>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Diese Prozedur erzeugt eine Instanz der DBEngine und spricht damit einen MySQL-Server an.<\/span><\/b><\/p>\n<p>Den <b>Connect<\/b>-String <b>sConx<\/b> verweist in diesem Beispiel auf einen <b>MySQL-ODBC<\/b>-Treiber. Der Server wird &uuml;ber den Standard-Port <b>3306<\/b> auf die lokale Maschine mit der <b>IP<\/b> <b>127.0.0.1<\/b> angesprochen und der Benutzername zur Autorisierung am Server ist <b>root<\/b>, das Passwort ist <b>aiupwd<\/b>. Die <b>Connection<\/b> <b>oConx<\/b> wird &uuml;ber diesen String ge&ouml;ffnet.<\/p>\n<p>Interessant ist in diesem Zusammenhang die Konstante <b>dbDriverNoPrompt<\/b>. Sie sagt <b>ODBCDirect<\/b>, dass kein Dialog erscheinen soll, wenn etwas am <b>Connect<\/b>-String nicht stimmt. In diesem Fall k&auml;me es zu einer Fehlermeldung. <\/p>\n<p>Setzten Sie stattdessen <b>dbDriverCompleteRequired<\/b> ein, so erscheint der <b>ODBC<\/b>-Dialog des <b>Datenquellenadministrators<\/b> von Windows. In dem sind dann die korrekten Angaben zur Verbindung vorausgef&uuml;llt. Lassen Sie etwa den Benutzernamen weg, so k&ouml;nnen Sie diesen dann im Dialog nachreichen.<\/p>\n<p>Schlie&szlig;lich &ouml;ffnet sich ein Recordset <b>rs<\/b> auf die Tabelle <b>tblArtikel<\/b> auf die <b>Connection<\/b>. In der folgenden Schleife werden dann die Werte der Felder <b>ID<\/b> und <b>Artikel<\/b> der Datens&auml;tze alle im VBA-Direktfenster ausgegeben. Zu erw&auml;hnen w&auml;re, dass diese Methode erheblich performanter ist, als <b>ADO<\/b> &uuml;ber <b>ODBC<\/b> auf den MySQL-Treiber. Es gibt n&auml;mlich keinen funktionierenden kostenlosen <b>MySQL<\/b>&#8211; oder <b>MariaDB-OLEDB-Provider<\/b>.<\/p>\n<h2>dBase &uuml;ber ODBCDirect<\/h2>\n<p>Noch ein Feature ist ab <b>Access 2013<\/b> dem Rotstift anheimgefallen: die Schnittstelle zu <b>dBase<\/b>. Bis dahin konnte man noch &uuml;ber das <b>Ribbon<\/b> und <b>Externe Daten<\/b> <b>dBase<\/b>-Dateien sowohl importieren, wie verkn&uuml;pfen oder exportieren. Das geht unter Umst&auml;nden eben nicht mehr, obwohl die Schnittstelle im neuesten <b>Access 2016 <\/b>wieder drin ist. <b>dBase<\/b> ist als Austauschformat und Schnittstelle zu manchen anderen Programmen (leider) noch immer aktuell.<\/p>\n<p>Der Umweg &uuml;ber eine <b>DSN<\/b>, welche Sie auf <b>dBase<\/b>-Dateien im <b>ODBC-Datenquellen-Administrator<\/b> anlegen, klappt ebenfalls nicht. Der Versuch, darauf eine <b>ODBC<\/b>-Verkn&uuml;pfung in Access aufzubauen scheitert mit der Meldung <b>Verkn&uuml;pfen von externen ISAM-Datenbanktabellen mit Ihrer Datenbank &uuml;ber ODBC ist nicht m&ouml;glich <\/b>&#8211; warum auch immer das so unsinnigerweise vorgesehen wurde. Die einzige L&ouml;sung ist hier in VBA <b>ODBCDirect<\/b> im Verein mit <b>GetCOMInstance<\/b>. Auch eine <b>Passthrough-Abfrage<\/b> auf den <b>ODBC<\/b>-Treiber funktioniert nicht, wie die Abfrage <b>qry_PT_dBase<\/b> der Demodatenbank zeigt.<\/p>\n<p>Kleiner Tipp am Rande: Unter <b>Windows 64<\/b> existiert wohl schon im Startmen&uuml; ein Link zum <b>ODBC-Datenquellenadministrator<\/b>. Doch dieser &ouml;ffnet die 64bit-Version desselben, in der demnach auch nur 64bit-Treiber aufgelistet sind. Mit diesen kann <b>Office x32<\/b> nichts anfangen. Legen Sie sich deshalb eine Verkn&uuml;pfung zur Version unter <b>SysWOW64<\/b> auf dem Desktop an (<b>C:\\Windows\\SysWOW64\\odbcad32.exe<\/b>). Sie sollte nach dem Start den Dialog &auml;hnlich zeigen, wie in Bild 2.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_05\/ODBCAdm32.png\" alt=\"Der 32bit-ODBC-Datenquellen-Administrator listet die 32bit-Treiber auf.\" width=\"500\" height=\"412,9099\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Der 32bit-ODBC-Datenquellen-Administrator listet die 32bit-Treiber auf.<\/span><\/b><\/p>\n<p>Sie k&ouml;nnen nun eine neue <b>Benutzer-DSN<\/b> zu <b>dBase<\/b>-Dateien anlegen, indem Sie unter dem entsprechenden Reiter die Schaltfl&auml;che Neu anklicken. In Bild 3 ist der Dialog nach Auswahl des <b>dBase<\/b>-Treibers ausgef&uuml;llt. &uuml;brigens k&ouml;nnen wir auch nicht garantieren, dass der Treiber auch wirklich auf Ihrem System installiert ist. Im Zweifel k&ouml;nnen Sie das nachholen, indem Sie das <b>Microsoft ODBC Desktop Driver Pack<\/b> installieren. Infos zum <b>dBase<\/b>-Treiber gibt es dann etwa in den <b>Microsoft Docs<\/b>.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_05\/ODBC_dBase_DSN.png\" alt=\"So sieht die Anlage einer DSN im ODBC-Dialog zu dBase-Dateien aus.\" width=\"500\" height=\"338,5744\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: So sieht die Anlage einer DSN im ODBC-Dialog zu dBase-Dateien aus.<\/span><\/b><\/p>\n<p>F&uuml;r unsere <b>ODBCDirect<\/b>-Verbindung ben&ouml;tigen wir eine solche <b>DSN<\/b> nicht, weil wir die <b>DSNless<\/b> anlegen. Der Dialog macht jedoch deutlich, was es mit dem <b>dBase<\/b>&#8211;<b>DBMS<\/b> auf sich hat. Sie w&auml;hlen am besten die Treiberversion <b>5.0<\/b> aus, die im <b>Connect<\/b>-String dem Eintrag <b>DriverID=533<\/b> entspricht.  Ansonsten geben Sie lediglich ein Verzeichnis an, in dem sich die <b>dBase<\/b>-Dateien befinden, was sich im Parameter <b>Dbq<\/b> wiederspiegelt. Die Verbindung geschieht also nicht zu einer einzelnen Datei, sondern zu einem Verzeichnis, das quasi die Datenbank darstellt, w&auml;hrend die Dateien die einzelnen Tabellen sind.<\/p>\n<p>Listing 2 zeigt den kompletten Code, der an sich nur eine erweiterte Version der <b>MySQL<\/b>-Routine darstellt. Interessant ist hier die SQL-Syntax beim &ouml;ffnen des Recordset. Da eine <b>dBase<\/b>-Datei imgrunde eine Tabelle darstellt, m&uuml;ssen Sie die auch im <b>FROM<\/b>-Statement samt Dateierweiterung angeben (<b>KUNDENLI.dbf<\/b>). <\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>ConnectdBaseODBCDirect()\r\n     <span style=\"color:blue;\">Dim <\/span>sFile<span style=\"color:blue;\"> As String<\/span>, sPath<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>oDbEng<span style=\"color:blue;\"> As <\/span>DAO.DBEngine\r\n     <span style=\"color:blue;\">Dim <\/span>oWrk<span style=\"color:blue;\"> As <\/span>DAO.Workspace\r\n     <span style=\"color:blue;\">Dim <\/span>oConx<span style=\"color:blue;\"> As <\/span>DAO.Connection, sConx<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>rs<span style=\"color:blue;\"> As <\/span>DAO.Recordset, fld<span style=\"color:blue;\"> As <\/span>DAO.Field\r\n     \r\n     sPath = CurrentProject.Path\r\n     sFile = References(\"DAO\").FullPath\r\n     sFile = <span style=\"color:blue;\">Replace<\/span>(sFile, \"OFFICE14\\ACEDAO.DLL\", \"DAO\\dao360.dll\")\r\n     <span style=\"color:blue;\">Debug.Print<\/span> sFile\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> oDbEng = GetCOMInstance(sFile, _\r\n         \"{00000100-0000-0010-8000-00AA006D2EA4}\", <span style=\"color:blue;\">True<\/span>)\r\n     <span style=\"color:blue;\">Set<\/span> oWrk = oDbEng.CreateWorkspace(\"\", \"\", \"\", dbUseODBC)\r\n     sConx = \"ODBC;Driver={Microsoft dBase Driver (*.dbf)};DriverID=533;Dbq=\" & sPath\r\n     <span style=\"color:blue;\">Set<\/span> oConx = oWrk.OpenConnection(\"\", dbDriverCompleteRequired, , sConx)\r\n     <span style=\"color:blue;\">Set<\/span> rs = oConx.OpenRecordset(\"SELECT * FROM KUNDENLI.DBF\", dbOpenDynaset)\r\n     For Each fld In rs.Fields\r\n         <span style=\"color:blue;\">Debug.Print<\/span> fld.Name,\r\n     <span style=\"color:blue;\">Next<\/span> fld\r\n     <span style=\"color:blue;\">Debug.Print<\/span>\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rs.EOF\r\n         For Each fld In rs.Fields\r\n             <span style=\"color:blue;\">Debug.Print<\/span> fld.Value,\r\n         <span style=\"color:blue;\">Next<\/span> fld\r\n         <span style=\"color:blue;\">Debug.Print<\/span>\r\n         rs.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     rs.Close\r\n     \r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     oWrk.Close: <span style=\"color:blue;\">Set<\/span> oWrk = Nothing\r\n     oConx.Close: <span style=\"color:blue;\">Set<\/span> oConx = Nothing\r\n     <span style=\"color:blue;\">Set<\/span> oDbEng = Nothing\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Die Prozedur &ouml;ffnet eine dBase-Tabelle und gibt s&auml;mtliche Datens&auml;tze im Direktfenster aus.<\/span><\/b><\/p>\n<p>Die Routine schreibt &uuml;ber die erste Spalte alle Feldnamen der Tabelle in das Direktfenster. In der zweiten verschachtelten Schleife geschieht dies jeweils f&uuml;r jeden Datensatz, wobei dann nicht <b>Field.Name<\/b> ausgegeben wird, sondern <b>Field.Value<\/b>. Die <b>dBase<\/b>-Datei ist durch Export aus einer Access-Tabelle <b>Kundenliste<\/b> entstanden. Sie sehen, dass <b>dBase<\/b> den Namen abk&uuml;rzt.<\/p>\n<p>Unter <b>dBase III <\/b>k&ouml;nnen Tabellennamen nur acht Zeichen lang sein. Feldnamen k&ouml;nnen l&auml;nger sein. Weitere Spezifikationen finden Sie etwa unter folgendem Link:<\/p>\n<pre>http:\/\/www.manmrk.net\/tutorials\/database\/xbase\/dbase_spec.html<\/pre>\n<h2>ODBCDirect-Daten im Formular<\/h2>\n<p>Zwar k&ouml;nnen Sie nun unter VBA &uuml;ber <b>ODBCDirect<\/b> auf die Daten eines SQL-Servers zugreifen. Vielleicht aber m&ouml;chten Sie diese auch in einem Formular anzeigen, anstatt sie lediglich per Code weiterzuverarbeiten.<\/p>\n<p>&uuml;ber die Eigenschaft <b>Recordset<\/b> eines Formulars, die nicht nur Lese-, sondern auch Schreibzugriff gestattet, k&ouml;nnten Sie ein <b>ODBCDirect<\/b>-Recordset direkt zuweisen. Das allerdings funktioniert nicht. Sie erhalten bei Zuweisung die Fehlermeldung <b>Das Objekt ist kein g&uuml;ltiges Recordset.<\/b> Denn Formulare unterst&uuml;tzen nur die normalen <b>DAO<\/b>-Recordsets oder <b>ADO<\/b>-Recordsets.<\/p>\n<p>Entweder verzichten Sie nun auf Formularfelder und geben die Feldwerte des Recordsets in einem Listenfeld aus, oder Sie wandeln das <b>ODBC<\/b>&#8211;<b>Recordset<\/b> in ein anderes vom Formular unterst&uuml;tztes um. <b>DAO<\/b> scheidet hier eigentlich aus, weil Sie da ein <b>Recordset<\/b> nur auf eine physische Tabelle &ouml;ffnen k&ouml;nnen. Anders bei <b>ADO<\/b>, wo ein <b>Disconnected Recordset<\/b> auch k&uuml;nstlich erzeugt werden kann. Zu dieser Methode haben wir gegriffen, wobei die L&ouml;sung nur eine rudiment&auml;re ist, da auf Datentypkonvertierung verzichtet wurde. Der Kern der L&ouml;sung besteht in der Klasse <b>cODBCConnection<\/b>, welche <b>ODBCDirect<\/b> komplett kapselt.<\/p>\n<p><b>cODBCConnection<\/b> hat folgende Methoden und Eigenschaften:<\/p>\n<ul>\n<li>Im Property <b>ConnectString<\/b> geben Sie die Verbindungzeichenfolge an oder lesen sie aus.<\/li>\n<li><b>ConnectSilent<\/b> schaltet, falls True, den ODBC-Dialog aus, wenn im Verbindungs-String etwas nicht stimmt. <\/li>\n<li><b>DAODLL<\/b> gibt rein informativ als String den Ort der <b>dao360.dll<\/b> aus.<\/li>\n<li>Die Funktion <b>Connect<\/b> stellt dann erst die Verbindung her und gibt ein <b>DAO.Connection<\/b>-Objekt zur&uuml;ck.<\/li>\n<li>Der Methode <b>OpenRecordset<\/b> &uuml;bergeben Sie einen SQL-String, wie gew&ouml;hnt. Als Ergebnis erhalten Sie ein <b>DAO-ODBC-Recordset<\/b>.<\/li>\n<li><b>OpenRecordsetADO<\/b> tut dasselbe, gibt aber direkt ein <b>ADODB-Recordset<\/b> zur&uuml;ck, welches Sie direkt einem Formular zuweisen k&ouml;nnen.<\/li>\n<\/ul>\n<p>Die letzte Methode ist auch die einzige, die wir n&auml;her beleuchten wollen, da die anderen Routinen weitgehend nur das bisher schon Gesagte wiederspiegeln. Listing 3 stellt die Prozedur dar.<\/p>\n<pre><span style=\"color:blue;\">Function <\/span>OpenRecordsetADO(ByVal sSQL<span style=\"color:blue;\"> As String<\/span>) _\r\n                                     <span style=\"color:blue;\"> As <\/span>ADODB.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>rs<span style=\"color:blue;\"> As <\/span>DAO.Recordset,.\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>rsADO<span style=\"color:blue;\"> As <\/span><span style=\"color:blue;\">New<\/span> ADODB.Recordset\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> rs = OpenRecordset(sSQL)\r\n     rsADO.CursorLocation = adUseClient\r\n     For Each fld In rs.Fields\r\n         rsADO.Fields.Append fld.Name, adBSTR\r\n     <span style=\"color:blue;\">Next<\/span> fld\r\n     rsADO.Open\r\n     rs.MoveFirst\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rs.EOF\r\n         rsADO.Add<span style=\"color:blue;\">New<\/span>\r\n         For Each fld In rs.Fields\r\n             rsADO(fld.Name).Value = Nz(fld.Value)\r\n         <span style=\"color:blue;\">Next<\/span> fld\r\n         rs.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     rsADO.UpdateBatch adAffectAll\r\n     rs.Close\r\n     <span style=\"color:blue;\">Set<\/span> OpenRecordsetADO = rsADO\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Die Funktion konvertiert ein ODBC-in ein ADO-Recordset.<\/span><\/b><\/p>\n<p>Die Objektvariable <b>rs<\/b> speichert zun&auml;chst das ODBC-Recordset, welches &uuml;ber die andere Klassenfunktion <b>OpenRecordset<\/b> und den &uuml;bergebenen SQL-String erhalten wird. Anschlie&szlig;end wird ein mit <b>New<\/b> deklariertes <b>ADODB-Recordset<\/b> von Grund auf neu erstellt. Dazu klappert die erste Schleife &uuml;ber die <b>Fields<\/b>-Auflistung alle Felder des <b>ODBC-Recordsets<\/b> ab und f&uuml;gt dem ADO-Recordset <b>rsADO<\/b> gleichnamige hinzu, wobei als Datentyp <b>adBSTR<\/b> verwendet wird. Das ist der String-Typ f&uuml;r normalen Text. <b>adVarChar<\/b> scheidet aus, weil Access hier nicht mit Unicode-Zeichen klark&auml;me. Nach dem &ouml;ffnen des ADO-Recordsets per <b>Open<\/b>-Anweisung k&ouml;nnen diesem direkt per <b>AddNew<\/b> neue Datens&auml;tze angef&uuml;gt werden, was die zweite Schleife erledigt. Ein Update nach jedem Durchgang ist bei <b>ADO<\/b> nicht n&ouml;tig: Das abschlie&szlig;ende <b>UpdateBatch<\/b> speichert alles auf einen Schlag, wie bei einer Transaktion. Das <b>ODBC-Recordset rs <\/b>kann nun geschlossen werden. Das Recordset <b>rsADO<\/b> wird nun als R&uuml;ckgabewert der Funktion gesetzt.<\/p>\n<p>So kurz die Routine auch ist, die Performance ist durch diese Konvertierung nat&uuml;rlich nicht &uuml;berw&auml;ltigend. Zur Anzeige in einem Formular spielt dies jedoch eine untergeordnete Rolle. Klar ist zudem, dass die Daten dieses Recordsets zwar auch beschrieben oder neue hinzugef&uuml;gt werden k&ouml;nnen, dies sich jedoch nicht r&uuml;ckw&auml;rts auf die <b>dBase<\/b>-Datei auswirkt.<\/p>\n<p>Diese Klasse <b>cODBCConnection<\/b> wird nun vom Formular <b>frmKundenliste<\/b> der Demo benutzt, um seine Textfelder zu f&uuml;llen. Der Entwurf des Formulars in Bild 4 zeigt zehn Textfelder und zehn an sie gekn&uuml;pfte Labels. Die Ansicht ist auf <b>Datenblatt<\/b> eingestellt, weshalb der Inhalt der Labels sp&auml;ter die Spaltenk&ouml;pfe angibt. Die Labels haben Namen von <b>L1<\/b> bis <b>L10<\/b>, die ungebundenen Textfelder nennen sich <b>T1<\/b> bis <b>T10<\/b>. Die Aufgabe des Startcodes des Formulars ist es nun, die Labels mit den Feldnamen des ADO-Recordsets zu f&uuml;llen (<b>Caption<\/b>) und zweitens den Steuerelementinhalt der Textfelder (<b>ControlSource<\/b>) ebenfalls auf diese Namen, damit eine Verkn&uuml;pfung hergestellt wird. Nat&uuml;rlich h&auml;tte man diese Elemente auch alle voreinstellen k&ouml;nnen, wenn bekannt w&auml;re, wie die <b>dBase<\/b>-Daten aufgebaut sind. Das Formular soll jedoch beliebige <b>dBase<\/b>-Dateien anzeigen k&ouml;nnen, weshalb dieser allgemeine Aufbau gew&auml;hlt wurde. <\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_05\/frmKundenliste_DS.png\" alt=\"Im Entwurf zeigt das Formular nur zehn Textfelder und Labels.\" width=\"350\" height=\"420,8333\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Im Entwurf zeigt das Formular nur zehn Textfelder und Labels.<\/span><\/b><\/p>\n<p>Da die Anzahl der Felder des ADO-Recordsets nicht bekannt ist, m&uuml;ssen die nicht genutzten Spalten zur Laufzeit ausgeblendet werden. Sonst zeigen sich die Textfelder im Datenblatt rechts neben den g&uuml;ltigen Spalten, wie <b>ID<\/b>, <b>Kundencode<\/b>, <b>Firma<\/b>, etwa als <b>T8<\/b>, <b>T9<\/b>, <b>T10<\/b> mit leeren Zellen. Dazu wird die Eigenschaft <b>ColumnHidden<\/b> der entsprechenden Textfelder per Code auf <b>True<\/b> gesetzt. W&uuml;rden Sie ein Formular in <b>Formularansicht<\/b> verwenden, so m&uuml;ssten Sie lediglich die <b>Visible<\/b>-Eigenschaft der Textfelder und Labels steuern.<\/p>\n<p>Wenn Sie wissen, dass Ihre <b>dBase<\/b>-Dateien auch Tabellen mit mehr als zehn Feldern aufweisen, so k&ouml;nnen Sie das Formular ja erweitern und mehr Textfelder und Labels einbauen. Ich exportiere etwa meine Bankums&auml;tze aus <b>StarMoney<\/b> in das <b>dBase<\/b>-Format, um sie unter Access f&uuml;r Steuererkl&auml;rungen analysieren zu k&ouml;nnen. Die resultierende Datei weist 33 Felder auf. Damit kann das Demoformular in vorliegender Version nicht umgehen.<\/p>\n<p>Zu erw&auml;hnen w&auml;re noch, dass die Eigenschaften <b>Daten eingeben<\/b>, <b>Anf&uuml;gen zulassen<\/b>, <b>L&ouml;schen zulassen<\/b> und <b>Bearbeitungen zulassen<\/b> des Formulars alle auf <b>Nein<\/b> eingestellt sind. Denn all dies w&auml;re beim ADO-Recordset durchaus m&ouml;glich, ergibt jedoch wenig Sinn, wenn sich solche &auml;nderungen an den Daten nicht auch in der <b>dBase<\/b>-Datei reflektieren. Lediglich <b>Filter zulassen<\/b> steht auf <b>Wahr<\/b>.<\/p>\n<p>Starten Sie einmal das Formular. Es stellt sich die Ansicht wie in Bild 5 ein, die sich aus dem Laden der Datei <b>kundenli.dbf<\/b> ergibt. Nach f&uuml;nf Sekunden jedoch kommt es zur Ansicht in Bild 6, was die Datei <b>orte.dbf<\/b> repr&auml;sentiert. Das Spiel wiederholt sich alle f&uuml;nf Sekunden. Das haben wir spa&szlig;eshalber nur zur Demonstration dessen eingebaut, dass das Formular dynamisch mit unterschiedlichen Datenquellen umgehen kann.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_05\/frmKundenliste_RT.png\" alt=\"Zur Laufzeit zeigen sich die Daten der dBase-Datei korrekt im auf dem ADO-Recordset basierenden Formular frmKundenliste.\" width=\"700\" height=\"267,6026\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Zur Laufzeit zeigen sich die Daten der dBase-Datei korrekt im auf dem ADO-Recordset basierenden Formular frmKundenliste.<\/span><\/b><\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_05\/frmKundenliste_RT2.png\" alt=\"Der Timer des Formulars wechselt die Datenherkunft alle 5 Sekunden und f&uuml;hrt damit alternativ zur Anzeige der Datei aus orte.dbf.\" width=\"700\" height=\"267,6026\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Der Timer des Formulars wechselt die Datenherkunft alle 5 Sekunden und f&uuml;hrt damit alternativ zur Anzeige der Datei aus orte.dbf.<\/span><\/b><\/p>\n<p>Listing 4 zeigt den wesentlichen Teil des Formularmoduls. Beim &ouml;ffnen wird eine neue Instanz der Klasse <b>cODBCConnection<\/b> in der Variablen <b>C<\/b> erzeugt. <b>ConnectSilent<\/b> weist an, beim Verbinden auf keinen Fall den ODBC-Dialog aufzurufen. Weiter geht es mit <b>Form_Load<\/b>. Dort wird lediglich der Zeitgeber des Formulars auf <b>5.000 ms<\/b> eingestellt, die <b>Timer<\/b>-Routine <b>Form_Timer<\/b> aber auch gleich k&uuml;nstlich aufgerufen. Denn nur die f&uuml;hrt zur Anzeige der <b>dBase<\/b>-Daten. Sie verneint die modulweit g&uuml;ltige Boolean-Variable <b>b<\/b>, so dass diese bei jedem Zeitgeberaufruf von <b>True<\/b> auf <b>False<\/b> und umgekehrt wechselt. Erst die nun aufgerufene zentrale Prozedur <b>ChangeDB<\/b> wertet die Variable aus.<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>rs<span style=\"color:blue;\"> As <\/span>ADODB.Recordset\r\n<span style=\"color:blue;\">Dim <\/span>C<span style=\"color:blue;\"> As <\/span>cODBCConnection\r\n<span style=\"color:blue;\">Dim <\/span>b<span style=\"color:blue;\"> As Boolean<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>Form_Open(Cancel<span style=\"color:blue;\"> As Integer<\/span>)\r\n   <span style=\"color:blue;\">Set<\/span> C = <span style=\"color:blue;\">New<\/span> cODBCConnection\r\n   C.ConnectSilent = <span style=\"color:blue;\">False<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>Form_Load()\r\n   DoCmd.Maximize\r\n   Me.TimerInterval = 5000: Form_Timer\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>Form_Timer()\r\n   b = <span style=\"color:blue;\">Not<\/span> b\r\n   ChangeDB\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>ChangeDB()\r\n   <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Long<\/span>\r\n   C.ConnectString = \"ODBC;\" & _\r\n      \"Driver={Microsoft dBase Driver (*.dbf)};\" & _\r\n      \"DriverID=533;Dbq=\" & CurrentProject.Path\r\n   C.Connect\r\n   <span style=\"color:blue;\">If <\/span>b<span style=\"color:blue;\"> Then<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> rs = C.OpenRecordsetADO( _\r\n                \"SELECT * FROM KUNDENLI.DBF\")\r\n   <span style=\"color:blue;\">Else<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> rs = C.OpenRecordsetADO( _\r\n                \"SELECT * FROM ORTE.DBF\")\r\n   <span style=\"color:blue;\">End If<\/span>\r\n   For i = 1 To 10\r\n     <span style=\"color:blue;\">With<\/span> Me.Controls(\"T\" & CStr(i))\r\n         <span style=\"color:blue;\">If <\/span>i &gt; rs.Fields.Count<span style=\"color:blue;\"> Then<\/span>\r\n           Me.Controls(\"T\" & CStr(i)).ColumnHidden = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Else<\/span>\r\n           .ColumnHidden = <span style=\"color:blue;\">False<\/span>\r\n           .ControlSource = rs.Fields(i - 1).Name\r\n           Me.Controls(\"L\" & CStr(i)).Caption = _\r\n             .ControlSource\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     End <span style=\"color:blue;\">With<\/span>\r\n   <span style=\"color:blue;\">Next<\/span> i\r\n   <span style=\"color:blue;\">Set<\/span> Me.Recordset = rs\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Das fast komplette Modul des Formulars frmKundenliste<\/span><\/b><\/p>\n<p>Sie bereitet zuerst den <b>ConnectString<\/b> auf und gibt in diesem den <b>ODBC-Treiber<\/b> und den Ort der <b>dBase<\/b>-Dateien an. Die <b>ODBCDirect<\/b>-Verbindung wird dann mit <b>Connect<\/b> aufgebaut. Je nach Zustand der Variablen <b>b<\/b> verzweigt die Routine in Zeilen, die &uuml;ber <b>SELECT<\/b>-Statements <b>ADO-Recordsets<\/b> auf verschiedene <b>dbf<\/b>-Dateien &ouml;ffnen.<\/p>\n<p>Nun k&ouml;nnen die Felder der Recordsets inspiziert werden. In der Schleife von <b>1<\/b> bis <b>10<\/b> werden alle Controls des Formulars durchlaufen. Ist <b>i<\/b> gr&ouml;&szlig;er, als die Anzahl der Felder (<b>Fields.Count<\/b>), so wird <b>ColumnHidden<\/b> auf <b>True<\/b> gesetzt. Andernfalls werden der Steuerelementinhalt der Textfelder (<b>ControlSource<\/b>) und die Beschreibung der Labels (<b>Caption<\/b>) auf den Feldnamen der Recordsets eingestellt (<b>Fields(i-1).Name<\/b>). Die Steuerelemente werden dabei jeweils &uuml;ber ein <b>L<\/b> oder ein <b>T<\/b> plus Z&auml;hler-String angesprochen. Abschlie&szlig;end wird das Formular-Recordset per <b>Set<\/b> auf das ADO-Recordset <b>rs<\/b> gesetzt.<\/p>\n<p>Access stellt nun die Verbindung zwischen Steuerelementen und Datenherkunft automatisch ein. Die Datenblattansicht zeigt die <b>dBase<\/b>-Daten jetzt an. Im Prinzip lie&szlig;e sich das Klassenmodul auch noch so erweitern, dass sich &auml;nderungen am ADO-Recordset etwa &uuml;ber eine Methode <b>SaveADO<\/b> &uuml;ber <b>ODBCDirect<\/b> zur&uuml;ck auf die Server-Tabellen &uuml;bertragen. Das allerdings w&auml;re eine heikle Angelegenheit, da die &auml;nderungen m&ouml;glicherweise nicht bedingungskonform w&auml;ren, weil die Tabelle auf dem Server etwa <b>Constraints<\/b> aufweist oder Fremdschl&uuml;ssel, die verletzt werden k&ouml;nnten.<\/p>\n<p>Die ganze Angelegenheit k&ouml;nnen Sie auch f&uuml;r andere <b>DBMS<\/b> einsetzen. Geben Sie im <b>ConnectString<\/b> etwa einfach einen <b>MySQL<\/b>-Treiber an und verbinden sich zu Tabellen, <b>Views<\/b> oder <b>SPs<\/b> auf einem <b>MySQL<\/b>-Server.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>KUNDENLI.DBF<\/p>\n<p>Kundenli.INF<\/p>\n<p>KUNDENLI.MDX<\/p>\n<p>ODBCDirect.accdb<\/p>\n<p>ORTE.DBF<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/BB023B2C-A735-43B9-8EBE-6A7B28C6C0AF\/aiu_1151.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Haben Sie ihr Backend in ein DBMS ausgelagert, also die Tabellen auf einen SQL-Server migriert, so steht Ihnen ab Access 2007 nur noch die Schnittstelle ADODB zur Verf&uuml;gung, um unter VBA auf sie zuzugreifen, falls Sie sich nicht nur auf verkn&uuml;pfte Tabellen beschr&auml;nken m&ouml;chten. Denn die Technologie ODBCDirect, mit der man direkt eine Verbindung zum Server aufbauen konnte, wurde ersatzlos gestrichen. Mit einem Trick schlagen Sie Microsoft jedoch ein Schnippchen!<\/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":[662018,66052018,44000035],"tags":[],"class_list":["post-55001151","post","type-post","status-publish","format-standard","hentry","category-662018","category-66052018","category-Datenzugriff_programmieren"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>ODBCDirect durch die Hintert&uuml;r - 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\/ODBCDirect_durch_die_Hintertuer\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ODBCDirect durch die Hintert&uuml;r\" \/>\n<meta property=\"og:description\" content=\"Haben Sie ihr Backend in ein DBMS ausgelagert, also die Tabellen auf einen SQL-Server migriert, so steht Ihnen ab Access 2007 nur noch die Schnittstelle ADODB zur Verf&uuml;gung, um unter VBA auf sie zuzugreifen, falls Sie sich nicht nur auf verkn&uuml;pfte Tabellen beschr&auml;nken m&ouml;chten. Denn die Technologie ODBCDirect, mit der man direkt eine Verbindung zum Server aufbauen konnte, wurde ersatzlos gestrichen. Mit einem Trick schlagen Sie Microsoft jedoch ein Schnippchen!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-13T21:11:54+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg06.met.vgwort.de\/na\/c00450571e2d41e28eb42a54ae4a5a28\" \/>\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=\"21\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"ODBCDirect durch die Hintert&uuml;r\",\"datePublished\":\"2020-05-13T21:11:54+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/\"},\"wordCount\":3472,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/c00450571e2d41e28eb42a54ae4a5a28\",\"articleSection\":[\"2018\",\"5\\\/2018\",\"Datenzugriff programmieren\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/\",\"name\":\"ODBCDirect durch die Hintert&uuml;r - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/c00450571e2d41e28eb42a54ae4a5a28\",\"datePublished\":\"2020-05-13T21:11:54+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/c00450571e2d41e28eb42a54ae4a5a28\",\"contentUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/c00450571e2d41e28eb42a54ae4a5a28\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ODBCDirect_durch_die_Hintertuer\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"ODBCDirect durch die Hintert&uuml;r\"}]},{\"@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":"ODBCDirect durch die Hintert&uuml;r - 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\/ODBCDirect_durch_die_Hintertuer\/","og_locale":"de_DE","og_type":"article","og_title":"ODBCDirect durch die Hintert&uuml;r","og_description":"Haben Sie ihr Backend in ein DBMS ausgelagert, also die Tabellen auf einen SQL-Server migriert, so steht Ihnen ab Access 2007 nur noch die Schnittstelle ADODB zur Verf&uuml;gung, um unter VBA auf sie zuzugreifen, falls Sie sich nicht nur auf verkn&uuml;pfte Tabellen beschr&auml;nken m&ouml;chten. Denn die Technologie ODBCDirect, mit der man direkt eine Verbindung zum Server aufbauen konnte, wurde ersatzlos gestrichen. Mit einem Trick schlagen Sie Microsoft jedoch ein Schnippchen!","og_url":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-13T21:11:54+00:00","og_image":[{"url":"http:\/\/vg06.met.vgwort.de\/na\/c00450571e2d41e28eb42a54ae4a5a28","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"21\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"ODBCDirect durch die Hintert&uuml;r","datePublished":"2020-05-13T21:11:54+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/"},"wordCount":3472,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/c00450571e2d41e28eb42a54ae4a5a28","articleSection":["2018","5\/2018","Datenzugriff programmieren"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/","url":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/","name":"ODBCDirect durch die Hintert&uuml;r - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/c00450571e2d41e28eb42a54ae4a5a28","datePublished":"2020-05-13T21:11:54+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/#primaryimage","url":"http:\/\/vg06.met.vgwort.de\/na\/c00450571e2d41e28eb42a54ae4a5a28","contentUrl":"http:\/\/vg06.met.vgwort.de\/na\/c00450571e2d41e28eb42a54ae4a5a28"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/ODBCDirect_durch_die_Hintertuer\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"ODBCDirect durch die Hintert&uuml;r"}]},{"@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\/55001151","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=55001151"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001151\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001151"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001151"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001151"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}