Fehlzeiten verwalten

Das Verwalten von Fehlzeiten bezieht sich auf Urlaub, Krankheit, Fortbildung et cetera und erfordert keine Wunderwerke der Datenmodellierung. Eine Tabelle mit Mitarbeitern, eine mit den Fehlzeiten – mehr benötigen Sie nicht. Interessant wird es jedoch, die Fehlzeiten einzugeben und diese übersichtlich darzustellen. Und zwar so, dass nicht nur die Fehlzeiten eines einzigen Mitarbeiters, sondern möglichst die aller Mitarbeiter sichtbar sind. Nur so lässt sich effektiv vorausplanen.

Die Musterlösung dieses Beitrags soll es erlauben, mehrere Mitarbeiter zu verwalten und für jeden Tag Fehlzeiten in Form halber Tage festzuhalten – es kann ja durchaus geschehen, dass ein Mitarbeiter mal einen halben Tag Urlaub nimmt, an einer Fortbildung teilnimmt oder sich nach dem Mittagessen mit einer Magenverstimmung verabschiedet.

Datenmodell

Das Datenmodell besteht aus einer einfachen Mitarbeitertabelle und einer Tabelle zur Verwaltung von Abteilungen. Außerdem gibt es eine Tabelle zum Speichern der verschiedenen Arten von Fehlzeiten und eine zum Aufnehmen der Fehlzeiten selbst.

Die Tabelle tblMitarbeiter ist recht einfach gehalten und enthält neben dem Primärschlüsselfeld nur zwei Felder zur Angabe von Vor- und Nachname, ein Feld zum Eintragen einer Bezeichnung, die in der Regel die Form <Nachname>, <Vorname> aufweist, und ein Nachschlagefeld zur Auswahl der Abteilung des Mitarbeiters (s. Bild 1). Die damit referenzierte Tabelle tblAbteilung ist eine schlichte Lookup-Tabelle, die nur das Primärschlüsselfeld AbteilungID sowie das Feld mit der Bezeichnung der Abteilung enthält.

pic004.png

Bild 3: Fehlzeiten werden jeweils als halbe Tage erfasst

Gleiches gilt für die Tabelle tblFehlzeitarten, die nur aus den beiden Feldern FehlzeitartID und Fehlzeitart besteht. Sie nimmt in der aktuellen Version die drei Werte Krankheit, Urlaub und Weiterbildung auf (s. Bild 2).

pic001.png

Bild 1: Die Tabelle tblMitarbeiter in der Entwurfsansicht

Fehlt noch die Tabelle tblFehlzeiten, welche die tatsächlichen Fehlzeiten aufnimmt. Sie enthält ein Primärschlüsselfeld namens FehlzeitID und ein Datumsfeld namens Fehlzeitdatum. Weitere zwei Felder sind Fremdschlüsselfelder und referenzieren die Datensätze der Tabellen tblMitarbeiter und tblFehlzeitarten.

Fehlt noch eine wichtige Information, die davon abhängt, ob Sie nur ganze Fehltage aufnehmen möchten oder auch halbe Fehltage (man könnte dies natürlich auch stundenweise erledigen, aber wenn jemand zwei Stunden frei haben möchte, um mit seinem Kind zum Arzt zu gehen, hängt er die zwei Stunden halt irgendwo hinten an).

Wie aber bekommen wir die halben Fehltage in den Griff Bei einem ganzen Fehltag wäre dies kein Problem: Sie legen einen Eintrag in der Tabelle tblFehltage an und der Fall ist erledigt. Bei halben Tagen brauchen wir aber zumindest noch ein weiteres Feld, mit dem wir die Fehlzeitdauer aufnehmen. Aber macht es Sinn, tatsächlich nur die Dauer, also einen Wert wie 1 oder 1/2 zu speichern Vielleicht brauchen wir noch weitere Informationen, zum Beispiel, ob der halbe Tag vormittags oder nachmittags beziehungsweise die erste oder die zweite Hälfte der Schicht betrifft

