{"id":55001089,"date":"2017-06-01T00:00:00","date_gmt":"2020-05-14T13:42:52","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1089"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"GoogleMaps_als_Kartendienst_im_Formular","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/","title":{"rendered":"Google-Maps als Kartendienst im Formular"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg09.met.vgwort.de\/na\/78fc71158a14401b907ba416d6991269\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Sie m&ouml;chten den Anwendern Ihrer Datenbank die M&ouml;glichkeit anbieten, neben den eigentlichen Adressdaten auch gleich dazugeh&ouml;rige Geoinformationen einzusehen Dazu eignen sich sicher die Dienste Google-Maps oder Bing-Maps. Ein Webbrowser-Steuerelement im Formular k&ouml;nnte als Host f&uuml;r jene dienen. Doch der Weg ist steiniger, als erwartet! Wie Sie die auftretenden Probleme l&ouml;sen k&ouml;nnen, beschreibt dieser Beitrag.<\/b><\/p>\n<h2>Google Maps<\/h2>\n<p>Wenn Sie nach einem Ort auf der Startseite von <b>Google Maps <\/b>(<b>https:\/\/www.google.de\/maps<\/b>) recherchieren, so geben Sie in das Suchfeld links oben die gew&uuml;nschte Adresse ein. Google verarbeitet die Anfrage mit seinen <b>Geo Location Services<\/b> und zeigt das Resultat im Browser an. Dabei &auml;ndert sich die Adresszeile entsprechend. Aus der Anfrage <b>Duisburg Borkhofer Str.<\/b> wird dann eine <b>URL<\/b>, die sich aus mehreren Teilen unterschiedlicher Bedeutung zusammensetzt:<\/p>\n<pre>https:\/\/www.google.de\/maps\/place\r\n     \/Borkhofer+Str.,+47137+Duisburg\r\n     \/@51.4634026,6.7777953,17z\r\n     \/data=!3m1!4b1!4m5!3m4!1\r\n     s0x47b8bfbe53cca829:0xb28d5de5549581d!8m2!3d51.4634026!4d6.7799893<\/pre>\n<p>Der Service hat zun&auml;chst ermittelt, dass es sich offenbar um den Ort <b>Duisburg<\/b> in Deutschland handeln soll, der die Postleitzahl <b>47137<\/b> besitzt. Die Angabe des Landes fehlt. Google geht davon aus, dass der Ort sich mit gro&szlig;er Wahrscheinlichkeit in dem Land befindet, von dem aus die Anfrage gesendet wurde. Dies geht etwa aus der &uuml;bermittelten <b>IP<\/b> hervor. Der Stra&szlig;enname vervollst&auml;ndigt diesen Teil, in dem nat&uuml;rlich keine Leerzeichen vorkommen d&uuml;rfen. Sie sind durch Pluszeichen ersetzt.<\/p>\n<p>Doch damit nicht genug! Hinter einem Slash befinden sich, durch ein <b>@<\/b> symbolisiert, auch gleich die Geokoordinaten des gefundenen Orts. L&auml;ngen- und Breitengrad kommen als Flie&szlig;kommazahlen daher, wobei als Dezimaltrennzeichen der Punkt dient. Kommas trennen hingegen die einzelnen Werte. Was jedoch hat es mit dem dritten Parameter dieses Teils auf sich, dem <b>17z<\/b><\/p>\n<p>Versuch und Irrtum machen schlau, denn Google hat den Aufbau dieser Parameter nicht wirklich dokumentiert. Etliche Leute, den Autor eingeschlossen, haben teilweise herausgefunden, was sie bedeuten. Am weitesten kam wohl <b>M. Sticklesville <\/b>mit der Aufstellung in seinem Blog  (<b>https:\/\/mstickles.wordpress.com\/2015\/06\/12\/gmaps-urls-options<\/b>). Der dritte Parameter gibt n&auml;mlich den Zoomgrad der Kartenansicht wieder.<\/p>\n<p>Sie k&ouml;nnen den Wert in der Adresszeile des Browsers einfach von Hand &auml;ndern, etwa in <b>11z<\/b>. Der Ort wird nun von weiter oben betrachtet. Bei <b>4z<\/b> ist allerdings Schluss. Damit wird fast die Erdhalbkugel angezeigt. Der h&ouml;chste Zoomfaktor betr&auml;gt <b>21z<\/b>. Bei allen anderen Werten au&szlig;erhalb dieses Bereichs kommt es nicht etwa zu einer Fehlermeldung, sondern Google korrigiert den Faktor automatisch durch Auf- oder Abrunden auf den n&auml;chsten Wert.<\/p>\n<p>Im dritten Teil der URL findet sich ein omin&ouml;ser <b>data<\/b>-Parameter. Zahlen, Buchstaben und Ausrufezeichen wechseln sich scheinbar willk&uuml;rlich ab. Tats&auml;chlich haben sie eine Bedeutung, der Sie auf die Schliche kommen, wenn Sie etwa die Ansicht der Karte auf <b>Satellit<\/b> einstellen, oder den Layer f&uuml;r das Verkehrsaufkommen einschalten. Bis auf diesen <b>data<\/b>-Parameter bleiben alle anderen Teile der URL dabei konstant. Der <b>data<\/b>-Parameter bestimmt das Layout der Karte. Wenn Sie mehr &uuml;ber seinen Aufbau erfahren m&ouml;chten, so kundschaften Sie den angegebenen Blog von <b>Sticklesville<\/b> aus. Wir kommen auf den <b>data<\/b>-String aber auch sp&auml;ter noch zu sprechen.<\/p>\n<p>Am Ende der URL schlie&szlig;t sich ein l&auml;nglicher String an, der wohl die <b>ID<\/b> der Suchanfrage enth&auml;lt. Google cachet diesen Wert auch in einem <b>Cookie<\/b>, um Rechenzeit einzusparen. Er ist f&uuml;r die Suchanfrage bedeutungslos.<\/p>\n<p>Sie k&ouml;nnen die URL nun dergestalt modifizieren, dass nur noch die wichtigsten Elemente enthalten sind. Das s&auml;he dann so aus:<\/p>\n<pre>https:\/\/www.google.de\/maps\/place\r\n     \/@51.4634026,6.7777953,17z\r\n     \/data=!3m1!4b1!4m5!3m4!1<\/pre>\n<p>Falls die Koordinaten dieselben sind, wie zuvor, so macht Google sofort wieder die urspr&uuml;ngliche Version daraus, weil es sie aus dem <b>Cookie<\/b> ausliest. Bei ge&auml;nderten Koordinaten hingegen bleibt der String meist erhalten. Allerdings &auml;ndert sich nun auch die Ansicht komplett: Das <b>Control Panel links<\/b> verschwindet und der Orts-<b>Marker<\/b> ist ebenfalls nicht mehr da.<\/p>\n<p>Man kann an dieser Stelle zusammenfassen, dass sich die Google-Maps-Anfragen in einer URL unterbringen und sich dabei sowohl Zoomfaktor, wie auch Gestalt des Kartengebnisses, beeinflussen lassen. Was will man mehr Damit ist der erste Teil der Aufgabe in Angriff genommen, eine Google-Maps-Karte in ein Formular zu bringen.<\/p>\n<h2>Das Webbrowser-Steuerelement<\/h2>\n<p>Als Host f&uuml;r die <b>Maps<\/b>-Seiten soll ein Webbrowser-Steuerelement dienen, das Microsoft seit der Access-Version 2007 in den Fundus der Steuerelemente integriert hat. Es unterscheidet sich in nichts vom gleichnamigen ActiveX-Steuerelement, das Windows immer mit sich f&uuml;hrt. Lediglich die M&ouml;glichkeit, es direkt an ein Datenfeld einer Tabelle oder Abfrage zu binden, welches die zu navigierende URL enth&auml;lt, ist ein Bonus-Feature.<\/p>\n<p>Zum Test setzen Sie das Webbrowser-Steuerelement in ein neues Formular ein, wie dies im Formular frmMaps der Beispieldatenbank <b>GoogleMaps.accdb<\/b> geschah (siehe Bild 1). Au&szlig;er dem <b>Webbrowser Control<\/b> enth&auml;lt es nur ein Textfeld rechts oben, welches den Inhalt des <b>URL<\/b>-Felds des aktuellen Datensatzes anzeigt. Die Tabelle <b>tblURLs<\/b> dient als Datenherkunft des Formulars. Sie weist neben der Autowert-<b>ID<\/b> nur das Feld <b>URL<\/b> aus und ein optionales Feld <b>Beschreibung<\/b>, welches hier nicht zum Einsatz kommt. An <b>URL<\/b> sind sowohl das Textfeld, wie auch das Webbrowser-Steuerelement gebunden.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/01_frmMaps.png\" alt=\"Im Testformular zur Tabelle tblURLs ist zentral ein Webbrowser-Steuerelement untergebracht\" width=\"650\" height=\"369,8449\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Im Testformular zur Tabelle tblURLs ist zentral ein Webbrowser-Steuerelement untergebracht<\/span><\/b><\/p>\n<p>Nach dem ersten Start pr&auml;sentiert das Formular eine leere Fl&auml;che, da die erste URL den Inhalt <b>about:blank<\/b> hat.  W&uuml;rde die URL n&auml;mlich aus einem Leer-String bestehen, so k&auml;me es zu einer Fehleranzeige im Browser wegen ung&uuml;ltiger Adresse. Der zweite Datensatz hat den folgenden Inhalt:<\/p>\n<pre>https:\/\/www.google.de\/maps\/<\/pre>\n<p>Sie erwarten, dass nun Google-Maps im Browser angezeigt wird Stattdessen konfrontiert uns Google mit der Meldung aus Bild 2. Aus irgendeinem Grund ist es mit dem Webbrowser-Steuerelement nicht zufrieden und verwehrt die Navigation zu <b>Maps<\/b>. Doch dieses verwendet intern ja lediglich den im System installierten <b>Internet Explorer<\/b>, der m&ouml;glicherweise in einer aktuellen Version <b>11<\/b> vorhanden ist (<b>Edge<\/b> bleibt au&szlig;en vor). Warum dann diese Meldung<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/02_IE_GM_NotOk.png\" alt=\"Statt Maps zeigt Google trotz korrekter URL zun&auml;chst eine Inkompatibilit&auml;tsmeldung an\" width=\"650\" height=\"336,3966\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Statt Maps zeigt Google trotz korrekter URL zun&auml;chst eine Inkompatibilit&auml;tsmeldung an<\/span><\/b><\/p>\n<h2>Webbrowser Control: Limitierungen und deren Aufhebung<\/h2>\n<p>Aus Sicherheitsgr&uuml;nden grenzt Microsoft die M&ouml;glichkeiten im <b>Webbrowser Controls<\/b> stark ein. Das gilt &uuml;brigens f&uuml;r das Access-Steuerelement gleicherma&szlig;en, wie f&uuml;r das ActiveX-Steuerelement. Die wichtigste &auml;nderung besteht darin, dass das Control grunds&auml;tzlich die Version  <b>IE7<\/b> nach au&szlig;en meldet.<\/p>\n<p>Genau damit ist Google nicht einverstanden, da die aktuelle Version von <b>Maps<\/b> einen neueren Browser f&uuml;r korrekte Funktion erwartet. Zudem erlaubt das Control nur eine eingeschr&auml;nkte Ausf&uuml;hrung von <b>JavaScript<\/b>. <\/p>\n<p>Das Ende der Fahnenstange ist damit zum Gl&uuml;ck noch nicht erreicht. Tats&auml;chlich k&ouml;nnen Sie das Verhalten des Webbrowser Controls durch Einstellungen in der <b>Registry<\/b> &auml;ndern! Und daf&uuml;r sind noch nicht einmal administrative Rechte erforderlich, da sich der entsprechende Zweig im Benutzerteil <b>HKEY_CURRENT_USER<\/b> befindet:<\/p>\n<pre>HKEY_CURRENT_USER\\Software\\Microsoft\r\n                    \\Internet Explorer\\Main\\FeatureControl<\/pre>\n<p>Unter diesem Zweig befinden sich noch weitere Schl&uuml;ssel, die verschiedene Funktionen des Controls steuern. Der wichtigste ist dabei der Folgende:<\/p>\n<pre>FEATURE_BROWSER_EMULATION<\/pre>\n<p>Unter diesem Schl&uuml;ssel tragen Sie einen <b>DWORD<\/b>-Wert ein, der den Namen <b>msaccess.exe<\/b> tr&auml;gt. Als Wert verwenden Sie <b>11001<\/b>. Dieser n&auml;mlich f&uuml;hrt dazu, dass Windows beim Start einer Access-Instanz und dem &ouml;ffnen eines Webbrowser-Steuerelements hier nachschaut, ob ein Eintrag zu finden ist. Falls Prozessname und Eintrag zueinander passen, so spendiert Windows dem zugrundeliegenden Internet Explorer die angegebenen Version. Beim Wert <b>11001<\/b> w&auml;re das die Version <b>11<\/b>. Funktionieren w&uuml;rde Google Maps auch noch mit der Version <b>9<\/b>, die dem Registry-Wert <b>9999<\/b> entspr&auml;che. Doch warum zu einer &auml;lteren Version greifen, wenn es eine neuere gibt Voraussetzung ist nat&uuml;rlich, dass auch tats&auml;chlich der <b>Internet Explorer 11<\/b> installiert ist. Passen Sie den Wert an die installierte Version an. Im <b>MSDN<\/b> gibt es eine Seite, die ersch&ouml;pfender dar&uuml;ber Auskunft gibt (<b>https:\/\/msdn.microsoft.com\/en-us\/library\/ee330730(v=vs.85).aspx<\/b>). <b>Edge<\/b> kann das Webbrowser Control &uuml;brigens nicht hosten. Es verwendet auch unter <b>Windows 10 <\/b>den Kompatibilit&auml;tsmodus des <b>IE11<\/b>.<\/p>\n<p>Bedenken brauchen Sie bei der Modifikation der Registry hier nicht zu haben. Zum einen sind Eintr&auml;ge unter dem Benutzerzweig recht unverd&auml;chtig, zum anderen betrifft die &auml;nderung nur ausschlie&szlig;lich Access-Prozesse. &uuml;brigens bedienen sich auch andere Entwickler dieser M&ouml;glichkeit. Wir fanden in diesem Zweig auch Eintr&auml;ge prominenter Anwendungen, wie <b>Visual Studio<\/b>, <b>RapidPHP<\/b> oder <b>Starmoney<\/b>.<\/p>\n<p>Da die &auml;nderungen an der Registry keine Administratorrechte erfordern, k&ouml;nnen Sie auch von Access aus &uuml;ber VBA get&auml;tigt werden. Dies geschieht auch in der Beispieldatenbank. Das Intro-Formular ruft beim Klick auf den gr&uuml;nen Button die Funktion <b>SetWebControlAsIE9<\/b> des Moduls <b>mdlWebcontrol<\/b> auf. Diese liest zun&auml;chst aus der Registry aus, ob der Wert f&uuml;r die <b>Browser Emulation<\/b> bereits gesetzt ist. Falls nicht, so holt sie das umgehend nach. Allerdings wirkt sich die &auml;nderung noch nicht unmittelbar aus. Erst nach einem Neustart von Access gibt das Webbrowser Control die Version <b>IE11<\/b> aus. Deshalb empfiehlt die Routine in diesem Fall auch gleich den Neustart (Bild 3) und bewerkstelligt diesen auch noch. Schauen wir uns diese Routine (ersterer Teil in Listing 1) einmal genauer an.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/03_Neustart.png\" alt=\"Automatische Aufforderung zum Neustart von Access &uuml;ber die Prozedur SetWebControlAsIE9 und eine Messagebox\" width=\"425\" height=\"166,895\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Automatische Aufforderung zum Neustart von Access &uuml;ber die Prozedur SetWebControlAsIE9 und eine Messagebox<\/span><\/b><\/p>\n<p>Da Access und VBA keine Methoden zum Auslesen oder Schreiben der Registry haben, ben&ouml;tigen wir den Verweis  auf eine externe Komponente. F&uuml;r unseren einfachen Zweck gelingt das am effizientesten mit der Bibliothek <b>Windows Script Host Object Model<\/b>, die im Objektkatalog nachher den Namen <b>IWshRuntimeLibrary<\/b> tr&auml;gt und auf der Datei <b>wshom.ocx <\/b>beruht. Diese Bibliothek ist Bestandteil von Windows und kann deshalb bedenkenlos zum Einsatz kommen. Ihre Klasse <b>WshShell<\/b> enth&auml;lt Methoden zur Modifikation der Registry.<\/p>\n<p>Die Objektvariable <b>oShell<\/b> nimmt eine Instanz dieser Klasse per <b>New<\/b> auf. Der Zweig der Registry ist in der String-Variablen <b>sKey<\/b> gespeichert, und zwar inklusive des Wertnamens. Die Funktion <b>RegRead<\/b> auf den Schl&uuml;ssel gibt dann den Wert als Variant in der Variablen <b>vKey<\/b> zur&uuml;ck. Da es zum Fehler kommt, wenn der Registry-Schl&uuml;ssel nicht existiert, ist der Aufruf der Funktion in eine Fehlerbehandlung &uuml;ber <b>On Error Resume Next<\/b> eingebettet. Der Fehlerwert betr&auml;gt in diesem Fall <b>-2147024894<\/b>, der in der folgenden Bedingung dazu f&uuml;hrt, dass der Schl&uuml;sselwert &uuml;ber die Methode <b>RegWrite<\/b> neu geschrieben wird. Die Klasse <b>WshShell<\/b> erlaubt also einen komfortablen Zugriff auf die Registry mit sehr wenig Aufwand.<\/p>\n<p>Existiert der Schl&uuml;sselwert zwar, so ist zu pr&uuml;fen, ob er dem gew&uuml;nschten entspricht. Das &uuml;bernehmen die folgenden Zeilen. Weicht der Inhalt von <b>vKey<\/b> von <b>11001<\/b> ab, so erfolgt abermals das Schreiben in den Schl&uuml;ssel. Ansonsten passiert au&szlig;er der informativen Ausgabe im VBA-Direktfenster weiter nichts. Wichtig aber ist noch eine Kleinigkeit: Wurde in die Registry geschrieben, so erh&auml;lt die Bool-Variable <b>bNewStart<\/b> den Wert <b>True<\/b>. Dieser Wert wird am Ende der Routine ausgewertet:<\/p>\n<pre>    <span style=\"color:blue;\">If <\/span>bNewStart<span style=\"color:blue;\"> Then<\/span>\r\n         RestartAccess\r\n     <span style=\"color:blue;\">End If<\/span><\/pre>\n<p><b>RestartAccess<\/b> ist eine weitere Prozedur im Modul, die den Neustart von Access veranlasst (siehe Listing 2). Wird die Nachfrage der <b>MsgBox<\/b> best&auml;tigt, so wird wieder das <b>Shell<\/b>-Objekt bem&uuml;ht. Seine Methode <b>Exec<\/b> entspricht ungef&auml;hr der <b>Shell<\/b>-Methode von VBA, ist aber etwas einfacher zu handhaben. In <b>sExec<\/b> wird ein String zusammengebastelt, der eine neue Instanz von Access startet, wobei &uuml;ber <b>SysCmd<\/b> erfahren wird, wo sich die <b>msaccess.exe<\/b> befindet. Als Parameter f&uuml;r den Prozess wird der Name der aktuellen Datenbank (<b>CurrentDb.Name<\/b>) &uuml;bergeben. In der Folge startet eine zus&auml;tzliche Instanz der Datenbank. Die aktuelle Instanz wird aber &uuml;ber <b>Quit<\/b> geschlossen. Das passiert so schnell, dass es kaum wahrnehmbar ist. Im Ergebnis befinden wir uns in der Datenbank mit dem neu aktiviertem <b>Webbrowser Control<\/b>.<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>RestartAccess()\r\n     If <span style=\"color:blue;\">MsgBox<\/span>(\"Die Datenbank und Access m&uuml;ssen neu gestartet werden,\" & <span style=\"color:blue;\">vbCrLf<\/span> & _\r\n         \"weil die Einstellungen f&uuml;r das WebControl ge&auml;ndert wurden.\" & <span style=\"color:blue;\">vbCrLf<\/span> & _\r\n         \"Jetzt neu starten\", vbQuestion Or vbYesNo, \"Best&auml;tigen:\") = vbYes Then\r\n         \r\n         <span style=\"color:blue;\">Dim <\/span>sExec<span style=\"color:blue;\"> As String<\/span>\r\n         <span style=\"color:blue;\">Dim <\/span>oShell<span style=\"color:blue;\"> As <\/span><span style=\"color:blue;\">New<\/span> WshShell\r\n         \r\n         sExec = Chr$(34) & SysCmd(acSysCmdAccessDir) & \"msaccess.exe\" & Chr$(34) & _\r\n                 \" \" & Chr$(34) & CurrentDb.Name & Chr$(34)\r\n         oShell.Exec sExec\r\n         Application.Quit acQuitSaveNone\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Die Routine RestartAccess &uuml;bernimmt gegebenenfalls den Neustart von Access<\/span><\/b><\/p>\n<p>Die Routine <b>SetWebControlAsIE9<\/b> enth&auml;lt noch einen zweiten Teil, der drei weitere Einstellungen f&uuml;r das Control vornimmt. Das passiert analog zum ersten Teil. Der Unterschied besteht nur darin, dass der Code-Block nicht dreimal wiederholt wird, sondern eine Schleife auf das Array <b>vRegElement<\/b> die einzelnen Registry-Schl&uuml;ssel anspricht:<\/p>\n<pre>vRegElement = Array(\"FEATURE_BLOCK_LMZ_SCRIPT\", \r\n     \"FEATURE_BLOCK_LMZ_OBJECT\", \r\n     \"FEATURE_BLOCK_LMZ_IMG\")\r\nFor i= 0 To 2\r\n     sKey = \"HKEY_CURRENT_USER\\Software\\Microsoft\\\" & _\r\n         \"Internet Explorer\\Main\\FeatureControl\\\" & _\r\n         vRegElement(i) & \"\\msaccess.exe\"\r\n     ...\r\n     oShell.RegWrite sKey, 1, \"REG_DWORD\"\r\n     ...\r\n<span style=\"color:blue;\">Next<\/span> i<\/pre>\n<p>Falls es noch nicht aufgefallen sein sollte: <b>RegWrite<\/b> &uuml;bernimmt in einem Rutsch die Anlage des Registry-Schl&uuml;ssels und des Werts! Einfacher geht&#8220;s nicht! Bei allen alternativen Methoden muss das separat erfolgen.<\/p>\n<p>Neben den Einstellungen, die so &uuml;ber die Registry vorgenommen werden k&ouml;nnen, gibt es noch einige weitere, die die weitgehende &uuml;bereinstimmung des Webbrowser-Steuerelements mit dem dem Internet Explorer herstellen k&ouml;nnen. Dazu jedoch muss eine Windows-API-Funktion bem&uuml;ht werden, die sich <b>CoInternetSetFeatureEnabled<\/b> nennt. Das Setzen dreier neuer Eigenschaften ist in die Prozedur <b>ChangeWebControlFeature<\/b> ausgelagert (Listing 3).<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>Declare Function CoInternetSetFeatureEnabled Lib \"urlmon.dll\" _\r\n     (ByVal FeatureEntry<span style=\"color:blue;\"> As <\/span>eINTERNETFEATURELIST, ByVal Flags<span style=\"color:blue;\"> As <\/span>eFEATURESetting, ByVal bEnable<span style=\"color:blue;\"> As Long<\/span>)<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Public <\/span>Declare Function CoInternetIsFeatureEnabled Lib \"urlmon.dll\" _\r\n     (ByVal FeatureEntry<span style=\"color:blue;\"> As <\/span>eINTERNETFEATURELIST, ByVal Flags<span style=\"color:blue;\"> As <\/span>eFEATURESetting)<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Sub <\/span>ChangeWebControlFeature()\r\n     <span style=\"color:blue;\">Dim <\/span>ret<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lret<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">If <\/span>CoInternetIsFeatureEnabled(FEATURE_BEHAVIORS, SET_FEATURE_ON_PROCESS) &lt;&gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         ret = CoInternetSetFeatureEnabled(FEATURE_BEHAVIORS, SET_FEATURE_ON_PROCESS, 1)\r\n         lret = ret\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span>CoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, SET_FEATURE_ON_PROCESS) &lt;&gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         ret = CoInternetSetFeatureEnabled(FEATURE_ZONE_ELEVATION, SET_FEATURE_ON_PROCESS, 1)\r\n         lret = lret + ret\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span>CoInternetIsFeatureEnabled(FEATURE_RESTRICT_ACTIVEXINSTALL, SET_FEATURE_ON_PROCESS) &lt;&gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n          ret = CoInternetSetFeatureEnabled(FEATURE_RESTRICT_ACTIVEXINSTALL, SET_FEATURE_ON_PROCESS, 0)\r\n         lret = lret + ret\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Debug.Print<\/span> IIf(lret = 0, \"Features adjusted\", \"Feature adjustment failed\")\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><!--30percent--><\/p>\n<p><b><span style=\"color:darkgrey;\">Listing 3: ChangeWebcontrolFeature setzt neue Eigenschaften f&uuml;r das Webbrowser Control per API<\/span><\/b><\/p>\n<p>Die Konstanten f&uuml;r Steueranweisungen, wie <b>FEATURE_BEHAVIOURS<\/b>, stehen im Kopf des Moduls. Sie bestimmen das anzusprechende Feature des Webbrowser Controls. F&uuml;r alle drei Aufrufe ist die Anweisung <b>SET_FEATURE_ON_PROCESS<\/b> angegeben. Das besagt, dass die Eigenschaft nur auf den laufenden Prozess, also  die Access-Instanz, wirken soll. Dabei fragt die zweite API-Funktion <b>CoInternetIsFeatureEnabled<\/b> jeweils zuerst ab, ob die Eigenschaft schon gesetzt ist. Die Prozedur <b>ChangeWebControlFeature<\/b> muss, da sie nur den Prozess betrifft, immer beim Start der Datenbank ausgef&uuml;hrt werden. Auf die Bedeutung der einzelnen Features m&ouml;chten wir an dieser Stelle nicht weiter eingehen. In der MSDN (<b>https:\/\/msdn.microsoft.com\/en-us\/library\/ee330720(v=vs.85).aspx<\/b>) sind die Features n&auml;her erl&auml;utert.<\/p>\n<p>Zur&uuml;ck zu unserem Testformular. Nach dem Durchlaufen der Anpassungsroutinen und Neustart von Access rufen Sie <b>frmMaps<\/b> erneut auf. Und nun pr&auml;sentiert sich beim zweiten Datensatz tats&auml;chlich die Startseite von Google Maps (s. Bild 4). Alles ok! Der dritte Datensatz verweist direkt auf eine zuvor in Maps im Browser ermittelte Ortsadresse:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/03_IE_GM_Ok.png\" alt=\"Google Maps nach der Anpassung des Webbrowser-Steuerlements &uuml;ber Registry und API\" width=\"650\" height=\"369,8449\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Google Maps nach der Anpassung des Webbrowser-Steuerlements &uuml;ber Registry und API<\/span><\/b><\/p>\n<pre>https:\/\/www.google.com\/maps\/place\/Berlin,+Deutschland\r\n     \/@52.5075419,13.4251364,11z\/data=!4m2!3m1!<\/pre>\n<p>Auch diese wird nun korrekt angesteuert (s. Bild 5). Da es sich um keine genaue Adresse handelt, sondern eine Stadt, wird diese in der Karte als Gebiet umrahmt. St&ouml;rend ist bei dieser Formulargr&ouml;&szlig;e allerdings, dass das <b>Control Panel<\/b> von Google Maps mehr Platz einnimmt, als der Kartenausschnitt. Leider l&auml;sst sich dieses Panel nach allem bisherigen Wissen nicht &uuml;ber Steuerparameter ausblenden. Da bleibt nur der Klick auf den Schlie&szlig;en-Button des Panels, der dann allerdings auch die Ortsmarkierung in der Karte entfernt&#8230;<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/04_IE_Ok.png\" alt=\"Google Maps zeigt nach Ansteuerung einer Such-URL das richtige Ergebnis mit Steuer-Panel\" width=\"650\" height=\"369,8449\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Google Maps zeigt nach Ansteuerung einer Such-URL das richtige Ergebnis mit Steuer-Panel<\/span><\/b><\/p>\n<p>Bei genauerem Hinsehen finden Sie in der Karte einen kleinen Blitz links neben den <b>+\/-<\/b>Elementen zu Zoomen der Karte eingebaut. Der fehlt beim Aufruf der Seite in einem Browser. Ein Klick auf ihn f&ouml;rdert ein Popup zutage, welches die Meldung in Bild 6 enth&auml;lt. Offenbar hat Google nun doch ermittelt, dass hier nicht mit einem vollwertigen Browser gearbeitet wird. Das liegt daran, dass bestimmte externe Objekte des Web-Dokuments hier nicht &uuml;ber <b>JavaScript<\/b> ansprechbar sind. Wir konnten im <b>Lite-Modus<\/b> jedoch keine wesentlichen Einschr&auml;nkungen feststellen. Alle Ansichten, inklusive <b>Street View,<\/b> konnten anstandslos eingeschaltet werden und verhielten sich erwartungsgem&auml;&szlig;.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/05_GM_Lite.png\" alt=\"Trotz Webbrowser-Control-Anpassungen schaltet Google-Maps dennoch in den sogenannten Lite-Modus\" width=\"425\" height=\"180,0493\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Trotz Webbrowser-Control-Anpassungen schaltet Google-Maps dennoch in den sogenannten Lite-Modus<\/span><\/b><\/p>\n<h2>Adressen im Webbrowser-Steuerelement automatisch &uuml;ber Formular ansteuern<\/h2>\n<p>Mit den bisherigen Erkenntnissen im Gep&auml;ck kann es an die Realisierung einer Beispiell&ouml;sung gehen. Ziel ist es, ein einfaches Adressformular zu Kunden der Datenbank um eine Kartenansicht zu bereichern. Hierf&uuml;r kommt das Datenmodell in Bild 7 zum Einsatz. In der Tabelle <b>tblKunden<\/b> sind Adressen gespeichert.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/00_Rellayout.png\" alt=\"Beziehungs-Layout der Beispieldatenbank (Kundenadressen)\" width=\"425\" height=\"279,551\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Beziehungs-Layout der Beispieldatenbank (Kundenadressen)<\/span><\/b><\/p>\n<p><b>tblAnreden<\/b> und <b>tblOrte<\/b> sind verkn&uuml;pfte Detailtabellen. Sie sind auch im Entwurf der Kundentabelle (s. Bild 8)  in den Feldern <b>IDAnrede<\/b> und <b>IDOrt<\/b> als Nachschlagetabellen f&uuml;r die hier verwendeten Kombinationsfelder eingetragen. <b>tblKunden<\/b> zeigt im Entwurf neben den &uuml;blichen Adressfeldern noch die zwei zus&auml;tzlichen Textfelder <b>MapsURL<\/b> und <b>BingURL<\/b>. In sie sollen sp&auml;ter die &uuml;ber Google- oder Bing-Maps im Webbrowser-Steuerelement ermittelten Such-URLs abgelegt werden. Bild 9 demonstriert einen Ausschnitt der Daten in der Datenblattansicht. Beide URL-Felder sind mit dem Vorgabewert <b>about:blank<\/b> belegt, der dann, wie im unteren Bereich zu sehen, durch die korrekten Maps-Adressen ersetzt wird. &uuml;brigens handelt es sich hier zwar um gefakte Adressen, bei denen jedoch die Kombination Stra&szlig;e, <b>PLZ<\/b> und Ort korrekt sind, damit die <b>Geo Services<\/b> etwas Sinnvolles finden k&ouml;nnen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/00_tblKunden_Design.png\" alt=\"Der Entwurf der Tabelle tblKunden zeigt die URL-Felder\" width=\"425\" height=\"284,2473\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Der Entwurf der Tabelle tblKunden zeigt die URL-Felder<\/span><\/b><\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/00_tblKunden_RT.png\" alt=\"Die Tabelle tblKunden ist mit etwa 7000 Fake-Adressen gef&uuml;llt, die zus&auml;tzlich die URL zu Google- oder Bing-Maps aufnehmen k&ouml;nnen\" width=\"700\" height=\"198,5998\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 9: Die Tabelle tblKunden ist mit etwa 7000 Fake-Adressen gef&uuml;llt, die zus&auml;tzlich die URL zu Google- oder Bing-Maps aufnehmen k&ouml;nnen<\/span><\/b><\/p>\n<p>Die Tabelle <b>tblKunden<\/b> stellt nun die Datenbasis f&uuml;r das Formular <b>frmKundenMaps<\/b>, dessen Entwurf Bild 10 darstellt. Die Steuerelemente im Detailbereich sind unmittelbar an die Datenfelder gekn&uuml;pft, wobei die Kombinationsfelder zu <b>Anrede<\/b> und <b>Ort<\/b> nat&uuml;rlich die entsprechenden Nachschlagetabellen heranziehen. Die gro&szlig;e wei&szlig;e Fl&auml;che ist ein mit <b>ctlWebX<\/b> benanntes Webbrowser-Steuerelement, das ebenfalls an das Feld <b>MapsURL<\/b> gebunden ist. Damit wird beim Aufruf des Formulars direkt zur Seite <b>about:blank<\/b>, dem Standardwert des Datenfels, navigiert. Andernfalls bek&auml;me man im Webbrowser Control die Meldung <b>Ung&uuml;ltige Adresse<\/b> zu Gesicht. Die Verankerung des Steuerelements ist auf <b>Quer und nach unten dehnen<\/b> eingestellt, damit sich der Webbrowser nach <b>Resizen<\/b> des ver&auml;nderbaren Formularrahmens entsprechend vergr&ouml;&szlig;ert.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/06_frmKundenDesign.png\" alt=\"Entwurfsansicht des Formulars frmKundenMaps mit dem Webbrowser-Steuerelement unten\" width=\"650\" height=\"462,3712\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 10: Entwurfsansicht des Formulars frmKundenMaps mit dem Webbrowser-Steuerelement unten<\/span><\/b><\/p>\n<p>&uuml;ber dem Webbrowser sind noch einige Steuerelemente ohne Datenbindung untergebracht. Sie dienen zur Steuerung der Kartenansicht. Zur Einstellung des Zoomfaktors kommt dabei ein ActiveX-Steuerelement, der <b>Microsoft Forms Scrollbar<\/b>, zum Einsatz, dessen Eigenschaften wie in Bild 11 gesetzt wurden. Der Minimalwert, den das Steuerelement mit nach links gezogenem Scroll-Ziehelement einnehmen kann, ist <b>4<\/b>. Ganz rechts kommt es zum Maximalwert <b>21<\/b>. Sie ahnen bereits, dass dies die Werte sind, die sp&auml;ter direkt f&uuml;r den <b>z-Parameter<\/b> der <b>Maps-URL<\/b> verwendet werden sollen. Der Standardwert ist <b>15z<\/b>. Ein Klick auf die Pfeil-Buttons erh&ouml;ht oder senkt den Faktor um eins, ein Klick auf die Balkenfl&auml;che um drei.<\/p>\n<p class=\"image\"><img loading=\"lazy\" decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/Props_ctlZoom.png\" alt=\"Eigenschaften des MS-Forms-Scrollbar-Steuerelements ctlZoom\" width=\"425\" height=\"425\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 11: Eigenschaften des MS-Forms-Scrollbar-Steuerelements ctlZoom<\/span><\/b><\/p>\n<p>Die Gruppe der drei Optionsschaltfl&auml;chen links stellt den Ansichtsmodus ein, die Optionsgruppe rechts den optionalen Karten-Layer f&uuml;r Radwege, Verkehrsaufkommen oder &ouml;ffentliche Verkehrsmittel. <\/p>\n<p>Mit dem blauen Pfeil-Button neben der Orts-Combo hat es folgende Bewandtnis: Manchmal kann Google die Adresse nicht richtig interpretieren, weil es sie etwa nicht gibt, Schreibweisen falsch sind, oder Felder schlicht leer gelassen wurden. Dann kommt auch keine g&uuml;ltige <b>Maps-URL<\/b> heraus und das Browser-Feld bleibt, wie wir noch sehen werden, leer. In diesem Fall f&uuml;hrt ein Klick auf den blauen Button zu einer neuen Suchanfrage, wobei hier lediglich der Ortsname &uuml;bergeben wird. Damit l&auml;sst sich dann wenigstens der auf der Karte darstellen.<\/p>\n<p>Und schlie&szlig;lich finden Sie noch ganz oben ein Kombinationsfeld <b>cbFind<\/b> mit der Beschriftung <b>Gehe zu<\/b>, in dem die Namen aller Kunden der Datenbank aufgelistet werden. Es dient zur Navigation durch den Kundenstamm, weil die <b>Navigationsschaltfl&auml;chen<\/b> des Formulars auf <b>Nein<\/b> stehen. Die Datenherkunft des Kombinationsfelds besteht aus einer <b>UNION-Abfrage<\/b>, die zwei k&uuml;nstliche Eintr&auml;ge zur Kundenliste hinzuf&uuml;gt:<\/p>\n<pre>(SELECT -1 AS ID, \" (Kunden L&ouml;schen)\" AS Vollname FROM tblKunden)\r\nUNION\r\n(SELECT 0 AS ID, \"  (Neuer Kunde)\" AS Vollname FROM tblKunden)\r\nUNION\r\n(SELECT tblKunden.ID, [Nachname] & \", \" & [Vorname] AS Vollname\r\n  FROM tblKunden) ORDER BY Vollname;<\/pre>\n<p>Die Abfrage gibt damit im Feld-Alias <b>Vollname<\/b> die aus Nach- und Vorname zusammengesetzten Namen der Tabelle <b>tblKunden<\/b> zur&uuml;ck, und zweitens die <b>ID<\/b> des Kunden, die immer gr&ouml;&szlig;er ist, als <b>0<\/b>. Hinzugef&uuml;gt werden die Eintr&auml;ge <b>(Kunden l&ouml;schen)<\/b> und <b>(Neuer Kunde)<\/b> mit den k&uuml;nstlichen <b>IDs<\/b> <b>-1<\/b> und <b>0<\/b>. Nach Aktualisierung der Combobox kann der sie gebundene <b>ID<\/b>-Wert ausgelesen und in der Ereignisprozedur ausgewertet werden. Infolge der aufsteigenden Sortierung der Datens&auml;tze stehen die k&uuml;nstlichen Datens&auml;tze mit der beginnenden Klammer immer ganz oben in der Liste. Der Code der Prozedur <b>Nach Aktualisierung<\/b> steht in Listing 4. Wertet das <b>Select-Case<\/b>-Statement die <b>0<\/b> f&uuml;r <b>(Neuer Kunde)<\/b> aus, so &uuml;bernimmt das <b>DoCmd.GotoRecord<\/b> mit dem Parameter <b>acNewRec<\/b> die Neuanlage eines Datensatzes. Bei der <b>-1<\/b> kommt es zum L&ouml;schen des Datensatzes &uuml;ber <b>RunCommand acCmdDeleteRecord<\/b>. Andernfalls springt das Formular &uuml;ber dessen Recordset und die <b>FindFirst<\/b>-Methode anhand der &uuml;bergebenen <b>ID<\/b> zum gew&uuml;nschten Kunden.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cbFind_AfterUpdate()\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     Select Case Me!cbFind.Value\r\n     <span style=\"color:blue;\">Case <\/span>0\r\n         DoCmd.GoToRecord acDataForm, Me.Name, acNewRec\r\n     <span style=\"color:blue;\">Case <\/span>-1\r\n         If <span style=\"color:blue;\">MsgBox<\/span>(\"Diesen Kunden wirklich l&ouml;schen\", _\r\n             vbYesNo Or vbExclamation, \"Best&auml;tigen:\") = vbYes Then\r\n                RunCommand acCmdDeleteRecord\r\n                Me!cbFind.Requery\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Case Else<\/span>\r\n         Me.Recordset.FindFirst \"ID=\" & Me!cbFind.Value\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Navigieren durch die Datens&auml;tze &uuml;ber das Kombinationsfelds cbFind<\/span><\/b><\/p>\n<p>Soweit die generelle Beschreibung des Formularentwurfs. Nun soll nach Auswahl eines Kunden sogleich die entsprechende Karte im Webbrowser angezeigt werden. Daf&uuml;r kommt dann das Ereignis <b>Beim Anzeigen<\/b> (<b>Form_Current<\/b>) infrage. In dessen Prozedur wird die Suchanfrage zusammengestellt. Listing 5 stellt die daf&uuml;r relevanten Teile dar. Zun&auml;chst wir hier getestet, ob der im Feld <b>MapsURL<\/b> der Datenherkunft gespeicherte Wert den String <b>about:blank<\/b> tr&auml;gt. Das ist standardm&auml;&szlig;ig ja der Fall und ein Indiz, dass noch keine <b>Maps<\/b>-Adresse ermittelt wurde. In diesem Fall schreitet die Routine zur Tat und stellt den Such-String anhand der Adressfelder zusammen. &uuml;brigens tut sie das auch dann, wenn die Variable <b>bForceUpdate<\/b> den Wert <b>True<\/b> besitzt. Diese globale Variable wird, wie noch zu erl&auml;utern ist, in anderen Prozeduren belegt und dient dann dazu, die Suchanfrage hier zu erzwingen.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Current()\r\n     <span style=\"color:blue;\">Dim <\/span>sURL<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>sLoc<span style=\"color:blue;\"> As String<\/span>\r\n     \r\n     <span style=\"color:blue;\">If <\/span>(Me!MapsURL.Value = \"about:blank\") Or (bForceUpdate = <span style=\"color:blue;\">True<\/span>)<span style=\"color:blue;\"> Then<\/span>\r\n         sURL = \"https:\/\/www.google.com\/maps\/place\/\"\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> IsNull(Me!IDOrt)<span style=\"color:blue;\"> Then<\/span>\r\n             Me!cbOrt.SetFocus\r\n             sLoc = Me!cbOrt.Text\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> IsNull(Me!PLZ)<span style=\"color:blue;\"> Then<\/span> sLoc = Me!PLZ & \" \" & sLoc\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> IsNull(Me!Strasse)<span style=\"color:blue;\"> Then<\/span> sLoc = Me!Strasse & \", \" & sLoc\r\n         sLoc = <span style=\"color:blue;\">Trim<\/span>(sLoc)\r\n         sLoc = <span style=\"color:blue;\">Replace<\/span>(sLoc, \" \", \"%20\")\r\n         \r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(sLoc) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n             Me!ctlImgOverlay.Visible = <span style=\"color:blue;\">True<\/span>\r\n             ctlWeb.Navigate2 sURL & sLoc & fuOptions\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             ctlWeb.Navigate2 \"about:blank\"\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         ctlWeb.Navigate2 Me!MapsURL.Value & fuOptions\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     bForceUpdate = <span style=\"color:blue;\">False<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Beim Anzeigen eines Datensatzes stellt die Prozedur die Suchanfrage f&uuml;r Maps zusammen<\/span><\/b><\/p>\n<p>Die String-Variable <b>sLoc<\/b> nimmt den Suchtext auf. Sie beginnt immer mit der generellen URL f&uuml;r Google-Maps, die aber zun&auml;chst in der Variablen <b>sURL<\/b> gespeichert wird. Statt <b>\/maps\/place\/<\/b> k&ouml;nnen Sie &uuml;brigens genauso gut <b>\/maps\/search\/<\/b> einsetzen. Das Ergebnis unterscheidet sich in der Regel dabei nicht. Ist eine Ortsangabe im Datensatz vorhanden, also <b>IDOrt<\/b> nicht <b>Null<\/b>, so liest der Code aus der Text-Eigenschaft des Kombinationsfelds <b>cbOrt<\/b> deren Namen aus, wozu erst der Fokus auf das Steuerelement gesetzt werden muss. Die Postleitzahl aus dem Datenfeld <b>PLZ<\/b> wird vorangestellt und die Stra&szlig;e ebenfalls, wobei der Ort hinten &uuml;ber ein Komma abgesetzt wird.<\/p>\n<p>Leerzeichen links und rechts werden anschlie&szlig;end mit der <b>Trim<\/b>-Funktion entfernt und Leerzeichen mitten im Text, die ja in URLs nichts zu suchen haben, durch die numerische Repr&auml;sentation <b>%20<\/b> ersetzt.<\/p>\n<p>Kommt dabei ein valider Such-String in <b>sLoc<\/b> heraus, was die <b>Len<\/b>-Funktion ermittelt, dann kommt es zum Aufruf der Methode <b>Navigate2<\/b> des Webbrowser-Steuerelements <b>ctlWeb<\/b>, die es anweist, die <b>URL<\/b> anzusteuern. Sie setzt sich aus der generellen URL in <b>sURL<\/b> zusammen, aus der Adresse in <b>sLoc<\/b> und aus einem String, der von der Hilfsfunktion <b>fuOptions<\/b> zur&uuml;ckgegeben wird. Diese Hilfsfunktion stellt die Parameter f&uuml;r das Layout der Karte zusammen, die im <b>data<\/b>-Block an die Suchadresse angeh&auml;ngt werden. Die Beschreibung dieser Funktion folgt gleich noch.<\/p>\n<p>Doch lautet der Name des Webbrowser-Steuerelements nicht <b>ctlWebX<\/b>, obwohl hier ein <b>ctlWeb<\/b> angesprochen wird Das ist korrekt. Tats&auml;chlich ist im Kopf des Formulars eine Objektvariable <b>ctlWeb<\/b> deklariert:<\/p>\n<pre><span style=\"color:blue;\">Private <\/span>WithEvents ctlWeb<span style=\"color:blue;\"> As <\/span>WebBrowser<\/pre>\n<p>Der Typ <b>Webbrowser<\/b> stammt aus der Bibliothek <b>Microsoft Internet Controls<\/b> (<b>shdocvw)<\/b>, die in den Verweisen des Projekts steht und f&uuml;r den <b>Internet Explorer<\/b> unter Windows verantwortlich ist. Im <b>Beim Laden<\/b>-Ereignis des Formulars (<b>Form_Load<\/b>) wird ihr das Webbrowser-Steuerelement zugewiesen:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Load()\r\n     <span style=\"color:blue;\">Set<\/span> ctlWeb = Me!ctlWebX.Object\r\n...<\/pre>\n<p>Kleiner, aber feiner Unterschied: Nicht das Steuerelement selbst, sondern dessen <b>Object<\/b>-Eigenschaft wird hier zugewiesen! Denn die ist absolut kompatibel mit der <b>Webbrowser<\/b>-Klasse in <b>shdocvw<\/b>. Der Grund f&uuml;r das Vorgehen: Microsoft hat etliche Eigenschaften und Methoden der Webbrowser-Klasse aus seinem Access- Steuerelement eliminiert. Es hat n&auml;mlich gar keine Methode, um die Navigation zu einer Web-Seite anzuordnen. Das hat bei ihm immer &uuml;ber die Datenbindung an den <b>Steuerelementinhalt<\/b> zu geschehen.<\/p>\n<p>Zur&uuml;ck zur Hilfsfunktion <b>fuOptions<\/b>, die in Listing 6 abgebildet ist. Die angesprochenen Optionsgruppen im Formular zur Steuerung der Kartenansicht nennen sich <b>fr1<\/b> und <b>fr2<\/b>. Der Wert ihrer Schaltfl&auml;chen betr&auml;gt einmal <b>1<\/b>, <b>2<\/b>, oder <b>4<\/b>, dann <b>0<\/b>, <b>8<\/b>, <b>16<\/b>, <b>32<\/b>. Die Werte beider Gruppen werden in der Variablen <b>n<\/b> addiert. Damit ergibt sich f&uuml;r jegliche Auswahlkombination ein eindeutiger Wert, der im folgenden <b>Select-Case<\/b>-Block ausgewertet wird. Die Zweige sind wohl selbsterkl&auml;rend.<\/p>\n<pre><span style=\"color:blue;\">Private Function <\/span>fuOptions()<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>n<span style=\"color:blue;\"> As Long<\/span>\r\n     \r\n     n = Me!fr1.Value + Me!fr2.Value\r\n     Select Case n\r\n     ''Normal:\r\n     <span style=\"color:blue;\">Case <\/span>1: fuOptions = \"\/data=!5m1!1e0\"    ''Normal\r\n     <span style=\"color:blue;\">Case <\/span>9: fuOptions = \"\/data=!5m1!1e3\"    ''+Fahrrad\r\n     <span style=\"color:blue;\">Case <\/span>17: fuOptions = \"\/data=!5m1!1e1\"   ''+Verkehrslage\r\n     <span style=\"color:blue;\">Case <\/span>33: fuOptions = \"\/data=!5m1!1e2\"   ''+&ouml;ffi\r\n     ''Gel&auml;nde:\r\n     <span style=\"color:blue;\">Case <\/span>4: fuOptions = \"\/data=!5m1!1e4\"\r\n     <span style=\"color:blue;\">Case <\/span>12: fuOptions = \"\/data=!5m2!1e4!1e3\"   ''+Fahrrad\r\n     <span style=\"color:blue;\">Case <\/span>20: fuOptions = \"\/data=!5m2!1e4!1e1\"   ''+Verkehr\r\n     <span style=\"color:blue;\">Case <\/span>36: fuOptions = \"\/data=!5m2!1e4!1e2\"   ''+&ouml;ffi\r\n     ''Satellit:\r\n     <span style=\"color:blue;\">Case <\/span>2: fuOptions = \"\/data=!3m1!1e3\"\r\n     <span style=\"color:blue;\">Case <\/span>10: fuOptions = \"\/data=!3m1!1e3!5m1!1e3\"   ''+Fahrrad\r\n     <span style=\"color:blue;\">Case <\/span>18: fuOptions = \"\/data=!3m1!1e3!5m1!1e1\"   ''+Verkehr\r\n     <span style=\"color:blue;\">Case <\/span>34: fuOptions = \"\/data=!3m1!1e3!5m1!1e2\"   ''+&ouml;ffi\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n     \r\n     ''Zoom:\r\n     fuOptions = \",\" & CStr(Me!ctlZoom.Object.Value) & \"z\" & fuOptions\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Ermitten des data-Parameter anhand des Werts der Optionsgruppen<\/span><\/b><\/p>\n<p>Anschlie&szlig;end kommt es noch zur Bestimmung des Zoom-Parameters. Der Zahlenwert des <b>Scrollbar<\/b>-Steuerelements <b>ctlZoom<\/b> ergibt sich aus der <b>Value<\/b>-Eigenschaft des Objekts. Ihr wird das <b>z<\/b> f&uuml;r die Google-Maps-URL angef&uuml;gt.<\/p>\n<p>Eine Suchanfrage nach <b>Duisburg<\/b> wird somit zusammenfassend im <b>Beim Anzeigen<\/b>-Ereignis dergestalt gebildet, wenn die normale Ansicht mit Fahrradwegen mit Zoomfaktor 15 gew&uuml;nscht ist:<\/p>\n<pre>sURL = \"https:\/\/www.google.com\/maps\/place\/\"\r\nsLoc = \"Duisburg\"\r\nfuOptions = \",15z\/data=!5m1!1e3\"<\/pre>\n<p>Das ergibt dann folgenden Link:<\/p>\n<pre>https:\/\/www.google.com\/maps\/place\/Duisburg,15z\/data=!5m1!1e3<\/pre>\n<p>Google analysiert die Parameter nun und sendet die Antwortseite an das Webbrowser-Steuerelement zur&uuml;ck. Dabei l&ouml;st das Steuerelement, beziehungsweise dessen Objektvariable <b>ctlWeb<\/b>, einige Ereignisse aus, auf die der Formularcode reagiert.<\/p>\n<p>Da w&auml;re zun&auml;chst einmal das Ereignis <b>BeforeNavigate2<\/b>, das ausgel&ouml;st wird, bevor die <b>URL<\/b> abgeschickt wird. Es wird im Formular nicht genutzt, sondern als Parameter &uuml;bertragene die <b>URL<\/b> rein informativ in das VBA-Direktfenster geschrieben, damit dort der chronologische Ablauf der Ereignisse kontrolliert werden kann.<\/p>\n<p>Darauf folgt das <b>Navigate2Complete<\/b>-Ereignis, welches aussagt, dass die URL abgeschickt wurde und nun verarbeitet wird. Schlie&szlig;lich folgt ein <b>DocumentComplete<\/b>, das eintritt, wenn die Antwort des Servers vollst&auml;ndig &uuml;bertragen wurde. Die Seite wird jetzt im Browser angezeigt.<\/p>\n<p>Das sieht dann aus, wie in Bild 12. Das Control Panel von Google Maps links im Fenster st&ouml;rt doch erheblich!  Freilich kann der Anwender nun das Kreuzchen anklicken, um das Panel zu entfernen. Doch eleganter w&auml;re es sicher, wenn es erst gar nicht angezeigt w&uuml;rde! Da wir keine Steuerparameter kennen, die Google Maps dazu veranlassen w&uuml;rden, dieses Panel nicht anzuzeigen, greifen wir zu einem Trick.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/07_frmKundenMaps_Intermediate.png\" alt=\"Das Control-Panel von Google Maps st&ouml;rt etwas.\" width=\"650\" height=\"534,1795\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 12: Das Control-Panel von Google Maps st&ouml;rt etwas.<\/span><\/b><\/p>\n<p>Das Ereignis <b>Navigate2Complete<\/b> &uuml;bergibt n&auml;mlich einen Parameter <b>URL<\/b>, in dem die abgesandte Suchanfrage modifiziert zur&uuml;ckgegeben wird. Sie reflektiert die korrigierte URL. Bei Suche nach <b>Duisburg<\/b> etwa kommt dabei dies heraus:<\/p>\n<pre>https:\/\/www.google.com\/maps\/place\r\n     \/Duisburg,+Deutschland\r\n     \/@51.4619202,6.6748446,13z\r\n    \/data=!4m5!3m4<\/pre>\n<p>Der Ort wurde automatisch um <b>Deutschland<\/b> erweitert und die ermittelten Koordinaten hinter dem <b>@<\/b> gleich auch mitgegeben. Damit l&auml;sst sich aus dieser URL per String-Funktonen der Koordinatenteil extrahieren. Die Ereignisprozedur tut dies und speichert sie in der globalen String-Variablen sCoordinates zwischen.  Dort st&uuml;nde dann etwa der Text @<b>51.4619202,6.6748446<\/b>. Jetzt wird eine neue Suchanfrage angesto&szlig;en, was aber nicht unmittelbar aus der <b>Navigate2Complete<\/b>-Prozedur heraus geschehen kann, weil dies den Webbrowser durcheinanderbringen k&ouml;nnte. Stattdessen wird der Formular-<b>Timer<\/b> eingeschaltet, indem sein Intervall einfach auf 300 Millisekunden eingestellt wird. Diese Spanne soll sicherstellen, dass der Browser in dieser Zeit schon das Dokument erhalten hat:<\/p>\n<pre>Me.TimerInterval = 300<\/pre>\n<p>Die Timer-Prozedur bildet dann gek&uuml;rzt Listing 7 ab. Zuerst wird der Timer wieder abgeschaltet, damit es bei einem einmaligen Ereignis bleibt. Sind in <b>sCoordinates<\/b> g&uuml;ltige Koordinaten enthalten, so wird dann die Such-URL neu zusammengestellt. Dabei wird nicht auf ein <b>\/place<\/b> verwiesen, sondern die Koordinaten mit den Ansichtsoptionen direkt an die generelle Maps-URL angeh&auml;ngt. Das n&auml;mlich f&uuml;hrt dazu, dass das Control Panel von Maps nicht angezeigt wird, sondern die Karte einfach zentriert auf die Koordinaten (Bild 13). Zus&auml;tzlich speichert die Routine diese URL im Datenfeld <b>MapsURL<\/b> der Tabelle, damit bei einem erneuten Aufruf des Datensatzes nicht mehr eine Suchanfrage abgesetzt werden muss, sondern Google Maps nur noch die Karte der Koordinaten zur&uuml;ckgeben muss.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/10_frmKundenMaps2.png\" alt=\"Nur nach Koordinaten gesucht zeigt Google Maps lediglich die Karte ohne Steuer-Panel\" width=\"650\" height=\"534,1795\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 13: Nur nach Koordinaten gesucht zeigt Google Maps lediglich die Karte ohne Steuer-Panel<\/span><\/b><\/p>\n<p>Einziges Manko ist, dass nun der Marker f&uuml;r den Ort leider nicht mehr in die Karte eingebaut ist. Das erschwert dem Anwender das Auffinden der Adresse doch ziemlich. Oder sehen Sie in der Abbildung die Hauptstr. 74 Erst ein Heranzoomen w&uuml;rde das erm&ouml;glichen. Der rote Punkt in der Abbildung ist nicht Bestandteil der Karte! Er kommt durch einen weiteren Trick zustande. Hier liegt ein anderes Steuerelement &uuml;ber dem Webbrowser-Steuerelement, also quasi ein <b>Fake-Marker<\/b>!<\/p>\n<h2>ActiveX-Overlays<\/h2>\n<p>Ein ActiveX-Steuerelement besitzt in der visuellen <b>Z-Order<\/b> eines Formulars immer Priorit&auml;t. Sie k&ouml;nnen kein anderes Access-Steuerelement &uuml;ber ein ActiveX-Steuerelement legen. Und das Webbrowser-Steuerelement ist imgrunde ein ActiveX-Steuerelement.<\/p>\n<p>Anders jedoch verh&auml;lt es sich mit neuen ActiveX-Elementen. Schlie&szlig;lich muss es unter mehreren dieser Steuerelemente auch eine Darstellungsreihenfolge geben. Tats&auml;chlich k&ouml;nnen Sie etwa ein <b>MS Forms-Image-Contro<\/b>l &uuml;ber das Webbrowser-Steuerelement legen, indem Sie es im Formularentwurf markieren und per Rechtsklick im Kontextmen&uuml; die Anweisung <b>In den Vordergrund<\/b> ausl&ouml;sen. In unserem Beispielformular befindet sich ein solches <b>Image Control<\/b> mit dem Namen <b>ctlImg<\/b> rechts oben im Detailbereich (Bild 14).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/10_ImgCtl.png\" alt=\"Ganz unscheinbar befindet sich hier ein MS Forms Image \" width=\"425\" height=\"365,6976\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 14: Ganz unscheinbar befindet sich hier ein MS Forms Image <\/span><\/b><\/p>\n<p>In der <b>Load<\/b>-Prozedur des Formulars wird es mit einem Bild best&uuml;ckt:<\/p>\n<pre><span style=\"color:blue;\">Set<\/span> ctlImg.Object.Picture = _\r\n     LoadPicture(CurrentProject.Path & \"\\circle.jpg\")<\/pre>\n<p>Die Datei <b>circle.jpg<\/b> muss sich nat&uuml;rlich im Ordnerpfad der Datenbank befinden. Im Ereignis <b>Bei Gr&ouml;&szlig;en&auml;nderung<\/b> (<b>Form_Resize<\/b>), welches ja bereits der Start des Formulars ausl&ouml;st, wird das Control positioniert:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Resize()\r\n     Me!ctlImg.<span style=\"color:blue;\">Left<\/span> = Me.InsideWidth \/ 2 - 200\r\n     Me!ctlImg.Top = Me.InsideHeight \/ 2 + 500\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Das ist eine nur recht vage Anordnung. Die Offsets <b>200<\/b> und <b>500<\/b> sollen ungef&auml;hr sicherstellen, dass sich das Control dann in der Mitte der Karte befindet, wie es Bild 13 zeigte. Eigentlich zentriert Google Maps die Karte genau auf die ermittelten Koordinaten, und folglich sollte sich der korrekte Ort eben in der Mitte des Webbrowser-Steuerelements befinden. Da f&uuml;r dieses jedoch das <b>Verankern<\/b>-Feature eingesetzt wird, m&uuml;ssten die Offsets an sich etwas komplizierter berechnet werden. Uns erschienen die hartkodierten Werte jedoch als ausreichend f&uuml;r den Zweck, den Fokus des Betrachters auf die Geoadresse zu lenken.<\/p>\n<p>Nun hat die Sache einen Pferdefu&szlig;: Egal, was der Browser anzeigt, es befindet sich immer der rote Punkt in der Mitte. Das ist weniger sch&ouml;n, da es etwa bei nicht von Google ermitteltem Ort zu einem <b>about:blank<\/b> kommt und dann eine wei&szlig;e Fl&auml;che mit einem Punkt erschiene. Doch auch hierf&uuml;r gibt es eine L&ouml;sung &uuml;ber ein zus&auml;tzliches <b>ActiveX-Overlay<\/b>.<\/p>\n<p>Im Formular ist ein <b>MS Forms Image<\/b>-Steuerelement <b>ctlImgOverlay<\/b> direkt &uuml;ber dem Webbrowser-Steuerelement platziert, wie Bild 15 demonstriert. Es hat die gleichen Abmessungen und ebenfalls die <b>Verankern<\/b>-Einstellung <b>Quer und nach unten dehnen<\/b>. Nach seinem Einf&uuml;gen wurde es <b>In den Vordergrund<\/b> gesetzt. Da das Image Control f&uuml;r den roten Punkt bereits im Formular existierte, bekommt das Overlay-Image nun eine noch h&ouml;here <b>Z-Order<\/b> und legt sich &uuml;ber die Punktgrafik. Schlicht durch Ein- und Ausschalten der <b>Visible<\/b>-Eigenschaft des Controls kann damit im Prinzip die Sichtbarkeit des darunterliegenden Webbrowsers gesteuert werden. Im Entwurf ist <b>Sichtbar<\/b> auf <b>Ja<\/b> gestellt. Erst im Ereignis <b>ctlWeb_DocumentComplete<\/b>, also bei erfolgreichem Erhalt der Webseite, setzt der Code das Overlay au&szlig;er Kraft (Listing 8):<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/08_frmKundenDesign_Overlay.png\" alt=\"Das zus&auml;tzliche MS Forms Image legt sich als Fl&auml;che exakt &uuml;ber das Webbrowser Control\" width=\"650\" height=\"485,4855\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 15: Das zus&auml;tzliche MS Forms Image legt sich als Fl&auml;che exakt &uuml;ber das Webbrowser Control<\/span><\/b><\/p>\n<pre>Me!ctlImgOverlay.Visible = <span style=\"color:blue;\">False<\/span><\/pre>\n<p>Das geschieht allerdings erst nach &uuml;berpr&uuml;fung einiger Bedingungen. Die Karte ist nur dann geladen, wenn die vier Ausdr&uuml;cke in Klammern des <b>If<\/b>-Zweigs <b>nicht<\/b> zutreffen. Andernfalls bleibt die Abdeckung des Webbrowsers bestehen.<\/p>\n<p>Da die Farbe des Image Overlays im <b>Load<\/b>-Ereignis des Formulars auf die des Detailbereichs eingestellt wird, wirkt es so, als w&auml;re der Webbrowser gar nicht vorhanden:<\/p>\n<pre>ctlImgOverlay.Object.BackColor\r\n  = Me.Section(acDetail).BackColor<\/pre>\n<p>Warum aber all diese Umst&auml;nde K&ouml;nnte man nicht gleich die Sichtbarkeit des Webbrowser-Steuerelements selbst &uuml;ber dessen <b>Visible<\/b>-Eigenschaft steuern Selbstverst&auml;ndlich ginge das, doch leider verh&auml;lt sich der Browser in unsichtbarem Zustand nicht mehr ordnungsgem&auml;&szlig;. Die Google-Skripte greifen nur dann, wenn das Web-Dokument sichtbar ist!<\/p>\n<h2>Bing Maps<\/h2>\n<p>Wir haben in die Beispieldatenbank auch ein analoges Kundenformular integriert (<b>frmKundenBing<\/b>), das den Microsoft&#8220;schen Karten-Service bem&uuml;ht. Die m&ouml;glichen Features zur Steuerung der Karte sind ganz &auml;hnlich. Doch leider zeigen die <b>Bing<\/b>-Karten seit einiger Zeit ebenfalls ein <b>Steuer-Panel<\/b> an, welches nicht wegzubekommen ist. Damit eignet sich Bing f&uuml;r unsere Zwecke weniger. Bei gro&szlig;en Formularen, in denen das Steuer-Panel nicht so ins Gewicht f&auml;llt, ist <b>Bing<\/b> aber durchaus eine Alternative. Erforschen Sie die Funktionen des Beispielformulars bei Interesse selbst!<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>browser_events_protocol.txt<\/p>\n<p>circle.jpg<\/p>\n<p>GoogleMaps.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/56FA07D8-FCB8-493C-ADE6-C8E013BDDC0C\/aiu_1089.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sie m&ouml;chten den Anwendern Ihrer Datenbank die M&ouml;glichkeit anbieten, neben den eigentlichen Adressdaten auch gleich dazugeh&ouml;rige Geoinformationen einzusehen Dazu eignen sich sicher die Dienste Google-Maps oder Bing-Maps. Ein Webbrowser-Steuerelement im Formular k&ouml;nnte als Host f&uuml;r jene dienen. Doch der Weg ist steiniger, als erwartet! Wie Sie die auftretenden Probleme l&ouml;sen k&ouml;nnen, beschreibt dieser Beitrag.<\/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":[662017,66032017,44000026],"tags":[],"class_list":["post-55001089","post","type-post","status-publish","format-standard","hentry","category-662017","category-66032017","category-Interaktiv"],"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>Google-Maps als Kartendienst im Formular - 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\/GoogleMaps_als_Kartendienst_im_Formular\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Google-Maps als Kartendienst im Formular\" \/>\n<meta property=\"og:description\" content=\"Sie m&ouml;chten den Anwendern Ihrer Datenbank die M&ouml;glichkeit anbieten, neben den eigentlichen Adressdaten auch gleich dazugeh&ouml;rige Geoinformationen einzusehen Dazu eignen sich sicher die Dienste Google-Maps oder Bing-Maps. Ein Webbrowser-Steuerelement im Formular k&ouml;nnte als Host f&uuml;r jene dienen. Doch der Weg ist steiniger, als erwartet! Wie Sie die auftretenden Probleme l&ouml;sen k&ouml;nnen, beschreibt dieser Beitrag.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-14T13:42:52+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg09.met.vgwort.de\/na\/78fc71158a14401b907ba416d6991269\" \/>\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=\"30\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Google-Maps als Kartendienst im Formular\",\"datePublished\":\"2020-05-14T13:42:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/\"},\"wordCount\":5338,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/78fc71158a14401b907ba416d6991269\",\"articleSection\":[\"2017\",\"3\\\/2017\",\"Interaktiv\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/\",\"name\":\"Google-Maps als Kartendienst im Formular - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/78fc71158a14401b907ba416d6991269\",\"datePublished\":\"2020-05-14T13:42:52+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/78fc71158a14401b907ba416d6991269\",\"contentUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/78fc71158a14401b907ba416d6991269\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/GoogleMaps_als_Kartendienst_im_Formular\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Google-Maps als Kartendienst im Formular\"}]},{\"@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":"Google-Maps als Kartendienst im Formular - 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\/GoogleMaps_als_Kartendienst_im_Formular\/","og_locale":"de_DE","og_type":"article","og_title":"Google-Maps als Kartendienst im Formular","og_description":"Sie m&ouml;chten den Anwendern Ihrer Datenbank die M&ouml;glichkeit anbieten, neben den eigentlichen Adressdaten auch gleich dazugeh&ouml;rige Geoinformationen einzusehen Dazu eignen sich sicher die Dienste Google-Maps oder Bing-Maps. Ein Webbrowser-Steuerelement im Formular k&ouml;nnte als Host f&uuml;r jene dienen. Doch der Weg ist steiniger, als erwartet! Wie Sie die auftretenden Probleme l&ouml;sen k&ouml;nnen, beschreibt dieser Beitrag.","og_url":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-14T13:42:52+00:00","og_image":[{"url":"http:\/\/vg09.met.vgwort.de\/na\/78fc71158a14401b907ba416d6991269","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"30\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Google-Maps als Kartendienst im Formular","datePublished":"2020-05-14T13:42:52+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/"},"wordCount":5338,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/78fc71158a14401b907ba416d6991269","articleSection":["2017","3\/2017","Interaktiv"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/","url":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/","name":"Google-Maps als Kartendienst im Formular - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/78fc71158a14401b907ba416d6991269","datePublished":"2020-05-14T13:42:52+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/#primaryimage","url":"http:\/\/vg09.met.vgwort.de\/na\/78fc71158a14401b907ba416d6991269","contentUrl":"http:\/\/vg09.met.vgwort.de\/na\/78fc71158a14401b907ba416d6991269"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/GoogleMaps_als_Kartendienst_im_Formular\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Google-Maps als Kartendienst im Formular"}]},{"@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\/55001089","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=55001089"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001089\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}