1:n-Daten mit HTML

Es gibt einige Darstellungen, die sich mit Access-Bordmitteln nicht oder nur mit sehr hohem Aufwand realisieren lassen. Dazu gehören beispielsweise alle Konstellationen aus 1:n-Beziehungen mit Unterformularen, bei denen man gern mehr als einen Datensatz im Hauptformular anzeigen würde. Zum Glück erlaubt Access einen Blick über den Tellerrand, und mit dem Webbrowser-Steuerelement und HTML erreichen Sie wohl alle denkbaren Darstellungen – in diesem Fall die Endlosanzeige von 1:n-Beziehungen.

Im vorliegenden Fall sollen alle Abteilungen einer Firma samt den dazugehörigen Mitarbeitern dargestellt werden, und zwar inklusive eines Kontrollkästchens je Abteilung und Mitarbeiter, mit dem man komplette Abteilungen oder einzelne Mitarbeiter aus- und abwählen kann. Das Beispielformular aus Abb. 1 gehört zu der Lösung aus dem Beitrag Fehlzeiten verwalten (www.access-im-unternehmen.de/850).

pic001.png

Abb. 1: 1:n-Beziehung im Webbrowser-Steuerelement

Das Formular soll die Daten der beiden Tabellen tblAbteilungen und tblMitarbeiter anzeigen, die per 1:n-Beziehung über das Fremdschlüsselfeld AbteilungID der Tabelle tblMitarbeiter miteinander verknüpft sind (s. Abb. 2). Das Ausgeben der Kontrollkästchen und der Texte allein ist relativ einfach, wenn Sie einmal verstanden haben, wie Sie mit HTMLTable-, HTMLRow- und HTMLCell-Objekten umgehen und diese in einem HTMLDocument-Objekt anlegen. Diese Anweisungen müssen Sie dann lediglich noch in die entsprechenden Do While-Schleifen zum Ausgeben der anzuzeigenden Daten einbetten. Zunächst benötigen Sie jedoch ein Formular mit einem Webbrowser-Steuerelement, das im Entwurf etwa wie in Abb. 3 aussieht. Das Webbrowser-Steuerelement erhält den Namen ctlWebbrowser.

pic237.png

Abb. 2: Tabellen der Beispielanwendung

pic002.png

Abb. 3: Das Beispielformular in der Entwurfsansicht

Um ein HTML-Dokument mit den Methoden der MSHTML-Bibliothek zu bestücken, benötigen Sie zunächst einen Verweis auf diese Bibliothek. Diesen legen Sie im Verweise-Dialog (Menüeintrag Optionen|Verweise im VBA-Editor) fest (s. Abb. 4). Danach können Sie bereits loslegen. Die Prozedur, die durch das Ereignis Beim Laden des Formulars ausgelöst wird, ruft wiederum die Prozedur MitarbeiterAnzeigen auf:

pic003.png

Abb. 4: Verweis auf die MSHTML-Bibliothek

Private Sub Form_Load()
    MitarbeiterAnzeigen
End Sub

Der weitere Aufbau wird von der Prozedur MitarbeiterAnzeigen gesteuert (s. Listing 1). Die Prozedur legt zunächst mit der Funktion DokumentAnlegen (s. Listing 2) ein Dokument im Webbrowser-Steuerelement an und speichert einen Verweis darauf in der Variablen objDocument.

Listing 1: Mitarbeiter im Webbrowser-Steuerelement anzeigen

Private Sub MitarbeiterAnzeigen()
    Dim db As DAO.Database
    Dim rstAbteilungen As DAO.Recordset
    Dim rstMitarbeiter As DAO.Recordset
    Dim objDocument As MSHTML.HTMLDocument
    Dim objTable As MSHTML.HTMLTable
    Dim objInnerRow As MSHTML.HTMLTableRow
    Dim objInnerCell As MSHTML.HTMLTableCell
    Dim objCheckbox As MSHTML.HTMLInputElement
    Set colCheckboxes_Mitarbeiter = New Collection
    Set colCheckboxes_Abteilungen = New Collection
    Set objDocument = DokumentHolen
    Set objTable = objDocument.createElement("Table")
    objDocument.Body.appendChild objTable
    objDocument.Body.Style.fontFamily = "calibri"
    objDocument.Body.Style.FontSize = "8px"
    objTable.Style.borderCollapse = "collapse"
    Set db = CurrentDb
    Set rstAbteilungen = db.OpenRecordset("SELECT * FROM qryAbteilungenMitMitarbeitern", dbOpenDynaset)
    Do While Not rstAbteilungen.EOF
        Set objInnerRow = ZeileZelleTabelleAnlegen(objDocument, objTable)
        Set objInnerCell = objInnerRow.insertCell
        objInnerCell.appendChild CheckboxAbteilungErstellen(objDocument, rstAbteilungen!AbteilungID)
        Set objInnerCell = objInnerRow.insertCell
        objInnerCell.innerText = rstAbteilungen!Abteilung
        Set rstMitarbeiter = db.OpenRecordset("SELECT * FROM qryMitarbeiterauswahl " _
            & "WHERE AbteilungID " & rstAbteilungen!AbteilungID, dbOpenDynaset)
        Do While Not rstMitarbeiter.EOF
            Set objInnerRow = ZeileZelleTabelleAnlegen(objDocument, objTable)
            Set objInnerCell = objInnerRow.insertCell
            objInnerCell.Width = "30px"
            Set objInnerCell = objInnerRow.insertCell
            Set objCheckbox = CheckboxMitarbeiterErstellen(objDocument, _
                rstMitarbeiter!MitarbeiterID)
            objInnerCell.appendChild objCheckbox
            objCheckbox.Checked = Not IsNull(rstMitarbeiter!MitarbeiterAnzeigenID)
            Set objInnerCell = objInnerRow.insertCell
            With objInnerCell
                .innerText = rstMitarbeiter!Bezeichnung
                .Style.fontFamily = "calibri"
                .Style.FontSize = "12px"
            End With
            rstMitarbeiter.MoveNext
        Loop
        rstAbteilungen.MoveNext
    Loop
    Set db = Nothing
End Sub

Listing 2: Browser mit leerem Dokument füllen

Private Function DokumentHolen() As MSHTML.HTMLDocument
    Dim objWebbrowser As SHDocVw.WebBrowser
    Dim objDocument As MSHTML.HTMLDocument
    Set objWebbrowser = GetWebbrowser
    DoEvents
    objWebbrowser.Navigate "about:blank"
    Do
        DoEvents
    Loop Until objWebbrowser.ReadyState = READYSTATE_COMPLETE
    Set objDocument = objWebbrowser.Document
    Set DokumentHolen = objDocument
End Function

Außerdem erstellt die Prozedur zwei Collection-Objekte, welche später Verweise auf Wrapper-Klassen für die Checkbox-Steuerelemente zum Auswählen der Abteilungen und der Mitarbeiter aufnehmen – dazu später mehr. Wichtig ist erstmal, dass die Collection-Elemente wie folgt im Kopf des Klassenmoduls des Formulars deklariert werden:

Dim colCheckboxes_Mitarbeiter As Collection
Dim colCheckboxes_Abteilungen As Collection

Auch die Wrapper-Klassen werden im Kopf des Moduls deklariert:

Dim objCheckboxWrapper_Mitarbeiter As clsCheckboxWrapper_Mitarbeiter
Dim objCheckboxWrapper_Abteilung As clsCheckboxWrapper_Abteilung

Nun geht erstmal der Aufbau der Tabellenstruktur im HTML-Dokument weiter. Die Prozedur erstellt ein HTMLTable-Objekt und hängt es als Kind-Element an das HTMLDocument-Element an. Einige Einstellungen bezüglich der Schriftart sorgen später für ein einheitliches Bild.

Danach kommt auch schon die Datenbank mit ihren Tabellen tblAbteilungen und tblMitarbeiter ins Spiel. Genau genommen öffnet die Prozedur zunächst eine Datensatzgruppe auf Basis der Abfrage qryAbteilungenMitMitarbeitern (s. Abb. 5). Diese liefert alle Datensätze der Tabelle tblAbteilungen, denen mindestens ein Mitarbeiter angehört. Diese Abteilungen werden in einer Do While-Schleife durchlaufen. Dabei erstellt die Prozedur MitarbeiterAnzeigen zunächst innerhalb einer Funktion namens ZeileZelleTabelleAnlegen einige Elemente im HTMLTable-Objekt, und zwar zunächst ein HTMLRow-Element, darin ein HTMLCell-Element, darin ein HTMLTable-Element und schließlich noch ein HTMLRow-Element (s. Listing 3).

Listing 3: Unabhängige Zeilen anlegen

Public Function ZeileZelleTabelleAnlegen(objDocument As MSHTML.HTMLDocument, _
        objTable As MSHTML.HTMLTable) As MSHTML.HTMLTableRow
    Dim objRow As MSHTML.HTMLTableRow
    Dim objCell As MSHTML.HTMLTableCell
    Dim objInnerTable As MSHTML.HTMLTable
    Dim objInnerRow As MSHTML.HTMLTableRow
    Set objRow = objTable.insertRow
    objRow.Style.verticalAlign = "top"
    Set objCell = objRow.insertCell
    Set objInnerTable = objDocument.createElement("Table")
    objInnerTable.Style.borderCollapse = "collapse"
    objCell.appendChild objInnerTable
    Set objInnerRow = objInnerTable.insertRow
    Set ZeileZelleTabelleAnlegen = objInnerRow
End Function

pic005.png

Abb. 5: Datenherkunft für die äußere Schleife

Sie haben das Ende des frei verfügbaren Textes erreicht. Möchten Sie ...

Workplace

Jahresabonnement TestzugangOder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar