Flexible HTML-Tabellen mit fester Kopfzeile

Wenn Sie ein Abonnement des Magazins 'Access im Unternehmen' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

Flexible HTML-Tabellen mit fester Kopfzeile

Im Beitrag »HTML-Tabellen mit fester Kopfzeile« haben wir gezeigt, wie Sie Daten aus einer bestimmten Abfrage in einem Webbrowser-Steuerelement so anzeigen, dass die Spaltenköpfe oben fixiert bleiben, während der Benutzer den Inhalt der Tabelle, also die eigentlichen Datensätze, nach unten scrollt. Wir wollen das Beispiel aus diesem Beitrag nun so erweitern, dass Sie die scrollbare HTML-Tabelle für beliebige Tabellen oder Abfragen als Datenquelle nutzen können. Diese sollen per Parameter beim Öffnen des Formulars festgelegt werden. Das Layout der Tabellen sowie die anzuzeigenden Daten sollen dann automatisch ermittelt werden – samt den enthaltenen Feldnamen oder -­bezeichnungen als Spaltenköpfen.

Das Ziel dieses Beitrags ist, die Lösung aus dem Artikel HTML-Tabellen mit fester Kopfzeile (www.access-im-unternehmen.de/1188) so anzupassen, dass Sie damit Daten aus beliebigen Tabellen oder Abfragen in einer ­scrollbaren HTML-Tabelle anzeigen können.

Das Ergebnis soll dann etwa so aussehen, dass Sie wie in Bild 1 einfach die anzuzeigende Tabelle oder Abfrage aus einem Kombinationsfeld auswählen können, und das Webbrowser-Steuerelement eine Tabelle mit den Daten der gewählten Tabelle oder Abfrage anzeigt.

HTML-Tabelle mit Scrollbalken

Bild 1: HTML-Tabelle mit Scrollbalken

Auswahl der Datenquelle

Dazu benötigen wir zunächst einmal ein Kombinationsfeld, mit dem Sie die Datenquelle auswählen können.

Dieses fügen wir dem Kopf des Formulars wie in Bild 2 hinzu und stellen die Eigenschaft Name auf cboDatenquelle ein.

Hinzufügen des Kombinationsfeldes zur Auswahl der Datenquelle

Bild 2: Hinzufügen des Kombinationsfeldes zur Auswahl der Datenquelle

Als Datensatzherkunft des Kombinationsfeldes verwenden wir die folgende Abfrage:

SELECT Name FROM MSysObjects WHERE Type In (1,5) And Not Left(Name,1)='~' And Not Left(Name,4)='MSys' And Not Left(Name,2)='f_' ORDER BY Name;

Diese Abfrage ermittelt alle Tabellen und Abfragen aus der Systemtabelle MSysObjects und sortiert diese nach dem Namen. Das Kombinationsfeld zeigt die Einträge dann etwa wie in Bild 3 an.

Auswahl der Datenquelle für die HTML-Tabelle

Bild 3: Auswahl der Datenquelle für die HTML-Tabelle

Daten beim Öffnen des Formulars anzeigen

Beim Öffnen des Formulars soll das Webbrowser-Steuerelement direkt die Daten der ersten Datenquelle des Kombinationsfeldes anzeigen.

Dazu sorgen wir dafür, dass direkt der erste Eintrag im Kombinationsfeld vorausgewählt wird, und zwar durch die zweite Zeile der Ereignisprozedur Form_Open:

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

Durch Einstellen der Eigenschaft TimerInterval auf den Wert 50 wird 50 Millisekunden nach dem Öffnen des Formulars die folgende Form_Timer-Prozedur ausgelöst:

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

Diese unterscheidet sich in einem Detail von der entsprechenden Prozedur, die wir im oben genannten Beitrag vorgestellt haben. Sie übergibt beim Aufruf der Funktion HTMLCode, welche den HTML-Code für die Darstellung der Tabelle zusammensetzt, für den Parameter strDatenquelle den Namen der Datenquelle.

Das Gleiche geschieht auch in der Prozedur, die der Benutzer durch einen Mausklick auf die Schaltfläche cmdAktualisieren auslöst. Die Ereignisprozedur ruft ebenfalls die Funktion HTMLCode mit dem Wert des Kombinationsfeldes cboDatenquelle als Parameter auf. Diese Prozedur wird dazu wie folgt geändert:

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

Schließlich möchten wir auch, dass der Inhalt des Web­browser-Steuerelements auch beim Aktualisieren der ausgewählten Datenquelle über das Kombinationsfeld cboDatenquelle aktualisiert wird, was wir mit der folgenden Ereignisprozedur realisieren:

Private Sub cboDatenquelle_AfterUpdate()
     If Not Len(Me!cboDatenquelle) = 0 Then
         objDocument.body.innerHTML =  HTMLCode(Me!cboDatenquelle)
     End If
End Sub

HTML-Code datenquellenabhängig zusammenstellen

Damit kommen wir zum interessanten Teil, nämlich dem Code, mit dem wir den HTML-Code abhängig von der gewählten Datenquelle zusammenstellen. Den ersten Teil dieser Funktion finden Sie in Listing 1.

Private Function HTMLCode(strDatenquelle As String) As String
     Dim db As DAO.Database, rst As DAO.Recordset, fld As DAO.Field
     Dim strHTML As String, strFeldname As String
     Dim i As Integer
     Set db = CurrentDb
     Set rst = db.OpenRecordset("SELECT TOP 100 * FROM " & strDatenquelle, dbOpenDynaset)
     strHTML = strHTML & HTMLStyle(rst)
     strHTML = strHTML & "<table class=""tableheaders"">" & vbCrLf
     strHTML = strHTML & "  <thead>" & vbCrLf
     strHTML = strHTML & "    <tr>" & vbCrLf
     For Each fld In rst.Fields
         Select Case fld.Type
             Case dbInteger, dbLong, dbText, dbMemo, dbCurrency, dbDate, dbSingle, dbDouble, dbBoolean
                 strFeldname = ""
                 On Error Resume Next
                 strFeldname = fld.Properties("Caption")
                 On Error GoTo 0
                 If Len(strFeldname) = 0 Then
                     strFeldname = fld.Name
                 End If
                 i = i + 1
                 strHTML = strHTML & "      <th class=""th" & i & """ scope=""col"">" & strFeldname & "</th> " & vbCrLf
             Case Else
         End Select
     Next fld
     strHTML = strHTML & "    </tr>" & vbCrLf
     strHTML = strHTML & "  </thead>" & vbCrLf
     ...
End Function

Listing 1: Listing zum Zusammenstellen des HTML-Codes, Teil 1

Die Funktion erwartet den Namen der mit dem Kombinationsfeld ausgewählten Tabelle oder Abfrage als Parameter. Sie erstellt ein Database-Objekt namens db sowie ein Recordset-Objekt namens rst, welches die ersten 100 Datensätze der gewählten Datenquelle auswählt. Die Erstellung des HTML-Codes dauert für größere Datenmengen relativ lange, daher haben wir diese Beschränkung für die Beispieldatei eingefügt. Sie können TOP 100 in der folgenden Anweisung entfernen, wenn Sie immer alle Datensätze laden wollen:

     Set rst = db.OpenRecordset("SELECT TOP 100 * FROM "  & strDatenquelle, dbOpenDynaset)

Danach ruft die Funktion eine weitere Funktion namens HTMLStyle auf und übergibt dieser das Recordset als Parameter. Die Beschreibung dieser Funktion, die den CSS-Code in Abhängigkeit der Datenquelle zusammenstellt, finden Sie weiter unten.

Danach fügt die Funktion die ersten HTML-Elemente für den Kopfbereich der Tabelle beziehungsweise die umfassende Tabelle an. Nach dem Anlegen der ersten drei Elemente table, thead und tr folgenden die Spaltenüberschriften für die Felder der Datenquelle.

Um dabei auf die jeweiligen Felder der gewählten Datenquelle zuzugreifen, durchlaufen wir die Felder des Recordset-Objekts rst in einer For Each-Schleife und weisen das jeweilige Field-Objekt der Variablen fld zu. Innerhalb dieser Schleife prüfen wir in einer Select Case-Bedingung den Typ des jeweiligen Feldes. Wir wollen nicht alle Felddatentypen in der Tabelle aufführen – so schließen wir beispielsweise OLE- und Anlagefelder aus. Die erste Case-Bedingung behandelt somit die Datentypen Integer, Long, Text, Memo, Currency, Date, Single, Double und Boolean. Weitere Datentypen können Sie nach Bedarf hinzufügen. Sollten Sie die Funktion in einer eigenen Anwendung einsetzen und die dort gewählte Datenquelle enthält ein Feld mit einem Datentyp, der hier nicht behandelt wird, gibt die Prozedur die Nummer des Datentyps im Direktbereich des VBA-Editors aus – dies geschieht im Else-Zweig der Select Case-Bedingung.

Handelt es sich bei fld um ein Feld mit einem unterstützten Datentyp, ermittelt die Funktion entweder den Feldnamen des Feldes oder, falls vorhanden, den Wert der Eigenschaft Beschriftung, den Sie in den Feldeigenschaften im Tabellenentwurf einstellen können.

Wir stellen die Variable strFeldname, die den Feldnamen aufnimmt, zunächst auf eine leere Zeichenkette ein. Dann schalten wir die Fehlerbehandlung temporär aus, und zwar für den Versuch, den Wert der Eigenschaft Caption über die Properties-Auflistung des Feldes zu ermitteln.

Gelingt dies, enthält strFeldname danach die Beschriftung dieses Feldes. Dies prüfen wir in der folgenden If...Then-Bedingung. Hat strFeldname dort eine Länge ungleich 0, tragen wir den Feldnamen aus der Eigenschaft Name in die Variable strFeldname ein und verwenden diesen als Spaltenüberschrift. Nun erhöhen wir eine Zählervariable namens i um den Wert 1 und stellen die HTML-Zeile für die aktuelle Spaltenüberschrift zusammen. Diese sieht dann etwa wie folgt aus:

      <th class="th1" scope="col">ArtikelID</th> 

Danach durchlaufen wir die übrigen Felder des Recordsets und stellen so die Spaltenüberschriften zusammen. Es folgen die schließenden Elemente wie </tr> und </thead>, bevor sich der folgende Teil um die Darstellung der Daten in der HTML-Tabelle kümmert.

Daten in die HTML-Tabelle schreiben

Damit kommen wir zum zweiten Teil der Prozedur, den Sie in Listing 2 finden.

Private Function HTMLCode(strDatenquelle As String) As String
     ...
     strHTML = strHTML & "  <tbody>" & vbCrLf
     strHTML = strHTML & "    <tr>" & vbCrLf
     strHTML = strHTML & "      <td colspan=""" & rst.Fields.Count & """>" & 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

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Neues aus unseren Magazinen
Listenfeld: Reihenfolge mehrerer Einträge...

Wir haben bereits in mehreren Beiträgen beschrieben, wie Sie die individuelle Reihenfolge von Elementen einer Tabelle über den Inhalt eines Feldes etwa namens »ReihenfolgeID« einstellen können –... [mehr]

Diagramme mit gefilterten Daten

In Ausgabe 2/2019 haben wir in zwei Artikeln die modernen Diagramme von Access vorgestellt. Im vorliegenen Beitrag zeigen wir Ihnen, wie Sie diese abhängig von den in einem Formular angezeigten... [mehr]

Benutzerverwaltung mit verschlüsselten...

Wenn Sie in einer Access-Anwendung Benutzer verwalten wollen, die sich per Benutzername und Kennwort an die Anwendung anmelden, sollten Sie sehr sensibel mit den in der Anwendung gespeicherten... [mehr]

HTML-Tabellen mit fester Kopfzeile

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... [mehr]

Flexible HTML-Tabellen mit fester Kopfzeile

Im Beitrag »HTML-Tabellen mit fester Kopfzeile« haben wir gezeigt, wie Sie Daten aus einer bestimmten Abfrage in einem Webbrowser-Steuerelement so anzeigen, dass die Spaltenköpfe oben fixiert... [mehr]

Berechtigungen per HTML verwalten

Im Beitrag »Benutzerverwaltung mit verschlüsselten Kennwörtern« stellen wir eine Lösung vor, in der wir die Berechtigungen von Benutzergruppen an Datenbankobjekten definieren. Dort benötigen wir... [mehr]

Benutzer und Berechtigungen ermitteln

In den Beiträgen »Benutzerverwaltung mit verschlüsselten Kennwörtern« und »Berechtigungen per HTML verwalten« haben wir die Voraussetzungen für eine Benutzerverwaltung geschaffen. Im vorliegenden... [mehr]

Zugriffsrechte mit Datenmakros

Es gibt verschiedene Möglichkeiten, auf Basis des aktuell angemeldeten Benutzers sicherzustellen, dass dieser nur die für ihn vorgesehenen Aktionen mit Daten durchführen darf – beispielsweise durch... [mehr]

Kennwörter generieren

Für den einen oder anderen Zweck möchten Sie vielleicht Kennwörter generieren oder in einer Benutzeroberfläche die Möglichkeit zum Generieren von Kennwörtern anbieten. Wenn Sie etwa Benutzer zu... [mehr]

Neuer Datensatz von Frontend zu Backend

Für manche Themen gibt es keine kurze, prägnante Überschrift. In diesem Fall wollen wir zeigen, wie Sie einen neuen Datensatz anlegen, der in einer temporären Tabelle im Frontend gespeichert wird,... [mehr]