{"id":55000850,"date":"2012-08-01T00:00:00","date_gmt":"2020-05-22T21:48:06","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=850"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Fehlzeiten_verwalten","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/","title":{"rendered":"Fehlzeiten verwalten"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg05.met.vgwort.de\/na\/11ed7458fd5843da953f7ae748e16be4\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>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 &#8211; mehr ben&ouml;tigen Sie nicht. Interessant wird es jedoch, die Fehlzeiten einzugeben und diese &uuml;bersichtlich darzustellen. Und zwar so, dass nicht nur die Fehlzeiten eines einzigen Mitarbeiters, sondern m&ouml;glichst die aller Mitarbeiter sichtbar sind. Nur so l&auml;sst sich effektiv vorausplanen.<\/b><\/p>\n<p>Die Musterl&ouml;sung dieses Beitrags soll es erlauben, mehrere Mitarbeiter zu verwalten und f&uuml;r jeden Tag Fehlzeiten in Form halber Tage festzuhalten &#8211; 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.<\/p>\n<p><b>Datenmodell<\/b><\/p>\n<p>Das Datenmodell besteht aus einer einfachen Mitarbeitertabelle und einer Tabelle zur Verwaltung von Abteilungen. Au&szlig;erdem gibt es eine Tabelle zum Speichern der verschiedenen Arten von Fehlzeiten und eine zum Aufnehmen der Fehlzeiten selbst.<\/p>\n<p>Die Tabelle <b>tblMitarbeiter <\/b>ist recht einfach gehalten und enth&auml;lt neben dem Prim&auml;rschl&uuml;sselfeld nur zwei Felder zur Angabe von Vor- und Nachname, ein Feld zum Eintragen einer Bezeichnung, die in der Regel die Form <b>&lt;Nachname&gt;, &lt;Vorname&gt; <\/b>aufweist, und ein Nachschlagefeld zur Auswahl der Abteilung des Mitarbeiters (s. Bild 1). Die damit referenzierte Tabelle <b>tblAbteilung <\/b>ist eine schlichte Lookup-Tabelle, die nur das Prim&auml;rschl&uuml;sselfeld <b>AbteilungID <\/b>sowie das Feld mit der Bezeichnung der Abteilung enth&auml;lt.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic004.png\" alt=\"pic004.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3: Fehlzeiten werden jeweils als halbe Tage erfasst<\/span><\/b><\/p>\n<p>Gleiches gilt f&uuml;r die Tabelle <b>tblFehlzeitarten<\/b>, die nur aus den beiden Feldern <b>FehlzeitartID <\/b>und <b>Fehlzeitart <\/b>besteht. Sie nimmt in der aktuellen Version die drei Werte <b>Krankheit<\/b>, <b>Urlaub <\/b>und <b>Weiterbildung <\/b>auf (s. Bild 2).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic001.png\" alt=\"pic001.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Die Tabelle tblMitarbeiter in der Entwurfsansicht<\/span><\/b><\/p>\n<p>Fehlt noch die Tabelle <b>tblFehlzeiten<\/b>, welche die tats&auml;chlichen Fehlzeiten aufnimmt. Sie enth&auml;lt ein Prim&auml;rschl&uuml;sselfeld namens <b>FehlzeitID<\/b> und ein Datumsfeld namens <b>Fehlzeitdatum<\/b>. Weitere zwei Felder sind Fremdschl&uuml;sselfelder und referenzieren die Datens&auml;tze der Tabellen <b>tblMitarbeiter<\/b> und <b>tblFehlzeitarten<\/b>.<\/p>\n<p>Fehlt noch eine wichtige Information, die davon abh&auml;ngt, ob Sie nur ganze Fehltage aufnehmen m&ouml;chten oder auch halbe Fehltage (man k&ouml;nnte dies nat&uuml;rlich auch stundenweise erledigen, aber wenn jemand zwei Stunden frei haben m&ouml;chte, um mit seinem Kind zum Arzt zu gehen, h&auml;ngt er die zwei Stunden halt irgendwo hinten an).<\/p>\n<p>Wie aber bekommen wir die halben Fehltage in den Griff Bei einem ganzen Fehltag w&auml;re dies kein Problem: Sie legen einen Eintrag in der Tabelle <b>tblFehltage <\/b>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&auml;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&auml;lfte der Schicht betrifft<\/p>\n<p>Dies wird n&auml;mlich beispielsweise interessant, wenn immer eine bestimmte Anzahl Mitarbeiter gebraucht wird. Und auch f&uuml;r eine grafische Darstellung der Fehlzeiten w&auml;re es sinnvoll, die Position des halben Fehltages anzeigen zu k&ouml;nnen. Welche M&ouml;glichkeiten haben wir nun<\/p>\n<ul>\n<li class=\"aufz-hlung\">Sie k&ouml;nnten ein Fremdschl&uuml;sselfeld und eine entsprechende Lookup-Tabelle anlegen, welche die beiden Werte <b>Vormittags <\/b>und <b>Nachmittags <\/b>enth&auml;lt. Dann brauchen Sie aber auch noch einen Wert f&uuml;r <b>Kompletter Tag<\/b>.<\/li>\n<li class=\"aufz-hlung\">Sie k&ouml;nnten zwei <b>Ja\/Nein<\/b>-Felder namens <b>Vormittag <\/b>und <b>Nachmittag <\/b>anlegen und entweder eines von beiden oder, im Falle eines kompletten Fehltages, beide Felder auf <b>Ja <\/b>einstellen.<\/li>\n<li class=\"aufz-hlung\">Sie legen grunds&auml;tzlich einen neuen Datensatz pro halben Fehltag in der Tabelle an und verwenden dabei nur ein Feld namens <b>Vormittags<\/b>, um den Zeitraum festzulegen. Ist <b>Vormittags <\/b>aktiviert, liegt der halbe Fehltag in der ersten Tagesh&auml;lfte, sonst in der zweiten Tagesh&auml;lfte. F&uuml;r einen kompletten Fehltag legen Sie also zwei Datens&auml;tze an, bei denen das Feld <b>Vormittags <\/b>einmal aktiviert ist und einmal nicht.<\/li>\n<\/ul>\n<p>Wir entscheiden uns f&uuml;r die letzte Variante. Die Tabelle <b>tblFehlzeiten<\/b> sieht somit wie in Bild 4).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic002.png\" alt=\"pic002.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: Tabelle zum Speichern der Fehlzeitarten<\/span><\/b><\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic005.png\" alt=\"pic005.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 4: Datenmodell der Musterl&ouml;sung<\/span><\/b><\/p>\n<p><b>Darstellung der Fehlzeiten im Formular<\/b><\/p>\n<p>F&uuml;r die Darstellung der Fehlzeiten gibt es mehrere M&ouml;glichkeiten. Grunds&auml;tzlich sollen die Spaltenk&ouml;pfe die Datumsangaben enthalten und die Zeilenk&ouml;pfe die Namen der Mitarbeiter. Die einzelnen Zellen erhalten dann eine die jeweilige Fehlzeitart repr&auml;sentierende Farbe (diese legen Sie &uuml;brigens in der Tabelle <b>tblFehlzeitarten <\/b>fest &#8211; sp&auml;ter lernen Sie ein Formular zur Bearbeitung der Fehlzeitarten kennen). Aber da wir uns nun schon darauf eingeschossen haben, auch halbt&auml;gige Fehlzeiten zu vergeben: Wie stellen wir diese in einer &Uuml;bersicht wie oben beschrieben dar Eigentlich gibt es nur zwei M&ouml;glichkeiten: entweder die Fehlzeit am Vormittag landet oben und die am Nachmittag unten oder die Fehlzeiten werden links und rechts im Kasten f&uuml;r den jeweiligen Tag angezeigt. F&uuml;r ganzt&auml;gige Fehlzeiten wird der komplette Kasten mit der entsprechenden Farbe gef&uuml;llt.<\/p>\n<p>Bild 5 zeigt, wie der zweite Vorschlag aussieht. Dieser ist die bessere L&ouml;sung, weil man die Fehlzeiten f&uuml;r den Vor- und den Nachmittag durch Pr&uuml;fen einer einzigen Spalte &uuml;berblicken kann. Diese Ansicht l&auml;sst sich mit Bordmitteln nicht realisieren. Zwar k&ouml;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 &uuml;bergeordneten Kategorie wie etwa Abteilungen gruppieren m&ouml;chten, haben Sie keine Chance. Daher stellen wir einmal dar, wie dies mit dem Webbrowser-Steuerelement und HTML funktioniert.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic007.png\" alt=\"pic007.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 5: Formular zum Hinzuf&uuml;gen von Fehlzeiten<\/span><\/b><\/p>\n<p>Wie werden die Fehlzeiten hinzugef&uuml;gt oder entfernt Dazu enth&auml;lt jedes einzelne Element in der Fehlzeiten&uuml;bersicht ein Kontextmen&uuml; (s. Bild 6). Klicken Sie mit der rechten Maustaste auf den Tag f&uuml;r den entsprechenden Mitarbeiter und w&auml;hlen Sie die gew&uuml;nschte Fehlzeitart samt Dauer aus.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic009.png\" alt=\"pic009.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 6: Fehlzeit per Kontextmen&uuml;<\/span><\/b><\/p>\n<p><b>Formular anlegen<\/b><\/p>\n<p>Das Formular sieht in der Entwurfsansicht wie in Bild 7 aus und enth&auml;lt zun&auml;chst ein Webbrowser-Steuerelement. Dieses f&uuml;gen Sie in den Access-Versionen bis Access 2007 als ActiveX-Steuerelement hinzu, ab Access 2010 verwenden Sie das eingebaute Webbrowser-Steuerelement.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic008.png\" alt=\"pic008.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 7: Das Formular zur Anzeige der Fehlzeiten&uuml;bersicht in der Entwurfsansicht<\/span><\/b><\/p>\n<p>Das Webbrowser-Steuerelement soll den Namen <b>ctlWebbrowser <\/b>erhalten.<\/p>\n<p>Im Kopfbereich des Formulars finden Sie folgende Steuerelemente:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>txtStart<\/b>: Textfeld zur Anzeige beziehungsweise Eingabe eines Tages, der in der ersten Woche der vierw&ouml;chigen Anzeige liegt<\/li>\n<li class=\"aufz-hlung\"><b>cmdNaechsteWoche<\/b>: Schaltfl&auml;che, welche die Anzeige um eine Woche in die Zukunft verschiebt<\/li>\n<li class=\"aufz-hlung\"><b>cmdVorherigeWoche<\/b>: Schaltfl&auml;che, welche die Anzeige um eine Woche in die Vergangenheit verschiebt<\/li>\n<li class=\"aufz-hlung\"><b>cmdMitarbeiterFiltern<\/b>: &Ouml;ffnet einen Dialog, mit dem Sie einstellen k&ouml;nnen, f&uuml;r welche Mitarbeiter die Fehlzeiten angezeigt werden sollen<\/li>\n<li class=\"aufz-hlung\"><b>cmdFuellen<\/b>: Aktualisiert die Anzeige<\/li>\n<li class=\"aufz-hlung\"><b>cmdFehlzeitarten<\/b>: &Ouml;ffnet einen Dialog zum Bearbeiten der Fehlzeitarten<\/li>\n<\/ul>\n<p><b>F&uuml;llen des Webbrowser-Steuerelements<\/b><\/p>\n<p>Die aufwendigste Aufgabe dieser Beispielanwendung ist nat&uuml;rlich das F&uuml;llen des Webbrowser-Steuerelements. Dies erledigt die Prozedur <b>FehlzeitenAnzeigen<\/b> &#8211; mehr dazu weiter unten.<\/p>\n<p>Diese Prozedur wird zu verschiedenen Gelegenheiten aufgerufen, als Erstes nat&uuml;rlich beim Anzeigen des Formulars &#8211; hier in der Prozedur, die durch das Ereignis <b>Beim Laden <\/b>ausgel&ouml;st wird:<\/p>\n<pre>Private Sub Form_Load()\r\n    Dim datMontag As Date\r\n    datMontag = MontagDerWoche(Date)\r\n    Me!txtStart = datMontag\r\n    FehlzeitenAnzeigen\r\nEnd Sub<\/pre>\n<p>Diese Prozedur leistet allerdings noch ein wenig Vorarbeit: Sie ermittelt mit der <b>Date<\/b>-Funktion das aktuelle Datum und daraus mit der Funktion <b>MontagDerWoche<\/b> den Montag der Woche, in der das Datum liegt:<\/p>\n<pre>Public Function MontagDerWoche(dat As Date) As Date\r\n    Dim intWeekday As Integer\r\n    intWeekday = Weekday(dat, vbMonday)\r\n    MontagDerWoche = DateAdd(&quot;d&quot;, -(intWeekday - 1), dat)\r\nEnd Function<\/pre>\n<p><b>MontagDerWoche <\/b>holt sich mit der <b>Weekday<\/b>-Funktion eine Zahl, welche den Tag der Woche repr&auml;sentiert, also beispielsweise den Wert <b>3<\/b>, wenn der Tag von <b>Date <\/b>ein Mittwoch ist (Montag entspricht <b>1<\/b>). 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.<\/p>\n<p>Dieses Datum tr&auml;gt <b>Form_Load <\/b>in das Textfeld <b>txtStart <\/b>ein und ruft dann die Prozedur <b>FehlzeitenAnzeigen <\/b>auf. Die Prozedur wird auch aufgerufen, wenn der Benutzer eine der beiden Schaltfl&auml;chen <b>cmdNaechsteWoche <\/b>oder <b>cmdVorherigeWoche <\/b>anklickt. Die dadurch ausgel&ouml;sten Prozeduren f&uuml;gen entweder sieben Tage zum Datum im Textfeld <b>txtStart <\/b>hinzu oder ziehen diese ab, um den Startzeitpunkt der Fehlzeitenanzeige um eine Woche nach vorn oder hinten zu verschieben:<\/p>\n<pre>Private Sub cmdNaechsteWoche_Click()\r\n    Me!txtStart = Me!txtStart + 7\r\n    FehlzeitenAnzeigen\r\nEnd Sub\r\nPrivate Sub cmdVorherigeWoche_Click()\r\n    Me!txtStart = Me!txtStart - 7\r\n    FehlzeitenAnzeigen\r\nEnd Sub<\/pre>\n<p>Das Anklicken der Schaltfl&auml;che <b>cmdFuellen <\/b>dient allein der Aktualisierung der Anzeige:<\/p>\n<pre>Private Sub cmdFuellen_Click()\r\n    FehlzeitenAnzeigen\r\nEnd Sub<\/pre>\n<p>Au&szlig;erdem wird die Anzeige noch nach dem Bearbeiten der anzuzeigenden Mitarbeiter und der Fehlzeitarten aktualisiert &#8211; mehr dazu weiter unten.<\/p>\n<p><b>Die Prozedur FehlzeitenAnzeigen<\/b><\/p>\n<p>Diese Prozedur, die Sie im Klassenmodul des Formulars <b>frmFehlzeiten <\/b>finden (und in <span class=\"verweis-ohneumbruch\"><a href=\"#anker-49-anchor\">Listing 1<\/a><\/span>), bildet das Grundger&uuml;st zum F&uuml;llen der Fehlzeiten-&Uuml;bersicht. Einige weitere Prozeduren &uuml;bernehmen die Kleinarbeit wie das Anlegen und Ausstatten der einzelnen Tabellenelemente wie Zeilen, Zellen, in Zellen enthaltene Tabellen und so weiter.<\/p>\n<p class=\"listingueberschrift\">Listing 1: F&uuml;llen des Webbrowser-Steuerelements<\/p>\n<pre>Private Sub FehlzeitenAnzeigen()\r\n    Dim objDocument As MSHTML.HTMLDocument\r\n    Dim db As DAO.Database\r\n    Dim rstMitarbeiter As DAO.Recordset\r\n    Dim rstAbteilungen As DAO.Recordset\r\n    Dim datAktuell As Date\r\n    Dim objTable As MSHTML.HTMLTable\r\n    Dim objRow As MSHTML.HTMLTableRow\r\n    Set colTableCells = New Collection\r\n    Set db = CurrentDb\r\n    Set rstAbteilungen = db.OpenRecordset(&quot;SELECT * FROM qryAbteilungenMitMitarbeitern&quot;, dbOpenDynaset)\r\n    Set objDocument = DokumentHolen\r\n    Set objTable = TabelleErstellen(objDocument)\r\n    Set objRow = objTable.insertRow\r\n    objRow.insertCell\r\n    objRow.insertCell\r\n    For datAktuell = Me!txtStart To DateAdd(&quot;d&quot;, 27, Me!txtStart)\r\n        ZelleTagAnlegen datAktuell, objRow\r\n    Next datAktuell\r\n    Do While Not rstAbteilungen.EOF\r\n        ZeileAbteilungEinfuegen objTable, rstAbteilungen!Abteilung\r\n        Set rstMitarbeiter = db.OpenRecordset(&quot;SELECT * FROM qryAusgewaehlteMitarbeiter &quot; _\r\n            &amp; &quot;WHERE AbteilungID = &quot; &amp; rstAbteilungen!AbteilungID, dbOpenDynaset)\r\n        Do While Not rstMitarbeiter.EOF\r\n            Set objRow = ZeileMitarbeiterEinfuegen(objTable)\r\n            ZeilenkopfMitarbeiterEinfuegen objRow, rstMitarbeiter!Bezeichnung\r\n            For datAktuell = Me!txtStart To DateAdd(&quot;d&quot;, 27, Me!txtStart)\r\n                Set objTableCell = ZelleTagMitarbeiterHinzufuegen(datAktuell, objRow, _\r\n                    rstMitarbeiter!MitarbeiterID, objDocument)\r\n                colTableCells.Add objTableCell, CLng(rstMitarbeiter!MitarbeiterID) &amp; &quot;|&quot; _\r\n                    &amp; CLng(datAktuell)\r\n            Next datAktuell\r\n            rstMitarbeiter.MoveNext\r\n        Loop\r\n        rstAbteilungen.MoveNext\r\n    Loop\r\n    FehlzeitenEintragen Me!txtStart, DateAdd(&quot;d&quot;, 27, Me!txtStart)\r\nEnd Sub<\/pre>\n<p>Im Deklarationsteil finden Sie unter anderem zwei Recordset-Objekte, mit denen erst die Abteilungen und dann die Mitarbeiter der Abteilungen durchlaufen werden, und au&szlig;erdem einige HTML-Objekte.<\/p>\n<p>Danach folgt direkt die Instanzierung eines Collection-Objekts, das im Kopf des Klassenmoduls des Formulars deklariert wird:<\/p>\n<pre>Dim colTableCells As Collection<\/pre>\n<p>Wozu das Jeder Tag soll ja zwei Zellen enthalten, die nach einem Mausklick ein Kontextmen&uuml; anzeigen. Dies gelingt nur, wenn Sie eine entsprechende Ereignisprozedur f&uuml;r die entsprechenden <b>HTMLTableCell<\/b>-Elemente anlegen. Nun w&auml;re es aber ein wahnsinniger Aufwand, vorab f&uuml;r viele hundert <b>HTMLTableCell<\/b>-Elemente Ereignisprozeduren anzulegen.<\/p>\n<p>Daher verwenden wir eine kleine Wrapper-Klasse, der wir einen Bezug auf das jeweilige <b>HTMLTableCell<\/b>-Element mitgeben. Diese Wrapper-Klasse enth&auml;lt die f&uuml;r die Anzeige des Kontextmen&uuml;s n&ouml;tigen Ereignisprozeduren. Vorteil: Sie brauchen die Klasse nur einmal zu programmieren und k&ouml;nnen sie f&uuml;r jedes der Kalender-Elemente, das ein Kontextmen&uuml; anzeigen soll, neu instanzieren.<\/p>\n<p>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.<\/p>\n<p><b>Abteilungen durchlaufen<\/b><\/p>\n<p>Das Recordset <b>rstAbteilungen<\/b> basiert auf einer Abfrage, die nicht alle Abteilungen der Tabelle <b>tblAbteilungen<\/b> zur&uuml;ckliefert, sondern nur diejenigen, die mindestens einen Mitarbeiter enthalten. Die dabei verwendete Abfrage <b>qryAbteilungenMitMitarbeitern <\/b>sieht wie in Bild 8 aus. Die Abfrage gibt zwar nur Felder der Tabelle <b>tblAbteilungen <\/b>zur&uuml;ck, aber dadurch, dass diese in der Abfrage mit der Tabelle <b>tblMitarbeiter <\/b>verkn&uuml;pft ist, werden die Datens&auml;tze ohne Bezug zu einem Mitarbeiter-Datensatz ignoriert.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic010.png\" alt=\"pic010.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 8: Abfrage zur Ermittlung aller Abteilungen mit mindestens einem Mitarbeiter<\/span><\/b><\/p>\n<p>Danach liefert die Funktion <b>DokumentHolen <\/b>einen Verweis auf ein HTML-Dokument, das innerhalb dieser Funktion erstellt wird:<\/p>\n<pre>Private Function DokumentHolen() As MSHTML.HTMLDocument\r\n    Dim objWebbrowser As SHDocVw.WebBrowser\r\n    Dim objDocument As MSHTML.HTMLDocument\r\n    Set objWebbrowser = GetWebbrowser\r\n    DoEvents\r\n    objWebbrowser.Navigate &quot;about:blank&quot;\r\n    Do\r\n        DoEvents\r\n    Loop Until objWebbrowser.ReadyState = READYSTATE_COMPLETE\r\n    Set objDocument = objWebbrowser.Document\r\n    Set DokumentHolen = objDocument\r\nEnd Function<\/pre>\n<p>Die Funktion verwendet zun&auml;chst eine weitere Funktion namens <b>GetWebbrowser<\/b>, um eine Referenz auf das im Formular enthaltene Webbrowser-Steuerelement zu erhalten. Diese wird nach dem Erstellen in der modulweit deklarierten Variablen gespeichert:<\/p>\n<pre>Dim WithEvents m_Webbrowser As WebBrowser<\/pre>\n<p>Die Funktion <b>GetWebbrowser <\/b>pr&uuml;ft, ob <b>m_Webbrowser <\/b>schon gef&uuml;llt ist, und holt dies gegebenenfalls nach. In jedem Fall gibt <b>GetWebbrowser <\/b>einen Verweis auf dieses Steuerelement zur&uuml;ck:<\/p>\n<pre>Private Function GetWebbrowser() As SHDocVw.WebBrowser\r\n    If m_Webbrowser Is Nothing Then\r\n        Set m_Webbrowser = _\r\n        Me!ctlWebbrowser.Object\r\n    End If\r\n    Set GetWebbrowser = m_Webbrowser\r\nEnd Function<\/pre>\n<p>Die Funktion <b>DokumentHolen <\/b>l&auml;dt dann zun&auml;chst eine leere Seite (<b>about:blank<\/b>) und wartet, bis diese Seite geladen ist. Wichtig ist der vorherige Aufruf der <b>DoEvents<\/b>-Anweisung, da das Webbrowser-Steuerelement sonst gegebenenfalls noch nicht bereit ist. Danach gibt die Funktion den Verweis auf das <b>HTMLDocument<\/b>-Objekt zur&uuml;ck.<\/p>\n<p><b>Haupttabelle erstellen<\/b><\/p>\n<p>Die Funktion <b>TabelleErstellen <\/b>erzeugt dann die Tabelle, die alle anderen Elemente enth&auml;lt, und liefert diese an die Objektvariable <b>objTable <\/b>zur&uuml;ck. Als Parameter erwartet diese Prozedur einen Verweis auf das <b>HTMLDocument<\/b>-Objekt:<\/p>\n<pre>Private Function TabelleErstellen(objDocument As MSHTML.HTMLDocument) As MSHTML.HTMLTable\r\n    Dim objTable As MSHTML.HTMLTable\r\n    Set objTable = objDocument.createElement(&quot;Table&quot;)\r\n    objDocument.Body.appendChild objTable\r\n    objDocument.Body.Style.fontFamily = &quot;calibri&quot;\r\n    objDocument.Body.Style.FontSize = &quot;8px&quot;\r\n    With objTable\r\n        .Style.borderCollapse = &quot;collapse&quot;\r\n    End With\r\n    Set TabelleErstellen = objTable\r\nEnd Function<\/pre>\n<p>Die Prozedur erstellt ein neues <b>HTMLTable<\/b>-Element im Kontext des <b>HTMLDocument<\/b>-Objekts und h&auml;ngt dieses dann an das <b>HTMLDocument<\/b>-Objekt an, sodass es Teil des Dokuments wird. Au&szlig;erdem stellt es einige Schrift-Eigenschaften ein und legt mit <b>borderCollapse <\/b>fest, dass die Rahmen zweier benachbarter Tabellenzellen miteinander verschmelzen sollen.<\/p>\n<p><b>Spaltenk&ouml;pfe erstellen<\/b><\/p>\n<p>Wir haben nun ein Tabellen-Objekt, das wir mit einigen Zeilen ausstatten wollen. Die erste Zeile soll die Spaltenk&ouml;pfe, also die Datumsangaben anzeigen, weshalb wir dieser Spalte 28 Zellen f&uuml;r je einen Tag zuweisen. Vorher werden jedoch noch zwei leere Zellen eingef&uuml;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).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic011.png\" alt=\"pic011.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 9: Zwei leere Zellen in der Zeile mit den Spaltenk&ouml;pfen<\/span><\/b><\/p>\n<p>Danach durchl&auml;uft eine Schleife 28 Tage ausgehend von dem im Textfeld <b>txtStart <\/b>angegebenen Tag. Der aktuelle Tag wird dabei in der Laufvariablen <b>datAktuell <\/b>gespeichert. Innerhalb der Schleife wird lediglich die Prozedur <b>ZelleTagAnlegen <\/b>aufgerufen (siehe <span class=\"verweis-ohneumbruch\"><a href=\"#anker-60-anchor\">Listing 2<\/a><\/span>). Die Prozedur ermittelt zun&auml;chst per <b>DLookup<\/b>-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 <b>mdlTools<\/b>).<\/p>\n<p class=\"listingueberschrift\">Listing 2: Zelle f&uuml;r die Spalten&uuml;berschrift mit Datum anlegen<\/p>\n<pre>Private Function ZelleTagAnlegen(dat As Date, objRow As MSHTML.HTMLTableRow)\r\n    Dim objCell As MSHTML.HTMLTableCell\r\n    Dim strBGColorCurrent As String\r\n    strBGColorCurrent = RGBToHTML(HexFromLong(DLookup(&quot;KalenderFarbeAktuellerTag&quot;, &quot;tblOptionen&quot;)))\r\n    Set objCell = objRow.insertCell\r\n    With objCell\r\n        .Style.fontFamily = &quot;Calibri&quot;\r\n        .Style.FontSize = &quot;12px&quot;\r\n        .innerHTML = Format(dat, &quot;ddd.&quot;) &amp; &quot;&lt;br&gt;&quot; &amp; Format(dat, &quot;dd.mm.&quot;)\r\n        .Style.TextAlign = &quot;center&quot;\r\n        .Style.padding = &quot;0px&quot;\r\n        .Style.margin = &quot;0px&quot;\r\n        .Style.Width = &quot;40px&quot;\r\n    End With\r\n    Select Case Weekday(dat, vbMonday)\r\n        Case 6, 7\r\n            objCell.Style.FontWeight = &quot;bold&quot;\r\n            objCell.Style.backgroundColor = &quot;#eeeeee&quot;\r\n    End Select\r\n    If dat = Date Then\r\n        objCell.Style.backgroundColor = strBGColorCurrent\r\n    End If\r\nEnd Function<\/pre>\n<p><!--30percent--><\/p>\n<p>Dann f&uuml;gt die <b>insertCell<\/b>-Methode eine neue Zelle zu der mit <b>objRow <\/b>referenzierten Zeile hinzu. Diese Zellen werden mit einer entsprechenden Schriftart, Ausrichtung, Textabstand und Breite ausgestattet und schlie&szlig;lich mit dem aktuellen Datum im Format <b>ddd.dd.mm <\/b>gef&uuml;llt, allerdings werden der abgek&uuml;rzte Tag (<b>ddd.<\/b>) und der Rest (<b>dd.mm.<\/b>) durch einen Zeilenumbruch (<b>&lt;br&gt;<\/b>) voneinander getrennt.<\/p>\n<p>Sollte es sich bei dem Tag um einen Samstag oder Sonntag handeln (<b>Weekday <\/b>liefert dann <b>6 <\/b>oder <b>7<\/b>), wird die Schrift noch fett gesetzt und ein grauer Hintergrund eingestellt. Schlie&szlig;lich stellt die Prozedur noch die zuvor ermittelte Hintergrundfarbe ein, falls die Spalten&uuml;berschrift das aktuelle Datum darstellt.<\/p>\n<p>Damit h&auml;tten wir nun eine Tabelle mit einer ersten Zeile, welche die Spalten&uuml;berschriften enth&auml;lt, in diesem Fall die Datumsangaben.<\/p>\n<p>Danach folgt das verschachtelte Durchlaufen zweier <b>Do While<\/b>-Schleifen. Die erste behandelt alle Eintr&auml;ge des Recordsets <b>rstAbteilungen<\/b>, die zweite alle Mitarbeiter, die in der &Uuml;bersicht angezeigt werden sollen.<\/p>\n<p>Das sind nicht unbedingt alle &#8211; mit der L&ouml;sung des Beitrags <b>1:n-Beziehung mit HTML <\/b>(<b>www.access-im-unternehmen.de\/851<\/b>) w&auml;hlen Sie n&auml;mlich die anzuzeigenden Mitarbeiter aus. Dabei werden diese Mitarbeiter in der Tabelle <b>tblMitarbeiterAnzeigen<\/b> gespeichert (s. Bild 10).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic013.png\" alt=\"pic013.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 11: Ermittlung aller anzuzeigenden Mitarbeiter f&uuml;r die aktuelle Abteilung<\/span><\/b><\/p>\n<p>Dementsprechend ber&uuml;cksichtigt das Recordset <b>rstMitarbeiter <\/b>nicht nur die in der &uuml;bergeordneten Schleife aktive Abteilung, sondern auch noch die Tabelle <b>tblMitarbeiterAnzeigen<\/b>. Wer zur aktuellen Abteilung geh&ouml;rt und auch noch angezeigt werden soll, wird mit der Abfrage <b>qryAusgewaehlteMitarbeiter <\/b>ermittelt (s. Bild 11).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic012.png\" alt=\"pic012.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 10: Diese Tabelle legt fest, welche Mitarbeiter in der Fehlzeiten&uuml;bersicht erscheinen sollen.<\/span><\/b><\/p>\n<p><b>Abteilungs&uuml;berschriften anlegen<\/b><\/p>\n<p>Die <b>OpenRecordset<\/b>-Methode filtert diese Abfrage noch nach der <b>AbteilungID <\/b>des Recordsets <b>rstAbteilungen<\/b>. Innerhalb dieser beiden Schleifen geschieht nun eine ganze Menge. Bevor die Schleife &uuml;ber die Mitarbeiter der Abteilung startet, f&uuml;gt die Prozedur <b>ZeileAbteilungEinfuegen<\/b> zun&auml;chst eine Zeile zur Tabelle hinzu, welche sich &uuml;ber die komplette Spalte erstreckt. Dabei erh&auml;lt die Prozedur einen Verweis auf das <b>HTMLTable<\/b>-Objekt sowie die Bezeichnung der Abteilung als Parameter. Im Gegensatz zu den Zeilen mit den Spalten&uuml;berschriften und den Mitarbeitern\/Fehltagen soll diese Zeile nur eine einzige Zelle enthalten. Deshalb legt die Prozedur zun&auml;chst eine Zeile an (<b>HTMLTableRow<\/b>) und dann eine einzige Zelle (<b>HTMLTableCell<\/b>). Normalerweise w&uuml;rde diese Zelle ihre Breite an der Breite der Zellen der &uuml;brigen Zeilen ausrichten. Die Prozedur legt aber f&uuml;r die Eigenschaft <b>colSpan <\/b>der Zelle den Wert <b>30 <\/b>fest, was bedeutet, dass sich die Zelle &uuml;ber 30 Zellen der &uuml;brigen Zeilen erstreckt &#8211; also &uuml;ber die gesamte Breite (eine Zelle mit der Mitarbeiterbezeichnung, eine Zelle als Platzhalter und 28 Zellen f&uuml;r die einzelnen Tage).<\/p>\n<pre>Private Sub ZeileAbteilungEinfuegen(objTable As MSHTML.HTMLTable, strAbteilung As String)\r\n    Dim objRow As MSHTML.HTMLTableRow\r\n    Dim objCell As MSHTML.HTMLTableCell\r\n    Set objRow = objTable.insertRow\r\n    With objRow\r\n        .Style.Height = &quot;20px&quot;\r\n    End With\r\n    Set objCell = objRow.insertCell\r\n    With objCell\r\n        .innerText = strAbteilung\r\n        .Style.borderTopColor = &quot;#000000&quot;\r\n        .Style.borderTopStyle = &quot;solid&quot;\r\n        .Style.borderTopWidth = &quot;1px&quot;\r\n        .Style.borderBottomColor = &quot;#000000&quot;\r\n        .Style.borderBottomStyle = &quot;solid&quot;\r\n        .Style.borderBottomWidth = &quot;1px&quot;\r\n        .colSpan = 30\r\n    End With\r\nEnd Sub<\/pre>\n<p>Erst nach dem Anlegen der &Uuml;berschrift f&uuml;r die Abteilung folgt die innere Schleife &uuml;ber alle Mitarbeiter dieser Tabelle.<\/p>\n<p><b>Mitarbeiter anlegen<\/b><\/p>\n<p>Die erste Zeile erstellt durch einen Aufruf der Funktion <b>ZeileMitMitarbeiterEinfuegen <\/b>eine neue Zeile in der Tabelle. Die Funktion erwartet das <b>HTMLTable<\/b>-Objekt und liefert einen Verweis auf eine neue, leere Zeile zur&uuml;ck. Diese wurde lediglich mit einigen Eigenschaften f&uuml;r H&ouml;he, Rahmenbreite und Abstand ausgestattet:<\/p>\n<pre>Private Function ZeileMitarbeiterEinfuegen( _\r\n        objTable As MSHTML.HTMLTable) _\r\n        As MSHTML.HTMLTableRow\r\n    Dim objRow As MSHTML.HTMLTableRow\r\n    Set objRow = objTable.insertRow\r\n    With objRow\r\n        .Style.Height = &quot;30px&quot;\r\n        .Style.BorderWidth = &quot;0px&quot;\r\n        .Style.margin = &quot;0px&quot;\r\n    End With\r\n    Set ZeileMitarbeiterEinfuegen = objRow\r\nEnd Function<\/pre>\n<p><b>Mitarbeitername einf&uuml;gen<\/b><\/p>\n<p>Mit dieser in der Variablen <b>objRow <\/b>gespeicherten Zeile geht es in die n&auml;chste Prozedur namens <b>ZeilenkopfMitarbeiterEinfuegen<\/b>, die au&szlig;erdem den anzuzeigenden Mitarbeiternamen entgegennimmt. Sie legt ein neues <b>HTMLTableCell<\/b>-Objekt an und f&uuml;llt es mit dem Namen des Mitarbeiters sowie Informationen zur Schriftart. Auch die Platzhalter-Zelle mit der Breite von 10 Pixeln wird hier angelegt:<\/p>\n<pre>Private Sub ZeilenkopfMitarbeiterEinfuegen(objRow As MSHTML.HTMLTableRow, strMitarbeiter As String)\r\n    Dim objCell As MSHTML.HTMLTableCaption\r\n    Set objCell = objRow.insertCell\r\n    With objCell\r\n        .innerText = strMitarbeiter\r\n        .Style.fontFamily = &quot;Calibri&quot;\r\n        .Style.FontSize = &quot;12px&quot;\r\n        .Style.verticalAlign = &quot;middle&quot;\r\n    End With\r\n    Set objCell = objRow.insertCell\r\n    objCell.Style.Width = &quot;10px&quot;\r\nEnd Sub<\/pre>\n<p><b>Kalenderelemente einf&uuml;gen<\/b><\/p>\n<p>Nun folgt das Raster zum Aufnehmen je einer Zelle pro Tag und Mitarbeiter. Dazu wird erneut eine Schleife &uuml;ber 28 Tage durchlaufen. Jedes Kalenderelement besteht nicht nur aus einer einfachen Zelle. Diese Zelle soll ja gegebenenfalls unterschiedliche Hintergrundfarben auch f&uuml;r halbe Fehlzeit-Tage anzeigen. Also muss jede Zelle wiederum zwei Zellen enthalten. Diese k&ouml;nnen Sie unter HTML jedoch nicht direkt in eine Zelle einf&uuml;gen. Stattdessen legen Sie in jeder der Zellen f&uuml;r einen Tag eine Tabelle mit einer Zeile und den zwei ben&ouml;tigten Zellen an.<\/p>\n<p>All dies und mehr erledigt die Funktion <b>ZelleTagMitarbeiterHinzufuegen<\/b>, die das aktuelle Datum, einen Verweis auf die Zeile f&uuml;r den Mitarbeiter (<b>HTMLTableRow<\/b>), die <b>MitarbeiterID <\/b>des Mitarbeiters sowie einen Verweis auf das <b>HTMLDocument<\/b>-Objekt erwartet (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-64-anchor\">Listing 3<\/a><\/span>).<\/p>\n<p class=\"listingueberschrift\">Listing 4: Hinzuf&uuml;gen einer Tabelle zur Fehlzeiten-Zelle<\/p>\n<pre>Private Function TabelleTagMitarbeiterHinzufuegen(objDocument As MSHTML.HTMLDocument, objCell As MSHTML.HTMLTableCell, objTableCell As clsTableCell)\r\n    Dim objInnerTable As MSHTML.HTMLTable\r\n    Set objInnerTable = objDocument.createElement(&quot;Table&quot;)\r\n    objCell.appendChild objInnerTable\r\n    With objInnerTable\r\n        .Style.borderCollapse = &quot;collapse&quot;\r\n    End With\r\n    ZeileTagMitarbeiterHinzufuegen objInnerTable, objTableCell\r\nEnd Function<\/pre>\n<p>Die Prozedur legt zun&auml;chst eine neue Zelle in der referenzierten Zeile an (dies entspricht dann neben der Zelle mit dem Mitarbeiternamen und der als Platzhalter erstellten Zelle der dritten Zelle der Zeile). Falls das &uuml;bergebene Datum auf einen Samstag oder Sonntag f&auml;llt, wird der Hintergrund grau gef&auml;rbt. Dann erh&auml;lt die Zelle einige Attribute. Das Attribut <b>id <\/b>wird auf den Tag eingestellt, also beim <b>31.1.2012 <\/b>etwa auf <b>31<\/b>. Au&szlig;erdem legt die Prozedur zwei benutzerdefinierte Attribute an, n&auml;mlich <b>Datum <\/b>(wird mit dem <b>Long<\/b>-Wert f&uuml;r das Datum gef&uuml;llt) und <b>MitarbeiterID <\/b>(erh&auml;lt den Wert von <b>lngMitarbeiter<\/b>).<\/p>\n<p>An dieser Stelle kommt nun die bereits erw&auml;hnte Wrapper-Klasse <b>clsTableCell <\/b>ins Spiel. Diese wird f&uuml;r jede in dieser Funktion hinzugef&uuml;gte Zelle erstellt und mit einem Verweis auf das <b>HTMLTableCell<\/b>-Objekt gef&uuml;llt. Das so erzeugte Objekt <b>objTableCell <\/b>wird am Ende der Prozedur auch als R&uuml;ckgabewert der Funktion festgelegt.<\/p>\n<p>Zwischendurch ruft die Funktion jedoch noch eine weitere Prozedur namens <b>TabelleTagMitarbeiterHinzufuegen <\/b>auf (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-65-anchor\">Listing 4<\/a><\/span>). Diese Prozedur erstellt ein neues <b>HTMLTable<\/b>-Element und f&uuml;gt es in die soeben erstellte Zelle ein. Dies ist die Voraussetzung, damit wir noch ein <b>HTMLTableRow<\/b>-Objekt und darin die beiden <b>HTMLTableCell<\/b>-Objekt zum Anzeigen der beiden Fehlzeiten-H&auml;lften f&uuml;r einen Tag hinzuf&uuml;gen k&ouml;nnen.<\/p>\n<p class=\"listingueberschrift\">Listing 5: Hinzuf&uuml;gen einer Zeile in die Tabelle der Fehlzeiten-Zelle<\/p>\n<pre>Private Sub ZeileTagMitarbeiterHinzufuegen(objInnerTable As MSHTML.HTMLTable, _\r\n        objTableCell As clsTableCell)\r\n    Dim objInnerRow As MSHTML.HTMLTableRow\r\n    Set objInnerRow = objInnerTable.insertRow\r\n    With objInnerRow\r\n        .Style.Height = &quot;30px&quot;\r\n    End With\r\n    Set objTableCell.cellLeft = InnereZelleTagMitarbeiterHinzufuegen(objInnerRow)\r\n    Set objTableCell.cellRight = InnereZelleTagMitarbeiterHinzufuegen(objInnerRow)\r\nEnd Sub<\/pre>\n<p>Von hier aus geht es gleich weiter zur Prozedur <b>ZeileTagMitarbeiterHinzufuegen<\/b>, welche auf &auml;hnliche Weise das <b>HTMLTableRow<\/b>-Element hinzuf&uuml;gt (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-68-anchor\">Listing 5<\/a><\/span>). Nach dem Hinzuf&uuml;gen der Zeile fehlen nur die beiden <b>HTMLTableCell<\/b>-Elemente, die schlie&szlig;lich mit der Funktion <b>InnereZelleTagMitarbeiterHinzufuegen <\/b>zu der per Parameter &uuml;bergebenen Zeile hinzugef&uuml;gt werden (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-69-anchor\">Listing 6<\/a><\/span>).<\/p>\n<p class=\"listingueberschrift\">Listing 6: Hinzuf&uuml;gen einer Zelle zur Zeile der Tabelle der Fehlzeiten-Zelle<\/p>\n<pre>Private Function InnereZelleTagMitarbeiterHinzufuegen(objInnerRow As MSHTML.HTMLTableRow)\r\n    Dim objInnerCell As MSHTML.HTMLTableCell\r\n    Dim strBGColorCells As String\r\n    strBGColorCells = RGBToHTML(HexFromLong(DLookup(&quot;KalenderHintergrundfarbe&quot;, &quot;tblOptionen&quot;)))\r\n    Set objInnerCell = objInnerRow.insertCell\r\n    With objInnerCell\r\n        .Style.backgroundColor = strBGColorCells\r\n        .Style.Width = &quot;20px&quot;\r\n    End With\r\n    Set InnereZelleTagMitarbeiterHinzufuegen = objInnerCell\r\nEnd Function<\/pre>\n<p>Diese Funktion hat wiederum einen R&uuml;ckgabewert, mit dem die beiden Eigenschaften <b>cellRight <\/b>und <b>cellLeft <\/b>der Wrapper-Klasse <b>clsTableCell <\/b>gef&uuml;llt werden &#8211; mehr dazu sp&auml;ter. Auf diese Weise werden f&uuml;r alle Mitarbeiter je 28 Zellen mit je einer Tabelle, einer Zeile und zwei weiteren Zellen zur Markierung der Fehlzeiten hinzugef&uuml;gt.<\/p>\n<p><b>Wrapper-Klasse merken<\/b><\/p>\n<p>Nicht vergessen werden darf die folgende Zeile der Prozedur <b>FehlzeitenAnzeigen<\/b>:<\/p>\n<pre>colTableCells.Add objTableCell, CLng(rstMitarbeiter!MitarbeiterID) &amp; &quot;|&quot; &amp; CLng(datAktuell)<\/pre>\n<p>Diese speichert die Wrapper-Klasse f&uuml;r die aktuelle Zelle in der Collection <b>colTableCells<\/b>. Interessant dabei ist, dass dort auch ein Schl&uuml;ssel &uuml;bergeben wird, der durch ein Pipe-Zeichen (<b>|<\/b>) aus der <b>MitarbeiterID <\/b>und dem als <b>Long<\/b>-Wert konvertierten Datum zusammengesetzt wird (zum Beispiel <b>9|41087<\/b>). Auf diese Weise k&ouml;nnen Sie sp&auml;ter per Code auf alle Elemente der Matrix zugreifen.<\/p>\n<p><b>Fehlzeiten eintragen<\/b><\/p>\n<p>Damit w&auml;re der Fehlzeitenplan fast fertig, wenn nicht noch das Wichtigste fehlen w&uuml;rde: die Markierung der Fehlzeiten. Dies erledigt die Prozedur <b>FehlzeitenEintragen<\/b>, die jedoch noch weitere Hilfsfunktionen aufruft (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-72-anchor\">Listing 7<\/a><\/span>).<\/p>\n<p class=\"listingueberschrift\">Listing 7: Eintragen der Fehlzeiten<\/p>\n<pre>Private Sub FehlzeitenEintragen(datStart As Date, datEnde As Date)\r\n    Dim db As DAO.Database\r\n    Dim rstFehlzeiten As DAO.Recordset\r\n    Dim strFarbe As String\r\n    Dim strFehlzeitart As String\r\n    Set db = CurrentDb\r\n    Set rstFehlzeiten = db.OpenRecordset(&quot;SELECT * FROM qryFehlzeitenUndFarben WHERE Fehlzeitdatum &gt;= &quot; _\r\n        &amp; ISODatum(datStart) &amp; &quot; AND Fehlzeitdatum &lt; &quot; &amp; ISODatum(datEnde), dbOpenDynaset)\r\n    Do While Not rstFehlzeiten.EOF\r\n        strFarbe = HexFromLong(rstFehlzeiten!Farbe)\r\n        strFehlzeitart = rstFehlzeiten!Fehlzeitart\r\n        FehlzeitEintragen CLng(rstFehlzeiten!Fehlzeitdatum), rstFehlzeiten!MitarbeiterID, _\r\n        rstFehlzeiten!Vormittags, strFarbe, strFehlzeitart\r\n        rstFehlzeiten.MoveNext\r\n    Loop\r\n    Set db = Nothing\r\nEnd Sub<\/pre>\n<p>Die Prozedur erwartet das erste und das letzte Datum der &Uuml;bersicht als Parameter. Sie erstellt eine Datensatzgruppe auf Basis der Abfrage <b>qryFehlzeitenUndFarben<\/b>, welche alle Fehlzeiten liefert sowie die jeweiligen Farbcodes (s. Bild 12).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic014.png\" alt=\"pic014.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 12: Diese Abfrage ermittelt die Fehlzeiten aller Mitarbeiter inklusive Farbe<\/span><\/b><\/p>\n<p>F&uuml;r die Datensatzgruppe wird diese Abfrage noch nach dem Zeitraum gefiltert. Beim Durchlaufen dieses Recordsets in einer <b>Do While<\/b>-Schleife ermittelt die Prozedur zun&auml;chst den Hex-Wert f&uuml;r den Farbcode und tr&auml;gt die <b>Fehlzeitart <\/b>in die Variable <b>strFehlzeitart <\/b>ein. Schlie&szlig;lich ruft sie eine weitere Prozedur namens <b>FehlzeitEintragen<\/b> mit den Werten des Recordsets als Parameter auf.<\/p>\n<p><b>Eine Fehlzeit eintragen<\/b><\/p>\n<p>Die Prozedur <b>FehlzeitEintragen <\/b>aus <span class=\"verweis-ohneumbruch\"><a href=\"#anker-71-anchor\">Listing 8<\/a><\/span> markiert die Fehlzeiten in der Fehlzeiten&uuml;bersicht. Dazu k&ouml;nnte man normalerweise alle Zellen durchlaufen und jeweils pr&uuml;fen, ob f&uuml;r den Mitarbeiter am entsprechenden Tag eine Fehlzeit vorliegt. Wir gehen jedoch einen Weg, der etwas pfiffiger programmiert ist und weniger Rechenaufwand bedeutet.<\/p>\n<p class=\"listingueberschrift\">Listing 8: Eintragen einer Fehlzeit<\/p>\n<pre>Public Sub FehlzeitEintragen(lngDatum As Long, lngMitarbeiterID As Long, intVormittags As Integer, _\r\n        strFarbe As String, strFehlzeitart As String)\r\n    Dim objTableCellWrapper As clsTableCell\r\n    Dim objTableCell As MSHTML.HTMLTableCell\r\n    Set objTableCellWrapper = colTableCells.Item(lngMitarbeiterID &amp; &quot;|&quot; &amp; lngDatum)\r\n    If intVormittags = -1 Then\r\n         Set objTableCell = objTableCellWrapper.cellLeft\r\n        With objTableCell\r\n            .Style.backgroundColor = RGBToHTML(strFarbe)\r\n            .Title = strFehlzeitart\r\n        End With\r\n    Else\r\n         Set objTableCell = objTableCellWrapper.cellRight\r\n        With objTableCell\r\n            .Style.backgroundColor = RGBToHTML(strFarbe)\r\n            .Title = strFehlzeitart\r\n        End With\r\n    End If\r\nEnd Sub<\/pre>\n<p>Die Prozedur verwendet den <b>Key <\/b>der Collection <b>colTableCells<\/b>, um &uuml;ber die <b>MitarbeiterID <\/b>und den <b>Long<\/b>-Wert des Datums auf die Instanz der Wrapper-Klasse zuzugreifen, die den entsprechenden Mitarbeiter\/Tag repr&auml;sentiert:<\/p>\n<pre>Set objTableCellWrapper = colTableCells.Item(lngMitarbeiterID &amp; &quot;|&quot; &amp; lngDatum)<\/pre>\n<p>Mit der Eigenschaft <b>cellLeft <\/b>der Wrapper-Klasse erhalten wir einen Verweis auf die linke Zelle f&uuml;r den Mitarbeiter\/Tag und k&ouml;nnen, wenn die Variable <b>intVormittag<\/b> den Wert <b>-1 <\/b>hat, den Hintergrund der Zelle entsprechend der Farbe f&uuml;r die Fehlzeit einstellen.<\/p>\n<p>Anderenfalls holt die Prozedur eine Referenz auf die rechte Zelle und f&auml;rbt diese entsprechend ein.<\/p>\n<p>Au&szlig;erdem legt die Prozedur die Eigenschaft <b>Title <\/b>des <b>HTMLTableCell<\/b>-Objekts noch auf die Bezeichnung der Fehlzeit ein. Auf diese Weise brauchen Sie nur mit der Maus &uuml;ber die Fehlzeit zu fahren und sehen die Bezeichnung der Fehlzeit (s. Bild 13).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic015.png\" alt=\"pic015.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 13: Fehlzeitmarkierung mit Bezeichnung<\/span><\/b><\/p>\n<p><b>Die Klasse clsTableCell<\/b><\/p>\n<p>Wozu ben&ouml;tigen wir die Wrapper-Klasse <b>clsTableCell<\/b> Damit wir einen Aufbewahrungsort f&uuml;r jeweils einen Verweis auf eine Zelle in der Datum\/Mitarbeiter-Matrix haben. Dieser Aufbewahrungsort stellt aber zus&auml;tzlich Ereignisprozeduren bereit, sodass jede individuelle Zelle ein Kontextmen&uuml; in Abh&auml;ngigkeit vom Datum und vom Mitarbeiter anzeigen kann. Die Klasse enth&auml;lt zun&auml;chst drei Variablen, die sp&auml;ter mit Verweisen auf die Hauptzelle, auf die linke Teilzelle und die rechte Teilzelle gef&uuml;llt werden:<\/p>\n<pre>Private WithEvents m_Cell As MSHTML.HTMLTableCell\r\nPrivate m_CellLeft As MSHTML.HTMLTableCell\r\nPrivate m_CellRight As MSHTML.HTMLTableCell<\/pre>\n<p>Weiter oben haben Sie bereits gesehen, wie die drei Eigenschaften <b>cell<\/b>, <b>celLeft <\/b>und <b>cellRight <\/b>von anderen Prozeduren aus gef&uuml;llt werden. Damit Sie diese Eigenschaften der Klasse f&uuml;llen k&ouml;nnen, ben&ouml;tigen Sie entsprechende <b>Property Set<\/b>-Methoden. Die f&uuml;r die Eigenschaft <b>cell <\/b>sieht etwa so aus:<\/p>\n<pre>Public Property Set cell(objCell As HTMLTableCell)\r\n    Set m_Cell = objCell\r\n    m_Cell.oncontextmenu = &quot;[Event Procedure]&quot;\r\nEnd Property<\/pre>\n<p>Die Prozedur nimmt einen Verweis auf das Objekt <b>objCell <\/b>entgegen und speichert diesen in der oben aufgef&uuml;hrten Variablen <b>m_Cell<\/b>. Diese wurde als <b>WithEvents <\/b>deklariert, also mit Ereignissen. Mit der Eigenschaft <b>oncontextmenu <\/b>legen Sie dann fest, dass beim Anklicken des <b>HTMLTableCell<\/b>-Elements im Klassenmodul <b>clsTableCell<\/b> nach einer entsprechenden Ereignisprozedur gesucht werden soll. Bei dieser Gelegenheit ist zu erw&auml;hnen, dass allein das Vorhandensein eines speziellen Ereignisses f&uuml;r das Aufrufen des Kontextmen&uuml;s eine angenehme Sache ist. Auf die entsprechende Ereignisprozedur kommen wir gleich im Anschluss. Zun&auml;chst noch die Definition der <b>Property Set<\/b>-Prozeduren f&uuml;r die &uuml;brigen beiden Elemente:<\/p>\n<pre>Public Property Set cellLeft(objCell As HTMLTableCell)\r\n    Set m_CellLeft = objCell\r\nEnd Property\r\nPublic Property Set cellRight(objCell As HTMLTableCell)\r\n    Set m_CellRight = objCell\r\nEnd Property<\/pre>\n<p>Diese Prozeduren nehmen also nur die Verweise auf die beiden in der Hauptzeile f&uuml;r den Mitarbeiter\/Tag enthaltenen Zellen f&uuml;r die erste und die zweite Tagesh&auml;lfte entgegen.<\/p>\n<p>Schlie&szlig;lich werden zumindest die in den Eigenschaften <b>m_CellLeft<\/b> und <b>m_CellRight <\/b>gespeicherten Verweise von anderen Prozeduren abgefragt. Daf&uuml;r stehen diese beiden <b>Property Get<\/b>-Prozeduren bereit:<\/p>\n<pre>Public Property Get cellLeft() As HTMLTableCell\r\n    Set cellLeft = m_CellLeft\r\nEnd Property\r\nPublic Property Get cellRight() As HTMLTableCell\r\n    Set cellRight = m_CellRight\r\nEnd Property<\/pre>\n<p><b>Kontextmen&uuml; zusammenstellen<\/b><\/p>\n<p>Nun kommen wir zu der Prozedur, die beim Rechtsklick auf eine der Mitarbeiter\/Datum-Zellen ausgel&ouml;st wird (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-75-anchor\">Listing 9<\/a><\/span>). Die Prozedur soll f&uuml;r jeden Datensatz der Tabelle <b>tblFehlzeitart <\/b>drei Eintr&auml;ge anzeigen, und zwar zum Hinzuf&uuml;gen der Fehlzeit zum Vormittag, zum Nachmittag oder zum kompletten Tag.<\/p>\n<p class=\"listingueberschrift\">Listing 9: Anzeigen des Kontextmen&uuml;s<\/p>\n<pre>Private Function m_Cell_oncontextmenu() As Boolean\r\n    Dim cbr As CommandBar\r\n    Dim cbc As CommandBarControl\r\n    Dim db As DAO.Database\r\n    Dim rst As DAO.Recordset\r\n    Dim lngMitarbeiterID As Long\r\n    Set db = CurrentDb\r\n    On Error Resume Next\r\n    CommandBars.Item(&quot;cbrCell&quot;).Delete\r\n    On Error GoTo 0\r\n    lngMitarbeiterID = CLng(m_Cell.Attributes(&quot;MitarbeiterID&quot;).Value)\r\n    Set cbr = CommandBars.Add(&quot;cbrCell&quot;, msoBarPopup)\r\n    Set rst = db.OpenRecordset(&quot;SELECT * FROM tblFehlzeitarten ORDER BY FehlzeitartID&quot;, dbOpenDynaset)\r\n    Do While Not rst.EOF\r\n        Set cbc = cbr.Controls.Add(msoControlButton)\r\n        With cbc\r\n            .Caption = rst!Fehlzeitart &amp; &quot; (kompletter Tag)&quot;\r\n            .onAction = &quot;=FehlzeitHinzufuegen(&quot; &amp; CLng(m_Cell.Attributes(&quot;Datum&quot;).Value) &amp; &quot;, &quot; _\r\n                &amp; lngMitarbeiterID &amp; &quot;, &quot; &amp; rst!FehlzeitartID &amp; &quot;, 1)&quot;\r\n        End With\r\n        Set cbc = cbr.Controls.Add(msoControlButton)\r\n        With cbc\r\n            .Caption = rst!Fehlzeitart &amp; &quot; (Vormittag)&quot;\r\n            .onAction = &quot;=FehlzeitHinzufuegen(&quot; &amp; CLng(m_Cell.Attributes(&quot;Datum&quot;).Value) &amp; &quot;, &quot; _\r\n                &amp; lngMitarbeiterID &amp; &quot;, &quot; &amp; rst!FehlzeitartID &amp; &quot;, -1)&quot;\r\n        End With\r\n        Set cbc = cbr.Controls.Add(msoControlButton)\r\n        With cbc\r\n            .Caption = rst!Fehlzeitart &amp; &quot; (Nachmittag)&quot;\r\n            .onAction = &quot;=FehlzeitHinzufuegen(&quot; &amp; CLng(m_Cell.Attributes(&quot;Datum&quot;).Value) &amp; &quot;, &quot; _\r\n                &amp; lngMitarbeiterID &amp; &quot;, &quot; &amp; rst!FehlzeitartID &amp; &quot;, 0)&quot;\r\n        End With\r\n        rst.MoveNext\r\n    Loop\r\n    Set cbc = cbr.Controls.Add(msoControlButton)\r\n    With cbc\r\n        .Caption = &quot;Fehlzeiten entfernen&quot;\r\n        .onAction = &quot;=FehlzeitenEntfernen(&quot; &amp; CLng(m_Cell.Attributes(&quot;Datum&quot;).Value) &amp; &quot;, &quot; _\r\n            &amp; lngMitarbeiterID &amp; &quot;)&quot;\r\n    End With\r\n    cbr.ShowPopup\r\nEnd Function<\/pre>\n<p>Bevor das Kontextmen&uuml; erstellt wird, l&ouml;scht die Prozedur zun&auml;chst ein eventuell noch vorhandenes Kontextmen&uuml; namens <b>cbrCell<\/b>. Danach liest die Prozedur die ID des Mitarbeiters, zu dem die Zelle geh&ouml;rt, aus dem Attribut <b>MitarbeiterID <\/b>des <b>HTMLTableCell<\/b>-Objekts ein. Danach wird der <b>CommandBars<\/b>-Auflistung mit der <b>Add<\/b>-Methode ein neues Kontextmen&uuml; hinzugef&uuml;gt.<\/p>\n<p>Anschlie&szlig;end &ouml;ffnet die Prozedur eine Datensatzgruppe mit allen Fehlzeitarten der Tabelle <b>tblFehlzeitarten<\/b> und durchl&auml;uft diese in einer <b>Do While<\/b>-Schleife. Innerhalb dieser Schleife legt die Prozedur jeweils einen neuen Eintrag im Kontextmen&uuml; an, der aus dem Namen der Fehlzeitart sowie den Zus&auml;tzen <b>(kompletter Tag)<\/b>, <b>(Vormittag) <\/b>und <b>(Nachmittag) <\/b>besteht. Der <b>onAction<\/b>-Eigenschaft dieser Eintr&auml;ge weist die Prozedur einen Ausdruck wie diesen zu:<\/p>\n<pre>=FehlzeitHinzufuegen(41087, 12, 3, 1)<\/pre>\n<p>Die erste Zahl steht f&uuml;r das Datum, die zweite f&uuml;r die <b>MitarbeiterID<\/b>, die dritte f&uuml;r die <b>FehlzeitartID<\/b> und die vierte f&uuml;r die Dauer (<b>1 <\/b>entspricht dem kompletten Tag, <b>-1 <\/b>dem Vormittag und <b>0 <\/b>dem Nachmittag).<\/p>\n<p>Nach dem Durchlaufen der Schleife f&uuml;r alle Fehlzeitarten legt die Prozedur noch ein Element im Kontextmen&uuml; an, mit dem alle Fehlzeiten f&uuml;r den angeklickten Tag entfernt werden k&ouml;nnen. Schlie&szlig;lich sorgt die Methode <b>ShowPopup <\/b>des <b>CommandBar<\/b>-Objekts f&uuml;r die Anzeige des Kontextmen&uuml;s.<\/p>\n<p><b>Auf Kontextmen&uuml;-Befehle reagieren<\/b><\/p>\n<p>Fehlt noch die f&uuml;r die Kontextmen&uuml;-Eintr&auml;ge angegebene Prozedur <b>FehlzeitHinzufuegen<\/b>. Diese Prozedur wird zwar durch einen Kontextmen&uuml;-Eintrag eines Elements der Klasse <b>clsTableCell <\/b>ausgel&ouml;st, aber die Funktion, die f&uuml;r die Eigenschaft <b>onAction <\/b>ausgel&ouml;st werden soll, k&ouml;nnen Sie nur in ein Standardmodul oder in das Klassenmodul des Formulars eintragen, das beim Aufrufen des Kontextmen&uuml;s den Fokus hat. Also f&uuml;gen Sie die Prozedur aus <span class=\"verweis-ohneumbruch\"><a href=\"#anker-77-anchor\">Listing 10<\/a><\/span> dem Klassenmodul des Formulars <b>frmFehlzeiten <\/b>hinzu.<\/p>\n<p class=\"listingueberschrift\">Listing 10: Hinzuf&uuml;gen von Fehlzeiten<\/p>\n<pre>Public Function FehlzeitHinzufuegen(lngDatum As Long, lngMitarbeiterID As Long, _\r\n        lngFehlzeitartID As Long, intTageszeit As Integer)\r\n    Dim db As DAO.Database\r\n    Dim strSQL As String\r\n    Dim strFarbe As String\r\n    Dim strFehlzeitart As String\r\n    Dim i As Integer\r\n    strFarbe = HexFromLong(DLookup(&quot;Farbe&quot;, &quot;tblFehlzeitarten&quot;, &quot;FehlzeitartID = &quot; &amp; lngFehlzeitartID))\r\n    strFehlzeitart = DLookup(&quot;Fehlzeitart&quot;, &quot;tblFehlzeitarten&quot;, &quot;FehlzeitartID = &quot; &amp; lngFehlzeitartID)\r\n    Set db = CurrentDb\r\n    Select Case intTageszeit\r\n        Case 1\r\n            strSQL = &quot;DELETE FROM tblFehlzeiten WHERE MitarbeiterID = &quot; &amp; lngMitarbeiterID _\r\n                &amp; &quot; AND Fehlzeitdatum = &quot; &amp; lngDatum\r\n            db.Execute strSQL, dbFailOnError\r\n            For i = -1 To 0\r\n                strSQL = &quot;INSERT INTO tblFehlzeiten(MitarbeiterID, Fehlzeitdatum, &quot; _\r\n                    &amp; &quot;FehlzeitartID, Vormittags) VALUES(&quot; &amp; lngMitarbeiterID &amp; &quot;, &quot; &amp; lngDatum _\r\n                    &amp; &quot;, &quot; &amp; lngFehlzeitartID &amp; &quot;, &quot; &amp; i &amp; &quot;)&quot;\r\n                db.Execute strSQL, dbFailOnError\r\n                FehlzeitEintragen CLng(lngDatum), lngMitarbeiterID, i, strFarbe, strFehlzeitart\r\n            Next i\r\n        Case Else\r\n            strSQL = &quot;DELETE FROM tblFehlzeiten WHERE MitarbeiterID = &quot; &amp; lngMitarbeiterID _\r\n                &amp; &quot; AND Fehlzeitdatum = &quot; &amp; lngDatum &amp; &quot; AND Vormittags = &quot; &amp; intTageszeit\r\n            db.Execute strSQL, dbFailOnError\r\n            strSQL = &quot;INSERT INTO tblFehlzeiten(MitarbeiterID, Fehlzeitdatum, &quot; _\r\n                &amp; &quot;FehlzeitartID, Vormittags) VALUES(&quot; &amp; lngMitarbeiterID &amp; &quot;, &quot; &amp; lngDatum _\r\n                &amp; &quot;, &quot; &amp; lngFehlzeitartID &amp; &quot;, &quot; &amp; intTageszeit &amp; &quot;)&quot;\r\n            db.Execute strSQL, dbFailOnError\r\n            FehlzeitEintragen CLng(lngDatum), lngMitarbeiterID, intVormittags, strFarbe, strFehlzeitart\r\n    End Select\r\n    Set db = Nothing\r\nEnd Function<\/pre>\n<p>Diese Funktion ermittelt zun&auml;chst mit zwei Aufrufen der <b>DLookup<\/b>-Funktion die Bezeichnung der Fehlzeitart sowie die Farbe dieser Fehlzeitart und speichert diese in entsprechenden Variablen.<\/p>\n<p>Danach pr&uuml;ft sie, welchen Wert der Parameter <b>intTageszeit <\/b>erhalten hat. <b>1 <\/b>steht f&uuml;r den kompletten Tag, <b>-1 <\/b>f&uuml;r den Vormittag und <b>0 <\/b>f&uuml;r den Nachmittag. Im Falle des Wertes <b>1 <\/b>muss die Prozedur der Tabelle <b>tblFehlzeiten <\/b>zwei Datens&auml;tze hinzuf&uuml;gen &#8211; einen f&uuml;r die Fehlzeit am Vormittag und eine f&uuml;r den Nachmittag. Zuvor jedoch m&uuml;ssen die bestehenden Fehlzeiten f&uuml;r den aktuellen Mitarbeiter und das aktuelle Datum gel&ouml;scht werden, was eine entsprechende <b>DELETE<\/b>-Anweisung erledigt. Danach legt die Prozedur in einer <b>For&#8230;Next<\/b>-Schleife &uuml;ber die Werte von <b>-1 <\/b>bis <b>0 <\/b>die beiden neuen Fehlzeiten f&uuml;r diesen Tag an. Warum eine solche Schleife Weil die in der Schleife enthaltenen Anweisungen den gleichen Datensatz einmal f&uuml;r den Wert <b>0 <\/b>(<b>False<\/b>) im Feld <b>Vormittags <\/b>und einmal f&uuml;r den Wert <b>-1 <\/b>(<b>True<\/b>) durchf&uuml;hren.<\/p>\n<p>Die enthaltenen Befehle rufen jeweils einmal eine <b>INSERT INTO<\/b>-Anweisung zum Anlegen der Fehlzeit in der Tabelle <b>tblFehlzeiten <\/b>und anschlie&szlig;end die Prozedur <b>FehlzeitEintragen <\/b>auf, damit die neue Fehlzeit auch in der Fehlzeiten-&Uuml;bersicht zu sehen ist.<\/p>\n<p>Der zweite Teil der <b>Select Case<\/b>-Anweisung wird angesteuert, wenn <b>intTageszeit <\/b>den Wert <b>-1 <\/b>oder <b>0 <\/b>enth&auml;lt, also entweder nur der Vormittag oder nur der Nachmittag von der Fehlzeit betroffen ist.<\/p>\n<p>In diesem Fall l&ouml;scht die Prozedur ebenfalls die Fehlzeiten f&uuml;r den &uuml;bergebenen Mitarbeiter und das Datum, legt allerdings nur f&uuml;r den Vormittag oder nur f&uuml;r den Nachmittag eine neue Fehlzeit an &#8211; je nach dem Wert von <b>intTageszeit<\/b>, der schlicht in das Feld <b>Vormittags <\/b>der Tabelle <b>tblFehlzeiten <\/b>eintragen wird. Auch hier wird die Fehlzeit noch in die Fehlzeiten-&Uuml;bersicht eingetragen.<\/p>\n<p><b>Entfernen einer Fehlzeit<\/b><\/p>\n<p>Wenn der Benutzer den letzten Eintrag des Kontextmen&uuml;s anklickt, sollen alle Fehlzeiten f&uuml;r den aktuellen Tag entfernt werden. Dies l&ouml;st die Prozedur <b>FehlzeitenEntfernen <\/b>aus, die Sie ebenfalls im Klassenmodul des Formulars <b>frmFehlzeiten <\/b>unterbringen (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-78-anchor\">Listing 11<\/a><\/span>).<\/p>\n<p class=\"listingueberschrift\">Listing 11: Entfernen einer Fehlzeit<\/p>\n<pre>Public Function FehlzeitenEntfernen(lngDatum As Long, lngMitarbeiterID As Long)\r\n    Dim db As DAO.Database\r\n    Dim strBGColorCells As String\r\n    Set db = CurrentDb\r\n    db.Execute &quot;DELETE FROM tblFehlzeiten WHERE MitarbeiterID = &quot; &amp; lngMitarbeiterID _\r\n        &amp; &quot; AND Fehlzeitdatum = &quot; &amp; lngDatum, dbFailOnError\r\n    strBGColorCells = HexFromLong(DLookup(&quot;KalenderHintergrundfarbe&quot;, &quot;tblOptionen&quot;))\r\n    FehlzeitEintragen lngDatum, lngMitarbeiterID, -1, strBGColorCells, &quot;&quot;\r\n    FehlzeitEintragen lngDatum, lngMitarbeiterID, 0, strBGColorCells, &quot;&quot;\r\n    Set db = Nothing\r\nEnd Function<\/pre>\n<p>Die Prozedur l&ouml;scht zun&auml;chst alle Eintr&auml;ge der Tabelle <b>tblFehlzeiten <\/b>f&uuml;r die per Parameter &uuml;bergebenen Werte f&uuml;r Datum und Mitarbeiter. Anschlie&szlig;end liest sie die aktuell in der Tabelle <b>tblOptionen <\/b>festgelegte Hintergrundfarbe ein. Um die Fehlzeiten aus der Fehlzeiten-&Uuml;bersicht zu entfernen, ruft die Prozedur zweimal die Prozedur <b>FehlzeitEintragen <\/b>auf &#8211; jeweils mit der neutralen Hintergrundfarbe und einer leeren Zeichenkette f&uuml;r den beim &Uuml;berfahren mit der Maus anzuzeigenden Text. Dadurch wird der betroffene Tag f&uuml;r den Mitarbeiter wie ein regul&auml;rer Tag dargestellt.<\/p>\n<p><b>Bearbeiten der Fehlzeitarten<\/b><\/p>\n<p>Die Fehlzeitarten werden wie in Bild 15):<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic016.png\" alt=\"pic016.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 14: Tabelle zum Speichern der Fehlzeit-Arten<\/span><\/b><\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic017.png\" alt=\"pic017.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 15: Fehlzeitarten verwalten<\/span><\/b><\/p>\n<pre>Private Sub cmdFehlzeitarten_Click()\r\n    DoCmd.OpenForm &quot;frmFehlzeitartenUebersicht&quot;, WindowMode:=acDialog\r\n    FehlzeitenAnzeigen\r\nEnd Sub<\/pre>\n<p>Das Formular <b>frmFehlzeitartenUebersicht <\/b>zeigt die Fehlzeitarten in einem Listenfeld an.<\/p>\n<p>Mit einem Doppelklick auf einen der Eintr&auml;ge im Listenfeld &ouml;ffnen Sie den Detaildialog zum Bearbeiten der Fehlzeitart. Klicken Sie dort auf <b>Farbe ausw&auml;hlen<\/b>, erscheint auch noch ein entsprechender Dialog zur Auswahl der entsprechenden Farbe (s. Bild 16).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_04\/FehlzeitenVerwalten-web-images\/pic018.png\" alt=\"pic018.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 16: Bearbeiten einer Fehlzeitart<\/span><\/b><\/p>\n<p>Doch eins nach dem anderen. Das Listenfeld <b>lstFehlzeitarten <\/b>wird mit der folgenden SQL-Anweisung gef&uuml;llt und zeigt somit alle Fehlzeitarten an (<b>Spaltenanzahl <\/b>und <b>Spaltenbreiten <\/b>sind auf die Werte <b>2 <\/b>und <b>0cm <\/b>eingestellt, damit die Werte der gebundenen Spalte im Listenfeld ausgeblendet werden):<\/p>\n<pre>SELECT FehlzeitartID, Fehlzeitart\r\nFROM tblFehlzeitarten ORDER BY Fehlzeitart;<\/pre>\n<p>Ein Doppelklick auf das Listenfeld l&ouml;st die folgende Prozedur aus:<\/p>\n<pre>Private Sub lstFehlzeitarten_DblClick(Cancel As Integer)\r\n    If Not IsNull(Me!lstFehlzeitarten) Then\r\n        DoCmd.OpenForm &quot;frmFehlzeitartdetails&quot;, WindowMode:=acDialog, _\r\n            WhereCondition:=&quot;FehlzeitartID = &quot; &amp; Me!lstFehlzeitarten, _\r\n        DataMode:=acFormEdit\r\n        Me!lstFehlzeitarten.Requery\r\n    End If\r\nEnd Sub<\/pre>\n<p>Die Prozdur pr&uuml;ft, ob der Benutzer auf einen Eintrag geklickt hat, und &ouml;ffnet dann das Formular <b>frmFehlzeitartDetails <\/b>mit dem ausgew&auml;hlten Datensatz. Nach dem Bearbeiten und Schlie&szlig;en des Formulars wird das Listenfeld aktualisiert.<\/p>\n<p>Ein Klick auf die Schaltfl&auml;che <b>L&ouml;schen <\/b>l&ouml;st die Prozedur aus <span class=\"verweis-ohneumbruch\"><a href=\"#anker-82-anchor\">Listing 12<\/a><\/span> aus. Diese Prozedur fragt zun&auml;chst, ob die Fehlzeitart wirklich gel&ouml;scht werden soll. Falls ja, wird die entsprechende <b>DELETE<\/b>-Anweisung ausgel&ouml;st &#8211; allerdings nicht, ohne zuvor die eingebauten Fehlermeldungen zu unterbinden und die eigene Fehlerbehandlung anzuschalten. Diese schl&auml;gt n&auml;mlich an, wenn die zu l&ouml;schende Fehlzeitart bereits einer Fehlzeit zugewiesen ist. Da f&uuml;r die Beziehung zwischen den Tabellen <b>tblFehlzeiten <\/b>und <b>tblFehlzeitarten <\/b>keine L&ouml;schweitergabe definiert ist (was anderenfalls dazu f&uuml;hren w&uuml;rde, dass mit der Fehlzeitart auch die verkn&uuml;pften Fehlzeiten gel&ouml;scht w&uuml;rden), l&ouml;st der Versuch, eine bereits verkn&uuml;pfte Fehlzeitart zu l&ouml;schen, den Fehler mit der Nummer <b>3200 <\/b>aus. In diesem Fall zeigt die Anwendung einen entsprechenden Hinweis an.<\/p>\n<p class=\"listingueberschrift\">Listing 12: L&ouml;schen einer Fehlzeitart<\/p>\n<pre>Private Sub cmdLoeschen_Click()\r\n    Dim db As DAO.Database\r\n    If Not IsNull(Me!lstFehlzeitarten) Then\r\n        If MsgBox(&quot;Soll die Fehlzeitart ''&quot; &amp; Me!lstFehlzeitarten.Column(1) &amp; &quot;'' wirklich gel&ouml;scht &quot; _\r\n                &amp; &quot;werden&quot;, vbYesNo + vbExclamation, &quot;Fehlzeitart l&ouml;schen&quot;) = vbYes Then\r\n            Set db = CurrentDb\r\n            On Error Resume Next\r\n            db.Execute &quot;DELETE FROM tblFehlzeitarten WHERE FehlzeitartID = &quot; _\r\n                &amp; Me!lstFehlzeitarten, dbFailOnError\r\n            If Err.Number = 3200 Then\r\n                MsgBox &quot;Die Fehlzeitart kann nicht gel&ouml;scht werden, da Sie bereits verwendet wird.&quot;\r\n                Exit Sub\r\n            End If\r\n            Me!lstFehlzeitarten.Requery\r\n            Set db = Nothing\r\n        End If\r\n    End If\r\nEnd Sub<\/pre>\n<p><b>Neue Fehlzeitart anlegen<\/b><\/p>\n<p>Mit der Schaltfl&auml;che <b>Neu <\/b>l&ouml;sen Sie die folgende Prozedur aus:<\/p>\n<pre>Private Sub cmdNeu_Click()\r\n    DoCmd.OpenForm &quot;frmFehlzeitartdetails&quot;, WindowMode:=acDialog, DataMode:=acFormAdd\r\n    Me!lstFehlzeitarten.Requery\r\nEnd Sub<\/pre>\n<p>Diese &ouml;ffnet das Detailformular <b>frmFehlzeitartDetails<\/b> zur Eingabe einer neuen Fehlzeitart. Nach dem Schlie&szlig;en dieses Formulars wird das Listenfeld <b>lstFehlzeitarten <\/b>aktualisiert.<\/p>\n<p><b>Das Formular zum Anlegen und Bearbeiten von Fehlzeitarten<\/b><\/p>\n<p>Das Formular <b>frmFehlzeitartDetails <\/b>wird zum Anlegen und Bearbeiten von Fehlzeitarten ge&ouml;ffnet. Das Interessante an diesem Formular ist die M&ouml;glichkeit, einen Farbauswahldialog zu &ouml;ffnen. Dies erledigen Sie mit einem Klick auf die Schaltfl&auml;che <b>Farbe ausw&auml;hlen<\/b>, die folgende Prozedur ausl&ouml;st:<\/p>\n<pre>Private Sub cmdFarbeAuswaehlen_Click()\r\n    Me!Farbe = FarbeAuswaehlen(Nz(Me!Farbe, 0))\r\n    Me!rctColor.BackColor = Me!Farbe\r\nEnd Sub<\/pre>\n<p>Die Funktion <b>FarbeAuswaehlen <\/b>erwartet als Parameter den Farbwert, der aus dem aktuellen Wert des Feldes <b>Farbe <\/b>der als Datenherkunft dienenden Tabelle <b>tblFehlzeitarten <\/b>bezogen wird. Das Rechteck <b>rctColor<\/b> wird beim Anzeigen des Datensatzes auf die entsprechende Farbe eingestellt, damit der Benutzer direkt sieht, welche Farbe hier ausgew&auml;hlt ist:<\/p>\n<pre>Private Sub Form_Current()\r\n    Me!rctColor.BackColor = Me!Farbe\r\nEnd Sub<\/pre>\n<p><b>Bearbeiten der anzuzeigenden Benutzer<\/b><\/p>\n<p>Fehlt noch die Auswahl der Benutzer, die in der Fehlzeiten-&Uuml;bersicht angezeigt werden sollen. Dies erledigen Sie mit einem Klick auf die Schaltfl&auml;che <b>cmdMitarbeiterFiltern<\/b>:<\/p>\n<pre>Private Sub cmdMitarbeiterFiltern_Click()\r\n    DoCmd.OpenForm &quot;frmMitarbeiterauswahl&quot;, WindowMode:=acDialog\r\n    FehlzeitenAnzeigen\r\nEnd Sub<\/pre>\n<p>Das hier ge&ouml;ffnete Formular <b>frmMitarbeiterauswahl<\/b> ist zwar in dieser Datenbank vorhanden, wird jedoch in einem weiteren Beitrag beschrieben (<b>1:n-Beziehung mit HTML<\/b>, <b>www.access-im-unternehmen.de\/851<\/b>).<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Diese L&ouml;sung erlaubt das Erfassen der Fehlzeiten von Mitarbeitern. Sinnvolle Erweiterungen w&auml;ren beispielsweise das Hinzuf&uuml;gen eines Urlaubskontos f&uuml;r die verschiedenen Mitarbeiter und die Anzeige der verbleibenden Urlaubstage f&uuml;r ein Jahr. <\/p>\n<p>Eine Erleichterung bei der Eingabe zusammenh&auml;ngender Fehltage w&auml;re auch das Markieren mehrerer Tage gleichzeitig.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>FehlzeitenVerwalten2000_2007.mdb<\/p>\n<p>FehlzeitenVerwalten2010.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{D62D8680-5F5C-4E0C-B35D-370FE6DD40B0}\/aiu_850.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &#8211; mehr ben&ouml;tigen Sie nicht. Interessant wird es jedoch, die Fehlzeiten einzugeben und diese &uuml;bersichtlich darzustellen. Und zwar so, dass nicht nur die Fehlzeiten eines einzigen Mitarbeiters, sondern m&ouml;glichst die aller Mitarbeiter sichtbar sind. Nur so l&auml;sst sich effektiv vorausplanen.<\/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":[662012,66042012,44000027],"tags":[],"class_list":["post-55000850","post","type-post","status-publish","format-standard","hentry","category-662012","category-66042012","category-Loesungen"],"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>Fehlzeiten verwalten - 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\/Fehlzeiten_verwalten\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Fehlzeiten verwalten\" \/>\n<meta property=\"og:description\" content=\"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&ouml;tigen Sie nicht. Interessant wird es jedoch, die Fehlzeiten einzugeben und diese &uuml;bersichtlich darzustellen. Und zwar so, dass nicht nur die Fehlzeiten eines einzigen Mitarbeiters, sondern m&ouml;glichst die aller Mitarbeiter sichtbar sind. Nur so l&auml;sst sich effektiv vorausplanen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T21:48:06+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg05.met.vgwort.de\/na\/11ed7458fd5843da953f7ae748e16be4\" \/>\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=\"37\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Fehlzeiten verwalten\",\"datePublished\":\"2020-05-22T21:48:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/\"},\"wordCount\":5463,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/11ed7458fd5843da953f7ae748e16be4\",\"articleSection\":[\"2012\",\"4\\\/2012\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/\",\"name\":\"Fehlzeiten verwalten - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/11ed7458fd5843da953f7ae748e16be4\",\"datePublished\":\"2020-05-22T21:48:06+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/11ed7458fd5843da953f7ae748e16be4\",\"contentUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/11ed7458fd5843da953f7ae748e16be4\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlzeiten_verwalten\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Fehlzeiten verwalten\"}]},{\"@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":"Fehlzeiten verwalten - 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\/Fehlzeiten_verwalten\/","og_locale":"de_DE","og_type":"article","og_title":"Fehlzeiten verwalten","og_description":"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&ouml;tigen Sie nicht. Interessant wird es jedoch, die Fehlzeiten einzugeben und diese &uuml;bersichtlich darzustellen. Und zwar so, dass nicht nur die Fehlzeiten eines einzigen Mitarbeiters, sondern m&ouml;glichst die aller Mitarbeiter sichtbar sind. Nur so l&auml;sst sich effektiv vorausplanen.","og_url":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T21:48:06+00:00","og_image":[{"url":"http:\/\/vg05.met.vgwort.de\/na\/11ed7458fd5843da953f7ae748e16be4","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"37\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Fehlzeiten verwalten","datePublished":"2020-05-22T21:48:06+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/"},"wordCount":5463,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg05.met.vgwort.de\/na\/11ed7458fd5843da953f7ae748e16be4","articleSection":["2012","4\/2012","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/","url":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/","name":"Fehlzeiten verwalten - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg05.met.vgwort.de\/na\/11ed7458fd5843da953f7ae748e16be4","datePublished":"2020-05-22T21:48:06+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/#primaryimage","url":"http:\/\/vg05.met.vgwort.de\/na\/11ed7458fd5843da953f7ae748e16be4","contentUrl":"http:\/\/vg05.met.vgwort.de\/na\/11ed7458fd5843da953f7ae748e16be4"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Fehlzeiten_verwalten\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Fehlzeiten verwalten"}]},{"@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\/55000850","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=55000850"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000850\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000850"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000850"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000850"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}