{"id":55001218,"date":"2020-02-01T00:00:00","date_gmt":"2020-07-10T09:39:16","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1218"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"HTMLCode_optimieren_per_VBA","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/","title":{"rendered":"HTML-Code optimieren per VBA"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg06.met.vgwort.de\/na\/f8b250ed91ab40f0a6e92cb5957cf149\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Im Beitrag &#8222;Von Access nach WordPress&#8220; (Heft 6\/2019) haben wir Routinen entwickelt, mit denen wir den Inhalt eines Textfeldes in SQL-Anweisungen exportiert und damit eine WordPress-Webseite gef&uuml;llt haben. Der Weg dorthin war nicht so einfach, wie es in diesem Beitrag beschrieben wurde. In der Tag lag der HTML-Code mit den Artikeln so vor, dass er in einem anderen Content Management System, hier Typo3, optimal angezeigt wurde. Wenn wir diesen HTML-Code in das WordPress-System importiert haben, sah das optisch allerdings nicht so ansprechend aus. Wir mussten also noch einige &Auml;nderungen am HTML-Code vornehmen. F&uuml;r Handarbeit war das bei rund 1.000 Artikel zu viel, also war die Programmierung entsprechender Konvertierungsroutinen angezeigt. Wie das grundlegend funktioniert, zeigen wir im vorliegenden Beitrag.<\/b><\/p>\n<p><b>Beispiele f&uuml;r notwendige Konvertierungen<\/b><\/p>\n<p>Typo3 war als Content Management System sehr nachsichtig, was die anzuzeigenden Inhalte anging. So konnten Sie ihm beispielsweise die deutschen Umlaute wie <b>&auml;<\/b>, <b>&ouml; <\/b>und <b>&uuml; <\/b>sowie das scharfe s (<b>&szlig;<\/b>) unterjubeln und es zeigte diese problemlos an. Unter WordPress funktioniert das nicht. Hier werden entsprechende HTML-Entit&auml;ten erwartet, die wie folgt aussehen:<\/p>\n<ul>\n<li><b>&auml;<\/b>: <b>&amp;auml;<\/b><\/li>\n<li><b>&ouml;<\/b>: <b>&amp;ouml;<\/b><\/li>\n<li><b>&uuml;<\/b>: <b>&amp;uuml;<\/b><\/li>\n<li><b>&Auml;<\/b>: <b>&amp;Auml;<\/b><\/li>\n<li><b>&Ouml;<\/b>: <b>&amp;Ouml;<\/b><\/li>\n<li><b>&Uuml;<\/b>: <b>&amp;Uuml;<\/b><\/li>\n<li><b>&szlig;<\/b>: <b>&amp;szlig;<\/b><\/li>\n<\/ul>\n<p>Auch der Vorname des Autors dieser Zeilen f&uuml;hrte zu Problemen: Also musste <b>Andr&eacute; <\/b>&uuml;berall in <b>Andr&eacute; <\/b>ge&auml;ndert werden. Und davon gab es noch viele weitere Beispiele.<\/p>\n<p><b>Gr&ouml;&szlig;er- und Kleiner-Zeichen<\/b><\/p>\n<p>Ein weiteres Problem sind im Text abgebildete HTML-Codes wie der folgende:<\/p>\n<pre>&lt;p&gt;Beispieltext&lt;\/p&gt;<\/pre>\n<p>Dies wurde unter Typo3 problemlos angezeigt, unter WordPress jedoch wurden die HTML-Auszeichnungen mehr oder weniger sinnvoll als solche interpretiert und nicht einfach ausgegeben. Also muss man auch hier die Kleiner- und Gr&ouml;&szlig;er-Zeichen durch entsprechende Entit&auml;ten ersetzen:<\/p>\n<ul>\n<li><b>&gt;<\/b>: <b>&amp;lt;<\/b><\/li>\n<li><b>&lt;<\/b>: <b>&amp;gt;<\/b><\/li>\n<\/ul>\n<p><b>Andere Zeichen<\/b><\/p>\n<p>Desweiteren haben wir noch einige andere Zeichen gefunden, die wir in den rund 1.000 Artikeln mehr oder weniger konsistent verwendet haben &#8211; zum Beispiel verschiedene Anf&uuml;hrungszeichen wie &#8220;, &#8222;&#8220;, &#8222;&#8220; oder &#8222;&#8220;. Hier haben wir versucht, die Anf&uuml;hrungszeichen auf diesem Wege zu vereinheitlichen.<\/p>\n<p>Mit Anf&uuml;hrungszeichen gab es vor allem Probleme, weil diese ja irgendwie in die <b>INSERT INTO<\/b>-Anweisungen integriert werden mussten, die ja ihrerseits die Werte f&uuml;r Textfelder in Anf&uuml;hrungszeichen angeben. Unter dem SQL-Dialekt von MySQL kann man Zeichenketten sowohl in Hochkommata (&#8218;) also auch in Anf&uuml;hrungszeichen angeben (&#8222;). Je nachdem, welches man verwendet, muss man aber im zu speichernden Text die Hochkommata oder Anf&uuml;hrungszeichen &#8222;escapen&#8220;, also durch ein zus&auml;tzliches Zeichen so codieren, dass es nicht als Ende der Zeichenkette interpretiert wird &#8211; denn das f&uuml;hrt regelm&auml;&szlig;ig zu Fehlern, da so der Rest der SQL-Anweisung fehlinterpretiert wird. Ein Beispiel:<\/p>\n<pre>INSERT INTO wp_posts(ID, post_content, ...) \r\nVALUES (55000999, 'Dies ist ein 'lustiger' Beispieltext', ...)<\/pre>\n<p>Das f&uuml;hrt zu einem Fehler, weil der SQL-Interpreter das Hochkomma vor <b>lustiger <\/b>als Ende der Zeichenkette erkennt. Danach wird ein Komma erwartet, aber es folgt noch weiterer Text, was den Fehler ausl&ouml;st.<\/p>\n<p>Abhilfe schafft es an dieser Stelle, einfach das Hochkomma in dem Text, der in das Feld eingef&uuml;gt werden soll, durch ein doppeltes Hochkomma zu ersetzen. Alternativ k&ouml;nnen Sie auch ein Anf&uuml;hrungszeichen verwenden &#8211; zumindest, wenn zur Markierung der einzuf&uuml;genden Texte Hochkommata verwendet werden.<\/p>\n<p><b>HTML-Auszeichnungen<\/b><\/p>\n<p>Au&szlig;erdem hatte ich die interessante Idee, nicht die &uuml;blichen HTML-Auszeichnungen etwa f&uuml;r &Uuml;berschriften zu verwenden, sondern ein Absatz-Element mit einer bestimmten CSS-Klasse (wobei: vermutlich war das gar nicht meine Idee, sondern die des Exports aus Word oder InDesign, das nat&uuml;rlich nicht erkennen konnte, dass die Absatzformatklasse <b>titel <\/b>eine &Uuml;berschrift beinhaltet):<\/p>\n<pre>&lt;p class=\"\"titel\"\"&gt;...&lt;\/p&gt;<\/pre>\n<p>Dennoch sollten solche Elemente so umformatiert werden, dass Folgendes herauskam:<\/p>\n<pre>&lt;h1&gt;...&lt;\/h1&gt;<\/pre>\n<p>Damit k&ouml;nnen dann auch die Suchmaschinen viel mehr anfangen &#8211; sonst w&auml;re es nicht m&ouml;glich, zu erkennen, in welchem Element sich die &Uuml;berschrift eines Textes befindet.<\/p>\n<p>Es gibt noch weitere, &auml;hnliche Beispiele &#8211; zum Beispiel f&uuml;r Zwischen&uuml;berschriften:<\/p>\n<pre>&lt;p class=\"zwischenueberschrift\"&gt;...&lt;\/p&gt;<\/pre>\n<p>Diese Auszeichnung soll beispielsweise zu dieser werden:<\/p>\n<pre>&lt;h2&gt;...&lt;\/h2&gt;<\/pre>\n<p>F&uuml;r Quellcode gab es die folgende Auszeichnung:<\/p>\n<pre>&lt;p class=\"Quellcode\"&gt;...&lt;\/p&gt;<\/pre>\n<p>Diese soll so umformatiert werden:<\/p>\n<pre>&lt;pre&gt;...&lt;\/pre&gt;<\/pre>\n<p>Innerhalb des Flie&szlig;textes wurde die folgende Auszeichnung verwendet, um Begriffe hervorzuheben:<\/p>\n<pre>...&lt;span class=\"kursiv\"&gt;...&lt;\/span&gt;...<\/pre>\n<p>Das wollen wir durch fette Schrift ersetzen:<\/p>\n<pre>...&lt;b&gt;...&lt;\/b&gt;...<\/pre>\n<p><b>Nicht sichtbare Zeichen<\/b><\/p>\n<p>Die bisher beschriebenen notwendigen &Auml;nderungen waren leicht zu erkennen. Entweder f&uuml;hrten Sie schon beim Versuch, die Texte in die Textfelder der MySQL-Tabelle zu importieren, zu Fehlern oder sie fielen dann beim manuellen Sichten der Texte auf der WordPress-Webseite auf. Einige Zeichen sorgten jedoch daf&uuml;r, dass der Text in WordPress einfach an einer bestimmten Stelle endete. Diese Zeichen mussten wir erst aufwendig ermitteln, indem wir die betroffene Stelle eingegrenzt haben und dann Zeichen f&uuml;r Zeichen die ASCII-Codes analysiert haben. Dabei zeigte sich, dass so manche Steuerzeichen aus dem Originaltext aus Word oder InDesign im HTML-Code gelandet sind, die von Typo3 ignoriert wurden &#8211; und unter WordPress dazu f&uuml;hrten, dass der Rest des Textes inklusive dieses Zeichens schlicht nicht mehr abgebildet wurde. Die ASCII-Codes dieser Zeichen lauten beispielsweise <b>7<\/b>, <b>22<\/b>, <b>30<\/b>, <b>63<\/b>, <b>141 <\/b>oder <b>157<\/b>.<\/p>\n<p><b>Umwandlungen per VBA<\/b><\/p>\n<p>Die meisten &Auml;nderungen, die notwendig sind, um die oben genannten, nicht in WordPress funktionierenden Zeichen und Elemente anzupassen, sind mit dem Aufruf der <b>Replace<\/b>-Funktion zu erledigen. Andere verlangen nach mehr Aufwand, zum Beispiel wenn es um das Ersetzen von Elementen wie <b><\/p>\n<p class=\"Titel\">&#8230;<\/p>\n<p> <\/b>durch <b> <\/b>geht.<\/p>\n<p><b>Einzelne Zeichen ersetzen<\/b><\/p>\n<p>Wir haben diese alle in eine einzige Funktion geschrieben, mit der wir einen Text entgegennehmen, diesen auf die zu ersetzenden Zeichen durchsuchen und diese direkt mit der <b>Replace<\/b>-Funktion ersetzen. Das sieht dann beispielsweise wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>Ersetzen(strText<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As String<\/span>\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"'\", \"'\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"'\", \"''\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"\", \"&gt;\/font&lt;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&auml;\", \"&auml;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&ouml;\", \"&ouml;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&uuml;\", \"&uuml;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&Auml;\", \"&Auml;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&Ouml;\", \"&Ouml;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&Uuml;\", \"&Uuml;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&szlig;\", \"&szlig;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&eacute;\", \"&eacute;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"\"\", \"\"\"\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"\"\", \"\"\"\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&sect;\", \"&sect;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"-\", \"-\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&euro;\", \"&euro;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&aacute;\", \"&aacute;\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"\"\", \"\"\"\")\r\n     strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"\"\", \"\"\"\")\r\n     ...\r\n     Ersetzen = strText\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>F&uuml;r die meisten Sonderzeichen lassen sich leicht die passenden HTML-Entit&auml;ten finden. Wenn das nicht gelingt, ist die Chance hoch, dass Sie das Ersetzen &uuml;ber den ASCII-Code des Zeichens wie folgt bewerkstelligen k&ouml;nnen:<\/p>\n<p>Sie ermitteln den ASCII-Code des Zeichens mit der <b>Asc<\/b>-Funktion:<\/p>\n<pre>  Asc(\"&#154;\")\r\n  154 <\/pre>\n<p>Dann stellen Sie den Ersetzungscode aus den Zeichen <b>&amp;#<\/b>, dem ASCII-Code und dem Semikolon (<b>;<\/b>) zusammen:<\/p>\n<pre>&amp;#154;<\/pre>\n<p>Dementsprechend sieht dann die Ersetzung aus:<\/p>\n<pre>strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&#154;\", \"&amp;#154;\")<\/pre>\n<p>oder<\/p>\n<pre>strText = <span style=\"color:blue;\">Replace<\/span>(strText, Chr(154), \"&amp;#154;\")<\/pre>\n<p><b>Umfangreichere Ersetzungen<\/b><\/p>\n<p>Etwas komplizierter wird es, wenn Sie &ouml;ffnende und schlie&szlig;ende HTML-Tags ersetzen wollen.<\/p>\n<p>Soll nur der &ouml;ffnende Tag angepasst werden, etwa <b>&lt;p class=&#8220;Fliess-text&#8220;&gt;<\/b> durch <b>&lt;p&gt;<\/b>, kann man das genau wie oben mit der <b>Replace<\/b>-Funktion erledigen:<\/p>\n<pre>strText = <span style=\"color:blue;\">Replace<\/span>(strText, \"&lt;p class=\"\"Fliesstext\"\"&gt;\", \"&lt;p&gt;\")<\/pre>\n<p>Zu beachten ist in diesem Fall, dass Sie das einfache Anf&uuml;hrungszeichen in der zu ersetzenden Zeichenkette durch doppelte Anf&uuml;hrungszeichen ersetzen, damit das Anf&uuml;hrungszeichen hinter <b>class=<\/b> nicht als schlie&szlig;endes Anf&uuml;hrungszeichen erkannt wird.<\/p>\n<p><!--30percent--><\/p>\n<p>Ein Beispiel f&uuml;r einen komplizierteren Fall ist der folgende:<\/p>\n<pre>&lt;p class=\"\"titel\"\"&gt;...&lt;\/p&gt;<\/pre>\n<p>soll ersetzt werden durch:<\/p>\n<pre>&lt;h1&gt;...&lt;\/h1&gt;<\/pre>\n<p>Das erledigen wir mit der Funktion aus Listing 1. Hier ermitteln wir mit der <b>InStr<\/b>-Funktion zun&auml;chst die Position im Text, an der das erste Mal die gesuchte Zeichenkette auftaucht und speichern diese in der Variablen <b>lngStart<\/b>. Danach steigen wir in eine <b>Do While<\/b>-Schleife ein. Warum eine Schleife Weil wir davon ausgehen, dass es nicht nur ein Vorkommen des zu ersetzenden Textes gibt. Deshalb l&auml;uft die <b>Do While<\/b>-Schleife solange, wie <b>lngStart <\/b>gr&ouml;&szlig;er als <b>0 <\/b>ist. Wenn wir beim ersten Aufruf von <b>InStr <\/b>also kein Vorkommen finden, hat <b>lngStart <\/b>den Wert <b>0 <\/b>und die Schleife wird gar nicht erst durchlaufen.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>ErsetzenH1(strText<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngStart<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngEnde<span style=\"color:blue;\"> As Long<\/span>\r\n     lngStart = <span style=\"color:blue;\">InStr<\/span>(1, strText, \"&lt;p class=\"\"titel\"\"&gt;\")\r\n     <span style=\"color:blue;\">Do While<\/span> lngStart &gt; 0\r\n         lngEnde = <span style=\"color:blue;\">InStr<\/span>(lngStart + 1, strText, \"&lt;\/p&gt;\")\r\n         strText = <span style=\"color:blue;\">Left<\/span>(strText, lngStart - 1) & \"&lt;h1&gt;\" & <span style=\"color:blue;\">Mid<\/span>(strText, lngStart + 17, lngEnde - lngStart - 17) _\r\n             & \"&lt;\/h1&gt;\" & <span style=\"color:blue;\">Mid<\/span>(strText, lngEnde + 4)\r\n         lngStart = <span style=\"color:blue;\">InStr<\/span>(lngStart + 1, strText, \"&lt;p class=\"\"titel\"\"&gt;\")\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     ErsetzenH1 = strText\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Ersetzen &ouml;ffnender und schlie&szlig;ender Tags<\/span><\/b><\/p>\n<p>Wenn der erste Aufruf der <b>InStr<\/b>-Funktion jedoch einen Treffer liefert, was wir durch einen Wert gr&ouml;&szlig;er <b>0 <\/b>f&uuml;r die Variable <b>lngStart <\/b>erkennen, starten wir in die <b>Do While<\/b>-Schleife. Wir suchen dann nach dem entsprechenden schlie&szlig;enden Element mit dem Text <b>&lt;\/p&gt;<\/b>. Bei diesem Aufruf der <b>InStr<\/b>-Funktion verwenden wir nicht den Wert <b>1 <\/b>als Startposition f&uuml;r die Suche, sondern den Wert der Variablen <b>lngStart <\/b>plus eins, damit wir auf jeden Fall ein Vorkommen von <b>&lt;\/p&gt; <\/b>finden, das hinter dem &ouml;ffnenden Element liegt.<\/p>\n<p>Dann folgt eine Anweisung mit Zeichenkettenfunktionen, die folgendes erledigt: Sie ermittelt zun&auml;chst den Text, der sich vor der Startposition des zuletzt gefundenen Auftretens von <b>&lt;p class=&#8220;&#8220;titel&#8220;&#8220;&gt; <\/b>befindet, und verwendet diesen als ersten Teil des neuen Inhalts der Variablen <b>strText<\/b>. Als n&auml;chstes folgt der ersetzende Ausdruck, n&auml;mlich <b>&lt;h1&gt;<\/b>. Dann liefert die <b>Mid<\/b>-Funktion den Text vom Ende des aktuell gefundenen Vorkommens von <b>&lt;p class=&#8220;&#8220;titel&#8220;&#8220;&gt; <\/b>bis zum Anfang des schlie&szlig;enden Tags <b>&lt;\/p&gt;<\/b>. Danach folgt der neue schlie&szlig;ende Tag, also <b>&lt;\/h1&gt;<\/b>. Und schlie&szlig;lich f&uuml;gt die <b>Mid<\/b>-Funktion noch den gesamten Text hinzu, der sich hinter dem schlie&szlig;enden Tag <b>&lt;\/p&gt; <\/b>befindet:<\/p>\n<pre><span style=\"color:blue;\">Left<\/span>(strText, lngStart - 1) _\r\n     & \"&lt;h1&gt;\" _\r\n     & <span style=\"color:blue;\">Mid<\/span>(strText, lngStart + 17, lngEnde - lngStart - 17) _\r\n     & \"&lt;\/h1&gt;\" _\r\n     & <span style=\"color:blue;\">Mid<\/span>(strText, lngEnde + 4)<\/pre>\n<p>Hier finden wir einige Zahlenwerte, n&auml;mlich <b>4 <\/b>und <b>17<\/b>. Der Teil zwischen dem &ouml;ffnenden und dem schlie&szlig;enden Tag soll beispielsweise 17 Zeichen hinter dem ersten Vorkommen des &ouml;ffnenden Tags beginnen. Woher kommt diese Zahl Ganz einfach: Der Text <b>&lt;p class=&#8220;&#8220;titel&#8220;&#8220;&gt;<\/b> ist genau 17 Zeichen lang. Deshalb suchen wir das erste Zeichen des Textes zwischen dem &ouml;ffnenden und dem schlie&szlig;enden Tag 17 Zeichen hinter dem Beginn des &ouml;ffnenden Tags. Und das Ende befindet sich an der Position, die durch die Startposition des schlie&szlig;enden Tags <b>&lt;\/p&gt;<\/b> minus der Startposition des &ouml;ffnenden Tags minus der L&auml;nge des &ouml;ffnenden Tags ermittelt wird.<\/p>\n<p>Und das Ende des Textes hinter dem schlie&szlig;enden Tag <b>&lt;\/p&gt; <\/b>ermitteln wir durch die Startposition dieses Tags plus der L&auml;nge der Zeichenkette, also <b>4<\/b>.<\/p>\n<p>Nachdem wir das erste Vorkommen in <b>strText <\/b>ersetzt haben, suchen wir mit der <b>InStr<\/b>-Funktion nach dem n&auml;chsten Vorkommen und steigen damit, wenn <b>lngStart <\/b>danach einen Wert gr&ouml;&szlig;er <b>0 <\/b>hat, in den n&auml;chsten Schleifendurchlauf ein. Falls nicht, haben wir alle Vorkommen ersetzt und die Funktion endet mit dem Zur&uuml;ckgeben von <b>strText <\/b>mit den ersetzten Elementen.<\/p>\n<p><b>Parametrisieren der Funktion<\/b><\/p>\n<p>Beim Aktualisieren der HTML-Codes von der Version, die in Typo3 lief, zu der, die unter WordPress so aussah wie gew&uuml;nscht, haben wir die zu ersetzenden Elemente St&uuml;ck f&uuml;r St&uuml;ck zu einer gro&szlig;en Ersetzen-Funktion hinzugef&uuml;gt, bis schlie&szlig;lich alle nicht funktionierenden Elemente ersetzt waren. Dabei haben wir die obigen Codezeilen f&uuml;r alle zu ersetzenden &ouml;ffnenden und schlie&szlig;enden Tags erneut kopiert und angepasst. Das k&ouml;nnen wir allerdings auch besser, und zwar indem wir die die Anweisungen der Funktion auslagern und diese parametrisieren.<\/p>\n<p>Die Parameter sind schnell gefunden:<\/p>\n<ul>\n<li>Text mit den zu ersetzenden Tags<\/li>\n<li>Zu ersetzender &ouml;ffnender Tag, zum Beispiel <b>&lt;p class=&#8220;&#8220;titel&#8220;&#8220;&gt;<\/b><\/li>\n<li>Zu ersetzender schlie&szlig;ender Tag, zum Beispiel <b>&lt;\/p&gt;<\/b><\/li>\n<li>Einzusetzender &ouml;ffnender Tag, zum Beispiel <b>&lt;h1&gt;<\/b><\/li>\n<li>Einzusetzender schlie&szlig;ender Tag, zum Beispiel <b>&lt;\/h1&gt;<\/b><\/li>\n<\/ul>\n<p>Dann brauchen wir nur noch die Funktion zu ersetzen, die anschlie&szlig;end wie in Listing 2 aussieht.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>ErsetzenStartUndEndTag(strText<span style=\"color:blue;\"> As String<\/span>, strStarttagAlt<span style=\"color:blue;\"> As String<\/span>, strEndtagAlt<span style=\"color:blue;\"> As String<\/span>, _\r\n         strStartTagNeu<span style=\"color:blue;\"> As String<\/span>, strEndtagNeu<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngStart<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngEnde<span style=\"color:blue;\"> As Long<\/span>\r\n     lngStart = <span style=\"color:blue;\">InStr<\/span>(1, strText, strStarttagAlt)\r\n     <span style=\"color:blue;\">Do While<\/span> lngStart &gt; 0\r\n         lngEnde = <span style=\"color:blue;\">InStr<\/span>(lngStart + 1, strText, strEndtagAlt)\r\n         strText = <span style=\"color:blue;\">Left<\/span>(strText, lngStart - 1) & strStartTagNeu & <span style=\"color:blue;\">Mid<\/span>(strText, lngStart + <span style=\"color:blue;\">Len<\/span>(strStarttagAlt), _\r\n             lngEnde - lngStart - <span style=\"color:blue;\">Len<\/span>(strStarttagAlt)) & strEndtagNeu & <span style=\"color:blue;\">Mid<\/span>(strText, lngEnde + <span style=\"color:blue;\">Len<\/span>(strEndtagAlt))\r\n         lngStart = <span style=\"color:blue;\">InStr<\/span>(lngStart + 1, strText, strStarttagAlt)\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     ErsetzenStartUndEndTag = strText\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Ersetzen &ouml;ffnender und schlie&szlig;ender Tags mit einer parametrisierten Funktion<\/span><\/b><\/p>\n<p>Der Aufruf dieser Funktion sieht nun beispielsweise wie folgt aus:<\/p>\n<pre>  ErsetzenstartUndEndtag(\"xxx&lt;p class=\"\"titel\"\"&gt;bla&lt;\/p&gt;yyy\", \"&lt;p class=\"\"titel\"\"&gt;\", \"&lt;\/p&gt;\", \"&lt;h1&gt;\", \"&lt;\/h1&gt;\")<\/pre>\n<p>Das Ergebnis lautet nun, wie auch mit der vorherigen Funktion:<\/p>\n<pre>xxx&lt;h1&gt;bla&lt;\/h1&gt;yyy<\/pre>\n<p>Dank dieser Funktion brauchen wir nur noch eine Anweisung f&uuml;r jedes Paar zu ersetzender Start- und Endtags. Au&szlig;erdem entf&auml;llt das Ausrechnen beziehungsweise ermitteln der L&auml;ngen von Start- und Endtags und somit entfallen auch viele Fehler, die sonst beim Ausprobieren der entsprechenden Zahlenwerte passiert sind.<\/p>\n<p>Wir k&ouml;nnen nun also einfach mehrere Aufrufe der gleichen Form in eine Funktion schreiben, die dann auch die Anweisungen zum Ersetzen der einfachen Elemente enth&auml;lt.<\/p>\n<p><b>HTML-Texte per DOM bearbeiten<\/b><\/p>\n<p>Eine andere Idee, die mir gekommen ist, als ich in diesem Beitrag das Ersetzen von Start- und Endtags beschrieben habe, ist das Document Object Model zum Bearbeiten von XML-Dokumenten. Mit den Befehlen dieses Objektmodells kann man ja gezielt auf die Elemente eines XML-Dokuments zugreifen und diese gegebenenfalls auch manipulieren. Aber ist das geeignet, um HTML-Dokumente zu manipulieren, wie wir diese vorliegen haben Wir probieren mit folgender Prozedur aus, ein solches Dokument in eine Objektvariable des Typs <b>DOMDocument <\/b>zu laden und lassen wohlweislich auch direkt die Fehlermeldung im Falle eines Fehlers beim Parsen ausgeben:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>ErsetzenPerXMLDOM()\r\n     <span style=\"color:blue;\">Dim <\/span>strText<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objXML<span style=\"color:blue;\"> As <\/span>MSXML2.DOMDocument60\r\n     strText = DLookup(\"InhaltOffen\", \"tblBeitraege\", _\r\n         \"BeitragID = 1000\")\r\n     <span style=\"color:blue;\">Set<\/span> objXML = <span style=\"color:blue;\">New<\/span> DOMDocument60\r\n     <span style=\"color:blue;\">Debug.Print<\/span> <span style=\"color:blue;\">Left<\/span>(strText, 1000)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> objXML.LoadXML(strText)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> objXML.parseError, _\r\n         objXML.parseError.reason\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Hier haben wir zun&auml;chst den Inhalt eines Artikels in die Variable <b>strText <\/b>geladen, dann ein neues <b>DOMDocument<\/b>-Objekt erstellt und mit der Variablen <b>objXML <\/b>referenziert und dann mit seiner <b>LoadXML<\/b>-Methode den Inhalt von <b>strText <\/b>eingelesen. Dies liefert den Wert False und die Ausgabe von <b>objXML.parseError.reason <\/b>liefert diese Antwort:<\/p>\n<pre>-1072896683   In einem XML-Dokument ist nur ein Element h&ouml;chster Ebene zugelassen.<\/pre>\n<p>Logisch &#8211; wir haben in unserer Tabelle kein &ouml;ffnendes und schlie&szlig;endes HTML-Element, was dem geforderten Element h&ouml;chster Ebene entsprechen w&uuml;rde, denn die Inhalte sollen ja in anderen HTML-Dokumenten, die vom jeweiligen Content Management System zur Verf&uuml;gung gestellt werden, eingebettet werden.<\/p>\n<p>Also f&uuml;gen wir zuvor ein &ouml;ffnendes und ein schlie&szlig;endes HTML-Element zu <b>strText <\/b>hinzu:<\/p>\n<pre>strText = \"&lt;html&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span> & strText & <span style=\"color:blue;\">vbCrLf<\/span> & \"&lt;\/html&gt;\"<\/pre>\n<p>Danach erhalten wir diesen Fehler:<\/p>\n<pre>-1072896659   Das Endtag 'p' stimmt nicht mit dem Starttag 'html' &uuml;berein.<\/pre>\n<p>Offensichtlich haben wir hier also noch nicht einmal ein sauberes HTML-Dokument, bei dem alle &ouml;ffnenden Elemente auch auf der gleichen Ebene wieder geschlossen werden. Wir f&uuml;gen also noch eine weitere Zeile zu unserer Prozedur hinzu, um herauszufinden, an welcher Stelle der Fehler aufgetreten ist:<\/p>\n<pre><span style=\"color:blue;\">Debug.Print<\/span> objXML.parseError.Line,  objXML.parseError.linepos<\/pre>\n<p>Das liefert f&uuml;r unser Beispiel Zeile 6, Zeichen 220. Das k&ouml;nnen wir uns nun in einem Texteditor ansehen. Hier stellen wir dann auch direkt fest, dass hier ein &uuml;berz&auml;hliges schlie&szlig;endes <b>&lt;\/p&gt;<\/b>-Tag enthalten ist. In der Folge stellte sich heraus, dass die angedachte Vorgehensweise zumindest f&uuml;r unseren Fall zu viel Vorarbeit erfordert.  Oder anders formuliert: Man m&uuml;sste zun&auml;chst dennoch mit einigen <b>Replace<\/b>-Aufrufen die f&uuml;r ein valides HTML-\/XML-Dokument erforderliche Form herbeif&uuml;hren. Dann kann man auch direkt die ben&ouml;tigten &Auml;nderungen auf die gleiche Weise vornehmen.<\/p>\n<p>Und wenn wir nun ein valides Dokument h&auml;tten K&ouml;nnen wir dann &Auml;nderungen an den Start- und Endtags wie geplant vornehmen, ohne unz&auml;hlige Aufrufe von Zeichenkettenfunktionen<\/p>\n<p>Das geht, aber es ist durchaus mit Programmieraufwand verbunden. Da wir solche Herausforderungen lieben, haben wir uns angesehen, wie das funktionieren kann. Das Ergebnis finden Sie in Listing 3.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>ErsetzenPerXMLDOM()\r\n     <span style=\"color:blue;\">Dim <\/span>strText<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objXML<span style=\"color:blue;\"> As <\/span>MSXML2.DOMDocument60\r\n     <span style=\"color:blue;\">Dim <\/span>objP<span style=\"color:blue;\"> As <\/span>MSXML2.IXMLDOMNode\r\n     <span style=\"color:blue;\">Dim <\/span>objPNeu<span style=\"color:blue;\"> As <\/span>MSXML2.IXMLDOMNode\r\n     <span style=\"color:blue;\">Dim <\/span>objChild<span style=\"color:blue;\"> As <\/span>MSXML2.IXMLDOMNode\r\n     strText = \"&lt;html&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & \"&lt;h1&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & \"&lt;p class=\"\"titel\"\"&gt;Bla&lt;\/p&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & \"&lt;\/h1&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & \"&lt;\/html&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> objXML = <span style=\"color:blue;\">New<\/span> DOMDocument60\r\n     <span style=\"color:blue;\">If <\/span>objXML.loadXML(strText) = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> objP = objXML.SelectSingleNode(\"\/\/p[@class='titel']\")\r\n         <span style=\"color:blue;\">Set<\/span> objPNeu = objXML.createElement(\"h2\")\r\n         objP.ParentNode.InsertBefore objPNeu, objP\r\n         For Each objChild In objP.ChildNodes\r\n             objPNeu.appendChild objChild\r\n         <span style=\"color:blue;\">Next<\/span> objChild\r\n         objP.ParentNode.RemoveChild objP\r\n         <span style=\"color:blue;\">Debug.Print<\/span> objXML.XML\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Das Dokument konnte nicht gelesen werden.\"\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 3: Elemente ersetzen per XML-Document Object Model<\/span><\/b><\/p>\n<p>Wir haben ein kleines HTML-Dokument erzeugt, das folgenden Code hat:<\/p>\n<pre>&lt;html&gt;\r\n   &lt;h1&gt;\r\n     &lt;p class=\"titel\"&gt;Bla&lt;\/p&gt;\r\n   &lt;\/h1&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>Wir wollen f&uuml;r das Element mit dem Starttag <b>&lt;p class=&#8220;titel&#8220;&gt; <\/b>den Elementnamen auf <b>h2 <\/b>&auml;ndern und das Attribut <b>class <\/b>entfernen. Dazu laden wir das Dokument zuerst in das <b>DOMDocument<\/b>-Objekt <b>objXML<\/b>. Dann ermitteln wir mit <b>SelectSingleNode <\/b>das Element mit dem Namen <b>p <\/b>und dem Wert <b>titel <\/b>f&uuml;r das Attribut <b>class<\/b>.<\/p>\n<p>Dieses referenzieren wir mit der Variablen <b>objP<\/b>. Dann erstellen wir ein neues Element mit dem Namen <b>h2 <\/b>und referenzieren es mit der Variablen <b>objPNeu<\/b>. Dieses Element ist nun noch frei, also nicht irgendeinem anderen Element des XML-Dokuments untergeordnet. Wenn Sie nun mit der Eigenschaft <b>XML <\/b>den Inhalt von <b>objXML <\/b>ausgeben lassen, erscheint das neue Element noch nicht im Elementbaum.<\/p>\n<p>Deshalb nutzen wir nun die Methode <b>InsertBefore <\/b>des &uuml;bergeordneten Elements von <b>objP<\/b>, das wir &uuml;ber die Eigenschaft <b>ParentNode <\/b>referenzieren. Als ersten Parameter geben wir das neue Objekt an (<b>objPNeu<\/b>), als zweiten das Objekt, zu dem es relativ an der vorherigen Position erscheinen soll (<b>objP<\/b>).<\/p>\n<p>Nun haben wir das neue Objekt <b>objPNeu <\/b>an die Stelle vor dem zu ersetzenden Objekt <b>objP <\/b>verschoben. Wenn wir nun den XML-Code ausgeben, erhalten wir Folgendes:<\/p>\n<pre>&lt;html&gt;\r\n     &lt;h1&gt;\r\n         &lt;h2\/&gt;\r\n         &lt;p class=\"titel\"&gt;Bla&lt;\/p&gt;\r\n     &lt;\/h1&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>Der Inhalt des Elements <b>objP<\/b>, also der Text <b>Bla<\/b>, befindet sich noch an Ort und Stelle, soll aber in das Objekt <b>objPNeu <\/b>verschoben werden. Das erledigen wir, indem wir in einer <b>For Each<\/b>-Schleife alle Elemente durchlaufen, die sich in <b>objP <\/b>befinden. Diese referenzieren wir mit der Eigenschaft <b>ChildNodes<\/b>. Beim Durchlaufen h&auml;ngen wir das mit <b>objChild <\/b>referenzierte Element dann jeweils an <b>objPNeu <\/b>an. Wird der Inhalt dadurch verschoben oder kopiert Das ergibt eine erneute Ausgabe von <b>objXML.XML<\/b>:<\/p>\n<pre>&lt;html&gt;\r\n     &lt;h1&gt;\r\n         &lt;h2&gt;Bla&lt;\/h2&gt;\r\n         &lt;p class=\"titel\"\/&gt;\r\n     &lt;\/h1&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>Hier wird deutlich, dass der Inhalt verschoben wird. Nun m&uuml;ssen wir nur noch das Element aus <b>objP <\/b>l&ouml;schen. Das erledigen wir mit einem Aufruf der Methode <b>RemoveChild <\/b>des &uuml;bergeordneten Elements von <b>objP<\/b>, das wir mit <b>ParentNode <\/b>referenzieren. Das Ergebnis sieht dann folgenderma&szlig;en aus:<\/p>\n<pre>&lt;html&gt;\r\n     &lt;h1&gt;\r\n         &lt;h2&gt;Bla&lt;\/h2&gt;\r\n     &lt;\/h1&gt;\r\n&lt;\/html&gt;<\/pre>\n<p><b>Mehrere Elemente gleichzeitig &auml;ndern<\/b><\/p>\n<p>Nun haben wir nur das erste gefundene Element ge&auml;ndert. Angenommen, das Dokument w&uuml;rde mehrere Elemente mit dem Starttag <b>&lt;p class=&#8220;titel&#8220;&gt; <\/b>enthalten, dann w&uuml;rden wir auch hier eine Schleife ben&ouml;tigen, um alle Elemente zu &auml;ndern.<\/p>\n<p>Diese Schleife verwendet die Variable <b>objP <\/b>als Laufvariable und durchl&auml;uft alle Elemente, die wir mit der Funktion <b>selectNodes <\/b>ermitteln k&ouml;nnen:<\/p>\n<pre>...\r\nFor Each objP In objXML.selectNodes(\"\/\/p[@class='titel']\")\r\n     <span style=\"color:blue;\">Set<\/span> objPNeu = objXML.createElement(\"h2\")\r\n     objP.ParentNode.InsertBefore objPNeu, objP\r\n     For Each objChild In objP.ChildNodes\r\n         objPNeu.appendChild objChild\r\n     <span style=\"color:blue;\">Next<\/span> objChild\r\n     objP.ParentNode.RemoveChild objP\r\n<span style=\"color:blue;\">Next<\/span> objP\r\n...<\/pre>\n<p>Wenn sich nun mehrere der zu ersetzenden Elemente im Dokument befinden, w&uuml;rden diese vollst&auml;ndig ersetzt werden.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>In diesem Beitrag haben wir die Techniken geliefert, mit denen Sie HTML-Dokumente so anpassen k&ouml;nnen, dass diese f&uuml;r Ihre Anforderungen geeignet sind. Das ist zum Beispiel praktisch, wenn Sie die Inhalte eines Content Management Systems in ein anderes &uuml;bertragen wollen.<\/p>\n<p>Der erste Ansatz ist die Verwendung reiner Zeichenkettenfunktionen, der zweite setzt ein valides HTML-Dokument voraus, das wir dann mit den Mitteln der XML-DOM-Bibliothek bearbeitet haben.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>HTMLCodeOptimierenPerVBA.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/56001581-939A-4995-A8BA-196EC784027B\/aiu_1218.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im Beitrag &#8222;Von Access nach Wordpress&#8220; haben wir Routinen entwickelt, mit denen wir den Inhalt eines Textfeldes in SQL-Anweisungen exportiert und damit eine Wordpress-Webseite gef&uuml;llt haben. Der Weg dorthin war nicht so einfach, wie es in diesem Beitrag beschrieben wurde. In der Tag lag der HTML-Code mit den Artikeln so vor, dass er in einem anderen Content Management System, hier Typo3, optimal angezeigt wurde. Wenn wir diesen HTML-Code in das Wordpress-System importiert haben, sah das optisch allerdings nicht so ansprechend aus. Wir mussten also noch einige &Auml;nderungen am HTML-Code vornehmen. F&uuml;r Handarbeit war das bei rund 1.000 Artikel zu viel, also war die Programmierung entsprechender Konvertierungsroutinen angezeigt. Wie das grundlegend funktioniert, zeigen wir im vorliegenden 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":[66012020,662020,44000026],"tags":[],"class_list":["post-55001218","post","type-post","status-publish","format-standard","hentry","category-66012020","category-662020","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>HTML-Code optimieren per VBA - 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\/HTMLCode_optimieren_per_VBA\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"HTML-Code optimieren per VBA\" \/>\n<meta property=\"og:description\" content=\"Im Beitrag &quot;Von Access nach Wordpress&quot; haben wir Routinen entwickelt, mit denen wir den Inhalt eines Textfeldes in SQL-Anweisungen exportiert und damit eine Wordpress-Webseite gef&uuml;llt haben. Der Weg dorthin war nicht so einfach, wie es in diesem Beitrag beschrieben wurde. In der Tag lag der HTML-Code mit den Artikeln so vor, dass er in einem anderen Content Management System, hier Typo3, optimal angezeigt wurde. Wenn wir diesen HTML-Code in das Wordpress-System importiert haben, sah das optisch allerdings nicht so ansprechend aus. Wir mussten also noch einige &Auml;nderungen am HTML-Code vornehmen. F&uuml;r Handarbeit war das bei rund 1.000 Artikel zu viel, also war die Programmierung entsprechender Konvertierungsroutinen angezeigt. Wie das grundlegend funktioniert, zeigen wir im vorliegenden Beitrag.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-07-10T09:39:16+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg06.met.vgwort.de\/na\/f8b250ed91ab40f0a6e92cb5957cf149\" \/>\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=\"18\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"HTML-Code optimieren per VBA\",\"datePublished\":\"2020-07-10T09:39:16+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/\"},\"wordCount\":2865,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/f8b250ed91ab40f0a6e92cb5957cf149\",\"articleSection\":[\"1\\\/2020\",\"2020\",\"Interaktiv\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/\",\"name\":\"HTML-Code optimieren per VBA - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/f8b250ed91ab40f0a6e92cb5957cf149\",\"datePublished\":\"2020-07-10T09:39:16+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/f8b250ed91ab40f0a6e92cb5957cf149\",\"contentUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/f8b250ed91ab40f0a6e92cb5957cf149\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLCode_optimieren_per_VBA\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"HTML-Code optimieren per VBA\"}]},{\"@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":"HTML-Code optimieren per VBA - 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\/HTMLCode_optimieren_per_VBA\/","og_locale":"de_DE","og_type":"article","og_title":"HTML-Code optimieren per VBA","og_description":"Im Beitrag \"Von Access nach Wordpress\" haben wir Routinen entwickelt, mit denen wir den Inhalt eines Textfeldes in SQL-Anweisungen exportiert und damit eine Wordpress-Webseite gef&uuml;llt haben. Der Weg dorthin war nicht so einfach, wie es in diesem Beitrag beschrieben wurde. In der Tag lag der HTML-Code mit den Artikeln so vor, dass er in einem anderen Content Management System, hier Typo3, optimal angezeigt wurde. Wenn wir diesen HTML-Code in das Wordpress-System importiert haben, sah das optisch allerdings nicht so ansprechend aus. Wir mussten also noch einige &Auml;nderungen am HTML-Code vornehmen. F&uuml;r Handarbeit war das bei rund 1.000 Artikel zu viel, also war die Programmierung entsprechender Konvertierungsroutinen angezeigt. Wie das grundlegend funktioniert, zeigen wir im vorliegenden Beitrag.","og_url":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-07-10T09:39:16+00:00","og_image":[{"url":"http:\/\/vg06.met.vgwort.de\/na\/f8b250ed91ab40f0a6e92cb5957cf149","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"18\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"HTML-Code optimieren per VBA","datePublished":"2020-07-10T09:39:16+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/"},"wordCount":2865,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/f8b250ed91ab40f0a6e92cb5957cf149","articleSection":["1\/2020","2020","Interaktiv"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/","url":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/","name":"HTML-Code optimieren per VBA - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/f8b250ed91ab40f0a6e92cb5957cf149","datePublished":"2020-07-10T09:39:16+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/#primaryimage","url":"http:\/\/vg06.met.vgwort.de\/na\/f8b250ed91ab40f0a6e92cb5957cf149","contentUrl":"http:\/\/vg06.met.vgwort.de\/na\/f8b250ed91ab40f0a6e92cb5957cf149"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/HTMLCode_optimieren_per_VBA\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"HTML-Code optimieren per VBA"}]},{"@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\/55001218","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=55001218"}],"version-history":[{"count":1,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001218\/revisions"}],"predecessor-version":[{"id":77001517,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001218\/revisions\/77001517"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001218"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001218"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001218"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}