Dies wird nämlich beispielsweise interessant, wenn immer eine bestimmte Anzahl Mitarbeiter gebraucht wird. Und auch für eine grafische Darstellung der Fehlzeiten wäre es sinnvoll, die Position des halben Fehltages anzeigen zu können. Welche Möglichkeiten haben wir nun

  • Sie könnten ein Fremdschlüsselfeld und eine entsprechende Lookup-Tabelle anlegen, welche die beiden Werte Vormittags und Nachmittags enthält. Dann brauchen Sie aber auch noch einen Wert für Kompletter Tag.
  • Sie könnten zwei Ja/Nein-Felder namens Vormittag und Nachmittag anlegen und entweder eines von beiden oder, im Falle eines kompletten Fehltages, beide Felder auf Ja einstellen.
  • Sie legen grundsätzlich einen neuen Datensatz pro halben Fehltag in der Tabelle an und verwenden dabei nur ein Feld namens Vormittags, um den Zeitraum festzulegen. Ist Vormittags aktiviert, liegt der halbe Fehltag in der ersten Tageshälfte, sonst in der zweiten Tageshälfte. Für einen kompletten Fehltag legen Sie also zwei Datensätze an, bei denen das Feld Vormittags einmal aktiviert ist und einmal nicht.

Wir entscheiden uns für die letzte Variante. Die Tabelle tblFehlzeiten sieht somit wie in Bild 4).

pic002.png

Bild 2: Tabelle zum Speichern der Fehlzeitarten

pic005.png

Bild 4: Datenmodell der Musterlösung

Darstellung der Fehlzeiten im Formular

Für die Darstellung der Fehlzeiten gibt es mehrere Möglichkeiten. Grundsätzlich sollen die Spaltenköpfe die Datumsangaben enthalten und die Zeilenköpfe die Namen der Mitarbeiter. Die einzelnen Zellen erhalten dann eine die jeweilige Fehlzeitart repräsentierende Farbe (diese legen Sie übrigens in der Tabelle tblFehlzeitarten fest – später lernen Sie ein Formular zur Bearbeitung der Fehlzeitarten kennen). Aber da wir uns nun schon darauf eingeschossen haben, auch halbtägige Fehlzeiten zu vergeben: Wie stellen wir diese in einer Übersicht wie oben beschrieben dar Eigentlich gibt es nur zwei Möglichkeiten: entweder die Fehlzeit am Vormittag landet oben und die am Nachmittag unten oder die Fehlzeiten werden links und rechts im Kasten für den jeweiligen Tag angezeigt. Für ganztägige Fehlzeiten wird der komplette Kasten mit der entsprechenden Farbe gefüllt.

Bild 5 zeigt, wie der zweite Vorschlag aussieht. Dieser ist die bessere Lösung, weil man die Fehlzeiten für den Vor- und den Nachmittag durch Prüfen einer einzigen Spalte überblicken kann. Diese Ansicht lässt sich mit Bordmitteln nicht realisieren. Zwar könnten Sie die Abwesenheiten aller Mitarbeiter untereinander mit einer ganzen Menge Steuerelemente und in der Endlosansicht anzeigen, aber wenn Sie wie in diesem Beispiel auch noch nach einer übergeordneten Kategorie wie etwa Abteilungen gruppieren möchten, haben Sie keine Chance. Daher stellen wir einmal dar, wie dies mit dem Webbrowser-Steuerelement und HTML funktioniert.

pic007.png

Bild 5: Formular zum Hinzufügen von Fehlzeiten

Wie werden die Fehlzeiten hinzugefügt oder entfernt Dazu enthält jedes einzelne Element in der Fehlzeitenübersicht ein Kontextmenü (s. Bild 6). Klicken Sie mit der rechten Maustaste auf den Tag für den entsprechenden Mitarbeiter und wählen Sie die gewünschte Fehlzeitart samt Dauer aus.

pic009.png

Bild 6: Fehlzeit per Kontextmenü

Formular anlegen

Das Formular sieht in der Entwurfsansicht wie in Bild 7 aus und enthält zunächst ein Webbrowser-Steuerelement. Dieses fügen Sie in den Access-Versionen bis Access 2007 als ActiveX-Steuerelement hinzu, ab Access 2010 verwenden Sie das eingebaute Webbrowser-Steuerelement.

pic008.png

Bild 7: Das Formular zur Anzeige der Fehlzeitenübersicht in der Entwurfsansicht

Das Webbrowser-Steuerelement soll den Namen ctlWebbrowser erhalten.

Im Kopfbereich des Formulars finden Sie folgende Steuerelemente:

  • txtStart: Textfeld zur Anzeige beziehungsweise Eingabe eines Tages, der in der ersten Woche der vierwöchigen Anzeige liegt
  • cmdNaechsteWoche: Schaltfläche, welche die Anzeige um eine Woche in die Zukunft verschiebt
  • cmdVorherigeWoche: Schaltfläche, welche die Anzeige um eine Woche in die Vergangenheit verschiebt
  • cmdMitarbeiterFiltern: Öffnet einen Dialog, mit dem Sie einstellen können, für welche Mitarbeiter die Fehlzeiten angezeigt werden sollen
  • cmdFuellen: Aktualisiert die Anzeige
  • cmdFehlzeitarten: Öffnet einen Dialog zum Bearbeiten der Fehlzeitarten

Füllen des Webbrowser-Steuerelements

Die aufwendigste Aufgabe dieser Beispielanwendung ist natürlich das Füllen des Webbrowser-Steuerelements. Dies erledigt die Prozedur FehlzeitenAnzeigen – mehr dazu weiter unten.

Diese Prozedur wird zu verschiedenen Gelegenheiten aufgerufen, als Erstes natürlich beim Anzeigen des Formulars – hier in der Prozedur, die durch das Ereignis Beim Laden ausgelöst wird:

Private Sub Form_Load()
    Dim datMontag As Date
    datMontag = MontagDerWoche(Date)
    Me!txtStart = datMontag
    FehlzeitenAnzeigen
End Sub

Diese Prozedur leistet allerdings noch ein wenig Vorarbeit: Sie ermittelt mit der Date-Funktion das aktuelle Datum und daraus mit der Funktion MontagDerWoche den Montag der Woche, in der das Datum liegt:

Public Function MontagDerWoche(dat As Date) As Date
    Dim intWeekday As Integer
    intWeekday = Weekday(dat, vbMonday)
    MontagDerWoche = DateAdd("d", -(intWeekday - 1), dat)
End Function

MontagDerWoche holt sich mit der Weekday-Funktion eine Zahl, welche den Tag der Woche repräsentiert, also beispielsweise den Wert 3, wenn der Tag von Date ein Mittwoch ist (Montag entspricht 1). Um den Montag der Woche zu ermitteln, in der sich das aktuelle Datum befindet, muss man nur noch die Differenz der Tage vom Montag bis zum aktuellen Tag ermitteln und vom aktuellen Tag abziehen.

Dieses Datum trägt Form_Load in das Textfeld txtStart ein und ruft dann die Prozedur FehlzeitenAnzeigen auf. Die Prozedur wird auch aufgerufen, wenn der Benutzer eine der beiden Schaltflächen cmdNaechsteWoche oder cmdVorherigeWoche anklickt. Die dadurch ausgelösten Prozeduren fügen entweder sieben Tage zum Datum im Textfeld txtStart hinzu oder ziehen diese ab, um den Startzeitpunkt der Fehlzeitenanzeige um eine Woche nach vorn oder hinten zu verschieben:

Private Sub cmdNaechsteWoche_Click()
    Me!txtStart = Me!txtStart + 7
    FehlzeitenAnzeigen
End Sub
Private Sub cmdVorherigeWoche_Click()
    Me!txtStart = Me!txtStart - 7
    FehlzeitenAnzeigen
End Sub

Das Anklicken der Schaltfläche cmdFuellen dient allein der Aktualisierung der Anzeige:

Private Sub cmdFuellen_Click()
    FehlzeitenAnzeigen
End Sub

Außerdem wird die Anzeige noch nach dem Bearbeiten der anzuzeigenden Mitarbeiter und der Fehlzeitarten aktualisiert – mehr dazu weiter unten.

Die Prozedur FehlzeitenAnzeigen

Diese Prozedur, die Sie im Klassenmodul des Formulars frmFehlzeiten finden (und in Listing 1), bildet das Grundgerüst zum Füllen der Fehlzeiten-Übersicht. Einige weitere Prozeduren übernehmen die Kleinarbeit wie das Anlegen und Ausstatten der einzelnen Tabellenelemente wie Zeilen, Zellen, in Zellen enthaltene Tabellen und so weiter.

Listing 1: Füllen des Webbrowser-Steuerelements

Private Sub FehlzeitenAnzeigen()
    Dim objDocument As MSHTML.HTMLDocument
    Dim db As DAO.Database
    Dim rstMitarbeiter As DAO.Recordset
    Dim rstAbteilungen As DAO.Recordset
    Dim datAktuell As Date
    Dim objTable As MSHTML.HTMLTable
    Dim objRow As MSHTML.HTMLTableRow
    Set colTableCells = New Collection
    Set db = CurrentDb
    Set rstAbteilungen = db.OpenRecordset("SELECT * FROM qryAbteilungenMitMitarbeitern", dbOpenDynaset)
    Set objDocument = DokumentHolen
    Set objTable = TabelleErstellen(objDocument)
    Set objRow = objTable.insertRow
    objRow.insertCell
    objRow.insertCell
    For datAktuell = Me!txtStart To DateAdd("d", 27, Me!txtStart)
        ZelleTagAnlegen datAktuell, objRow
    Next datAktuell
    Do While Not rstAbteilungen.EOF
        ZeileAbteilungEinfuegen objTable, rstAbteilungen!Abteilung
        Set rstMitarbeiter = db.OpenRecordset("SELECT * FROM qryAusgewaehlteMitarbeiter " _
            & "WHERE AbteilungID = " & rstAbteilungen!AbteilungID, dbOpenDynaset)
        Do While Not rstMitarbeiter.EOF
            Set objRow = ZeileMitarbeiterEinfuegen(objTable)
            ZeilenkopfMitarbeiterEinfuegen objRow, rstMitarbeiter!Bezeichnung
            For datAktuell = Me!txtStart To DateAdd("d", 27, Me!txtStart)
                Set objTableCell = ZelleTagMitarbeiterHinzufuegen(datAktuell, objRow, _
                    rstMitarbeiter!MitarbeiterID, objDocument)
                colTableCells.Add objTableCell, CLng(rstMitarbeiter!MitarbeiterID) & "|" _
                    & CLng(datAktuell)
            Next datAktuell
            rstMitarbeiter.MoveNext
        Loop
        rstAbteilungen.MoveNext
    Loop
    FehlzeitenEintragen Me!txtStart, DateAdd("d", 27, Me!txtStart)
End Sub

Im Deklarationsteil finden Sie unter anderem zwei Recordset-Objekte, mit denen erst die Abteilungen und dann die Mitarbeiter der Abteilungen durchlaufen werden, und außerdem einige HTML-Objekte.

Danach folgt direkt die Instanzierung eines Collection-Objekts, das im Kopf des Klassenmoduls des Formulars deklariert wird:

Dim colTableCells As Collection

Wozu das Jeder Tag soll ja zwei Zellen enthalten, die nach einem Mausklick ein Kontextmenü anzeigen. Dies gelingt nur, wenn Sie eine entsprechende Ereignisprozedur für die entsprechenden HTMLTableCell-Elemente anlegen. Nun wäre es aber ein wahnsinniger Aufwand, vorab für viele hundert HTMLTableCell-Elemente Ereignisprozeduren anzulegen.

Daher verwenden wir eine kleine Wrapper-Klasse, der wir einen Bezug auf das jeweilige HTMLTableCell-Element mitgeben. Diese Wrapper-Klasse enthält die für die Anzeige des Kontextmenüs nötigen Ereignisprozeduren. Vorteil: Sie brauchen die Klasse nur einmal zu programmieren und können sie für jedes der Kalender-Elemente, das ein Kontextmenü anzeigen soll, neu instanzieren.

Wie das genau funktioniert, erfahren Sie weiter unten. An dieser Stelle ist erstmal wichtig, dass es eine Collection gibt, welche Verweise auf alle Instanzen der Wrapper-Klasse aufnimmt, damit diese nach dem Erzeugen nicht im Nirwana verschwinden.

Abteilungen durchlaufen

