Belegungsplan mit Kalender

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

Bei der Suche nach sinnvollen Anwendungszwecken für die Kalendersteuerelemente dieser Ausgabe fiel die Entscheidung für ein Beispiel schwer. Wir demonstrieren deren Einsatz nun an einem fingierten Belegungsplan für Ferienwohnungen, der zudem das übersichtskalenderelement noch um das eine oder andere Feature erweitert.

Wohnobjekte und Vermietungszeiträume

Buchen Sie im Web eine Ferienwohnung, so werden Sie häufig mit übersichtskalendern konfrontiert, die die noch freien Zeiträume eines Objekts abbilden. Das ist im Prinzip ein idealer Anwendungsfall fü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ösen gilt.

Die Buchung des Objekts ist das eine, die übersicht für den Vermieter das andere. Bild 1 zeigt zunächst die Version für den Vermieter. Seine Buchungsdatenbank enthält alle Daten zu seinen Objekten, den Kunden und den gebuchten Zeiträumen. Die bekommt er nun im Formular frmBelegung präsentiert.

Der Belegungsplan für Ferienwohnungen enthält das dreimonatige Kalendersteuerelement mit mehrfachen Bedingten Formatierungen zur Hervorhebung der Zeiträume

Bild 1: Der Belegungsplan für Ferienwohnungen enthält das dreimonatige Kalendersteuerelement mit mehrfachen Bedingten Formatierungen zur Hervorhebung der Zeiträume

Im Kombinationsfeld oben kann er ein Objekt auswählen, dessen Vermietungszeiträ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.

Grüne Felder bedeuten, dass diese Tage für das Objekt noch nicht belegt sind, rote, dass diese Tage vermietet sind. Möglicherweise würde das bereits ausreichen, doch es gibt auch noch anders geartete Termine. Zur Reinigung oder Wartung der Objekte etwa fallen unter Umständen zusätzliche Tage an. Eventuell nutzt der Vermieter das Objekt auch für den Eigenbedarf. Auch sonst kann das Objekt aus bestimmten Gründen für die Vermietung gesperrt sein. All diese Typen von Belegung sollen sich im Kalender durch eine entsprechende Farbgebung unterscheiden lassen.

Datenmodell

Im Prinzip gibt es drei Einheiten, die es zu verknüpfen gilt. Einmal sind da die Wohnungen, die mindestens durch Bezeichnungen und Adressen repräsentiert werden.

Zum anderen gibt es Kunden, die durch Namen und Adressdaten festgelegt sind. Beide kommen über die Belegungszeiträume zueinander. Eine Belegung benö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 tblKunden, tblWohnungen und tblBelegung nennen. Sie sind miteinander über indizierte Schlüsselfelder verknüpft, wie in Bild 2.

Das grundlegende Datenmodell der Beispieldatenbank zum Belegungsplan

Bild 2: Das grundlegende Datenmodell der Beispieldatenbank zum Belegungsplan

Diese drei Haupttabellen weisen zusätzlich je ein Feld Vermerk auf, in das optional zu jedem Datensatz eine beliebige Notiz oder Information eingetragen werden kann. Das Feld IDTypBeleg in tblBelegung verweist außerdem auf eine Nachschlagetabelle tblBelegungstyp, in der die Arten der Belegung festgehalten sind.

Beginnen wir mit der Tabelle für die Wohnungen (s. Bild 3). Außer der ID vom Long-Typ Autowert enthält sie nur die Bezeichnung des Objekts und die Adresse in Form eines Memo-Felds.

Die Tabelle tblWohnungen im Entwurf

Bild 3: Die Tabelle tblWohnungen im Entwurf

Normalerweise würde man die Adresse in mehrere Felder aufteilen, für unseren Zweck lassen wir es aber bei dieser einfachen Lösung. Die Kundentabelle (s. Bild 4) kennen Sie so oder ähnlich schon aus anderen Zusammenhängen. Sie weist hier keinerlei Besonderheiten auf.

Die Tabelle tblKunden in der Entwurfsansicht

Bild 4: Die Tabelle tblKunden in der Entwurfsansicht

In der Belegungstabelle (s. Bild 5) gibt es zunächst Start– und Enddatum eines Mietzeitraums. Dann verweist das Feld IDKunde auf die ID eines Kundendatensatzes. Genauso verweist wiederum IDWohnung auf die ID eines Wohnungsdatensatzes. Vervollständigt wird sie mit dem Feld IDTypBeleg, das eine Zahl zur Art der Belegung abspeichert, welche aus der Tabelle tblBelegungstyp stammt.

Tabelle tblBelegung im Entwurf

Bild 5: Tabelle tblBelegung im Entwurf

Alle Beziehungen sind mit Referenzieller Integrität ausgestattet, was bedeutet, dass die Tabelle tblBelegung keine Datensätze annimmt, bei denen die Verweis-IDs in den Fremdtabellen nicht existieren. Außerdem ist für die Beziehungen Aktualisierungs- und Löschweitergabe eingestellt.

Damit führt das Löschen eines Kunden oder einer Wohnung automatisch auch zum Löschen aller beteiligten Belegungen, die Verweise auf jene besitzen. Das macht übrigens erforderlich, dass die Felder IDKunde und IDWohnung indiziert sind und die ID-Felder der Haupttabellen jeweils den Primärschlüssel stellen.

Die möglichen Belegungsarten sind in der Tabelle tblBelegungstyp (s. Bild 6) untergebracht. Der Standard wäre der Datensatz mit dem ID-Wert 2, was Vermietet bedeutet. Vielleicht fallen Ihnen noch weitere Typen ein.

Die möglichen Belegungsarten der Tabelle tblBelegungstyp in der Datenblattansicht

Bild 6: Die möglichen Belegungsarten der Tabelle tblBelegungstyp in der Datenblattansicht

Wir sind auch keine Wohnungsmakler und wissen nicht, ob die Einträge Gesperrt oder Unbestimmt einen tieferen Sinn besitzen. Das Feld Farbe (Datentyp Text) nimmt weiter in hexadezimaler Form einen RGB-Farbwert an, der später für den Hintergrund der Kalenderzellen über Bedingte Formatierung herhalten soll. Das Feld findet nur interne Verwendung. Sein Inhalt kann von Ihnen nach Belieben geändert werden.

Sehen Sie sich einige Datensätze der Tabelle tblBelegung in Bild 7 an. Die Felder IDKunde, IDWohnung und IDTypBeleg enthalten eigentlich verweisende Long-Werte, die aber in der Datenblattansicht nicht erscheinen, weil diese Felder als Nachschlagefelder mit Kombinationsfeldern als Steuerelement ausgeführt sind.

Die Tabelle tblBelegung einhält die drei Spalten IDKunde, IDWohnung und IDTypBeleg als Nachschlagefelder

Bild 7: Die Tabelle tblBelegung einhält die drei Spalten IDKunde, IDWohnung und IDTypBeleg als Nachschlagefelder

Exemplarisch zeigt Bild 8 das für die Spalte IDKunde. Der Herkunftstyp ist hier auf Tabelle/Abfrage eingestellt und als Quelle dient die Tabelle tblKunden, aus der die erste Spalte (ID) angebunden werden soll. Anzeigen aber soll das Feld den Namen des Kunden, welcher sich im dritten Feld befindet. Darum ist Spaltenanzahl auch auf 3 gesetzt.

Das Feld IDKunde in tblBelegung ist ein Nachschlagefeldlegungstyp in der Datenblattansicht

Bild 8: Das Feld IDKunde in tblBelegung ist ein Nachschlagefeldlegungstyp in der Datenblattansicht

Da auch wirklich nur der Name auftauchen soll, müssen zusätzlich die ersten beiden Spaltenbreiten des Kombinationsfelds auf 0 cm eingestellt sein. Um möglichst viele Kunden bei der DropDown-Auswahl berücksichtigen zu können, steht die Zeilenanzahl, abweichend vom Access-Standard 16, auf 30.

Damit ist das eigentliche Datenmodell der Datenbank hinreichend erläutert. Für unseren speziellen Anwendungsfall ist nun aber noch die für das Kalendersteuerelement verantwortliche Tabelle tblCalendarMonths zu verändern. Zur Erinnerung: Die enthält 21 Felder vom Typ Zahl (Long), in denen Datumswerte abgespeichert werden.

Negative Werte bestimmten dabei jene Bereiche des Kalenders, die farblich hinterlegt werden sollen.

Nun haben wir es bei unserem Belegungsplan aber nicht nur mit einer möglichen Farbe zu tun, sondern, je nach Art der Belegung, mit mehreren.

Folglich muss ein Datenfeld dieser Tabelle mehr Informationen hergeben, als nur das Datum und ein Vorzeichen.

Deshalb änderten wir alle Felder auf den Typ Text. Der mögliche Inhalt der Felder geht aus der Datenblattansicht in Bild 9 hervor, nachdem sich die Tabelle über das Formular sfrmCalendarMonths füllte.

Die Tabelle tblCalendarMonths kombiniert in ihren Feldern das Datum und den Belegtyp eines Kalendereintrags in einer Textform

Bild 9: Die Tabelle tblCalendarMonths kombiniert in ihren Feldern das Datum und den Belegtyp eines Kalendereintrags in einer Textform

Das eigentliche Datum steht nun an vorderster Stelle und ist immer 5 Zeichen lang. Danach schließt sich als visueller Trenner ein Unterstrich an, auf den der Typ der Belegung als Ziffer folgt. Es ist logisch, dass diese änderung der Tabelle dann auch Modifikationen der beteiligten Routinen im Formular, wie der Prozedur FillCalendar, erfordert. Dazu später mehr.

Kunden und Wohnungsobjekte

Für die Kunden und Wohnungen der Datenbank gibt es keine Anzeige- oder Eingabeformulare, da wir uns komplett auf die Kalenderansichten konzentrieren. Diese müssten Sie gegebenenfalls selbst nachrüsten. Die Datensätze sind bei den Kunden aus den hinlänglich bekannten Demo-Adresstabellen von Access Basics importiert. Die Wohnobjekte sind natürlich fingiert. Bild 10 zeigt alle in die Beispieldatenbank eingebauten.

Die Tabelle tblWohnungen speichert alle vermiet- und belegbaren Objekte

Bild 10: Die Tabelle tblWohnungen speichert alle vermiet- und belegbaren Objekte

Neben verlockenden Ferienwohnungen erfanden wir noch Einzelzimmer und Pensionszimmer. Die Pension Zum Hirschen kann nur ein Zimmer anbieten.

Die Einträge in der Spalte Vermerk zeigen, wofür Sie intern für den Vermieter verwendet werden könnte. Wollten Sie die Sache professionell gestalten, so enthielte diese Tabelle noch weit mehr Felder. So etwa zu Ausstattungsmerkmalen oder in einem Anlagefeld Fotos des Interieurs.

änderungen am Kalendersteuerelement sfrmCalendarMonths

Nachdem die Tabelle tblCalendarMonths nun String-, statt Long-Werte erwartet, muss die Routine FillCalendar zum Füllen der Tabelle komplett überarbeitet werden. In Listing 1 ist nur jener Teil abgebildet, der sich gegenüber der Ursprungsprozedur verändert hat.

Private Sub FillCalendar()
     (...)
     Set rs = CurrentDb.OpenRecordset("tblCalendarMonths", dbOpenDynaset)
     For n = 0 To 4
         rs.AddNew
         For i = 1 To 3
             MaxDate = DateSerial(m_Year, m_Month + i - 1, 0)
             For j = 1 To 7
                 DTmp = DateAdd("m", i - 1, StartDate)
                 DTmp = DateAdd("d", n * 7 + j - 1, DTmp)
                 If DTmp > MaxDate Then Exit For
                 lType = IsInRanges(DTmp)
                 rs.Fields("D" & CStr(j) & CStr(i)).Value = CLng(DTmp) & "_" & CStr(lType)
             Next j
         Next i
         rs.Update
     Next n
     (...)
End Sub

Listing 1: Neues Befüllen der Tabelle tblCalendarMonths

Dabei ist der Grundaufbau mit den drei ineinander verschachtelten Schleifen gleich geblieben. Ebenso die Berechnung der Datumswerte in der Variablen DTmp und die Abbruchbedingung beim Vergleich mit MaxDate.

Neu hingegen ist die Speicherung des Belegungstyps in der Long-Variablen lType, der aus der ebenfalls modifizierten Routine IsInRanges (s. Listing 2) stammt. Diese gibt nun nicht mehr einfach True oder False zurück, sondern eine Zahl, die der ID in der Tabelle tblBelegungsarten entspricht. Einem Datenfeld von tblCalendarMonths wird schließlich der per CLng erhaltene Integer-Wert des Datums DTmp zugewiesen, gefolgt vom Unterstrich und dem Inhalt der soeben ermittelten Variablen lType.

Private Type TRange
     StartDate As Date
     EndDate As Date
     Type As Long
End Type 
Private Function IsInRanges(D As Date) As Long
     Dim i As Long, n As Long
     On Error Resume Next
     n = UBound(arrRanges)
     If Err.Number <> 0 Then
         On Error GoTo 0:  Exit Function
     End If
     On Error GoTo 0
     For i = 0 To n
         If (D >= arrRanges(i).StartDate) And (D <= arrRanges(i).EndDate) Then
                 IsInRanges = arrRanges(i).Type:  Exit For
         End If
     Next i
End Function

Listing 2: Auch die Hilfsfunktion IsInRanges ändert sich

Das Array arrRanges des Moduls, welches die Zeiträume aufnimmt, basiert nun auf dem erweiterten Typ TRange im Modulkopf. Neben StartDate und EndDate weist dieser Typ nun zusätzlich das Element Type aus. Beim Zuweisen eines Zeitraums über die Methode AddRange müssen Sie nun auch den Belegungstyp angeben (s. Listing 3).

Public Sub AddRange(StartDate As Date, EndDate As Date, Typ As Long)
     (...)
    ReDim Preserve arrRanges(n)
     arrRanges(n).StartDate = StartDate
     arrRanges(n).EndDate = EndDate
     arrRanges(n).Type = Typ
     (...)
End Sub

Listing 3: Prozedur zum Zuweisen eines Zeitraums

Ermittelt die Funktion IsInRanges, dass sich das übergebene Datum D innerhalb der abgespeicherten Zeiträume befindet, so gibt sie nun die Zahl aus arrRanges(i).Type zurück.

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

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar