{"id":55001102,"date":"2017-10-01T00:00:00","date_gmt":"2020-05-14T13:38:10","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1102"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Belegungsplan_mit_Kalender","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/","title":{"rendered":"Belegungsplan mit Kalender"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg09.met.vgwort.de\/na\/56e1ea5b19254e1289566f60b6e3b27d\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Bei der Suche nach sinnvollen Anwendungszwecken f&uuml;r die Kalendersteuerelemente dieser Ausgabe fiel die Entscheidung f&uuml;r ein Beispiel schwer. Wir demonstrieren deren Einsatz nun an einem fingierten Belegungsplan f&uuml;r Ferienwohnungen, der zudem das &uuml;bersichtskalenderelement noch um das eine oder andere Feature erweitert.<\/b><\/p>\n<h2>Wohnobjekte und Vermietungszeitr&auml;ume<\/h2>\n<p>Buchen Sie im Web eine Ferienwohnung, so werden Sie h&auml;ufig mit &uuml;bersichtskalendern konfrontiert, die die noch freien Zeitr&auml;ume eines Objekts abbilden. Das ist im Prinzip ein idealer Anwendungsfall f&uuml;r das dreimonatige Kalendersteuerelement dieser Ausgabe.  Der Teufel liegt allerdings, wie wir noch sehen werden, im Detail. Ohne Modifikation des Steuerelements treffen Sie auf einige Probleme, die es im Folgenden zu l&ouml;sen gilt.<\/p>\n<p>Die Buchung des Objekts ist das eine, die &uuml;bersicht f&uuml;r den Vermieter das andere. Bild 1 zeigt zun&auml;chst die Version f&uuml;r den Vermieter. Seine Buchungsdatenbank enth&auml;lt alle Daten zu seinen Objekten, den Kunden und den gebuchten Zeitr&auml;umen. Die bekommt er nun im Formular <b>frmBelegung<\/b> pr&auml;sentiert.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/frmBelegung_RT.png\" alt=\"Der Belegungsplan f&uuml;r Ferienwohnungen enth&auml;lt das dreimonatige Kalendersteuerelement mit mehrfachen Bedingten Formatierungen zur Hervorhebung der Zeitr&auml;ume\" width=\"649,559\" height=\"285,6149\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Der Belegungsplan f&uuml;r Ferienwohnungen enth&auml;lt das dreimonatige Kalendersteuerelement mit mehrfachen Bedingten Formatierungen zur Hervorhebung der Zeitr&auml;ume<\/span><\/b><\/p>\n<p>Im Kombinationsfeld oben kann er ein Objekt ausw&auml;hlen, dessen Vermietungszeitr&auml;ume sich danach im Kalender unten abbilden. Mit den Navigationselementen kann er sich dabei durch beliebige Jahre und Monate bewegen. Die Hintergrundfarben symbolisieren verschiedenen Belegungsarten.<\/p>\n<p>Gr&uuml;ne Felder bedeuten, dass diese Tage f&uuml;r das Objekt noch nicht belegt sind, rote, dass diese Tage vermietet sind. M&ouml;glicherweise w&uuml;rde das bereits ausreichen, doch es gibt auch noch anders geartete Termine. Zur Reinigung oder Wartung der Objekte etwa fallen unter Umst&auml;nden zus&auml;tzliche Tage an. Eventuell nutzt der Vermieter das Objekt auch f&uuml;r den Eigenbedarf. Auch sonst kann das Objekt aus bestimmten Gr&uuml;nden f&uuml;r die Vermietung gesperrt sein. All diese Typen von Belegung sollen sich im Kalender durch eine entsprechende Farbgebung unterscheiden lassen.<\/p>\n<h2>Datenmodell<\/h2>\n<p>Im Prinzip gibt es drei Einheiten, die es zu verkn&uuml;pfen gilt. Einmal sind da die Wohnungen, die mindestens durch Bezeichnungen und Adressen repr&auml;sentiert werden.<\/p>\n<p>Zum anderen gibt es Kunden, die durch Namen und Adressdaten festgelegt sind. Beide kommen &uuml;ber die Belegungszeitr&auml;ume zueinander. Eine Belegung ben&ouml;tigt daher einen Verweis auf einen Kunden, einen auf eine Wohnung und dann noch den Mietzeitraum, welcher durch das Datum des Beginns und das des Endes der Buchung bestimmt ist. Somit kommt es zu drei Tabellen, die sich in der Beispieldatenbank <b>tblKunden<\/b>, <b>tblWohnungen<\/b> und <b>tblBelegung<\/b> nennen. Sie sind miteinander &uuml;ber indizierte Schl&uuml;sselfelder verkn&uuml;pft, wie in Bild 2.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/RelLayout.png\" alt=\"Das grundlegende Datenmodell der Beispieldatenbank zum Belegungsplan\" width=\"649,559\" height=\"416,1908\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Das grundlegende Datenmodell der Beispieldatenbank zum Belegungsplan<\/span><\/b><\/p>\n<p>Diese drei Haupttabellen weisen zus&auml;tzlich je ein Feld <b>Vermerk<\/b> auf, in das optional zu jedem Datensatz eine beliebige Notiz oder Information eingetragen werden kann. Das Feld <b>IDTypBeleg<\/b> in <b>tblBelegung<\/b> verweist au&szlig;erdem auf eine Nachschlagetabelle <b>tblBelegungstyp<\/b>, in der die Arten der Belegung festgehalten sind.<\/p>\n<p>Beginnen wir mit der Tabelle f&uuml;r die Wohnungen (s. Bild 3). Au&szlig;er der <b>ID<\/b> vom <b>Long<\/b>-Typ <b>Autowert<\/b> enth&auml;lt sie nur die <b>Bezeichnung<\/b> des Objekts und die <b>Adresse<\/b> in Form eines <b>Memo<\/b>-Felds.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/tblWohnungen_DS.png\" alt=\"Die Tabelle tblWohnungen im Entwurf\" width=\"499,6607\" height=\"153,504\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Die Tabelle tblWohnungen im Entwurf<\/span><\/b><\/p>\n<p>Normalerweise w&uuml;rde man die Adresse in mehrere Felder aufteilen, f&uuml;r unseren Zweck lassen wir es aber bei dieser einfachen L&ouml;sung. Die Kundentabelle (s. Bild 4) kennen Sie so oder &auml;hnlich schon aus anderen Zusammenh&auml;ngen. Sie weist hier keinerlei Besonderheiten auf.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/tblKunden_DS.png\" alt=\"Die Tabelle tblKunden in der Entwurfsansicht\" width=\"499,6607\" height=\"313,9461\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Die Tabelle tblKunden in der Entwurfsansicht<\/span><\/b><\/p>\n<p>In der Belegungstabelle (s. Bild 5) gibt es zun&auml;chst <b>Start<\/b>&#8211; und <b>Enddatum<\/b> eines Mietzeitraums. Dann verweist das Feld <b>IDKunde<\/b> auf die <b>ID<\/b> eines Kundendatensatzes. Genauso verweist wiederum <b>IDWohnung<\/b> auf die <b>ID<\/b> eines Wohnungsdatensatzes. Vervollst&auml;ndigt wird sie mit dem Feld <b>IDTypBeleg<\/b>, das eine Zahl zur Art der Belegung abspeichert, welche aus der Tabelle <b>tblBelegungstyp<\/b> stammt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/tblBelegung_DS.png\" alt=\"Tabelle tblBelegung im Entwurf\" width=\"349,7625\" height=\"230,9958\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Tabelle tblBelegung im Entwurf<\/span><\/b><\/p>\n<p>Alle Beziehungen sind mit <b>Referenzieller Integrit&auml;t<\/b> ausgestattet, was bedeutet, dass die Tabelle <b>tblBelegung<\/b> keine Datens&auml;tze annimmt, bei denen die Verweis-<b>IDs<\/b> in den Fremdtabellen nicht existieren. Au&szlig;erdem ist f&uuml;r die Beziehungen <b>Aktualisierungs- und L&ouml;schweitergabe<\/b> eingestellt.<\/p>\n<p>Damit f&uuml;hrt das L&ouml;schen eines Kunden oder einer Wohnung automatisch auch zum L&ouml;schen aller beteiligten Belegungen, die Verweise auf jene besitzen. Das macht &uuml;brigens erforderlich, dass die Felder <b>IDKunde<\/b> und <b>IDWohnung<\/b> indiziert sind und die <b>ID<\/b>-Felder der Haupttabellen jeweils den Prim&auml;rschl&uuml;ssel stellen.<\/p>\n<p>Die m&ouml;glichen Belegungsarten sind in der Tabelle <b>tblBelegungstyp<\/b> (s. Bild 6) untergebracht. Der Standard w&auml;re der Datensatz mit dem <b>ID<\/b>-Wert <b>2<\/b>, was <b>Vermietet<\/b> bedeutet. Vielleicht fallen Ihnen noch weitere Typen ein.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/tblBelegungstyp.png\" alt=\"Die m&ouml;glichen Belegungsarten der Tabelle tblBelegungstyp in der Datenblattansicht\" width=\"349,7625\" height=\"201,347\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Die m&ouml;glichen Belegungsarten der Tabelle tblBelegungstyp in der Datenblattansicht<\/span><\/b><\/p>\n<p>Wir sind auch keine Wohnungsmakler und wissen nicht, ob die Eintr&auml;ge <b>Gesperrt<\/b> oder <b>Unbestimmt<\/b> einen tieferen Sinn besitzen. Das Feld <b>Farbe<\/b> (Datentyp <b>Text<\/b>) nimmt weiter in hexadezimaler Form einen <b>RGB<\/b>-Farbwert an, der sp&auml;ter f&uuml;r den Hintergrund der Kalenderzellen &uuml;ber <b>Bedingte Formatierung <\/b>herhalten soll. Das Feld findet nur interne Verwendung. Sein Inhalt kann von Ihnen nach Belieben ge&auml;ndert werden.<\/p>\n<p>Sehen Sie sich einige Datens&auml;tze der Tabelle <b>tblBelegung<\/b> in Bild 7 an. Die Felder <b>IDKunde<\/b>, <b>IDWohnung<\/b> und <b>IDTypBeleg<\/b> enthalten eigentlich verweisende <b>Long<\/b>-Werte, die aber in der Datenblattansicht nicht erscheinen, weil diese Felder als <b>Nachschlagefelder<\/b> mit Kombinationsfeldern als Steuerelement ausgef&uuml;hrt sind.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/tblBelegung_RT.png\" alt=\"Die Tabelle tblBelegung einh&auml;lt die drei Spalten IDKunde, IDWohnung und IDTypBeleg als Nachschlagefelder\" width=\"700\" height=\"170,1076\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Die Tabelle tblBelegung einh&auml;lt die drei Spalten IDKunde, IDWohnung und IDTypBeleg als Nachschlagefelder<\/span><\/b><\/p>\n<p>Exemplarisch zeigt Bild 8 das f&uuml;r die Spalte <b>IDKunde<\/b>. Der <b>Herkunftstyp<\/b> ist hier auf T<b>abelle\/Abfrage<\/b> eingestellt und als Quelle dient die Tabelle <b>tblKunden<\/b>, aus der die erste Spalte (<b>ID<\/b>) angebunden werden soll. Anzeigen aber soll das Feld den Namen des Kunden, welcher sich im dritten Feld befindet. Darum ist <b>Spaltenanzahl<\/b> auch auf <b>3<\/b> gesetzt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/tblBelegung_Nachschlage.png\" alt=\"Das Feld IDKunde in tblBelegung ist ein Nachschlagefeldlegungstyp in der Datenblattansicht\" width=\"499,6607\" height=\"298,5315\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Das Feld IDKunde in tblBelegung ist ein Nachschlagefeldlegungstyp in der Datenblattansicht<\/span><\/b><\/p>\n<p>Da auch wirklich nur der Name auftauchen soll, m&uuml;ssen zus&auml;tzlich die ersten beiden <b>Spaltenbreiten<\/b> des Kombinationsfelds auf <b>0 cm<\/b> eingestellt sein. Um m&ouml;glichst viele Kunden bei der <b>DropDown<\/b>-Auswahl ber&uuml;cksichtigen zu k&ouml;nnen, steht die <b>Zeilenanzahl<\/b>, abweichend vom Access-Standard <b>16<\/b>, auf <b>30<\/b>.<\/p>\n<p>Damit ist das eigentliche Datenmodell der Datenbank hinreichend erl&auml;utert. F&uuml;r unseren speziellen Anwendungsfall ist nun aber noch die f&uuml;r das Kalendersteuerelement verantwortliche Tabelle <b>tblCalendarMonths<\/b> zu ver&auml;ndern. Zur Erinnerung: Die enth&auml;lt 21 Felder vom Typ Zahl (<b>Long<\/b>), in denen Datumswerte abgespeichert werden.<\/p>\n<p>Negative Werte bestimmten dabei jene Bereiche des Kalenders, die farblich hinterlegt werden sollen.<\/p>\n<p>Nun haben wir es bei unserem Belegungsplan aber nicht nur mit einer m&ouml;glichen Farbe zu tun, sondern, je nach Art der Belegung, mit mehreren.<\/p>\n<p>Folglich muss ein Datenfeld dieser Tabelle mehr Informationen hergeben, als nur das Datum und ein Vorzeichen.<\/p>\n<p>Deshalb &auml;nderten wir alle Felder auf den Typ <b>Text<\/b>. Der m&ouml;gliche Inhalt der Felder geht aus der Datenblattansicht in Bild 9 hervor, nachdem sich die Tabelle &uuml;ber das Formular <b>sfrmCalendarMonths<\/b> f&uuml;llte.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/tblCalendarMonths_RT.png\" alt=\"Die Tabelle tblCalendarMonths kombiniert in ihren Feldern das Datum und den Belegtyp eines Kalendereintrags in einer Textform\" width=\"599,593\" height=\"258,3352\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 9: Die Tabelle tblCalendarMonths kombiniert in ihren Feldern das Datum und den Belegtyp eines Kalendereintrags in einer Textform<\/span><\/b><\/p>\n<p>Das eigentliche Datum steht nun an vorderster Stelle und ist immer 5 Zeichen lang. Danach schlie&szlig;t sich als visueller Trenner ein Unterstrich an, auf den der Typ der Belegung als Ziffer folgt. Es ist logisch, dass diese &auml;nderung der Tabelle dann auch Modifikationen der beteiligten Routinen im Formular, wie der Prozedur <b>FillCalendar<\/b>, erfordert. Dazu sp&auml;ter mehr.<\/p>\n<h2>Kunden und Wohnungsobjekte<\/h2>\n<p>F&uuml;r die Kunden und Wohnungen der Datenbank gibt es keine Anzeige- oder Eingabeformulare, da wir uns komplett auf die Kalenderansichten konzentrieren. Diese m&uuml;ssten Sie gegebenenfalls selbst nachr&uuml;sten. Die Datens&auml;tze sind bei den Kunden aus den hinl&auml;nglich bekannten Demo-Adresstabellen von <b>Access Basics<\/b> importiert. Die Wohnobjekte sind nat&uuml;rlich fingiert. Bild 10 zeigt alle in die Beispieldatenbank eingebauten.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/tblWohnungen_RT.png\" alt=\"Die Tabelle tblWohnungen speichert alle vermiet- und belegbaren Objekte\" width=\"700\" height=\"278,9856\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 10: Die Tabelle tblWohnungen speichert alle vermiet- und belegbaren Objekte<\/span><\/b><\/p>\n<p>Neben verlockenden Ferienwohnungen erfanden wir noch Einzelzimmer und Pensionszimmer. Die <b>Pension Zum Hirschen<\/b> kann nur ein Zimmer anbieten.<\/p>\n<p>Die Eintr&auml;ge in der Spalte <b>Vermerk<\/b> zeigen, wof&uuml;r Sie intern f&uuml;r den Vermieter verwendet werden k&ouml;nnte. Wollten Sie die Sache professionell gestalten, so enthielte diese Tabelle noch weit mehr Felder. So etwa zu Ausstattungsmerkmalen oder in einem <b>Anlagefeld<\/b> Fotos des Interieurs.<\/p>\n<h2>&auml;nderungen am Kalendersteuerelement sfrmCalendarMonths<\/h2>\n<p>Nachdem die Tabelle <b>tblCalendarMonths<\/b> nun <b>String<\/b>-, statt <b>Long<\/b>-Werte erwartet, muss die Routine <b>FillCalendar<\/b> zum F&uuml;llen der Tabelle komplett &uuml;berarbeitet werden. In Listing 1 ist nur jener Teil abgebildet, der sich gegen&uuml;ber der Ursprungsprozedur ver&auml;ndert hat. <\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>FillCalendar()\r\n     (...)\r\n     <span style=\"color:blue;\">Set<\/span> rs = CurrentDb.OpenRecordset(\"tblCalendarMonths\", dbOpenDynaset)\r\n     For n = 0 To 4\r\n         rs.Add<span style=\"color:blue;\">New<\/span>\r\n         For i = 1 To 3\r\n             MaxDate = DateSerial(m_Year, m_Month + i - 1, 0)\r\n             For j = 1 To 7\r\n                 DTmp = DateAdd(\"m\", i - 1, StartDate)\r\n                 DTmp = DateAdd(\"d\", n * 7 + j - 1, DTmp)\r\n                 <span style=\"color:blue;\">If <\/span>DTmp &gt; MaxDate<span style=\"color:blue;\"> Then<\/span> <span style=\"color:blue;\">Exit For<\/span>\r\n                 lType = IsInRanges(DTmp)\r\n                 rs.Fields(\"D\" & CStr(j) & CStr(i)).Value = CLng(DTmp) & \"_\" & CStr(lType)\r\n             <span style=\"color:blue;\">Next<\/span> j\r\n         <span style=\"color:blue;\">Next<\/span> i\r\n         rs.Update\r\n     <span style=\"color:blue;\">Next<\/span> n\r\n     (...)\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><!--30percent--><\/p>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Neues Bef&uuml;llen der Tabelle tblCalendarMonths<\/span><\/b><\/p>\n<p>Dabei ist der Grundaufbau mit den drei ineinander verschachtelten Schleifen gleich geblieben. Ebenso die Berechnung der Datumswerte in der Variablen <b>DTmp<\/b> und die Abbruchbedingung beim Vergleich mit <b>MaxDate<\/b>.<\/p>\n<p>Neu hingegen ist die Speicherung des Belegungstyps in der Long-Variablen <b>lType<\/b>, der aus der ebenfalls modifizierten Routine <b>IsInRanges<\/b> (s. Listing 2) stammt. Diese gibt nun nicht mehr einfach <b>True<\/b> oder <b>False<\/b> zur&uuml;ck, sondern eine Zahl, die der <b>ID<\/b> in der Tabelle <b>tblBelegungsarten<\/b> entspricht. Einem Datenfeld von <b>tblCalendarMonths<\/b> wird schlie&szlig;lich der per <b>CLng<\/b> erhaltene Integer-Wert des Datums <b>DTmp<\/b> zugewiesen, gefolgt vom Unterstrich und dem Inhalt der soeben ermittelten Variablen <b>lType<\/b>.<\/p>\n<pre><span style=\"color:blue;\">Private <\/span>Type TRange\r\n     StartDate<span style=\"color:blue;\"> As Date<\/span>\r\n     EndDate<span style=\"color:blue;\"> As Date<\/span>\r\n     Type<span style=\"color:blue;\"> As Long<\/span>\r\nEnd Type \r\n<span style=\"color:blue;\">Private Function <\/span>IsInRanges(D<span style=\"color:blue;\"> As Date<\/span>)<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Long<\/span>, n<span style=\"color:blue;\"> As Long<\/span>\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     n = <span style=\"color:blue;\">UBound<\/span>(arrRanges)\r\n     <span style=\"color:blue;\">If <\/span>Err.Number &lt;&gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">On Error GoTo<\/span> 0:  <span style=\"color:blue;\">Exit Function<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     For i = 0 To n\r\n         <span style=\"color:blue;\">If <\/span>(D &gt;= arrRanges(i).StartDate) And (D &lt;= arrRanges(i).EndDate)<span style=\"color:blue;\"> Then<\/span>\r\n                 IsInRanges = arrRanges(i).Type:  <span style=\"color:blue;\">Exit For<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Auch die Hilfsfunktion IsInRanges &auml;ndert sich<\/span><\/b><\/p>\n<p>Das Array <b>arrRanges<\/b> des Moduls, welches die Zeitr&auml;ume aufnimmt, basiert nun auf dem erweiterten Typ <b>TRange<\/b> im Modulkopf. Neben <b>StartDate<\/b> und <b>EndDate<\/b> weist dieser Typ nun zus&auml;tzlich das Element <b>Type<\/b> aus. Beim Zuweisen eines Zeitraums &uuml;ber die Methode <b>AddRange<\/b> m&uuml;ssen Sie nun auch den Belegungstyp angeben (s. Listing 3).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>AddRange(StartDate<span style=\"color:blue;\"> As Date<\/span>, EndDate<span style=\"color:blue;\"> As Date<\/span>, Typ<span style=\"color:blue;\"> As Long<\/span>)\r\n     (...)\r\n    ReDim Preserve arrRanges(n)\r\n     arrRanges(n).StartDate = StartDate\r\n     arrRanges(n).EndDate = EndDate\r\n     arrRanges(n).Type = Typ\r\n     (...)\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Prozedur zum Zuweisen eines Zeitraums<\/span><\/b><\/p>\n<p>Ermittelt die Funktion <b>IsInRanges<\/b>, dass sich das &uuml;bergebene Datum <b>D<\/b> innerhalb der abgespeicherten Zeitr&auml;ume befindet, so gibt sie nun die Zahl aus <b>arrRanges(i).Type<\/b> zur&uuml;ck.<\/p>\n<p>Mehr gibt es zum F&uuml;llen der Tabelle <b>tblCalendarMonths<\/b> nicht zu sagen. Was nun noch aussteht, sind &auml;nderungen an den Textboxen des Detailbereichs, denn weder die Ausdr&uuml;cke f&uuml;r den Steuerelementinhalt, noch jene f&uuml;r die <b>Bedingte Formatierung<\/b> stimmen nunmehr infolge der Textdaten der Tabelle.<\/p>\n<p>Die Steuerelementinhalte &auml;ndern sich von <\/p>\n<pre>=Wenn(IstNull([D11]);\"\";Tag(Abs([D11])))<\/pre>\n<p>auf den folgenden Inhalt:<\/p>\n<pre>=Wenn(IstNull([D11]);\"\";Tag(Links([D11];5)))<\/pre>\n<p>Nicht mehr der Feldwert selbst (<b>D11<\/b>) wird zur Berechnung herangezogen, sondern die ersten f&uuml;nf Ziffern. Tats&auml;chlich hat die <b>Day<\/b>-Funktion von VBA (<b>Tag()<\/b>) kein Problem mit dem von <b>Left<\/b> zur&uuml;ckgegebenen String. Hier findet intern wohl eine zweifache Konvertierung statt: Aus dem Text entsteht ein Integer und aus diesem wiederum ein Datumswert. VBA nimmt diese beim Ansprechen von <b>Day()<\/b> ganz automatisch vor! Es w&auml;re ein m&uuml;hsames Unterfangen, diese Ausdr&uuml;cke alle manuell anzulegen.<\/p>\n<p>Die Routine <b>SetCtlSource<\/b> im Modul <b>mdlHelper<\/b> (s. Listing 4) der Datenbank setzt sie automatisiert alle auf einen Schlag, nachdem Sie das Formular <b>sfrmCalendarMonths<\/b> in der Entwurfsansicht &ouml;ffnen. Alle Textboxen des Detailbereichs werden in einer Schleife durchlaufen, der Datenfeldname aus dem Steuerelementnamen extrahiert und in <b>S<\/b> gespeichert.<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>SetCtlSource()\r\n     <span style=\"color:blue;\">Dim <\/span>frm<span style=\"color:blue;\"> As <\/span>Access.Form\r\n     <span style=\"color:blue;\">Dim <\/span>ctl<span style=\"color:blue;\"> As <\/span>Access.TextBox\r\n     <span style=\"color:blue;\">Dim <\/span>S<span style=\"color:blue;\"> As String<\/span>\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> frm = Screen.ActiveForm\r\n     For Each ctl In frm.Section(acDetail).Controls\r\n         S = \"[\" & <span style=\"color:blue;\">Mid<\/span>(ctl.Name, 4) & \"]\"\r\n         ctl.ControlSource = \"=IIF(IsNull(\" & S & \"),\"\"\"\",Day(<span style=\"color:blue;\">Left<\/span>(\" & S & \",5)))\"\r\n     <span style=\"color:blue;\">Next<\/span> ctl\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Automatisiertes Setzen der Textbox-Ausdr&uuml;cke<\/span><\/b><\/p>\n<p>Die <b>ControlSource<\/b> (<b>Steuerelementinhalt<\/b>) wird nun zusammengebastelt und der Textbox <b>ctl<\/b> zugewiesen, wobei im Ausdruck die englische Syntax zur Anwendung kommen muss.<\/p>\n<p>&auml;hnlich verf&auml;hrt die Hilfsroutine zum Setzen der <b>Bedingten Formatierungen<\/b>. Hier w&auml;re die manuelle Anlage eine wahre Sisyphusarbeit! Denn f&uuml;r jede der 21 Textfelder m&uuml;ssen Sie nun, wie in Bild 11, je f&uuml;nf Regeln vorsehen, damit die unterschiedlichen Hintergrundfarben zum Tragen kommen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/FormatConditions.png\" alt=\"Jedes Textfeld des Kalenders ben&ouml;tigt nun f&uuml;nf bedingte Format-Regeln\" width=\"599,593\" height=\"313,8156\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 11: Jedes Textfeld des Kalenders ben&ouml;tigt nun f&uuml;nf bedingte Format-Regeln<\/span><\/b><\/p>\n<p>Die rechte Seite des Datenfeld-Strings wird abgeschnitten und mit einer der Zahlen von <b>1<\/b> bis <b>5<\/b> verglichen.<\/p>\n<p>Trifft das zu, so f&auml;rbt die Regel den Zellhintergrund entsprechend ein. Beispiel:<\/p>\n<pre>D31 = \"42889_2\"&nbsp;&nbsp;&nbsp;&nbsp;-&gt; Sa, 03.07.2017; Vermietung\r\n<span style=\"color:blue;\">Right<\/span>([D31]) = \"2\"&nbsp;&nbsp;&nbsp;&nbsp;-&gt; roter Hintergrund<\/pre>\n<p>Bei mehrfachen Regeln zu einer <b>Bedingten Formatierung<\/b> werden diese von oben nach unten abgearbeitet. St&uuml;nde in allen der gleiche Vergleichsausdruck, so k&auml;me es bei &uuml;bereinstimmung zum untersten Format, also der grauen Hintergrundfarbe.<\/p>\n<p>Die Regeln werden in der Routine <b>SetFormatConditions<\/b> auf die gleiche Weise angelegt, wie wir das bereits im Beitrag zum Kalendersteuerelement demonstrierten. Listing 5 bildet die Prozedur ab. Basis bildet die Tabelle <b>tblBelegungstyp<\/b>, auf die ein <b>Recordset<\/b> ge&ouml;ffnet wird.<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>SetFormatConditions()\r\n     <span style=\"color:blue;\">Dim <\/span>frm<span style=\"color:blue;\"> As <\/span>Access.Form\r\n     <span style=\"color:blue;\">Dim <\/span>ctl<span style=\"color:blue;\"> As <\/span>Access.TextBox\r\n     <span style=\"color:blue;\">Dim <\/span>S<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>fmtcond<span style=\"color:blue;\"> As <\/span>FormatCondition\r\n     <span style=\"color:blue;\">Dim <\/span>rs<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> rs = CurrentDb.OpenRecordset(\"SELECT * FROM tblBelegungstyp\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Set<\/span> frm = Screen.ActiveForm\r\n     For Each ctl In frm.Section(acDetail).Controls\r\n         S = \"[\" & <span style=\"color:blue;\">Mid<\/span>(ctl.Name, 4) & \"]\"\r\n         ctl.FormatConditions.Delete\r\n         rs.MoveFirst\r\n         <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rs.EOF\r\n             <span style=\"color:blue;\">Set<\/span> fmtcond = ctl.FormatConditions.Add( _\r\n                 acExpression, , \"<span style=\"color:blue;\">Right<\/span>(\" & S & \",1)=\" & rs!Id.Value)\r\n             fmtcond.BackColor = Val(\"&H\" & rs!Farbe.Value)\r\n             rs.Move<span style=\"color:blue;\">Next<\/span>\r\n         <span style=\"color:blue;\">Loop<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> ctl\r\n     rs.Close\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Automatisiertes Setzen der bedingten Formate im Detailbereich von sfrmCalendarMonths<\/span><\/b><\/p>\n<p>F&uuml;r jede Textbox <b>ctl<\/b> werden die Datens&auml;tze des Recordsets jeweils in <b>Do-While<\/b> durchlaufen und der Vergleichsausdruck anhand des <b>ID<\/b>-Werts der Tabelle bestimmt. Auch hier ist zwingend englische Syntax zu verwenden!<\/p>\n<p>Die Hintergrundfarbe setzt die Eigenschaft <b>BackColor<\/b> der einzelnen <b>FormatCondition<\/b> <b>fmtCond<\/b>, wobei der Farbwert sich direkt aus dem Datenfeld <b>Farbe<\/b> des Recordsets ableitet. Aus dem Hexadezimal-String wird &uuml;ber <b>Val<\/b> und das <b>Hex-Pr&auml;fix &#038;H <\/b>ein <b>Long<\/b>-Wert erhalten.<\/p>\n<p>Nach dem Aufruf der Routine m&uuml;ssen Sie das Formular im Entwurf dezidiert speichern, bevor Sie es schlie&szlig;en, denn bei Entwurfs&auml;nderungen, die per VBA vorgenommen wurden, fragt Access in der Regel nicht automatisch nach!<\/p>\n<p>Sie ersparen sich also mit dieser Hilfsprozedur die manuelle Anlage von 105 Formatierungsausdr&uuml;cken! In der daf&uuml;r ben&ouml;tigten Zeit ist sie l&auml;ngst programmiert. Hinzu kommt, dass Sie die Hintergrundfarben in der Tabelle <b>tblBelegungstyp<\/b> eventuell auch einmal &auml;ndern m&ouml;chten. Dann w&auml;ren alle Formatierungsregeln zu modifizieren. Mit der Routine gelingt das im Nu!<\/p>\n<p>&uuml;brigens sind die Textboxen in dieser Version des Kalendersteuerelements nicht transparent, sondern mit einem festen gr&uuml;nen Hintergrund versehen, der die freien Buchungszeitr&auml;ume symbolisiert.<\/p>\n<p>Gleich vorweg: Das Auswerten und Rendern der <b>Bedingten Formatierung<\/b> ist, da es f&uuml;r jede Zelle des Kalenders geschehen muss, ein rechenintensiver Prozess. Immerhin enth&auml;lt der Kalender bis zu 126 Zellen, die jeweils ausgewertet werden.<\/p>\n<p>Das f&uuml;hrt, je nach Rechnerausstattung, zu einer kleinen Verz&ouml;gerung. Sie k&ouml;nnen den Vorgang etwas beschleunigen, indem Sie das Neuzeichnen des Formulars kurzfristig aussetzen. Am Anfang der Prozedur <b>FillCalendar<\/b> k&ouml;nnten Sie etwa die Eigenschaft <b>Painting<\/b> des Formulars deaktivieren und am Schluss wieder aktivieren:<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>FillCalender()\r\n     Me.Painting = <span style=\"color:blue;\">False<\/span>\r\n     (Berechnungen...)\r\n     Me.Painting = <span style=\"color:blue;\">True<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Grunds&auml;tzlich aber kann auf das Rendern der <b>Bedingten Formatierungen<\/b> nur wenig Einfluss genommen werden. Bei umfangreichen Datenbl&auml;ttern wird die sequenzielle Formatierung von oben nach unten durchaus sichtbar. Warum Microsoft keine M&ouml;glichkeit vorgesehen hat, die Farben der <b>einzelnen<\/b> Zellen eines Datenblatts oder eines Endlosbereichs &uuml;ber eine VBA-Eigenschaft direkt zu beeinflussen, ist etwas r&auml;tselhaft, da die Einzelformatierung im Prinzip intern ja eingebaut ist. Andere <b>ActiveX-Grids<\/b> sehen derlei durchaus vor.<\/p>\n<h2>Zus&auml;tzliches Click-Ereignis<\/h2>\n<p>Bei Klick auf ein Datum des Kalenders passiert in der bisherigen Version gar nichts. Das m&ouml;chten wir &auml;ndern. Dazu muss f&uuml;r jede der 21 Textboxen eine <b>Click<\/b>-Ereignisprozedur angelegt werden, die wieder lediglich die <b>Sub-Prozedur fuClick<\/b> aufruft. Diese soll dann das Datum der Zelle ermitteln und an ein Ereignis weiterleiten. Das neue Ereignis ist im Kopf des Moduls so deklariert:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>Event DateClicked(ByVal ThisDate<span style=\"color:blue;\"> As Date<\/span>, Typ<span style=\"color:blue;\"> As Long<\/span>)<\/pre>\n<p>Neben dem Datum in <b>ThisDate<\/b> soll das Ereignis zus&auml;tzlich in <b>Typ<\/b> die Information &uuml;ber den Belegungstyp des Datums liefern. Zun&auml;chst die Klickereignisse der Textboxen:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtD11_Click()\r\n     fuClick\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>txtD12_Click()\r\n     fuClick\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n... etc. ...<\/pre>\n<p>Die Prozedur <b>fuClick<\/b> wertet wieder das aktive Steuerelement (<b>ActiveControl<\/b>) im Formular aus:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>fuClick()\r\n     <span style=\"color:blue;\">Dim <\/span>S<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>D<span style=\"color:blue;\"> As Date<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>T<span style=\"color:blue;\"> As Long<\/span>\r\n     \r\n     S = <span style=\"color:blue;\">Mid<\/span>(Me.ActiveControl.Name, 4)\r\n     D = CDate(<span style=\"color:blue;\">Left<\/span>(Me.Controls(S).Value, 5))\r\n     T = CLng(<span style=\"color:blue;\">Right<\/span>(Me.Controls(S).Value, 1))\r\n     RaiseEvent DateClicked(D, T)\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>In <b>S<\/b> wird der Name des Datenfelds gespeichert, an das die Textbox gebunden ist. Aus <b>txtD13<\/b> wird so etwa <b>D13<\/b>. Denn nicht den &uuml;ber einen Ausdruck erhaltenen sichtbaren Wert der Textbox selbst ben&ouml;tigen wir hier, sondern den Wert des Datenfelds.<\/p>\n<p>Auf dieses k&ouml;nnen wir nun Bezug nehmen, denn zu jedem Datenfeld enth&auml;lt ein Formular ein verstecktes unsichtbares Steuer-element gleichen Namens. Deshalb gibt <b>Controls(S).Value<\/b> direkt den zugrunde liegenden Datenwert zur&uuml;ck. Von diesem wird zun&auml;chst der linke Teil mit den f&uuml;nf Ziffern ber&uuml;cksichtigt, der das eigentliche Datum darstellt und sich &uuml;ber <b>CDate<\/b> in <b>D<\/b> speichert.<\/p>\n<p>Die eine rechte Ziffer hingegen symbolisiert den <b>Belegungstyp<\/b> und kommt als <b>Long<\/b>-Wert (<b>CLng<\/b>) in die Variable <b>T<\/b>. Beide zusammen werden dem Ereignis <b>DateClicked<\/b> &uuml;berreicht, das nun per <b>RaiseEvent<\/b> ausgel&ouml;st wird.<\/p>\n<h2>Einbau des Kalender-steuerelements in das Formular Belegungsplan<\/h2>\n<p>Nachdem das Formular <b>sfrmCalendarMonths<\/b> f&uuml;r den &uuml;bersichtskalender unseren Anforderungen entsprechend umgestaltet wurde, kann es in ein Hauptformular eingebaut werden, das sich in der Beispieldatenbank <b>frmBelegung<\/b> nennt. Im Entwurf stellt es sich dar, wie in Bild 12. Als einziges zus&auml;tzliches Steuerelement enth&auml;lt es oben ein Kombinationsfeld zur Auswahl des Mietobjekts.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/frmBelegung_DS.png\" alt=\"Das Formular frmBelegung im Entwurf mit integriertem Kalenderunterformular\" width=\"700\" height=\"350,0001\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 12: Das Formular frmBelegung im Entwurf mit integriertem Kalenderunterformular<\/span><\/b><\/p>\n<p>Diese Combobox <b>cbObjekt<\/b> speist sich direkt aus der Tabelle <b>tblWohnungen<\/b> und gibt nach Auswahl die <b>ID<\/b> der Wohnung als Wert zur&uuml;ck. Das Ereignis <b>Nach Aktualisieren<\/b> (<b>AfterUpdate<\/b>) der Combobox zieht die Vorg&auml;nge in Listing 6 nach sich. <\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cbObjekt_AfterUpdate()\r\n     <span style=\"color:blue;\">Dim <\/span>rs<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     \r\n     oCalendar.DeleteRanges\r\n     <span style=\"color:blue;\">If <\/span>IsNull(Me!cbObjekt.Value)<span style=\"color:blue;\"> Then<\/span> <span style=\"color:blue;\">Exit Sub<\/span>\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> rs = CurrentDb.OpenRecordset(\"SELECT * FROM tblBelegung WHERE IDWohnung=\" & cbObjekt.Value, dbOpenDynaset)\r\n     Me.Painting = <span style=\"color:blue;\">False<\/span>\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rs.EOF\r\n         oCalendar.AddRange rs!Startdatum.Value, _\r\n                 rs!Enddatum.Value, rs!IDTypBeleg.Value\r\n         rs.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     Me.Painting = <span style=\"color:blue;\">True<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Nach Auswahl eines Mietobjekts f&uuml;gt diese Ereignisprozedur dem Kalender neue Zeitr&auml;ume hinzu.<\/span><\/b><\/p>\n<p>Erst werden alle eventuell gespeicherten Zeitr&auml;ume des Kalendersteuerelements &uuml;ber die Anweisung <b>DeleteRanges<\/b> gel&ouml;scht. Au&szlig;erdem wird die Routine gleich verlassen, wenn in der Combobox nichts ausgew&auml;hlt ist, ihr Wert also <b>Null<\/b> betr&auml;gt.<\/p>\n<p>Ansonsten &ouml;ffnet sich ein Recordset auf eine Abfrage, die die Tabelle <b>tblBelegung<\/b> hernimmt und nach der Wohnung mit der von der Combobox zur&uuml;ckgegebenen <b>ID<\/b> filtert. Eine Schleife arbeitet nun alle Zeitr&auml;ume ab und weist sie dem Kalender &uuml;ber die Methode <b>AddRange<\/b> zu.<\/p>\n<p>Jedes Zuweisen eines Zeitraums f&uuml;hrt zu einem Neuzeichnen des Kalenders. Um das dabei auftretende Flackern zu eliminieren, ist f&uuml;r die ganze Schleife das Neurendern &uuml;ber <b>Painting = False<\/b> deaktiviert.<\/p>\n<p>Erst am Ende findet deshalb die visuelle Ausgabe statt, nachdem die Eigenschaft wieder auf <b>True<\/b> gesetzt ist.<\/p>\n<p>Die einzige weitere Prozedur des Moduls ist die Reaktion auf das neue Ereignis <b>DateClicked<\/b> des Kalendersteuerelements, welches der Objektvariablen <b>oCalendar<\/b> zugewiesen wurde. Sie entnimmt den &uuml;bergebenen Parametern das Datum und den Typ der Belegung und zeigt dann informativ in einem Meldungsfenster an, ob dieses Datum f&uuml;r das Mietobjekt schon belegt oder frei ist. <\/p>\n<h2>Buchung &uuml;ber den Kalender<\/h2>\n<p>Eine Erweiterung des Belegungsformulars findet sich im Formular <b>frmBuchung<\/b> der Beispieldatenbank (s. Bild 13). Hier kann nicht nur ein Wohnobjekt aus einem Kombinationsfeld gew&auml;hlt werden, sondern auch ein Kunde. Das Kalendersteuerelement zeigt die Zeitr&auml;ume auf gleiche Weise an, wie der Belegungsplan zuvor.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/frmBuchung_DS.png\" alt=\"Das Formular frmBuchungen im Entwurf ist eine Erweiterung von frmBelegung\" width=\"649,559\" height=\"398,5521\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 13: Das Formular frmBuchungen im Entwurf ist eine Erweiterung von frmBelegung<\/span><\/b><\/p>\n<p>&uuml;ber die Schaltfl&auml;chen <b>Vom&#8230;<\/b> und <b>Bis&#8230;<\/b> k&ouml;nnen Sie hier jedoch f&uuml;r den Kunden einen Buchungszeitraum festlegen, der dann auch in der Tabelle <b>tblBelegung<\/b> abgespeichert wird und sich sofort in der Ansicht wiederspiegelt. <\/p>\n<p>Die beiden Schaltfl&auml;chen rufen jeweils den einfachen Auswahlkalender dieser Ausgabe auf. Das ist ein Verhalten, das h&auml;ufig bei Buchungssystem im Web zu finden ist. Bei uns sieht das dann aus, wie in Bild 14. Aus dem &uuml;berlagernden Popup-Kalender wird hier das Enddatum der Buchung ausgew&auml;hlt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/frmBuchung_RT.png\" alt=\"Formular frmBuchungen zur Laufzeit und ein Popup-Datumsauswahlkalender\" width=\"699,525\" height=\"358,9667\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 14: Formular frmBuchungen zur Laufzeit und ein Popup-Datumsauswahlkalender<\/span><\/b><\/p>\n<p>Allerdings wird das Auswahlkalenderformular <b>sfrmCalendar<\/b> nicht standalone aufgerufen, sondern ist in ein Hauptformular <b>frmCalendarDlg<\/b> eingebaut, das einige Eigenschaften des Steuerelements steuert.<\/p>\n<p>F&uuml;r dessen Aufruf haben wir eine Prozedur <b>GetDateDialog<\/b> (<b>mdlCalendar<\/b>) erstellt (s. Listing 7):<\/p>\n<pre><span style=\"color:blue;\">Function <\/span>GetDateDialog(<span style=\"color:blue;\">Optional<\/span> SelDate<span style=\"color:blue;\"> As Variant<\/span>, <span style=\"color:blue;\">Optional<\/span> Title<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Variant<\/span>\r\n     DoCmd.OpenForm \"frmCalendarDlg\", , , , , acDialog, SelDate & \"|\" & Title\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     GetDateDialog = Forms!frmCalendarDlg.SelectedDate\r\n     DoCmd.Close acForm, \"frmCalendarDlg\"\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 7: Beispiel f&uuml;r das &ouml;ffnen des Datumsdialogs<\/span><\/b><\/p>\n<p>Sie k&ouml;nnen diese etwa auch aus dem VBA-Direktfenster so aufrufen:<\/p>\n<pre>  GetDateDialog(\"01.01.2019\", \"Test\")<\/pre>\n<p>Damit &ouml;ffnet sich der Popup-Kalender mit der in <b>Title<\/b> &uuml;bergebenen &uuml;berschrift und dem gew&uuml;nschten voreingestellten Datum. Nach Klick auf ein Datum oder nach Schlie&szlig;en des Datumdialogs &uuml;ber die <b>Schlie&szlig;en<\/b>-Schaltfl&auml;che erscheint das geklickte Datum im Ausgabefenster als R&uuml;ckgabewert der Funktion.<\/p>\n<p>Die Funktion &ouml;ffnet zun&auml;chst das Formular <b>frmCalendarDlg<\/b> als Dialog. In diesem Modus h&auml;lt die Prozedur an und wartet, bis es sich geschlossen hat oder unsichtbar wurde. Genau Letzteres macht auch das Formular <b>frmCalendarDlg<\/b>. Bei Auswahl eines Datums stellt sie seine <b>Visible<\/b>-Eigenschaft auf <b>False<\/b>, nachdem es eine <b>Member<\/b>-Variable <b>m_Date<\/b> auf das angeklickte Datum eingestellt hat. Dadurch f&uuml;hrt <b>GetDateDialog<\/b> die weiteren Code-Zeilen aus. Sie liest aus dem im Hintergrund immer noch bestehenden Formular das Datum &uuml;ber dessen Eigenschaft <b>SelectedDate<\/b> aus und schlie&szlig;t es dann erst &uuml;ber die <b>DoCmd<\/b>-Anweisung. <\/p>\n<p>Eben diese allgemein verwendbare Funktion rufen die beiden Schaltfl&auml;chen des Formulars <b>frmBuchung<\/b> auf.  Aus Platzgr&uuml;nden k&ouml;nnen wir weder auf den Code dieses Formulars eingehen, noch auf den des Dialogformulars. Inspizieren Sie diese bei Interesse selbst. Sie k&ouml;nnen die Funktion jedoch in Ihren eigenen Datenbanken verwenden, indem Sie die folgenden Elemente aus der Beispieldatenbank importieren:<\/p>\n<ul>\n<li><b>sfrmCalendar<\/b><\/li>\n<li><b>frmCalendarDlg<\/b><\/li>\n<li><b>mdlCalendar<\/b><\/li>\n<li><b>tblCalendar<\/b><\/li>\n<\/ul>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>Belegungsplan.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/36C9F2F1-88BA-4D4A-B703-3DE6F17BDF27\/aiu_1102.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bei der Suche nach sinnvollen Anwendungszwecken f&uuml;r die Kalendersteuerelemente dieser Ausgabe fiel die Entscheidung f&uuml;r ein Beispiel schwer. Wir demonstrieren deren Einsatz nun an einem fingierten Belegungsplan f&uuml;r Ferienwohnungen, der zudem das &Uuml;bersichtskalenderelement noch um das eine oder andere Feature erweitert.<\/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":[662017,66052017,44000027],"tags":[],"class_list":["post-55001102","post","type-post","status-publish","format-standard","hentry","category-662017","category-66052017","category-Loesungen"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Belegungsplan mit Kalender - 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\/Belegungsplan_mit_Kalender\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Belegungsplan mit Kalender\" \/>\n<meta property=\"og:description\" content=\"Bei der Suche nach sinnvollen Anwendungszwecken f&uuml;r die Kalendersteuerelemente dieser Ausgabe fiel die Entscheidung f&uuml;r ein Beispiel schwer. Wir demonstrieren deren Einsatz nun an einem fingierten Belegungsplan f&uuml;r Ferienwohnungen, der zudem das &Uuml;bersichtskalenderelement noch um das eine oder andere Feature erweitert.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-14T13:38:10+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg09.met.vgwort.de\/na\/56e1ea5b19254e1289566f60b6e3b27d\" \/>\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=\"20\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Belegungsplan mit Kalender\",\"datePublished\":\"2020-05-14T13:38:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/\"},\"wordCount\":3452,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/56e1ea5b19254e1289566f60b6e3b27d\",\"articleSection\":[\"2017\",\"5\\\/2017\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/\",\"name\":\"Belegungsplan mit Kalender - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/56e1ea5b19254e1289566f60b6e3b27d\",\"datePublished\":\"2020-05-14T13:38:10+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/56e1ea5b19254e1289566f60b6e3b27d\",\"contentUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/56e1ea5b19254e1289566f60b6e3b27d\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Belegungsplan_mit_Kalender\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Belegungsplan mit Kalender\"}]},{\"@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":"Belegungsplan mit Kalender - 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\/Belegungsplan_mit_Kalender\/","og_locale":"de_DE","og_type":"article","og_title":"Belegungsplan mit Kalender","og_description":"Bei der Suche nach sinnvollen Anwendungszwecken f&uuml;r die Kalendersteuerelemente dieser Ausgabe fiel die Entscheidung f&uuml;r ein Beispiel schwer. Wir demonstrieren deren Einsatz nun an einem fingierten Belegungsplan f&uuml;r Ferienwohnungen, der zudem das &Uuml;bersichtskalenderelement noch um das eine oder andere Feature erweitert.","og_url":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-14T13:38:10+00:00","og_image":[{"url":"http:\/\/vg09.met.vgwort.de\/na\/56e1ea5b19254e1289566f60b6e3b27d","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"20\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Belegungsplan mit Kalender","datePublished":"2020-05-14T13:38:10+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/"},"wordCount":3452,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/56e1ea5b19254e1289566f60b6e3b27d","articleSection":["2017","5\/2017","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/","url":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/","name":"Belegungsplan mit Kalender - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/56e1ea5b19254e1289566f60b6e3b27d","datePublished":"2020-05-14T13:38:10+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/#primaryimage","url":"http:\/\/vg09.met.vgwort.de\/na\/56e1ea5b19254e1289566f60b6e3b27d","contentUrl":"http:\/\/vg09.met.vgwort.de\/na\/56e1ea5b19254e1289566f60b6e3b27d"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Belegungsplan_mit_Kalender\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Belegungsplan mit Kalender"}]},{"@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\/55001102","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=55001102"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001102\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001102"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001102"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001102"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}