Das Recordset rstAbteilungen basiert auf einer Abfrage, die nicht alle Abteilungen der Tabelle tblAbteilungen zurückliefert, sondern nur diejenigen, die mindestens einen Mitarbeiter enthalten. Die dabei verwendete Abfrage qryAbteilungenMitMitarbeitern sieht wie in Bild 8 aus. Die Abfrage gibt zwar nur Felder der Tabelle tblAbteilungen zurück, aber dadurch, dass diese in der Abfrage mit der Tabelle tblMitarbeiter verknüpft ist, werden die Datensätze ohne Bezug zu einem Mitarbeiter-Datensatz ignoriert.

pic010.png

Bild 8: Abfrage zur Ermittlung aller Abteilungen mit mindestens einem Mitarbeiter

Danach liefert die Funktion DokumentHolen einen Verweis auf ein HTML-Dokument, das innerhalb dieser Funktion erstellt wird:

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

Die Funktion verwendet zunächst eine weitere Funktion namens GetWebbrowser, um eine Referenz auf das im Formular enthaltene Webbrowser-Steuerelement zu erhalten. Diese wird nach dem Erstellen in der modulweit deklarierten Variablen gespeichert:

Dim WithEvents m_Webbrowser As WebBrowser

Die Funktion GetWebbrowser prüft, ob m_Webbrowser schon gefüllt ist, und holt dies gegebenenfalls nach. In jedem Fall gibt GetWebbrowser einen Verweis auf dieses Steuerelement zurück:

Private Function GetWebbrowser() As SHDocVw.WebBrowser
    If m_Webbrowser Is Nothing Then
        Set m_Webbrowser = _
        Me!ctlWebbrowser.Object
    End If
    Set GetWebbrowser = m_Webbrowser
End Function

Die Funktion DokumentHolen lädt dann zunächst eine leere Seite (about:blank) und wartet, bis diese Seite geladen ist. Wichtig ist der vorherige Aufruf der DoEvents-Anweisung, da das Webbrowser-Steuerelement sonst gegebenenfalls noch nicht bereit ist. Danach gibt die Funktion den Verweis auf das HTMLDocument-Objekt zurück.

Haupttabelle erstellen

Die Funktion TabelleErstellen erzeugt dann die Tabelle, die alle anderen Elemente enthält, und liefert diese an die Objektvariable objTable zurück. Als Parameter erwartet diese Prozedur einen Verweis auf das HTMLDocument-Objekt:

Private Function TabelleErstellen(objDocument As MSHTML.HTMLDocument) As MSHTML.HTMLTable
    Dim objTable As MSHTML.HTMLTable
    Set objTable = objDocument.createElement("Table")
    objDocument.Body.appendChild objTable
    objDocument.Body.Style.fontFamily = "calibri"
    objDocument.Body.Style.FontSize = "8px"
    With objTable
        .Style.borderCollapse = "collapse"
    End With
    Set TabelleErstellen = objTable
End Function

Die Prozedur erstellt ein neues HTMLTable-Element im Kontext des HTMLDocument-Objekts und hängt dieses dann an das HTMLDocument-Objekt an, sodass es Teil des Dokuments wird. Außerdem stellt es einige Schrift-Eigenschaften ein und legt mit borderCollapse fest, dass die Rahmen zweier benachbarter Tabellenzellen miteinander verschmelzen sollen.

Spaltenköpfe erstellen

Wir haben nun ein Tabellen-Objekt, das wir mit einigen Zeilen ausstatten wollen. Die erste Zeile soll die Spaltenköpfe, also die Datumsangaben anzeigen, weshalb wir dieser Spalte 28 Zellen für je einen Tag zuweisen. Vorher werden jedoch noch zwei leere Zellen eingefügt, weil die folgenden Zeilen auch zwei Zellen zur Anzeige der Mitarbeiternamen und zum Herstellen eines Abstands zwischen Mitarbeiternamen und den Zellen zur Anzeige der Fehlzeiten enthalten (Bild 9 veranschaulicht die beiden leeren Zellen).

pic011.png

Bild 9: Zwei leere Zellen in der Zeile mit den Spaltenköpfen

Danach durchläuft eine Schleife 28 Tage ausgehend von dem im Textfeld txtStart angegebenen Tag. Der aktuelle Tag wird dabei in der Laufvariablen datAktuell gespeichert. Innerhalb der Schleife wird lediglich die Prozedur ZelleTagAnlegen aufgerufen (siehe Listing 2). Die Prozedur ermittelt zunächst per DLookup-Anweisung, mit welcher Farbe der aktuelle Tag hinterlegt werden soll, und wandelt den Farbwert in ein Format um, das mit HTML dargestellt werden kann (die dazu verwendeten Funktionen finden Sie im Modul mdlTools).

Listing 2: Zelle für die Spaltenüberschrift mit Datum anlegen

Private Function ZelleTagAnlegen(dat As Date, objRow As MSHTML.HTMLTableRow)
    Dim objCell As MSHTML.HTMLTableCell
    Dim strBGColorCurrent As String
    strBGColorCurrent = RGBToHTML(HexFromLong(DLookup("KalenderFarbeAktuellerTag", "tblOptionen")))
    Set objCell = objRow.insertCell
    With objCell
        .Style.fontFamily = "Calibri"
        .Style.FontSize = "12px"
        .innerHTML = Format(dat, "ddd.") & "<br>" & Format(dat, "dd.mm.")
        .Style.TextAlign = "center"
        .Style.padding = "0px"
        .Style.margin = "0px"
        .Style.Width = "40px"
    End With
    Select Case Weekday(dat, vbMonday)
        Case 6, 7
            objCell.Style.FontWeight = "bold"
            objCell.Style.backgroundColor = "#eeeeee"
    End Select
    If dat = Date Then
        objCell.Style.backgroundColor = strBGColorCurrent
    End If
End Function

Dann fügt die insertCell-Methode eine neue Zelle zu der mit objRow referenzierten Zeile hinzu. Diese Zellen werden mit einer entsprechenden Schriftart, Ausrichtung, Textabstand und Breite ausgestattet und schließlich mit dem aktuellen Datum im Format ddd.dd.mm gefüllt, allerdings werden der abgekürzte Tag (ddd.) und der Rest (dd.mm.) durch einen Zeilenumbruch (<br>) voneinander getrennt.

Sollte es sich bei dem Tag um einen Samstag oder Sonntag handeln (Weekday liefert dann 6 oder 7), wird die Schrift noch fett gesetzt und ein grauer Hintergrund eingestellt. Schließlich stellt die Prozedur noch die zuvor ermittelte Hintergrundfarbe ein, falls die Spaltenüberschrift das aktuelle Datum darstellt.

Damit hätten wir nun eine Tabelle mit einer ersten Zeile, welche die Spaltenüberschriften enthält, in diesem Fall die Datumsangaben.

Danach folgt das verschachtelte Durchlaufen zweier Do While-Schleifen. Die erste behandelt alle Einträge des Recordsets rstAbteilungen, die zweite alle Mitarbeiter, die in der Übersicht angezeigt werden sollen.

Das sind nicht unbedingt alle – mit der Lösung des Beitrags 1:n-Beziehung mit HTML (www.access-im-unternehmen.de/851) wählen Sie nämlich die anzuzeigenden Mitarbeiter aus. Dabei werden diese Mitarbeiter in der Tabelle tblMitarbeiterAnzeigen gespeichert (s. Bild 10).

pic013.png

Bild 11: Ermittlung aller anzuzeigenden Mitarbeiter für die aktuelle Abteilung

Dementsprechend berücksichtigt das Recordset rstMitarbeiter nicht nur die in der übergeordneten Schleife aktive Abteilung, sondern auch noch die Tabelle tblMitarbeiterAnzeigen. Wer zur aktuellen Abteilung gehört und auch noch angezeigt werden soll, wird mit der Abfrage qryAusgewaehlteMitarbeiter ermittelt (s. Bild 11).

pic012.png

Bild 10: Diese Tabelle legt fest, welche Mitarbeiter in der Fehlzeitenübersicht erscheinen sollen.

Abteilungsüberschriften anlegen

Die OpenRecordset-Methode filtert diese Abfrage noch nach der AbteilungID des Recordsets rstAbteilungen. Innerhalb dieser beiden Schleifen geschieht nun eine ganze Menge. Bevor die Schleife über die Mitarbeiter der Abteilung startet, fügt die Prozedur ZeileAbteilungEinfuegen zunächst eine Zeile zur Tabelle hinzu, welche sich über die komplette Spalte erstreckt. Dabei erhält die Prozedur einen Verweis auf das HTMLTable-Objekt sowie die Bezeichnung der Abteilung als Parameter. Im Gegensatz zu den Zeilen mit den Spaltenüberschriften und den Mitarbeitern/Fehltagen soll diese Zeile nur eine einzige Zelle enthalten. Deshalb legt die Prozedur zunächst eine Zeile an (HTMLTableRow) und dann eine einzige Zelle (HTMLTableCell). Normalerweise würde diese Zelle ihre Breite an der Breite der Zellen der übrigen Zeilen ausrichten. Die Prozedur legt aber für die Eigenschaft colSpan der Zelle den Wert 30 fest, was bedeutet, dass sich die Zelle über 30 Zellen der übrigen Zeilen erstreckt – also über die gesamte Breite (eine Zelle mit der Mitarbeiterbezeichnung, eine Zelle als Platzhalter und 28 Zellen für die einzelnen Tage).

Private Sub ZeileAbteilungEinfuegen(objTable As MSHTML.HTMLTable, strAbteilung As String)
    Dim objRow As MSHTML.HTMLTableRow
    Dim objCell As MSHTML.HTMLTableCell
    Set objRow = objTable.insertRow
    With objRow
        .Style.Height = "20px"
    End With
    Set objCell = objRow.insertCell
    With objCell
        .innerText = strAbteilung
        .Style.borderTopColor = "#000000"
        .Style.borderTopStyle = "solid"
        .Style.borderTopWidth = "1px"
        .Style.borderBottomColor = "#000000"
        .Style.borderBottomStyle = "solid"
        .Style.borderBottomWidth = "1px"
        .colSpan = 30
    End With
End Sub

Erst nach dem Anlegen der Überschrift für die Abteilung folgt die innere Schleife über alle Mitarbeiter dieser Tabelle.

Mitarbeiter anlegen

Die erste Zeile erstellt durch einen Aufruf der Funktion ZeileMitMitarbeiterEinfuegen eine neue Zeile in der Tabelle. Die Funktion erwartet das HTMLTable-Objekt und liefert einen Verweis auf eine neue, leere Zeile zurück. Diese wurde lediglich mit einigen Eigenschaften für Höhe, Rahmenbreite und Abstand ausgestattet:

Private Function ZeileMitarbeiterEinfuegen( _
        objTable As MSHTML.HTMLTable) _
        As MSHTML.HTMLTableRow
    Dim objRow As MSHTML.HTMLTableRow
    Set objRow = objTable.insertRow
    With objRow
        .Style.Height = "30px"
        .Style.BorderWidth = "0px"
        .Style.margin = "0px"
    End With
    Set ZeileMitarbeiterEinfuegen = objRow
End Function

Mitarbeitername einfügen

Mit dieser in der Variablen objRow gespeicherten Zeile geht es in die nächste Prozedur namens ZeilenkopfMitarbeiterEinfuegen, die außerdem den anzuzeigenden Mitarbeiternamen entgegennimmt. Sie legt ein neues HTMLTableCell-Objekt an und füllt es mit dem Namen des Mitarbeiters sowie Informationen zur Schriftart. Auch die Platzhalter-Zelle mit der Breite von 10 Pixeln wird hier angelegt:

Private Sub ZeilenkopfMitarbeiterEinfuegen(objRow As MSHTML.HTMLTableRow, strMitarbeiter As String)
    Dim objCell As MSHTML.HTMLTableCaption
    Set objCell = objRow.insertCell
    With objCell
        .innerText = strMitarbeiter
        .Style.fontFamily = "Calibri"
        .Style.FontSize = "12px"
        .Style.verticalAlign = "middle"
    End With
    Set objCell = objRow.insertCell
    objCell.Style.Width = "10px"
End Sub

Kalenderelemente einfügen

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

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar