{"id":55000862,"date":"2012-12-01T00:00:00","date_gmt":"2020-05-22T21:49:30","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=862"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"TreeView_ohne_ActiveX","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/","title":{"rendered":"TreeView ohne ActiveX"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg05.met.vgwort.de\/na\/3e9d68261600455bb63980501820389d\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Im August 2012 verteilte Microsoft &uuml;ber Windows-Update f&uuml;r alle Office-Installationen ab Version 2003 automatisch Security Patches, die nur eine einzige Komponente austauschten: die ActiveX-Bibliothek mscomctl.ocx, welche, unter anderem, das viel verwendete TreeView-Steuerelement enth&auml;lt. Dabei machte die COM-Version der Bibliothek einen Sprung von 2.0 auf 2.1, was VBA-Module, in denen deren Elemente angesprochen werden, teilweise inkompatibel macht. Ergebnis sind deshalb Datenbanken, die seltsame Fehler melden, wenn Formulare mit TreeViews oder Listviews aufgerufen werden. <\/b><\/p>\n<p>In Foren und Blogs wurden Workarounds f&uuml;r das Problem diskutiert, die im Wesentlichen Manipulationen der Registry vorschlagen, und auch Microsoft ver&ouml;ffentlichte schlie&szlig;lich einen Patch zum Patch, ohne jedoch das Problem an sich zu l&ouml;sen. Mit solchen Workarounds, die zudem Administratorrechte erfordern, mag man am Einzelplatz gl&uuml;cklich werden, wer aber Datenbanken f&uuml;r Unternehmen mit Dutzenden von Arbeitspl&auml;tzen entwickelt, steht vor &auml;rgerlichen Umst&auml;nden.<\/p>\n<p>Die Auffassung von IT-Verantwortlichen, dass ActiveX-Komponenten zu vermeiden seien, bekommt hier verst&auml;ndlicherweise neue Nahrung. Dabei war die MSComCtl-Bibliothek bisher relativ unverd&auml;chtig &#8211; ist sie doch Bestandteil der Office-Installation selbst.<\/p>\n<p>Das wirft die Frage auf, ob diese Steuerelemente denn nicht durch andere L&ouml;sungen zu ersetzen w&auml;ren. Und selbstverst&auml;ndlich gibt es diese. M&ouml;gliche Alternativen sind API-Module, die etwa ein TreeView-Fenster nativ von Grund auf neu erstellen. Schwierigkeiten bekommt man hier indessen meist mit den notwendigen Subclassing-Routinen, die VBA instabil werden lassen.<\/p>\n<p>Auch existieren L&ouml;sungen, die TreeViews allein mit Access-Bordmitteln realisieren. Von den Features, dem Komfort und der Performance her k&ouml;nnen diese allerdings nicht wirklich mit dem ActiveX-Pendant konkurrieren.<\/p>\n<p>Schaut man sich um, so findet man TreeViews aber nicht alleine in Anwendungen, sondern etwa auch auf Internetseiten, wo sie h&auml;ufig Navigationszwecken dienen.<\/p>\n<p>Diese TreeViews sind zumeist in JavaScript oder PHP programmiert. Es gibt sie in zahlreichen Varianten &#8211; umfangreiche oder simple, mit oder ohne AJAX. Und viele k&ouml;nnen von den M&ouml;glichkeiten her durchaus mit dem MSComCtl-TreeView mithalten. Was liegt da n&auml;her, als solch ein geskriptetes TreeView in einem Webbrowser-Steuerelement anzuzeigen<\/p>\n<p>So begab ich mich auf die Suche nach einem JavaScript-TreeView, das in den M&ouml;glichkeiten dem ActiveX-TreeView nahekommt. Einige Internetseiten bieten einen &Uuml;berblick &uuml;ber freie TreeViews.<\/p>\n<p>Nach dem Test diverser L&ouml;sungen fiel die Wahl auf das <b>CoolJSTree<\/b>, welches in einer abgespeckten freien sowie in einer umfangreicheren Bezahlversion (Professional) angeboten wird. <\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Das CoolJSTree<\/p>\n<p>Sie finden diese Script-L&ouml;sung unter <b>http:\/\/javascript.softdrawer.com\/scripts\/cooltree <\/b>zum Download.<\/p>\n<p>Das Paket enth&auml;lt zahlreiche Beispiele, die Sie sofort im Browser begutachten k&ouml;nnen. Eine &uuml;bersichtliche Dokumentation fehlt ebenfalls nicht. <\/p>\n<p>Im Prinzip brauchen Sie die folgenden Dateien f&uuml;r ein <b>CoolJSTree<\/b>-TreeView:<\/p>\n<ul>\n<li class=\"aufz-hlung\">die zentrale Datei <b>cooltree.js<\/b>, welche das JavaScript f&uuml;r den Aufbau des Baums enth&auml;lt,<\/li>\n<li class=\"aufz-hlung\">die <b>tree_format.js<\/b>, die Formatierungen der Nodes steuert,<\/li>\n<li class=\"aufz-hlung\">die Datei <b>tree_nodes.js<\/b>, welche die Definition der anzuzeigenden Nodes beherbergt,<\/li>\n<li class=\"aufz-hlung\">und ein Verzeichnis mit den Bilddateien f&uuml;r die Symbole der Nodes.<\/li>\n<\/ul>\n<p>Es k&ouml;nnen aber, wie etliche der vom Entwickler beigesteuerten Beispiele zeigen, die Skripte nat&uuml;rlich auch zu einer kompakten Datei zusammengefasst oder sogar in das anzuzeigende HTML-Dokument selbst eingebaut werden. Dann m&uuml;ssen au&szlig;er dieser HTML-Datei nur noch die Bilddateien vorhanden sein.<\/p>\n<p><b>Von der Tabelle in den Browser<\/b><\/p>\n<p>Wie aber kommt das JavaScript-TreeView als Steuerelement in ein Access-Formular, wie werden seine Knoten angelegt und gesteuert<\/p>\n<p>Zuerst braucht es hier ein Webbrowser Control, das Access 2010 bereits als Steuerelement beisteuert, w&auml;hrend fr&uuml;here Versionen auf das ActiveX-Steuerelement Microsoft Web Browser angewiesen sind.<\/p>\n<p>Beide sind im Prinzip identisch und stellen einen kleinen Internet Explorer zur Verf&uuml;gung, nur die Steuerung &uuml;ber das Objektmodell f&auml;llt marginal unterschiedlich aus. Das Steuerelement ziehen Sie auf die Ausma&szlig;e, die das TreeView haben soll. Ab Access 2007 k&ouml;nnen Sie es schlie&szlig;lich noch verankern &#8211; etwa mit der Option <b>Quer nach unten dehnen <\/b>-, wodurch es sich zur Laufzeit der Formulargr&ouml;&szlig;e anpasst.<\/p>\n<p>Inhalt wird in das Control &uuml;blicherweise &uuml;ber dessen Methode <b>Navigate2 <\/b>und Angabe einer HTML-Datei als Parameter geladen. Ob diese aus dem Internet bezogen wird oder lokal, spielt dabei keine Rolle.<\/p>\n<p>Man k&ouml;nnte also &uuml;ber VBA einen HTML-String zusammenbauen, der die Elemente des TreeViews und das JavaScript enthielte, und ihn anschlie&szlig;end als HTML-Datei abspeichern, damit der Webbrowser sie laden kann &#8211; w&auml;re da nicht das Rechtesystem und Zonenmodell des Internet Explorers! Denn das Webbrowser-Steuerelement weigert sich beharrlich, jegliches JavaScript in lokalen Dateien auszuf&uuml;hren.<\/p>\n<p>Auch &auml;nderungen an den Zoneneinstellungen des Internet Explorers &auml;ndern daran nichts. Allerdings gibt es einen Trick, dem Browser einen Netzwerkpfad vorzugaukeln, wodurch dieser offenbar andere Sicherheitseinstellungen verwendet. Schreiben Sie den Pfad zur Datei als URL beispielsweise in dieser Form:<\/p>\n<pre>file:\/\/127.0.0.1\/c$\/meinverzeichnis\/test.html<\/pre>\n<p>Mit dieser Pfadangabe (hier: <b>Laufwerk C:<\/b>) f&uuml;hrt der Browser dann seltsamerweise auch integrierte JavaScripts aus.<\/p>\n<p>Es gibt jedoch eine wesentlich elegantere Form, dem Control zur Anzeige von HTML-Inhalten zu verhelfen, als &uuml;ber den Umweg einer dynamisch erzeugten Datei.<\/p>\n<p>Legen Sie zun&auml;chst ein leeres Dokument im Control an und schreiben Sie anschlie&szlig;end beliebigen Inhalt &uuml;ber die <b>write<\/b>-Methode desselben in es hinein. Das k&ouml;nnte so aussehen:<\/p>\n<pre>WebControlObject.Navigate2 &quot;about:blank&quot;\r\nsHTML = &quot;&lt;HTML&gt;&lt;BODY&gt;Hallo!&lt;\/BODY&gt;&lt;\/HTML&gt;&quot;\r\nWebControlObject.Document.write sHTML<\/pre>\n<p>Die <b>write<\/b>-Methode l&ouml;st im Browser das erneute Rendern der Seite mit dem Inhalt der String-Variablen <b>sHTML <\/b>aus.<\/p>\n<p>Das gezeigte Beispiel wird allerdings so nicht funktionieren, weil Sie vor dem Absetzen der <b>write<\/b>-Anweisung noch abwarten m&uuml;ssen, bis das leere Dokument komplett erzeugt ist. Dazu m&uuml;sste vor der letzten Zeile noch &uuml;ber die <b>ReadyState<\/b>-Eigenschaft des WebControls der Status des Dokuments abgefragt werden, der mindestens den Wert <b>Interactive <\/b>haben muss. Das kann etwa mittels einer Schleife geschehen:<\/p>\n<pre>Do\r\n    DoEvents\r\nLoop Until WebControlObject.ReadyState &gt;= READYSTATE_INTERACTIVE<\/pre>\n<p>Statt des simplen HTML-Strings oben ist nun der Aufbau der TreeView-Seite mitsamt den integrierten Skripten der Variablen sHTML zuzuweisen. Wie das in der Demo zum Beitrag gel&ouml;st ist und wie auf Ereignisse des TreeViews reagiert werden kann, erfahren Sie in den folgenden Abschnitten.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Eine einfache Demo-Anwendung<\/p>\n<p>In der Demodatenbank <b>TreeViewJS.mdb <\/b>existiert ein Formular <b>frmSample<\/b>, das sich nach Klick auf die Schaltfl&auml;che <b>Lade TreeView <\/b>wie in Bild 1 pr&auml;sentiert.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_06\/HTMLTreeview-web-images\/pic001.png\" alt=\"pic001.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Einfaches Formular mit JavaScript-TreeView im Webbrowser-Steuerelement<\/span><\/b><\/p>\n<p>Beim Laden des Formulars wird lediglich die Objektvariable <b>oTree <\/b>auf das <b>WebControl<\/b>-Objekt gesetzt:<\/p>\n<pre>    Private WithEvents oTree As SHDocVw.WebBrowser\r\n    Set oTree = Me!ctlWeb.Object<\/pre>\n<p>Das w&auml;re f&uuml;r den weiteren Code nicht unbedingt n&ouml;tig, vereinfacht aber die Schreibweise im Modul.<\/p>\n<p>Die eigentliche Routine zum Laden des TreeViews steht hinter dem Click-Ereignis <b>cmdLoad_Click <\/b>des Formulars. Nachdem hier ein leeres HMTL-Dokument im WebControl angelegt wurde, holt sich die Prozedur zuerst den Inhalt der Datei <b>tree_template.html <\/b>in eine String-Variable <b>sDoc<\/b>. Der Pfad zur Datei ist hier hartkodiert und steht auf dem Unterverzeichnis <b>\\trees <\/b>der Datenbank; passen Sie das gegebenenfalls an. Im String werden dann diverse Platzhalter mit Inhalt gef&uuml;llt und abschlie&szlig;end der HTML-String einfach in das leere Dokument geschrieben:<\/p>\n<pre>    oTree.Document.write sDoc<\/pre>\n<p>Schon f&uuml;llt sich das Browser-Fenster mit dem TreeView, in dem Sie die einzelnen Nodes mit der Maus ein- und ausklappen k&ouml;nnen.<\/p>\n<p>Was hier in Kurzform dargestellt wurde, ist in Wirklichkeit nat&uuml;rlich etwas umfangreicher &#8211; die Prozedur verzweigt in verschiedene Unterfunktionen, die den Inhalt f&uuml;r die Platzhalter bereitstellen. Zun&auml;chst aber einiges zum Aufbau des HTML-Templates selbst.<\/p>\n<p><b>Das Tree-Template<\/b><\/p>\n<p>Statt der oben erw&auml;hnten drei eingebundenen <b>CoolJSTree<\/b>-JavaScripts sind deren Routinen alle in das Template selbst aufgenommen. Es enth&auml;lt also alles, was eine HTML-Datei ben&ouml;tigt, und zus&auml;tzlich vier Skript-Abschnitte. Der wichtigste ist ganz am Ende zu finden:<\/p>\n<pre>    &lt;script type=&quot;text\/javascript&quot;&gt;\r\n    var tree = new COOLjsTree(&quot;tree1&quot;, TREE_ITEMS, TREE_FORMAT);\r\n    &lt;\/script&gt;<\/pre>\n<p>Mit der Funktion <b>COOLjsTree <\/b>wird der Baum tats&auml;chlich erstellt. Als Parameter werden eine beliebige Klassen-ID f&uuml;r den <b>DIV<\/b>-Abschnitt des TreeView erwartet, eine Variable, die die Nodes des Baums definiert, und eine Variable, die die Formatierungsanweisungen enth&auml;lt. Die Funktion selbst ist im Skript-Block dar&uuml;ber mit seinem etwas kryptischen Code enthalten.<\/p>\n<p>Die Variable <b>TREE_FORMAT <\/b>f&uuml;r die Formatierungen ist oben gleich nach dem <b>BODY<\/b>-Tag definiert. Dort steht kommentiert, welche Formatierungsm&ouml;glichkeiten fest vergeben werden k&ouml;nnen. Das sind etwa Angaben zu Einr&uuml;ckungen, Positionierung und vor allem zu den Icons. Der Aufbau des Blocks ist in der <b>CoolJSTree<\/b>-Dokumentation gut beschrieben. Das Interessante an den Abschnitten f&uuml;r die Icons sind die Pfadangaben zu den Bilddateien, die etwa so aussehen:<\/p>\n<pre>    [&quot;folder.png&quot;, &quot;folderopen.png&quot;, &quot;page.png&quot;]<\/pre>\n<p>Da die Icons irgendwo vom Browser gelesen werden m&uuml;ssen, es aber keine relative URL geben kann &#8211; das Dokument wurde ja aus dem Nichts per <b>about:blank <\/b>erzeugt -, m&uuml;ssen hier absolute Pfade stehen. Und deshalb sind die Dateinamen mit drei Fragezeichen als Pr&auml;fix versehen.<\/p>\n<p>Diese Platzhalter werden sp&auml;ter per VBA durch das tats&auml;chliche Icon-Verzeichnis ersetzt:<\/p>\n<pre>    sDoc = Replace(sDoc, &quot;&quot;, sIconPath)<\/pre>\n<p>Der Vollst&auml;ndigkeit halber nachfolgend ein kleines Schnipsel, wie sich aus einem Windows-Pfad die URL f&uuml;r das Verzeichnis bildet:<\/p>\n<pre>    sIconPath = CurrentProject.Path &amp; &quot;\\trees\\icons\\&quot;\r\n    sIconPath = Replace(sIconPath, &quot;\\&quot;, &quot;\/&quot;)\r\n    sIconPath = &quot;file:\/\/&quot; &amp; sIconPath<\/pre>\n<p><!--30percent--><\/p>\n<p>Statt der im <b>icons<\/b>-Verzeichnis mitgelieferten Icons k&ouml;nnen Sie selbstverst&auml;ndlich beliebige andere Bilddateien verwenden, die auch nicht zwingend im Format 16 x 16 daherkommen m&uuml;ssen. Das <b>CoolJSTree <\/b>passt seine Zeilen automatisch der Symbolgr&ouml;&szlig;e an.<\/p>\n<p>Im <b>TREE_FORMAT<\/b>-Block steht allerdings nicht, wie die Texte des TreeViews formatiert werden sollen. Diese Node-Texte stellen allesamt A-Tags, also Hyperlinks dar. Also kann man sie einfach mit einer CSS-Style-Definition formatieren, die im <b>HEAD<\/b>-Abschnitt der HTML-Datei enthalten ist:<\/p>\n<pre>    &lt;head&gt;\r\n    &lt;style type=&quot;text\/css&quot;&gt;\r\n    &sect;&sect;&sect;\r\n    &lt;\/style&gt;\r\n    &lt;\/head&gt;<\/pre>\n<p>Viel ist das nicht &#8211; aber Sie werden sich denken k&ouml;nnen, dass auch hier das <b>$$$ <\/b>nur ein Platzhalter ist, der sp&auml;ter per VBA mit der tats&auml;chlichen Definition ersetzt wird, damit das TreeView von Access aus formatiert werden kann.<\/p>\n<p>Die entsprechende Funktion im Formular daf&uuml;r nennt sich <b>GetStyleString() <\/b>und bastelt einfach die Style-Anweisungen hartkodiert zusammen. (Vorgriff: In der anderen in der Beispieldatenbank enthaltenen Demo wird dieser Style-String allerdings dynamisch aus Klasseneigenschaften zusammengesetzt.)<\/p>\n<p>Bliebe noch die Variable <b>TREE_ITEMS <\/b>als Parameter f&uuml;r die <b>COOLjsTree<\/b>-Funktion. Darin m&uuml;ssen die Nodes, also die Struktur des Baums, definiert sein. Das <b>COOLJSTree <\/b>sieht daf&uuml;r etwa folgenden Aufbau vor:<\/p>\n<pre>    [0,[1],[2],[3],[4,[5],[6]]]<\/pre>\n<p>Jeder durch eine Zahl symbolisierte Node wird durch eine ge&ouml;ffnete und eine geschlossene rechteckige Klammer angegeben. Innerhalb der Klammer k&ouml;nnen jedoch wiederum weitere Nodes stehen, sodass eine hierarchische Struktur entsteht. Im Beispiel ist <b>0 <\/b>das Root-Node, dem als Kindelemente die Nodes <b>1<\/b>, <b>2<\/b>, <b>3 <\/b>und <b>4 <\/b>untergeordnet sind. Der Node <b>4 <\/b>seinerseits beherbergt die Unterelemente <b>5 <\/b>und <b>6<\/b>.<\/p>\n<p>Statt der Zahlen sind jeweils mindestens drei Parameter einzusetzen: Optional die ID des Elements, zwingend sein Text, die URL f&uuml;r den Hyperlink, das Hyperlink-Zielfenster beziehungsweise Ziel-Frame und optional ein f&uuml;r den jeweiligen Node spezifischer Formatierungs-String. Beispiel f&uuml;r einen Node-Eintrag:<\/p>\n<pre>    [{&quot;id&quot;:3}, ''Mein Node-Text'', ''http:\/xyz.com'', ''_self']<\/pre>\n<p>Ein Mausklick auf den Node mit der ID <b>3 <\/b>und der Aufschrift <b>Mein Node-Text<\/b> f&uuml;hrte dazu, dass im selben Browser-Fenster zu <b>http:\/xyz.com <\/b>navigiert w&uuml;rde &#8211; zu diesem Umstand sp&auml;ter mehr. Die Variable <b>TREE_ITEMS <\/b>ist im Template so codiert:<\/p>\n<pre>    &lt;script type=&quot;text\/javascript&quot;&gt;\r\n    var iconpath;\r\n    iconpath=&quot;&quot;;\r\n    var TREE_ITEMS = [@@@];\r\n    &lt;\/script&gt;<\/pre>\n<p>Abermals finden Sie hier einen Platzhalter, der im Formular dann &uuml;ber die Prozedur <b>GetMenuString <\/b>ersetzt wird, in der &uuml;brigens, wie bei den Styles, der Node-Aufbau hartkodiert ist:<\/p>\n<pre>    sMenu = GetMenuString()\r\n    sDoc = Replace(sDoc, &quot;@@@&quot;, sMenu)<\/pre>\n<p>&Uuml;ber dieses Template-System l&auml;sst sich sch&ouml;n die Baumstruktur dynamisch anlegen und anzeigen. Nebenbei sei erw&auml;hnt, dass das Template statt &uuml;ber eine Datei genauso gut auch aus einem Memo-Feld einer Tabelle bezogen werden k&ouml;nnte.<\/p>\n<p><b>Auf Klicks reagieren<\/b><\/p>\n<p>&Uuml;blicherweise will man bei Klick auf einen Node ein Ereignis ausl&ouml;sen und darauf reagieren. Das l&auml;sst sich mit dem <b>CoolJSTree <\/b>recht einfach realisieren, weil alle Nodes Hyperlink-Ziele enthalten.<\/p>\n<p>Ein Klick f&uuml;hrt also dazu, dass ein neues Dokument geladen werden will. Das aber kann man mit der Ereignisprozedur <b>BeforeNavigate <\/b>des WebControls abfangen (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-50-anchor\">Listing 1<\/a><\/span>).<\/p>\n<p class=\"listingueberschrift\">Listing 1: Prozedur, die durch das Ereignis BeforeNavigate ausgel&ouml;st wird<\/p>\n<pre>Private Sub oTree_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)\r\n    If Right(URL, 1) = &quot;x&quot; Or Right(URL, 1) = &quot;y&quot; Then\r\n        Dim sRet As String\r\n        Dim n As Long\r\n        n = InStrRev(URL, &quot;\\&quot;)\r\n        sRet = Mid(URL, n + 1)\r\n        sRet = Replace(sRet, &quot;about:&quot;, &quot;&quot;)\r\n        LblInfo.Caption = &quot;Click auf &quot; &amp; sRet\r\n        Cancel = True\r\n    End If\r\nEnd Sub<\/pre>\n<p>URL ist in der Ereignisprozedur der Parameter, welcher das Hyperlink-Ziel zur&uuml;ckgibt. Findet die Routine hier am Ende ein <b>x <\/b>oder ein <b>y<\/b>, so erfolgt eine Spezialbehandlung. Das macht deshalb Sinn, weil in der Demo ein Node etwa so definiert wird:<\/p>\n<pre>    [{&quot;id&quot;:3}, ''Node-Text'', ''3x'', null]<\/pre>\n<p>Als Hyperlink wurde <b>3x <\/b>angegeben, also die Node-ID mit einem Suffix <b>x<\/b> kombiniert, was zur URL <b>about:3x <\/b>f&uuml;hrt, weil <b>about:blank <\/b>quasi das Root-Verzeichnis der Webseite ist.<\/p>\n<p>Per String-Behandlung wird zuerst die ID aus der URL ermittelt, die weiterverwendet werden kann &#8211; hier zur Ausgabe in einem Bezeichnungsfeld &#8211; und schlie&szlig;lich der Parameter <b>Cancel <\/b>auf <b>True <\/b>gesetzt. Das f&uuml;hrt dazu, dass eben nicht zum Hyperlink-Ziel navigiert, der Sprung also abgebrochen wird, und das TreeView im Browser stehen bleibt, als w&auml;re nichts geschehen.<\/p>\n<p>Gibt es Anwendungsf&auml;lle f&uuml;r dieses einfache Formular<\/p>\n<p>Da der Inhalt des TreeViews statisch ist, k&ouml;nnte man es etwa zu Navigationszwecken benutzen, um andere Formulare oder Berichte aufzurufen, oder aber, um eine Dokumentation bereitzuhalten, wie in Winhelp- oder CHM-Help-Dateien. Wenn lediglich hierarchische Strukturen dargestellt werden sollen, k&ouml;nnen Sie gar auf die Routine in <b>BeforeNavigate <\/b>verzichten.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">TreeView im Unterformular<\/p>\n<p>Wesentlich m&auml;chtiger ist da die zweite L&ouml;sung der Demo-Datenbank, die das TreeView in einem TreeView-Unterformular namens <b>sfrmHTMLTreeView <\/b>anzeigt, welches in das Hauptformular <b>frmHTMLTreeView <\/b>eingebettet ist &#8211; s. Bild 2.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_06\/HTMLTreeview-web-images\/pic002.png\" alt=\"pic002.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: Gesteuertes JavaScript-TreeView im Unterformular<\/span><\/b><\/p>\n<p>Das Unterformular <b>sfrmHTMLTreeView <\/b>enth&auml;lt ein komplexes Klassenmodul, &uuml;ber dessen Eigenschaften und Methoden sich die Nodes und Formatierungen des TreeView steuern lassen. Die komplette Beschreibung aller enthaltenen Funktionen w&uuml;rde den Rahmen dieses Beitrags sprengen. Daher im Folgenden nur eine Zusammenfassung der wichtigsten Features und Tricks.<\/p>\n<p>Wie in der vorhergehenden Demo zeigt sich das TreeView erst nach Klick auf den Button <b>Lade TreeView<\/b>. Danach werden auch die abgebildeten Schaltfl&auml;chen sichtbar. Der Button f&uuml;r den Quellcode &ouml;ffnet Notepad mit dem Quelltext der erzeugten HTML-Seite. Damit k&ouml;nnen Sie kontrollieren, was der VBA-Code aus dem Template anstellte.<\/p>\n<p>Mit <b>&auml;ndere Font <\/b>wird dem TreeView ein neuer Style verpasst, was komfortabel &uuml;ber die <b>Font<\/b>&#8211; und <b>HoverFont<\/b>-Eigenschaften des Klassenmoduls geschieht. <\/p>\n<p>Mit <b>&auml;ndere Cursor <\/b>wird statt des Pfeils ein Handsymbol f&uuml;r den Mauszeiger im TreeView angezeigt. Dies geschieht mittels einer einzigen Zeile:<\/p>\n<pre>    oTree.Cursor = eTreeCursorHand<\/pre>\n<p>Diese Eigenschaft wird vom Modul in Style-Definitionen f&uuml;r das <b>A<\/b>-Tag &uuml;bersetzt (Prozedur <b>GetStyleString<\/b>), wie im &Uuml;brigen auch die <b>Font<\/b>&#8211; und Hintergrundeigenschaften.<\/p>\n<p>Dass auch gezielt ein Node per ID &uuml;ber VBA angesprungen und in den sichtbaren Bereich gescrollt werden kann &#8211; Stichwort: <b>EnsureVisible <\/b>&#8211; zeigt der n&auml;chste Button.<\/p>\n<p><b>Toggle Node-ID 319 <\/b>bewirkt, dass ein Verzeichnis-Knoten per Code ein- und ausgeklappt wird. Dazu muss lediglich die Methode <b>ToggleNode <\/b>unter Angabe der ID des Knotens aufgerufen werden.<\/p>\n<p>Genauso wenig fehlen Routinen, um den kompletten Baum auf- und zuzuklappen (<b>ExpandAll<\/b>, <b>CollapseAll<\/b>).<\/p>\n<p>An dieser Stelle die Erl&auml;uterung, wie die Nodes &uuml;berhaupt angelegt werden. Das Hauptformular erzeugt die Nodes aus einer Tabelle <b>tblMenu <\/b>mit rekursivem Inhalt und Tausend Datens&auml;tzen &uuml;ber die Methode <b>AddItem <\/b>des Klassenmoduls. Diese erwartet folgende Parameter:<\/p>\n<pre>    Function AddItem(ByVal sText As String, _\r\n        ID As Long, _\r\n        Optional ParentID As Long, _\r\n        Optional Image As String)<\/pre>\n<p><b>sText <\/b>ist der anzuzeigende Text des Node, <b>ID <\/b>seine eindeutige ID, die vorzugsweise aus dem Prim&auml;rschl&uuml;ssel einer Tabelle kommt, <b>ParentID <\/b>verweist auf den Eltern-Node mit entsprechender ID und <b>Image <\/b>schlie&szlig;lich gibt optional ein von den Standard-Icons abweichendes Symbol f&uuml;r den Node an.<\/p>\n<p>Diese Bilddatei muss im gleichen Verzeichnis liegen, wie die anderen und darf keine Pfadangabe enthalten, sondern nur den Dateinamen!<\/p>\n<p>Das Klassenmodul speichert alle Node-Angaben zun&auml;chst in einem Array ab, um diese sp&auml;ter beim Anzeigen des TreeViews in der Routine <b>GetMenuString <\/b>in die Struktur zu &uuml;berf&uuml;hren, die das <b>CoolJSTree <\/b>erwartet. Dass dies nicht so ganz einfach ist, zeigt ein Blick in die immerhin 50 Zeilen lange Funktion samt Aufruf einer rekursiven Unterfunktion <b>GetSubItems<\/b>. <\/p>\n<p>Zur&uuml;ck zu den Formatierungsm&ouml;glichkeiten. Der Button <b>F&auml;rbe Node-IDs 1185\/6 <\/b>l&auml;sst die Nodes mit den IDs <b>1185 <\/b>und <b>1186 <\/b>erscheinen und f&auml;rbt sie nachtr&auml;glich ein, wie in Bild 3 zu sehen.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_06\/HTMLTreeview-web-images\/pic003.png\" alt=\"pic003.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3: Einf&auml;rben von Element-Texten<\/span><\/b><\/p>\n<p>Dies geschieht dynamisch, ohne dass der Baum neu aufgebaut werden muss! Dazu ein Code-Ausschnitt:<\/p>\n<pre>        Dim oNode As IHTMLElement\r\n        Set oNode = oTree.HTMLElementFromId(1185)\r\n        With oNode.Style\r\n            .backgroundColor = &quot;#a0a0f0&quot;\r\n            .FontWeight = &quot;700&quot;\r\n            .Color = &quot;#ff4040&quot;\r\n        End With<\/pre>\n<p>Die entscheidende aufgerufene Funktion lautet hier <b>HTMLElementFromId<\/b>. Das Klassenmodul h&auml;lt sie bereit, um aus der ID eines Nodes seine DOM-Klassen-ID zu ermitteln und das entsprechende HTML-Element zur&uuml;ckzugeben.<\/p>\n<p>Diese DOM-ID hat mit der bei <b>AddItem <\/b>&uuml;bergebenen ID gar nichts zu tun und lautet im Beispiel etwa <b>nttree1_39an<\/b>.<\/p>\n<p>Auf das HTML-Element kann man nun beliebige Aktionen ausf&uuml;hren. Im Objektmodell zu IHTMLElement findet man tonnenweise Anweisungen, wovon die <b>Style<\/b>-Eigenschaften nur einen kleinen Bruchteil darstellen. Genaugenommen handelt es sich bei einem Node-Element im <b>CoolJSTree <\/b>um ein <b>HTMLAnchorElement<\/b>. Sehen Sie sich im Objektkatalog an, was sich mit diesem anstellen l&auml;sst.<\/p>\n<p>&auml;hnliches passiert, wenn Sie einen Node im Baum anklicken. Das ruft die Ereignisprozedur <b>ItemClick <\/b>des Klassenmoduls auf:<\/p>\n<pre>        Sub oTree_ItemClick(ByVal ID As Long, _\r\n            ByVal Text As String, _\r\n            ByVal DOMID As Variant, _\r\n            ByVal IsFolder As Boolean, _\r\n            ByVal sImage As String)<\/pre>\n<p>Das Ereignis &uuml;bergibt folgende Parameter:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>ID <\/b>ist die ID, die per <b>AddItem <\/b>angegeben wurde, mithin der Prim&auml;rschl&uuml;ssel des zugrunde liegenden Datensatzes,<\/li>\n<li class=\"aufz-hlung\">Text ist der im Node angezeigte String,<\/li>\n<li class=\"aufz-hlung\"><b>DOMID <\/b>ist die DOM-Klassen-ID des Node-HTML-Elements,<\/li>\n<li class=\"aufz-hlung\"><b>IsFolder <\/b>gibt an, ob der Knoten Kindelemente enth&auml;lt, und<\/li>\n<li class=\"aufz-hlung\"><b>sImage <\/b>enth&auml;lt den Dateinamen des als Symbol f&uuml;r den Node verwendeten Bilds.<\/li>\n<\/ul>\n<p>Damit hat man ausreichend Informationen beisammen, um auf den Klick zu reagieren. Unter anderem etwa das Neuformatieren des Textes &uuml;ber die <b>DOMID<\/b>, wie dies auch in der Demo passiert (s. Bild 4):<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_06\/HTMLTreeview-web-images\/pic004.png\" alt=\"pic004.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 4: Klick auf einen Node formatiert diesen dynamisch um.<\/span><\/b><\/p>\n<pre>            Dim oNode As IHTMLElement\r\n            Set oNode = oTree.HTMLElementFromId(MID)\r\n            oNode.Style.Color = &quot;#ff4040&quot;<\/pre>\n<p>Einen Pferdefu&szlig; hat die Sache allerdings: Sie k&ouml;nnen nur Nodes ansprechen, die auch tats&auml;chlich im TreeView sichtbar sind. Ein nicht sichtbarer Node existiert beim Rendering noch nicht und deshalb gibt es auch noch keine Klassen-ID f&uuml;r diesen. Daher m&uuml;ssen Sie erst die Methode <b>EnsureVisible <\/b>aufrufen. Alternativ k&ouml;nnen Sie auch den gesamten Baum per <b>ExpandAll <\/b>ausklappen, die Nodes formatieren und ihn dann wieder per <b>CollapseAll <\/b>einklappen.<\/p>\n<p>In diesem Fall sind bereits alle n&ouml;tigen HTML-Elemente angelegt, auch wenn sie nicht sichtbar sind.<\/p>\n<p>Und schlie&szlig;lich k&ouml;nnen Sie auch auf das Browser-Fenster selbst zugreifen und es steuern. Der Button <b>Tree scrollen <\/b>zeigt ein Beispiel. <\/p>\n<p>Das Klassenmodul hat eine Eigenschaft <b>HTMLWindow<\/b>, die das <b>HTMLWindow2<\/b>-Objekt des WebControls zur&uuml;ckgibt, und dieses weist ebenso zahllose Methoden und Eigenschaften auf. So etwa die <b>scrollBy<\/b>-Methode:<\/p>\n<pre>            oTree.HTMLWindow.scrollBy 0, -16<\/pre>\n<p>Das scrollt den Baum um 16 Pixel nach oben.<\/p>\n<p>Das <b>HTMLWindow2<\/b>-Objekt aus folgendem Ausdruck erhalten:<\/p>\n<pre>            WebControl.Document.parentWindow<\/pre>\n<p>Um noch einige Interna der Klasse zu erl&auml;utern: Das <b>CoolJSTree <\/b>ver&ouml;ffentlicht sogar selbst zwei Objekte &#8211; das <b>Tree<\/b>-Objekt und das <b>Node<\/b>-Objekt. Das <b>Tree<\/b>-Objekt erh&auml;lt man raffiniert &uuml;ber das <b>Window<\/b>-Objekt und in der Klasse wird es in der Variablen <b>JSTree<\/b> gespeichert:<\/p>\n<pre>            Dim JSTree As Object\r\n            Set JSTree = oDoc.parentWindow.window.CTrees.tree1<\/pre>\n<p>Hier hat man also in einer VBA-Variablen ein JavaScript-Objekt gespeichert! In der API-Dokumentation zu <b>CoolJSTree <\/b>findet man etwa die Funktion <b>NodeByID <\/b>zum <b>Tree<\/b>-Objekt, welche ein <b>CoolJSTree<\/b>-Node-Objekt f&uuml;r eine &uuml;bergebene ID zur&uuml;ckgibt. Diese Funktion kann man allerdings nicht etwa so verwenden, wie bei Objektmethoden unter VBA &uuml;blich. Ein Aufruf etwa wie<\/p>\n<pre>            Set Node = JSTree.NodeById (1185)<\/pre>\n<p>schl&auml;gt fehl, weil der Punkt-Operator f&uuml;r das Objekt falsch ausgewertet wird und nicht JavaScript-kompatibel ist. Stattdessen muss die VBA-Funktion <b>CallByName <\/b>benutzt werden. Eine Routine des Klassenmoduls sieht etwa wie in <span class=\"verweis-ohneumbruch\"><a href=\"#anker-59-anchor\">Listing 2<\/a><\/span> aus.<\/p>\n<p class=\"listingueberschrift\">Listing 2: Einsatz der Funktion CallByName zum Ermitteln eines Nodes<\/p>\n<pre>Function NodeIndexFromID(ByVal ElementID As Long) As Variant\r\n    Dim oNode As Object\r\n    On Error Resume Next\r\n    Set oNode = CallByName(JSTree, &quot;nodeByID&quot;, VbMethod, CStr(ElementID))\r\n    If Err.Number = 0 Then\r\n        NodeIndexFromID = CallByName(oNode, &quot;index&quot;, VbGet)\r\n        Set oNode = Nothing\r\n    End If\r\nEnd Function<\/pre>\n<p>Nachdem hier das <b>Node<\/b>-Objekt erhalten wurde, wird auch noch dessen Index ermittelt &#8211; abermals &uuml;ber die <b>CallByName<\/b>-Funktion, diesmal jedoch unter Angabe von <b>VbGet<\/b>, was bedeutet, dass eine Eigenschaft (<b>Property<\/b>) abgefragt werden soll.<\/p>\n<p>Abschlie&szlig;end noch ein Hinweis auf das Kontextmen&uuml; des Webbrowser Controls. Normalerweise zeigt dieses dasselbe Kontextmen&uuml; in einer Seite an, wie auch der Internet Explorer. Das m&ouml;chte man im TreeView selbstverst&auml;ndlich nicht, weshalb es im Klassenmodul auch &uuml;ber das <b>oncontextmenu<\/b>-Ereignis des <b>HTMLDocuments <\/b>ausgefiltert wird. Man muss der Ereignisfunktion als R&uuml;ckgabe lediglich den Wert <b>False <\/b>zuweisen. Als special feature ist hier aber noch m&ouml;glich, ein in die Datenbank eingebautes Kontextmen&uuml; aufzurufen, wenn man es der Klasse &uuml;ber deren Eigenschaft <b>ContextMenu <\/b>bekannt gemacht hat. In der Demo wird das selbstgebaute Men&uuml; namens <b>contexttest<\/b> verwendet.<\/p>\n<p>Wenn Sie das TreeView-Unterformular in Ihre eigenen Anwendungen einbauen m&ouml;chten, so importieren Sie es in diese und setzen zus&auml;tzlich einen Verweis auf die Bibliothek <b>MSHTML <\/b>(<b>Microsoft HTML Object Library<\/b>). Die Template-Datei samt Bildverzeichnis darf nat&uuml;rlich auch nicht fehlen.<\/p>\n<p>Sollten Sie selbst mit der Steuerung des Trees experimentieren wollen, dann setzen Sie sich zuvor mit DOM auseinander, also dem Objektmodell der MSHTML-Bibliothek.<\/p>\n<p><b>Was fehlt der CoolJSTree-Klasse<\/b><\/p>\n<p>Es gibt einige Einschr&auml;nkungen, mit denen man in der dargestellten Form des <b>CoolJSTree <\/b>im Verein mit dem VBA-Klassenmodul leben muss. <\/p>\n<p>Die vielleicht wichtigste ist die fehlende M&ouml;glichkeit, Nodes zur Laufzeit hinzuzuf&uuml;gen oder zu l&ouml;schen. Das l&auml;sst sich jedoch l&ouml;sen, indem man die Professional Version des <b>CoolJSTree <\/b>kauft. Diese sieht solche erweiterten Steuerungsm&ouml;glichkeiten vor. Das Klassenmodul m&uuml;sste dann aber noch an diese angepasst werden.<\/p>\n<p>Eine weitere Unzul&auml;nglichkeit ist die fehlende Tastatursteuerung. Leider kann man sich nicht mit den Pfeiltasten innerhalb des Baums bewegen, sondern ist allein auf die Maus angewiesen.<\/p>\n<p>F&uuml;r Tastatursteuerung m&uuml;ssten zus&auml;tzliche <b>HTMLDocument<\/b>-Ereignisse im Klassenmodul ausgewertet werden.<\/p>\n<p><b>ActiveX- vs. JavaScript-Version<\/b><\/p>\n<p>Vorteil der ActiveX-L&ouml;sung ist sicherlich, dass nur eine Datei, die <b>mscomctl.ocx<\/b>, ben&ouml;tigt wird. Die JavaScript-L&ouml;sung hingegen setzt mindestens zus&auml;tzlich ein Verzeichnis mit den Symbol-Bilddateien voraus.<\/p>\n<p>Der HTML- und Script-Aufbau kann im Prinzip auch in der Datenbank selbst gespeichert werden, doch Grafikelemente ben&ouml;tigen ein <b>href<\/b>-Tag, das zwingend auf Dateien oder URLs verweist. <\/p>\n<p>Entscheidender Vorteil des ActiveX-TreeViews ist aber seine Performance. Es l&auml;sst sich problemlos mit zigtausenden Nodes f&uuml;llen, ohne dass mit Performance-Einbr&uuml;chen zu rechnen w&auml;re.<\/p>\n<p>Ein HTML-TreeView, das f&uuml;r seine Nodes allesamt jeweils mehrere Tabellenzellen anlegen muss, kann hier nicht konkurrieren. Aus diesem Grund eignet sich das HTML-TreeView eher zur Anzeige &uuml;berschaubarer Datenmengen.<\/p>\n<p>Auch die Programmierung ist, zumindest in der vorgestellten Form, zun&auml;chst deutlich aufwendiger. Es gibt kein hierarchisches Objektmodell, &uuml;ber das man etwa gezielt Nodes formatieren k&ouml;nnte. Problem ist dabei in erster Linie, dass im Browser nur Nodes angesprochen werden k&ouml;nnen, die bereits angezeigt sind. Andernfalls m&uuml;ssten die Skripte noch weiter aufgebohrt werden. <\/p>\n<p>Auf der anderen Seite sind die Formatierungsm&ouml;glichkeiten des ActiveX-Steuerelements ziemlich begrenzt und starr. &Uuml;ber HTML und DOM lassen sich dagegen beliebige Textformatierungen anweisen oder gar ganze HTML-Formulare in Nodes einsetzen. Der Fantasie sind hier keine Grenzen gesetzt. <\/p>\n<p>Wer einen dynamischen Aufbau der Nodes ben&ouml;tigt, kommt um die Professional-Version des <b>CoolJSTree <\/b>nicht herum.<\/p>\n<p>Auch mit den meisten alternativen freien Skripten ist es nicht m&ouml;glich, Nodes hinzuzuf&uuml;gen oder zu l&ouml;schen, ohne den Baum komplett neu aufzubauen. Hier hat das ActiveX-TreeView zun&auml;chst die Nase vorn.<\/p>\n<p>Aber schlie&szlig;lich der Punkt, der zu diesem Beitrag f&uuml;hrte: Die HTML-L&ouml;sung ben&ouml;tigt keine ActiveX-Datei und keine Registrierung, erfordert also mithin keine administrativen Rechte auf dem System. Und vor Abh&auml;ngigkeiten, sowie der DLL-Hell durch inkompatible Versionen, ist man ebenfalls gefeit.<\/p>\n<p><b>Kleiner Ausflug zu HTML5<\/b><\/p>\n<p>Mit <b>HTML5 <\/b>wird es zuk&uuml;nftig auch m&ouml;glich sein, Bildelemente statt aus Dateien &uuml;ber Arrays zu beziehen. &Uuml;ber Methoden des <b>Canvas<\/b>-Elements &#8211; Stichwort CanvasRendering-<b>Context2D.putimageData <\/b>&#8211; kann man Grafiken auch on the fly aus bin&auml;ren Arrays erzeugen.<\/p>\n<p>Diese k&ouml;nnten dann wiederum aus bin&auml;ren Datenbankfeldern stammen. Zuk&uuml;nftig deshalb, weil <b>HTML5<\/b> erst seit dem Internet Explorer 9 unterst&uuml;tzt wird, welchen man aktuell auf den Zielsystemen noch nicht unbedingt voraussetzen kann.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>Demo.zip<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{ABE6C018-D66C-423C-B984-49DB8B0299E0}\/aiu_862.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im August 2012 verteilte Microsoft &uuml;ber Windows-Update f&uuml;r alle Office-Installationen ab Version 2003 automatisch Security Patches, die nur eine einzige Komponente austauschten: die ActiveX-Bibliothek mscomctl.ocx, welche, unter anderem, das viel verwendete TreeView-Steuerelement enth&auml;lt. Dabei machte die COM-Version der Bibliothek einen Sprung von 2.0 auf 2.1, was VBA-Module, in denen deren Elemente angesprochen werden, teilweise inkompatibel macht. Ergebnis sind deshalb Datenbanken, die seltsame Fehler melden, wenn Formulare mit TreeViews oder Listviews aufgerufen werden. <\/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":[662012,66062012,44000023],"tags":[],"class_list":["post-55000862","post","type-post","status-publish","format-standard","hentry","category-662012","category-66062012","category-Mit_Formularen_arbeiten"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>TreeView ohne ActiveX - 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\/TreeView_ohne_ActiveX\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"TreeView ohne ActiveX\" \/>\n<meta property=\"og:description\" content=\"Im August 2012 verteilte Microsoft &uuml;ber Windows-Update f&uuml;r alle Office-Installationen ab Version 2003 automatisch Security Patches, die nur eine einzige Komponente austauschten: die ActiveX-Bibliothek mscomctl.ocx, welche, unter anderem, das viel verwendete TreeView-Steuerelement enth&auml;lt. Dabei machte die COM-Version der Bibliothek einen Sprung von 2.0 auf 2.1, was VBA-Module, in denen deren Elemente angesprochen werden, teilweise inkompatibel macht. Ergebnis sind deshalb Datenbanken, die seltsame Fehler melden, wenn Formulare mit TreeViews oder Listviews aufgerufen werden.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T21:49:30+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg05.met.vgwort.de\/na\/3e9d68261600455bb63980501820389d\" \/>\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=\"22\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"TreeView ohne ActiveX\",\"datePublished\":\"2020-05-22T21:49:30+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/\"},\"wordCount\":3994,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/3e9d68261600455bb63980501820389d\",\"articleSection\":[\"2012\",\"6\\\/2012\",\"Mit Formularen arbeiten\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/\",\"name\":\"TreeView ohne ActiveX - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/3e9d68261600455bb63980501820389d\",\"datePublished\":\"2020-05-22T21:49:30+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/3e9d68261600455bb63980501820389d\",\"contentUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/3e9d68261600455bb63980501820389d\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/TreeView_ohne_ActiveX\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"TreeView ohne ActiveX\"}]},{\"@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":"TreeView ohne ActiveX - 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\/TreeView_ohne_ActiveX\/","og_locale":"de_DE","og_type":"article","og_title":"TreeView ohne ActiveX","og_description":"Im August 2012 verteilte Microsoft &uuml;ber Windows-Update f&uuml;r alle Office-Installationen ab Version 2003 automatisch Security Patches, die nur eine einzige Komponente austauschten: die ActiveX-Bibliothek mscomctl.ocx, welche, unter anderem, das viel verwendete TreeView-Steuerelement enth&auml;lt. Dabei machte die COM-Version der Bibliothek einen Sprung von 2.0 auf 2.1, was VBA-Module, in denen deren Elemente angesprochen werden, teilweise inkompatibel macht. Ergebnis sind deshalb Datenbanken, die seltsame Fehler melden, wenn Formulare mit TreeViews oder Listviews aufgerufen werden.","og_url":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T21:49:30+00:00","og_image":[{"url":"http:\/\/vg05.met.vgwort.de\/na\/3e9d68261600455bb63980501820389d","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"22\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"TreeView ohne ActiveX","datePublished":"2020-05-22T21:49:30+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/"},"wordCount":3994,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/#primaryimage"},"thumbnailUrl":"http:\/\/vg05.met.vgwort.de\/na\/3e9d68261600455bb63980501820389d","articleSection":["2012","6\/2012","Mit Formularen arbeiten"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/","url":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/","name":"TreeView ohne ActiveX - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/#primaryimage"},"thumbnailUrl":"http:\/\/vg05.met.vgwort.de\/na\/3e9d68261600455bb63980501820389d","datePublished":"2020-05-22T21:49:30+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/#primaryimage","url":"http:\/\/vg05.met.vgwort.de\/na\/3e9d68261600455bb63980501820389d","contentUrl":"http:\/\/vg05.met.vgwort.de\/na\/3e9d68261600455bb63980501820389d"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/TreeView_ohne_ActiveX\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"TreeView ohne ActiveX"}]},{"@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\/55000862","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=55000862"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000862\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}