HTML-Tabellen mit fester Kopfzeile

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

In den vorherigen Ausgaben von Access im Unternehmen und in der aktuellen Ausgabe arbeiten wir in einigen Beiträgen mit dem Webbrowser-Steuerelement und stellen Daten, die wir mit den Bordmitteln von Access nicht adäquat darstellen können, mit HTML im Webbrowser-Steuerelement dar. Damit erhalten wir wesentlich flexiblere Möglichkeiten, aber auch der Aufwand steigt. Eine Anforderung, die bisher nicht erfüllt wurde, ist das Fixieren der obersten Zeile in einer Ansicht, in der wir zur Anzeige aller Daten nach unten scrollen mussten. Wie wir den Daten einer Tabelle eine fixe Kopfzeile hinzufügen, zeigen wir in diesem Beitrag.

Problem

Wenn wir in einem Webbrowser-Steuerelement eine HTML-Seite mit einer größeren Menge Daten in einer HTML-Tabelle laden, wird diese wie gewünscht angezeigt – auch inklusive der Überschriften im Tabellenkopf.

Sobald wir jedoch nach unten scrollen, um die aktuell nicht sichtbaren Daten anzusehen, verschwinden nicht nur die obersten Datensätze, sondern auch die Kopfzeile mit den Spaltenüberschriften wird nach oben aus dem sichtbaren Bereich geschoben. Das wollen wir ändern, indem wir die Kopfzeile irgendwie oben fixieren.

Im Web werden viele Lösungen für dieses Problem vorgeschlagen. Viele davon nutzen Techniken wie Javascript. Hier ist nicht sichergestellt, dass alle Browser dies wie gewünscht darstellen.

Da das Webbrowser-Steuerelement den aktuell im System als Standardbrowser eingestellten Browser verwendet, sollten Sie hier eine Technik verwenden, die möglichst von allen aktuellen Browsern unterstützt wird. Unser Ergebnis soll wie in Bild 1 aussehen.

HTML-Tabelle mit Scrollbalken

Bild 1: HTML-Tabelle mit Scrollbalken

Lösung

In diesem Fall wählen wir eine Lösung, die nur auf CSS basiert. In diesem Fall wollen wir nicht mehr, dass der Benutzer den kompletten Inhalt des Webbrowser-Steuerelements scrollen muss, sondern nur noch den Teil der Tabelle mit den Daten.

Der Trick dabei ist, dass wir zwei Tabellen nutzen: Die erste zeigt nur eine Zeile mit den Spaltenüberschriften an, die zweite die eigentlichen Daten. Damit der Benutzer in der zweiten Tabelle durch die Datensätze scrollen kann, benötigen wir ein spezielles Attribut. Außerdem fügen wir die zweite Tabelle in die erste Tabelle ein.

Füllen des Webbrowser-Steuerelements

Bevor wir uns die Funktionen zum Erstellen des HTML-Codes und des CSS-Codes ansehen, wollen wir noch die Prozeduren zum Formular hinzufügen, welche das Webbrowser-Steuerelement mit den Daten aus diesen Funktionen füllen. Im Klassenmodul des Formulars fügen wir im allgemeinen Teil zwei Objektvariablen ein:

Dim WithEvents objWebbrowser As WebBrowser
Dim WithEvents objDocument As HTMLDocument

Die erste wird in der Prozedur gefüllt, die durch das Ereignis Beim Öffnen des Formulars ausgelöst wird:

Private Sub Form_Open(Cancel As Integer)
     Set objWebbrowser = Me!ctlWebbrowser.Object
     Me.TimerInterval = 50
End Sub

Hier füllen wir das Webbrowser-Steuerelement allerdings noch nicht. Dies erledigen wir nach einer kurzen, aus technischen Gründen notwendigen Verzögerung. Dazu stellen wir das Zeitgeberintervall auf 50ms ein und hinterlegen eine Prozedur für das Ereignis Bei Zeitgeber, die nach diesem Zeitraum ausgelöst wird:

Private Sub Form_Timer()
     objWebbrowser.Navigate "about:blank"
     Set objDocument = objWebbrowser.Document
     Me.TimerInterval = 0
     DoEvents
     objDocument.body.innerHTML = HTMLCode
     Inzwischenablage objDocument.body.innerHTML
End Sub

Die Prozedur leert das Webbrowser-Steuerelement, weist der Objektvariablen objDocument das im Webbrowser-Steuerelement enthaltene Dokument zu, setzt TimerInterval auf 0, damit diese Ereignisprozedur nicht nochmals ausgelöst wird, und weist dann der Eigenschaft innerHTML das Ergebnis der später vorgestellten Funktion HTMLCode zu. Diese liefert den vollständigen HTML-Code.

Damit Sie bei Änderungen des HTML-Codes die Änderungen direkt einsehen können, haben wir die Schaltfläche cmdAktualisieren hinzugefügt. Diese liest den HTML-Code neu ein:

Private Sub cmdAktualisieren_Click()
     objDocument.body.innerHTML = HTMLCode
     Inzwischenablage objDocument.body.innerHTML
End Sub

Außerdem rufen beide Prozeduren die Routine InZwischenablage auf, um den Inhalt des Webbrowser-Steuerelements in die Zwischenablage zu kopieren. Sie können diesen dann etwa in einen Texteditor einfügen, um sich den resultierenden HTML-Code anzusehen. Wenn Sie diese Funktion nicht benötigen, können Sie die Aufrufe von InZwischenablage auch einfach entfernen.

HTML-Code in zwei Prozeduren

Wir haben die Anweisungen für das Zusammenstellen des HTML-Codes zunächst in zwei Prozeduren aufgeteilt. Die erste übernimmt die Hauptaufgabe und stellt den eigentlichen HTML-Code zusammen, die zweite steuert das Style-Element mit den CSS-Eigenschaften bei.

Schauen wir uns zunächst die Prozedur HTMLCode an, die Sie in Listing 1 finden. Hier starten wir gleich mit der Deklaration einer Database- und einer Recordset-Variablen sowie einer Textvariablen namens strHTML, in welcher wir den HTML-Code zusammenstellen.

Private Function HTMLCode() As String
     Dim db As DAO.Database
     Dim rst As DAO.Recordset
     Dim strHTML As String
     Set db = CurrentDb
     Set rst = db.OpenRecordset("SELECT * FROM qryArtikelMitKategorieUndLieferant", dbOpenDynaset)
     strHTML = strHTML & HTMLStyle
     strHTML = strHTML & "<table class=""tableheaders"">" & vbCrLf
     strHTML = strHTML & "  <thead>" & vbCrLf
     strHTML = strHTML & "    <tr>" & vbCrLf
     strHTML = strHTML & "      <th class=""th1"" scope=""col"">ID</th> " & vbCrLf
     strHTML = strHTML & "      <th class=""th2"" scope=""col"">Artikelname</th> " & vbCrLf
     strHTML = strHTML & "      <th class=""th3"" scope=""col"">Lieferant</th> " & vbCrLf
     strHTML = strHTML & "      <th class=""th4"" scope=""col"">Kategorie</th> " & vbCrLf
     strHTML = strHTML & "      <th class=""th5"" scope=""col"">Einzelpreis</th> " & vbCrLf
     strHTML = strHTML & "    </tr>" & vbCrLf
     strHTML = strHTML & "  </thead>" & vbCrLf
     strHTML = strHTML & "  <tbody>" & vbCrLf
     strHTML = strHTML & "    <tr>" & vbCrLf
     strHTML = strHTML & "      <td colspan=""5"">" & vbCrLf
     strHTML = strHTML & "        <div class=""scrolling"">" & vbCrLf
     strHTML = strHTML & "          <table class=""tablecontent"">" & vbCrLf
     strHTML = strHTML & "            <tbody>" & vbCrLf
     Do While Not rst.EOF
         If rst.AbsolutePosition Mod 2 = 0 Then
             strHTML = strHTML & "              <tr>" & vbCrLf
         Else
             strHTML = strHTML & "              <tr class=""dk"">" & vbCrLf
         End If
         strHTML = strHTML & "                <th class=""td1"" scope=""row"">" & rst!ArtikelID & "</th>" & vbCrLf
         strHTML = strHTML & "                <td class=""td2"">" & rst!Artikelname & "</td>" & vbCrLf
         strHTML = strHTML & "                <td class=""td3"">" & rst!Firma & "</td>" & vbCrLf
         strHTML = strHTML & "                <td class=""td4"">" & rst!Kategoriename & "</td>" & vbCrLf
         strHTML = strHTML & "                <td class=""td5"">" & Format(rst!Einzelpreis, "0.00 €") & "</td>" _
             & vbCrLf
         strHTML = strHTML & "              </tr>" & vbCrLf
         rst.MoveNext
     Loop
     strHTML = strHTML & "            </tbody>" & vbCrLf
     strHTML = strHTML & "          </table>" & vbCrLf
     strHTML = strHTML & "        </div>" & vbCrLf
     strHTML = strHTML & "      </td>" & vbCrLf
     strHTML = strHTML & "    </tr>" & vbCrLf
     strHTML = strHTML & "  </tbody>" & vbCrLf
     strHTML = strHTML & "</table>" & vbCrLf
     HTMLCode = strHTML
End Function

Listing 1: Listing zum Zusammenstellen des HTML-Codes

Die Prozedur referenziert das aktuelle Database-Objekt mit der Variablen db und alle Datensätze der Abfrage qryArtikelMitKategorieUndLieferant mit der Recordset-Variablen rst.

Die Abfrage qryArtikelMitKategorieUndLieferant stellt die Daten der Tabellen tblArtikel, tblKategorien und tblLieferanten wie in Bild 2 zusammen.

Datenquelle für die HTML-Tabelle

Bild 2: Datenquelle für die HTML-Tabelle

Im Anschluss beginnt die Prozedur mit dem Zusammenstellen des HTML-Codes in der Variablen strHTML. Direkt zu Beginn greift sie dabei auf die Funktion HTMLStyle zu, welche die CSS-Definition liefert – mehr dazu weiter unten. Der Teil nach der CSS-Definition sieht wie folgt aus. Dabei startet der HTML-Code mit einem table-Element mit der Klasse tableheaders:

<table class="tableheaders">

Danach folgen im thead-Element die Spaltenüberschriften, denen wir als Klasse th1 bis th6 zuweisen:

   <thead>
     <tr>
       <th class="th1" scope="col">ID</th> 
       <th class="th2" scope="col">Artikelname</th> 
       <th class="th3" scope="col">Lieferant</th> 
       <th class="th4" scope="col">Kategorie</th> 
       <th class="th5" scope="col">Einzelpreis</th> 
     </tr>
   </thead>

Das tbody-Element nimmt zunächst ein tr– und ein td-Element auf, wobei das td-Element fünf Spalten umfassen soll (colspan=”5″). Somit ist es genauso breit wie die fünf Überschriftenspalten:

   <tbody>
     <tr>
       <td colspan="5">

Darunter beginnen wir ein div-Element, dass die Klasse scrolling abbildet:

         <div class="scrolling">

Darin finden wir schließlich die Tabelle mit den eigentlichen Daten, die in jeweils einem tr-Element je Zeile und fünf th– beziehungsweise td-Elementen für jede Spalte abgebildet werden. Hier haben wir beispielhaft die ersten beiden Elemente dargestellt, damit Sie einen kleinen, aber feinen Unterschied erkennen, der für jedes zweite tr-Element auftaucht – nämlich die Zuweisung einer Klasse für die alternative Hintergrundfarbe mit class=”dk”:

           <table class="tablecontent">
             <tbody>
               <tr>
                 <th class="td1" scope="row">1</th>
                 <td class="td2">Chai</td>
                 <td class="td3">Exotic Liquids</td>
                 <td class="td4">Getränke</td>
                 <td class="td5">9,00 €</td>
               </tr>
               <tr class="dk">
                 <th class="td1" scope="row">2</th>
                 <td class="td2">Chang</td>
                 <td class="td3">Exotic Liquids</td>
                 <td class="td4">Getränke</td>
                 <td class="td5">9,50 €</td>
               </tr>
             ...
             </tbody>
           </table>

Danach folgen noch die schließenden Tags für die bereits geöffneten Elemente:

         </div>
       </td>
     </tr>
   </tbody>
</table>

Dieser Code wird im Grunde Zeile für Zeile zusammengesetzt. Einen dynamischen Teil gibt es dort, wo das tr-Element für den jeweiligen Datensatz zusammengestellt wird. Dies geschieht innerhalb einer Do While-Schleife über alle Elemente des Recordsets rst.

In diesem Recordset prüft die Prozedur zunächst das Ergebnis des Ausdrucks rst.AbsolutePosition Mod 2 und vergleicht dieses mit dem Wert 0. Bedeutet: Wenn sich die absolute Recordset-Position ohne Rest durch zwei teilen lässt, wollen wir das tr-Element mit der Klasse dk versehen:

If rst.AbsolutePosition Mod 2 = 0 Then
     strHTML = strHTML & "              <tr>" & vbCrLf
Else
     strHTML = strHTML & "              <tr class=""dk"">" _
         & vbCrLf
End If

Danach folgen dann die einzelnen Spalten des aktuellen Datensatzes. Schließlich weist die Funktion den Inhalt der Variablen strHTML dem Funktionswert HTMLCode zu.

Zusammenstellen der CSS-Befehle

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar