{"id":55001161,"date":"2018-12-01T00:00:00","date_gmt":"2020-05-13T21:12:55","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1161"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"HTMLKreuztabelle_1_Basics","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/","title":{"rendered":"HTML-Kreuztabelle 1: Basics"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg06.met.vgwort.de\/na\/69a682a177e44d7f914a4cac72589231\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Kreuztabellenabfragen sind eine praktische Sache, wenn es darum geht, Kombinationen aus m:n-Beziehungen abzubilden &#8211; zum Beispiel die Preise f&uuml;r verschiedene Bauelemente oder Materialien in Abh&auml;ngigkeit von der H&ouml;he und der Breite des Materials. Dabei ben&ouml;tigen Sie noch nicht einmal eine m:n-Beziehung, die in einer Kreuztabelle darzustellenden Daten k&ouml;nnen auch aus einer einzigen Tabelle stammen. Der Haken an Kreuztabellen ist, dass diese in der Regel nicht bearbeitet werden k&ouml;nnen. Wenn Sie also etwa den Preis f&uuml;r ein Bauelement mit einer H&ouml;he von einem Meter und einer Breite von 50 Zentimetern einstellen wollen, m&uuml;ssen Sie wieder die zugrunde liegende Tabelle oder das darauf aufbauende Formular bem&uuml;hen. Im vorliegenden Beitrag wollen wir zun&auml;chst einmal die Grundlage f&uuml;r die Bearbeitung schaffen &#8211; indem wir die Daten der Tabelle per HTML in Kreuztabellenform darstellen.<\/b><\/p>\n<h2>Basistabelle<\/h2>\n<p>Als Basistabelle verwenden wir die Tabelle <b>tblMaterialpreise<\/b>. Diese enth&auml;lt die Felder <b>MaterialpreisID<\/b>, <b>Breite<\/b>, <b>Hoehe <\/b>und <b>Preis<\/b>. Die Datentypen k&ouml;nnen Sie dem Tabellenentwurf aus Bild 1 entnehmen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_06\/pic_1161_001.png\" alt=\"Entwurf der Tabelle tblMaterialpreise\" width=\"649,559\" height=\"355,8094\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Entwurf der Tabelle tblMaterialpreise<\/span><\/b><\/p>\n<p>Hier sehen Sie auch, dass wir f&uuml;r die beiden Felder <b>Hoehe <\/b>und <b>Breite <\/b>einen zusammengesetzten, eindeutigen Index definiert haben. Damit stellen wir sicher, dass f&uuml;r jede Kombination aus H&ouml;he und Breite nur ein Preis festgelegt werden kann &#8211; mehr k&ouml;nnen wir in der Kreuztabelle nicht darstellen.<\/p>\n<h2>Daten in Kreuztabellenform ausgeben<\/h2>\n<p>Die Daten sollen nun so ausgegeben werden, dass die Spalten&uuml;berschriften die H&ouml;he, die Zeilen&uuml;berschriften die Breite und die Zellen selbst den jeweiligen Preis f&uuml;r die Kombination aus H&ouml;he und Breite anzeigen. Dazu f&uuml;gen wir der Tabelle erst einmal ein paar Datens&auml;tze zum Spielen hinzu. Die gef&uuml;llte Tabelle sieht dann wie in Bild 2 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_06\/pic_1161_002.png\" alt=\"Beispieldaten in der Tabelle tblMaterialpreise\" width=\"424,7115\" height=\"268,1907\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Beispieldaten in der Tabelle tblMaterialpreise<\/span><\/b><\/p>\n<p>Danach wollen wir zuerst einmal die Daten in Kreuztabellenform im Direktbereich des VBA-Editors ausgeben. Erst nachdem wir den grundlegenden Ablauf programmiert haben, nehmen wir die Darstellung in einer HTML-Tabelle hinzu.<\/p>\n<p>Die Ausgabe im Direktbereich soll durch die Prozedur <b>Kreuztabelle <\/b>erfolgen (siehe Listing 1). Diese definiert eine Variable f&uuml;r das aktuelle Datenbankobjekt (<b>db<\/b>) sowie drei <b>Recordset<\/b>-Variablen. Das Recordset <b>rstSpaltenkoepfe <\/b>nimmt alle Werte des Feldes <b>Hoehe <\/b>der Tabelle <b>tblMaterialpreise <\/b>auf. Damit jeder Wert nur einmal vorkommt, f&uuml;gen wir neben <b>SELECT <\/b>als zweites Schl&uuml;sselwort noch <b>DISTINCT<\/b> hinzu. Auf diese Weise liefert das Recordset jeden Wert des Feldes <b>Hoehe <\/b>nur einmal, hier <b>800<\/b>, <b>900 <\/b>und <b>1.000<\/b>. Au&szlig;erdem sortieren wir die Werte nach der Gr&ouml;&szlig;e. Damit k&ouml;nnen wir schon einmal die Spalten&uuml;berschriften in den Direktbereich schreiben. Hier beginnen wir mit einer leeren Spalte, was wir durch die Ausgabe einer leeren Zeichenkette plus dem Komma-Zeichen (<b>,<\/b>) stellvertretend f&uuml;r einen Tabulator-Schritt erledigen. Dann durchlaufen wir in einer <b>Do While<\/b>-Schleife alle Datens&auml;tze des Recordsets <b>rstSpaltenkoepfe <\/b>und geben nacheinander alle Werte in einer Zeile aus. Damit <b>Debug.Print <\/b>nach der Ausgabe eines Wertes nicht in die n&auml;chste Zeile springt, h&auml;ngen wir auch hier jeweils das Komma an. Dadurch wird auch hier ein Tabulator eingef&uuml;gt statt des &uuml;blichen Zeilenumbruchs. Damit w&auml;re die Zeile mit den Spaltenk&ouml;pfen bereits geschafft. Das Ergebnis sieht bisher so aus:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Kreuztabelle()\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>rstSpaltenkoepfe<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>rstZeilen<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>rstWerte<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     <span style=\"color:blue;\">Set<\/span> rstSpaltenkoepfe = db.OpenRecordset(\"SELECT DISTINCT Hoehe FROM tblMaterialpreise ORDER BY Hoehe\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> ,\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstSpaltenkoepfe.EOF\r\n         <span style=\"color:blue;\">Debug.Print<\/span> rstSpaltenkoepfe!Hoehe,\r\n         rstSpaltenkoepfe.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     <span style=\"color:blue;\">Debug.Print<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> rstZeilen = db.OpenRecordset(\"SELECT DISTINCT Breite FROM tblMaterialpreise ORDER BY Breite\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstZeilen.EOF\r\n         <span style=\"color:blue;\">Debug.Print<\/span> rstZeilen!Breite,\r\n         <span style=\"color:blue;\">Set<\/span> rstWerte = db.OpenRecordset(\"SELECT Preis FROM tblMaterialpreise WHERE Breite = \" & rstZeilen!Breite _\r\n             & \" ORDER BY Hoehe\", dbOpenDynaset)\r\n         <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstWerte.EOF\r\n             <span style=\"color:blue;\">Debug.Print<\/span> rstWerte!Preis,\r\n             rstWerte.Move<span style=\"color:blue;\">Next<\/span>\r\n         <span style=\"color:blue;\">Loop<\/span>\r\n         <span style=\"color:blue;\">Debug.Print<\/span>\r\n         rstZeilen.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Ausgabe der Spaltenk&ouml;pfe, Zeilenk&ouml;pfe und Preise im Direktbereich<\/span><\/b><\/p>\n<pre>               800           900           1000         <\/pre>\n<p>Damit wir danach mit der ersten Zeile mit Daten fortfahren k&ouml;nnen, folgt nun der Aufruf der <b>Debug.Print<\/b>-Anweisung ohne Parameter. Damit springen wir direkt in die n&auml;chste Zeile. Das zweite Recordset namens <b>rstZeilen <\/b>f&uuml;llen wir mit allen Eintr&auml;gen des Feldes <b>Breite <\/b>der Tabelle <b>tblMaterialpreise<\/b>, diesmal aufsteigend sortiert nach dem Feld <b>Breite<\/b>. Auch hier verwenden wir das <b>DISTINCT<\/b>-Schl&uuml;sselwort, damit jede Breite nur einmal aufgenommen wird. Dieses Recordset enth&auml;lt nun also jeweils einen Datensatz f&uuml;r jede Breite, hier <b>800<\/b>, <b>900 <\/b>und <b>1.000<\/b>.<\/p>\n<p>Dieses Recordset durchlaufen wir nun in der n&auml;chsten <b>Do While<\/b>-Schleife und wollen in jedem Durchlauf eine komplette Zeile mit dem Zeilenkopf und den Werten f&uuml;r die Kombination aus Spaltenkopf und Zeilenkopf in den Direktbereich schreiben. Den Zeilenkopf geben wir schon einmal per <b>Debug.Print <\/b>aus, wobei wir dieser als Parameter den Wert <b>rstZeilen!Breite <\/b>plus einem Komma f&uuml;r einen Sprung zur n&auml;chsten Tabulatorposition statt in die n&auml;chste Zeile.<\/p>\n<p>Au&szlig;erdem brauchen wir f&uuml;r jede Zeile noch ein weiteres Recordset, das die Werte f&uuml;r die aktuelle Zeile und die jeweilige Spalte abruft. Dieses hei&szlig;t <b>rstWerte <\/b>und enth&auml;lt alle Werte des Feldes <b>Preis <\/b>der Tabelle <b>tblMaterialpreise<\/b>, deren Feld <b>Breite <\/b>den Wert des aktuellen Spaltenkopfes enth&auml;lt &#8211; wieder sortiert nach dem Feld <b>Hoehe<\/b>.<\/p>\n<p>Auch diese Werte durchlaufen wir in einer <b>Do While<\/b>-Schleife und geben in dieser jeweils den Inhalt des Feldes Preis aus &#8211; gefolgt von einem Komma, damit kein Zeilen-umbruch, sondern ein Sprung an die n&auml;chste Tabulator-Stelle erfolgt. Das Ergebnis nach dem Durchlaufen sieht dann wie folgt aus:<\/p>\n<pre>              800           900           1000         \r\n  800           64            72            80           \r\n  900           72            81            90           \r\n  1000          80            90            100   <\/pre>\n<p>Gar nicht schlecht f&uuml;r den Start! Allerdings enth&auml;lt diese Vorgehensweise eine kleine Schwachstelle. Wir erg&auml;nzen die Tabelle <b>tblMaterialpreise <\/b>wie in Bild 3. Wie Sie sehen, haben wir mit <b>700 <\/b>eine neue H&ouml;he eingef&uuml;hrt, aber nur Werte f&uuml;r die Breiten <b>800 <\/b>und <b>1.000 <\/b>angegeben &#8211; die Kombination aus <b>700 <\/b>und <b>900 <\/b>fehlt. Das Ergebnis im Direktfenster sieht dann wie in Bild 4 aus. Der Preis f&uuml;r die Kombination <b>700 <\/b>und <b>900 <\/b>wird einfach weggelassen und die &uuml;brigen Kombinationen f&uuml;r die H&ouml;he von 700 mm werden einfach nach links verschoben.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_06\/pic_1161_003.png\" alt=\"Erweiterte Beispieldaten in der Tabelle tblMaterialpreise\" width=\"424,7115\" height=\"302,0578\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Erweiterte Beispieldaten in der Tabelle tblMaterialpreise<\/span><\/b><\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_06\/pic_1161_004.png\" alt=\"Ausgabe der neuen Beispieldaten\" width=\"549,6265\" height=\"151,0499\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Ausgabe der neuen Beispieldaten<\/span><\/b><\/p>\n<h2>Alle Kombinationen ohne Ausnahme ausgeben<\/h2>\n<p>Wie bekommen wir es also hin, dass alle Kombinationen ber&uuml;cksichtigt werden, auch wenn ein Wert nicht angegeben ist &#8211; in der Form, dass die entsprechende Stelle einfach frei gelassen wird<\/p>\n<p>Dazu m&uuml;ssen wir eine kleine Erg&auml;nzung vornehmen, und zwar innerhalb der zweiten <b>Do While<\/b>-Schleife (siehe Listing 2). In dieser f&uuml;gen wie zun&auml;chst eine Anweisung ein, welche den Datensatzzeiger des Recordsets, das wir zum Einf&uuml;gen der Spaltenk&ouml;pfe verwendet haben, f&uuml;r jeden Datensatz des Recordsets <b>rstZeilen<\/b> auf den ersten Datensatz zur&uuml;cksetzt (<b>MoveFirst<\/b>). Warum das Weil wir sicherstellen wollen, dass die Markierung im Direktfenster f&uuml;r jeden Spaltenkopf in jeder Zeile auch um eine Tabulatorposition vorr&uuml;ckt &#8211; unabh&auml;ngig davon, ob es auch einen Wert f&uuml;r die Kombination aus den im Spalten- und Zeilenkopf angezeigten Werten gibt. Innerhalb der inneren <b>Do While<\/b>-Schleife, in der wir bisher einfach nur die Werte des Feldes <b>Preis <\/b>in den Direktbereich geschrieben haben, f&uuml;gen wir nun eine <b>If&#8230;Then<\/b>-Bedingung ein, die pr&uuml;ft, ob der Wert des Feldes <b>Hoehe <\/b>des Recordsets <b>rstSpaltenkoepfe <\/b>mit dem des Recordsets <b>rstWerte <\/b>&uuml;bereinstimmt. Ist dies der Fall, wird der Inhalt des Feldes <b>Preis <\/b>ausgeben und wir gehen mit der <b>MoveNext<\/b>-Methode einen Schritt weiter im Recordset <b>rstWerte<\/b>. Falls nicht, geben wir nur einen Tabulatorschritt im Direktfenster aus. In beiden F&auml;llen bewegen wir den Datensatzzeiger des Recordsets <b>rstSpaltenkoepfe <\/b>um eine Position weiter. Auf diese Weise geben wir f&uuml;r Kombinationen, f&uuml;r die es keinen Preis gibt, einen Tabulatorsprung im Direktbereich aus. Das Ergebnis sieht nun wie in Bild 5 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_06\/pic_1161_005.png\" alt=\"Ausgabe der neuen Beispieldaten mit Leerstellen\" width=\"549,6265\" height=\"151,0499\"\/><\/p>\n<p><!--30percent--><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Ausgabe der neuen Beispieldaten mit Leerstellen<\/span><\/b><\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Kreuztabelle()\r\n     ''''... wie in der ersten Fassung\r\n     <span style=\"color:blue;\">Set<\/span> rstZeilen = db.OpenRecordset(\"SELECT DISTINCT Breite FROM tblMaterialpreise ORDER BY Breite\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstZeilen.EOF\r\n         rstSpaltenkoepfe.MoveFirst\r\n         <span style=\"color:blue;\">Debug.Print<\/span> rstZeilen!Breite,\r\n         <span style=\"color:blue;\">Set<\/span> rstWerte = db.OpenRecordset(\"SELECT Preis, Hoehe FROM tblMaterialpreise WHERE Breite = \" _\r\n             & rstZeilen!Breite & \" ORDER BY Hoehe\", dbOpenDynaset)\r\n         <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstWerte.EOF\r\n             <span style=\"color:blue;\">If <\/span>rstSpaltenkoepfe!Hoehe = rstWerte!Hoehe<span style=\"color:blue;\"> Then<\/span>\r\n                 <span style=\"color:blue;\">Debug.Print<\/span> rstWerte!Preis,\r\n                 rstWerte.Move<span style=\"color:blue;\">Next<\/span>\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 <span style=\"color:blue;\">Debug.Print<\/span> ,\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             rstSpaltenkoepfe.Move<span style=\"color:blue;\">Next<\/span>\r\n         <span style=\"color:blue;\">Loop<\/span>\r\n         <span style=\"color:blue;\">Debug.Print<\/span>\r\n         rstZeilen.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Ausgabe der Spaltenk&ouml;pfe, Zeilenk&ouml;pfe und Preise im Direktbereich auch mit leeren Kombinationen<\/span><\/b><\/p>\n<p>Damit k&ouml;nnen wir die grundlegende Ausgabe als erledigt betrachten und uns der ersten Erweiterung zuwenden &#8211; der Ausgabe im HTML-Format im Webbrowser-Steuerelement von Access.<\/p>\n<h2>Webbrowser-Steuerelement anlegen<\/h2>\n<p>Dazu legen wir ein neues Formular namens <b>frmKreuztabelleHTML <\/b>an und f&uuml;gen diesem ein <b>Webbrowser<\/b>-Steuerelement aus der Toolbox hinzu. Danach stellen sie noch seine Eigenschaften <b>Horizontaler Anker <\/b>und <b>Vertikaler Anker <\/b>auf den Wert <b>Beide <\/b>ein, damit sich die Gr&ouml;&szlig;e des Webbrowser-Steuerelements beim Ver&auml;ndern der Gr&ouml;&szlig;e des Formulars an dieses anpasst (siehe Bild 6).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_06\/pic_1161_006.png\" alt=\"Hinzuf&uuml;gen des Webbrowser-Steuerelements\" width=\"549,6265\" height=\"415,9846\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Hinzuf&uuml;gen des Webbrowser-Steuerelements<\/span><\/b><\/p>\n<p>Dann wollen wir zun&auml;chst daf&uuml;r sorgen, dass beim &ouml;ffnen des Formulars eine leere Webseite erscheint. Dazu f&uuml;gen wir dem VBA-Projekt der Anwendung zun&auml;chst einen Verweis auf die Bibliothek <b>Microsoft HTML Object Library<\/b> hinzu &#8211; und zwar &uuml;ber den Dialog, den Sie mit dem Men&uuml;befehl <b>Extras|Verweise <\/b>&ouml;ffnen (siehe Bild 7). Danach legen wir eine neue Ereignisprozedur f&uuml;r das Ereignis <b>Beim &ouml;ffnen <\/b>des Formulars an. Die dort verwenden Variablen deklarieren wir im allgemeinen Teil des Klassenmoduls des Formulars:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_06\/pic_1161_007.png\" alt=\"Verweis auf die Bibliothek Microsoft HTML Object Library\" width=\"424,7115\" height=\"334,8159\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Verweis auf die Bibliothek Microsoft HTML Object Library<\/span><\/b><\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>WithEvents objWebbrowser<span style=\"color:blue;\"> As <\/span>WebBrowser\r\n<span style=\"color:blue;\">Dim <\/span>objDocument<span style=\"color:blue;\"> As <\/span>HTMLDocument<\/pre>\n<p>Die erste Variable nimmt einen Verweis auf das Web-browser-Steuerelement auf, die zweite einen auf das darin angezeigte Dokument. Die Variablen f&uuml;llen wir mit der Ereignisprozedur <b>Form_Open<\/b>, die wir wie folgt erweitern:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Open(Cancel<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Set<\/span> objWebbrowser = Me!ctlWebbrowser.Object\r\n     Me.TimerInterval = 300\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Prozedur weist zuerst der Variablen <b>objWebbrowser <\/b>den Verweis auf das Webbrowser-Steuerelement zu. Wir k&ouml;nnten nun direkt mit der <b>Navigate<\/b>-Methode den Wert <b>about:blank <\/b>als Zielseite einstellen. Allerdings f&uuml;hrt das manchmal zu Problem. Abhilfe schafft dann das verz&ouml;gerte Laden dieser Seite, also aktivieren wir hier den Timer f&uuml;r das Formular, indem wir die Eigenschaft <b>TimerInterval <\/b>auf den Wert <b>300 <\/b>einstellen (das entspricht 300 Millisekunden).<\/p>\n<p>Erst in der f&uuml;r das Ereignis <b>Bei Zeitgeber <\/b>angegebenen Ereignisprozedur navigiert sie mit der <b>Navigate<\/b>-Methode zu einer leeren Seite namens <b>about:blank<\/b>. Au&szlig;erdem setzen wir noch die Variable <b>objDocument <\/b>auf das im Webbrowser angezeigte Dokument. Schlie&szlig;lich setzen wir <b>Me.TimerInterval <\/b>auf den Wert <b>0<\/b>, damit der Zeitgeber deaktiviert wird.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Timer()\r\n     objWebbrowser.Navigate \"about:blank\"\r\n     <span style=\"color:blue;\">Set<\/span> objDocument = objWebbrowser.Document\r\n     Me.TimerInterval = 0\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Damit erhalten wir nach dem &ouml;ffnen des Formulars das Bild aus Bild 8.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_06\/pic_1161_008.png\" alt=\"Leeres Webbrowser-Steuerelement\" width=\"424,7115\" height=\"243,5716\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Leeres Webbrowser-Steuerelement<\/span><\/b><\/p>\n<h2>F&uuml;llen mit HTML-Kreuztabelle<\/h2>\n<p>Nun wollen wir die Ausgabe, die wir bereits in den Direktbereich vorgenommen haben, an den Browser schicken. Dazu bedarf es noch einiger Erweiterungen, n&auml;mlich in Form von HTML-Tags. Dabei wollen wir gar nicht erst damit anfangen, HTML in Form einer Zeichenkette zusammenzustellen und dann dem Dokument als Inhalt zuzuweisen. Wir wollen gleich auf der Objekt-Ebene arbeiten und damit die Grundlage schaffen, sp&auml;ter auf Ereignisse der Elemente reagieren zu k&ouml;nnen. Daf&uuml;r ist zwar noch ein weiterer Schritt n&ouml;tig, aber die nachfolgend beschriebene Prozedur zeigt, wie Sie ein HTML-Dokument auf Basis von HTML-Objekten aufbauen. Hier kommt nun auch der Verweis auf die Bibliothek <b>Microsoft HTML Object Library<\/b> zum Tragen, den wir bereits weiter oben angelegt haben. Die neue Funktion <b>KreuztabelleErstellen <\/b>rufen wir von der Ereignisprozedur <b>Form_Timer <\/b>auf, die wir wie folgt erg&auml;nzen:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Timer()\r\n     objWebbrowser.Navigate \"about:blank\"\r\n     <span style=\"color:blue;\">Set<\/span> objDocument = objWebbrowser.Document\r\n     Me.TimerInterval = 0\r\n     DoEvents\r\n     KreuztabelleErstellen\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Prozedur aus Listing 3 verwendet einige neue Variablen, welche die Verweise auf die erstellten Objekt wie die HTML-Tabelle, die Zeile und die Zelle aufnehmen:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>KreuztabelleErstellen()\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>rstSpaltenkoepfe<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>rstZeilen<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>rstWerte<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>objTable<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTable\r\n     <span style=\"color:blue;\">Dim <\/span>objRow<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableRow\r\n     <span style=\"color:blue;\">Dim <\/span>objCell<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableCell\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     <span style=\"color:blue;\">Set<\/span> objTable = objDocument.createElement(\"Table\")\r\n     objDocument.body.appendChild objTable\r\n     <span style=\"color:blue;\">Set<\/span> rstSpaltenkoepfe = db.OpenRecordset(\"SELECT DISTINCT Hoehe FROM tblMaterialpreise ORDER BY Hoehe\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Set<\/span> objRow = objTable.insertRow\r\n     <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstSpaltenkoepfe.EOF\r\n         <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n         objCell.innerText = rstSpaltenkoepfe!Hoehe\r\n         rstSpaltenkoepfe.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> rstZeilen = db.OpenRecordset(\"SELECT DISTINCT Breite FROM tblMaterialpreise ORDER BY Breite\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstZeilen.EOF\r\n         <span style=\"color:blue;\">Set<\/span> objRow = objTable.insertRow\r\n         rstSpaltenkoepfe.MoveFirst\r\n         <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n         objCell.innerText = rstZeilen!Breite\r\n         <span style=\"color:blue;\">Set<\/span> rstWerte = db.OpenRecordset(\"SELECT Preis, Hoehe FROM tblMaterialpreise WHERE Breite = \" _\r\n             & rstZeilen!Breite & \" ORDER BY Hoehe\", dbOpenDynaset)\r\n         <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstWerte.EOF\r\n             <span style=\"color:blue;\">If <\/span>rstSpaltenkoepfe!Hoehe = rstWerte!Hoehe<span style=\"color:blue;\"> Then<\/span>\r\n                 <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n                 objCell.innerText = rstWerte!Preis\r\n                 rstWerte.Move<span style=\"color:blue;\">Next<\/span>\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             rstSpaltenkoepfe.Move<span style=\"color:blue;\">Next<\/span>\r\n         <span style=\"color:blue;\">Loop<\/span>\r\n         rstZeilen.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Ausgabe der Spaltenk&ouml;pfe, Zeilenk&ouml;pfe und Preise als HTML-Objekte<\/span><\/b><\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>objTable<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTable\r\n<span style=\"color:blue;\">Dim <\/span>objRow<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableRow\r\n<span style=\"color:blue;\">Dim <\/span>objCell<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableCell<\/pre>\n<p>Nach dem obligatorischen Erstellen des Verweises auf die aktuelle Datenbank erstellen wir mit der <b>createElement<\/b>-Methode des Objekts <b>objDocument <\/b>ein neues <b>Table<\/b>-Element. Dieses schwebt noch im luftleeren Raum, daher m&uuml;ssen wir es noch dem <b>body<\/b>-Element des Dokuments hinzuf&uuml;gen, und zwar als Parameter der <b>appendChild<\/b>-Methode. Danach legen wir eine neue Zeile an (die erste) und eine neue Zelle (ebenfalls die erste, n&auml;mlich die, welche oben links die Spalten- und die Zellen&uuml;berschriften kreuzt). Dazu nutzen wir die <b>insertRow<\/b>-Methode des <b>objTable<\/b>-Objekts, deren Ergebnis wir in der Variablen <b>objRow <\/b>speichern. Die neue Zelle f&uuml;gen wir dann dem <b>objRow<\/b>-Objekt &uuml;ber seine Methode <b>insertCell <\/b>hinzu und referenzieren es mit der Variablen <b>objCell<\/b>.<\/p>\n<p>Danach f&uuml;gen wir die Spalten&uuml;berschriften ein, und zwar in der gleichen <b>Do While<\/b>-Schleife wie in der vorherigen Prozedur. Hier kommt dann in jedem Durchlauf die <b>insertCell<\/b>-Methode zum Einsatz, die jeweils eine neue Zelle hinzuf&uuml;gt. Diese sollen aber nicht mehr leer sein, sondern die Spalten&uuml;berschrift anzeigen. Dazu weisen wir der Eigenschaft <b>innerText <\/b>des jeweils neu hinzugef&uuml;gten Objekts den Namen der Spalte zu, in dem Fall entnommen aus dem Feld <b>Hoehe <\/b>des Recordsets <b>rstSpaltenkoepfe<\/b>. Danach folgt die verschachtelte <b>Do While<\/b>-Schleife, in der wir die weiteren Zeilen und Zellen zum HTML-Dokument hinzuf&uuml;gen. Hier kommen wieder die beiden Methoden <b>insertRow <\/b>und <b>insertCell <\/b>zum Einsatz. Der Aufbau der beiden <b>Do While<\/b>-Schleifen entspricht dem im vorherigen Beispiel. Wir legen also immer erst eine neue Zeile an und f&uuml;gen dann die Zellen zu dieser Zeile hinzu. Daraus entsteht dann die Kreuztabelle aus Bild 9. Die Ansicht ist nat&uuml;rlich noch nicht besonders h&uuml;bsch, also f&uuml;gen wir noch ein paar Formatierungen hinzu.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_06\/pic_1161_009.png\" alt=\"Kreuztabelle im Webbrowser-Steuerelement\" width=\"424,7115\" height=\"207,1301\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 9: Kreuztabelle im Webbrowser-Steuerelement<\/span><\/b><\/p>\n<h2>CSS-Formatierungen hinzuf&uuml;gen<\/h2>\n<p>Um Formatierungen mit CSS hinzuzuf&uuml;gen, ben&ouml;tigen wir zwei Dinge: Eine Datei oder einen String mit den CSS-Formatierungen und Auszeichnungen der zu formatierenden Elemente, die dann in den CSS-Formatierungen referenziert werden. Bei diesen Auszeichnungen kann es sich ganz allgemein um die Elementnamen handeln, also etwa <b>TABLE<\/b>, <b>TR <\/b>oder <b>TD<\/b>. Es kann aber auch eine spezielle Auszeichnung sein, die durch die Eigenschaft <b>className <\/b>f&uuml;r das jeweilige Element festgelegt wird. Im Folgenden haben wir die Prozedur <b>KreuztabelleErstellen <\/b>entsprechend angepasst. Die ersten Zeilen deklarieren und erstellen ein Objekt, das die CSS-Definitionen aufnehmen wird. Dieses legen wir mit der Methode <b>createStyleSheet <\/b>als neues Objekt an. Dann weisen wir seiner Eigenschaft <b>cssText <\/b>den Wert der Funktion <b>CSS <\/b>zu:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>KreuztabelleErstellen()\r\n     ...\r\n     <span style=\"color:blue;\">Dim <\/span>objCSS<span style=\"color:blue;\"> As Object<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> objCSS = objDocument.createStyleSheet(\"\")\r\n     objCSS.cssText = CSS\r\n     ...<\/pre>\n<p>F&uuml;r das <b>Table<\/b>-Element, das eine eigene CSS-Auszeichnung enthalten wird, die alle grundlegenden Definitionen enth&auml;lt, brauchen wir nichts weiter zu tun:<\/p>\n<pre>     <span style=\"color:blue;\">Set<\/span> objTable = objDocument.createElement(\"Table\")\r\n     ...<\/pre>\n<p>Das <b>Cell<\/b>-Objekt oben links statten wir mit den beiden Klassen <b>columnHeader <\/b>und <b>rowHeader <\/b>aus:<\/p>\n<pre>     <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n     objCell.className = \"columnHeader rowHeader\"<\/pre>\n<p>Dadurch soll es sp&auml;ter die Eigenschaften &uuml;bernehmen, die wir f&uuml;r diese beiden Klassen festlegen. Im Wesentlichen wird das ein Rahmen links (<b>columnHeader<\/b>) und ein Rahmen oben (<b>rowHeader<\/b>) sein. Die &uuml;brigen Elemente, die als Spaltenk&ouml;pfe dienen, definieren wir mit der Klasse <b>columnHeader<\/b>:<\/p>\n<pre>     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstSpaltenkoepfe.EOF\r\n         <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n         objCell.className = \"columnHeader\"\r\n         ...\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     ...<\/pre>\n<p>Schlie&szlig;lich fehlen noch die Zeilenk&ouml;pfe, die wir als <b>rowHeader <\/b>markieren:<\/p>\n<pre>     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstZeilen.EOF\r\n         ...\r\n         <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n         objCell.className = \"rowHeader\"\r\n         ...\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Der resultierende HTML-Code<\/h2>\n<p>Der HTML-Code sieht f&uuml;r unsere Beispieldaten nun wie folgt aus &#8211; hier k&ouml;nnen Sie erkennen, welche Elemente welchen Elementtyp aufweisen und mit welcher Klasse diese versehen sind:<\/p>\n<pre>&lt;table&gt;\r\n   &lt;tbody&gt;\r\n     &lt;tr&gt;\r\n       &lt;td class=\"header rowheader\"&gt;&lt;\/td&gt;\r\n       &lt;td class=\"header\"&gt;700&lt;\/td&gt;\r\n       ...\r\n     &lt;\/tr&gt;\r\n     &lt;tr&gt;\r\n       &lt;td class=\"rowheader\"&gt;800&lt;\/td&gt;\r\n       &lt;td&gt;56&lt;\/td&gt;\r\n       ...\r\n     &lt;\/tr&gt;\r\n     ...\r\n   &lt;\/tbody&gt;\r\n&lt;\/table&gt;<\/pre>\n<h2>Die CSS-Definition<\/h2>\n<p>Die CSS-Definition stellen wir in einer eigenen String-Funktion zusammen, die wir <b>CSS <\/b>nennen. Sie sieht wie folgt aus und definiert zun&auml;chst die Eigenschaften, die tabellenweit gelten sollen &#8211; dementsprechend legen wir diese f&uuml;r das Element <b>table <\/b>fest. Hier definieren wir die Schriftart (<b>Calibri<\/b>), die Textausrichtung (<b>center<\/b>) sowie die Breite der Tabelle gemessen an der HTML-Seite (<b>100%<\/b>, also Ausdehnung &uuml;ber den gesamten Browser) und legen fest, dass Rahmen von zwei benachbarten Elementen zusammengefasst werden sollen (<b>border-collapse: collapse<\/b>):<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>CSS()\r\n     <span style=\"color:blue;\">Dim <\/span>strCSS<span style=\"color:blue;\"> As String<\/span>\r\n     strCSS = strCSS & \"table {\"\r\n     strCSS = strCSS & \"  font-family: Calibri;\"\r\n     strCSS = strCSS & \"  text-align: center;\"\r\n     strCSS = strCSS & \"  width: 100%;\"\r\n     strCSS = strCSS & \"  border-collapse: collapse;\"\r\n     strCSS = strCSS & \"}\"<\/pre>\n<p>Danach geht es weiter mit der Klasse <b>columnHeader <\/b>f&uuml;r die <b>td<\/b>-Elemente. Diese legt fest, dass der enthaltene Text fett ausgegeben werden soll (<b>font-weight: bold<\/b>) und dass der untere Rand der Zelle mit einer Linie der Breite <b>1px <\/b>versehen werden soll &#8211; diese soll durchgezogen sein (<b>solid<\/b>) und die Farbe schwarz haben (<b>black<\/b>):<\/p>\n<pre>     strCSS = strCSS & \"td.columnHeader {\"\r\n     strCSS = strCSS & \"  font-weight: bold;\"\r\n     strCSS = strCSS & \"  border-bottom: 1px solid black;\"\r\n     strCSS = strCSS & \"}\"<\/pre>\n<p>Auf &auml;hnliche Weise definieren wir die Klasse <b>td.rowHeader<\/b>. Der Unterschied ist, dass es hier eine Rahmenlinie am rechten Rand geben soll:<\/p>\n<pre>     strCSS = strCSS & \"td.rowHeader {\"\r\n     strCSS = strCSS & \"  font-weight: bold;\"\r\n     strCSS = strCSS & \"  border-right: 1px solid black;\"\r\n     strCSS = strCSS & \"}\"\r\n     CSS = strCSS\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>Nach dem erneuten Aufruf des Formulars sieht die HTML-Tabelle nun wie in Bild 10 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_06\/pic_1161_010.png\" alt=\"Kreuztabelle mit CSS-Formatierung\" width=\"424,7115\" height=\"171,0248\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 10: Kreuztabelle mit CSS-Formatierung<\/span><\/b><\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Damit ist die erste Version zur Ausgabe einer Kreuztabelle per HTML fertig. Neue Datens&auml;tze werden beim n&auml;chsten Aufruf wie in Bild 11 angezeigt. Im Beitrag <b>HTML-Kreuztabelle 2: Werte bearbeiten <\/b>(<b>www.access-im-unternehmen.de\/1162<\/b>) zeigen wir, wie Sie die Daten direkt in der Kreuztabelle editieren k&ouml;nnen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_06\/pic_1161_011.png\" alt=\"Kreuztabelle mit neuem Wert\" width=\"424,7115\" height=\"171,0248\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 11: Kreuztabelle mit neuem Wert<\/span><\/b><\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>AenderbareKreuztabellePerHTML.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/20713944-367C-4160-916F-2C1EE3B4A328\/aiu_1161.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Kreuztabellenabfragen sind eine praktische Sache, wenn es darum geht, Kombinationen aus m:n-Beziehungen abzubilden &#8211; zum Beispiel die Preise f&uuml;r verschiedene Bauelemente oder Materialien in Abh&auml;ngigkeit von der H&ouml;he und der Breite des Materials. Dabei ben&ouml;tigen Sie noch nicht einmal eine m:n-Beziehung, die in einer Kreuztabelle darzustellenden Daten k&ouml;nnen auch aus einer einzigen Tabelle stammen. Der Haken an Kreuztabellen ist, dass diese in der Regel nicht bearbeitet werden k&ouml;nnen. Wenn Sie also etwa den Preis f&uuml;r ein Bauelement mit einer H&ouml;he von einem Meter und einer Breite von f&uuml;nfzig Zentimetern einstellen wollen, m&uuml;ssen Sie wieder die zugrunde liegende Tabelle oder das darauf aufbauende Formular bem&uuml;hen. Im vorliegenden Beitrag wollen wir zun&auml;chst einmal die Grundlage f&uuml;r die Bearbeitung schaffen &#8211; indem wir die Daten der Tabelle per HTML in Kreuztabellenform darstellen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662018,66062018,44000023],"tags":[],"class_list":["post-55001161","post","type-post","status-publish","format-standard","hentry","category-662018","category-66062018","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>HTML-Kreuztabelle 1: Basics - 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\/HTMLKreuztabelle_1_Basics\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"HTML-Kreuztabelle 1: Basics\" \/>\n<meta property=\"og:description\" content=\"Kreuztabellenabfragen sind eine praktische Sache, wenn es darum geht, Kombinationen aus m:n-Beziehungen abzubilden - zum Beispiel die Preise f&uuml;r verschiedene Bauelemente oder Materialien in Abh&auml;ngigkeit von der H&ouml;he und der Breite des Materials. Dabei ben&ouml;tigen Sie noch nicht einmal eine m:n-Beziehung, die in einer Kreuztabelle darzustellenden Daten k&ouml;nnen auch aus einer einzigen Tabelle stammen. Der Haken an Kreuztabellen ist, dass diese in der Regel nicht bearbeitet werden k&ouml;nnen. Wenn Sie also etwa den Preis f&uuml;r ein Bauelement mit einer H&ouml;he von einem Meter und einer Breite von f&uuml;nfzig Zentimetern einstellen wollen, m&uuml;ssen Sie wieder die zugrunde liegende Tabelle oder das darauf aufbauende Formular bem&uuml;hen. Im vorliegenden Beitrag wollen wir zun&auml;chst einmal die Grundlage f&uuml;r die Bearbeitung schaffen - indem wir die Daten der Tabelle per HTML in Kreuztabellenform darstellen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-13T21:12:55+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg06.met.vgwort.de\/na\/69a682a177e44d7f914a4cac72589231\" \/>\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=\"16\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"HTML-Kreuztabelle 1: Basics\",\"datePublished\":\"2020-05-13T21:12:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/\"},\"wordCount\":2616,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/69a682a177e44d7f914a4cac72589231\",\"articleSection\":[\"2018\",\"6\\\/2018\",\"Mit Formularen arbeiten\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/\",\"name\":\"HTML-Kreuztabelle 1: Basics - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/69a682a177e44d7f914a4cac72589231\",\"datePublished\":\"2020-05-13T21:12:55+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/69a682a177e44d7f914a4cac72589231\",\"contentUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/69a682a177e44d7f914a4cac72589231\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/HTMLKreuztabelle_1_Basics\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"HTML-Kreuztabelle 1: Basics\"}]},{\"@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-Kreuztabelle 1: Basics - 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\/HTMLKreuztabelle_1_Basics\/","og_locale":"de_DE","og_type":"article","og_title":"HTML-Kreuztabelle 1: Basics","og_description":"Kreuztabellenabfragen sind eine praktische Sache, wenn es darum geht, Kombinationen aus m:n-Beziehungen abzubilden - zum Beispiel die Preise f&uuml;r verschiedene Bauelemente oder Materialien in Abh&auml;ngigkeit von der H&ouml;he und der Breite des Materials. Dabei ben&ouml;tigen Sie noch nicht einmal eine m:n-Beziehung, die in einer Kreuztabelle darzustellenden Daten k&ouml;nnen auch aus einer einzigen Tabelle stammen. Der Haken an Kreuztabellen ist, dass diese in der Regel nicht bearbeitet werden k&ouml;nnen. Wenn Sie also etwa den Preis f&uuml;r ein Bauelement mit einer H&ouml;he von einem Meter und einer Breite von f&uuml;nfzig Zentimetern einstellen wollen, m&uuml;ssen Sie wieder die zugrunde liegende Tabelle oder das darauf aufbauende Formular bem&uuml;hen. Im vorliegenden Beitrag wollen wir zun&auml;chst einmal die Grundlage f&uuml;r die Bearbeitung schaffen - indem wir die Daten der Tabelle per HTML in Kreuztabellenform darstellen.","og_url":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-13T21:12:55+00:00","og_image":[{"url":"http:\/\/vg06.met.vgwort.de\/na\/69a682a177e44d7f914a4cac72589231","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"16\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"HTML-Kreuztabelle 1: Basics","datePublished":"2020-05-13T21:12:55+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/"},"wordCount":2616,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/69a682a177e44d7f914a4cac72589231","articleSection":["2018","6\/2018","Mit Formularen arbeiten"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/","url":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/","name":"HTML-Kreuztabelle 1: Basics - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/69a682a177e44d7f914a4cac72589231","datePublished":"2020-05-13T21:12:55+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/#primaryimage","url":"http:\/\/vg06.met.vgwort.de\/na\/69a682a177e44d7f914a4cac72589231","contentUrl":"http:\/\/vg06.met.vgwort.de\/na\/69a682a177e44d7f914a4cac72589231"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/HTMLKreuztabelle_1_Basics\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"HTML-Kreuztabelle 1: Basics"}]},{"@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\/55001161","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=55001161"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001161\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001161"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001161"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}