|
Die Verwaltung von wiederkehrenden Jahrestagen, wie etwa Geburtstagen, datumsgebundenen Feiertagen wie Weihnachten, Gedenktagen und dergleichen, wird ein wenig dadurch verkompliziert, dass die Jahreszahl eigentlich ohne Belang ist. Bei Datumsangaben von Geburtstagen, die beispielsweise zumeist als vollständiges Datum mit dem Geburtsjahr vorliegen, könnte daher die Jahresangabe abgeschnitten werden. Die Jahresangabe des Herkunftsjahres ist tatsächlich ohne Belang. Doch das Jahr, das verwaltet werden soll, hat jedoch zunächst schon eine Bedeutung - nämlich hinsichtlich der Existenz eines 29. Februars. Außerdem lässt es sich mit vollständigen Datumsangaben und den Visual Basic-Datums-Funktionen recht komfortabel operieren, wie Ihnen die im Folgenden beschriebene Klasse clsAnniversaries zeigen soll.
Das Grundkonzept beruht auf einem Array mit je einem Element für jeden Tag des zu verwaltenden Jahres. Dieses Element für jeden ist als Collection vorgesehen, die später gegebenenfalls für den entsprechenden Tag instanziert wird und beliebige Datenelemente (Strings, Objekte, was auch immer) für diesen aufnehmen kann.
Beim Instanzieren der Klasse wird zunächst angenommen, dass das aktuelle Jahr verwaltet werden soll.
Private mAnniversaries() As Collection
Private pYear As Integer
Private Sub Class_Initialize()
pYear = Year(Now)
zRedimAnniversaries
End Sub
Zunächst wird das Array für den Bereich von 1 bis zur Anzahl der Tage im aktuellen Jahr vordimensioniert. Die Zahl der Tage ermitteln wir über die DatePart-Funktion für den 31.12. eines Jahres.
Private Sub zRedimAnniversaries()
ReDim mAnniversaries(1 To _
DatePart("y", DateSerial(pYear, 12, 31)))
End Sub
Zur Verwaltung beliebiger anderer Jahre setzen Sie das gewünschte Jahr über die Eigenschaft Year. Nur wenn das Jahr tatsächlich geändert wird, wird das Array entsprechend neu dimensioniert.
Public Property Get Year() As Integer
Year = pYear
End Property
Public Property Let Year(New_Year As Integer)
Select Case New_Year
Case pYear
Case Else
pYear = New_Year
zRedimAnniversaries
End Select
End Property
Über die Add-Methode fügen Sie ein beliebiges Datenelement für einen bestimmten Tag des Jahres ein. Dabei können Sie im ersten Parameter einen Datumswert übergeben, zum dem dann zur Einsortierung die entsprechende Nummer des Tages im Jahr ermittelt wird. Sie können aber auch direkt die Tagesnummer angeben, oder zusammen mit dem optionalen Parameter Month eine Kombination aus Monat und Tag im Monat. Zusätzlich können Sie optional einen Schlüssel (Key) für das Einfügen in die Tages-Collection übergeben - für die Funktion der Klasse ist dieser Schlüssel ohne Bedeutung.
Public Sub Add(Item As Variant, ByVal Day As Variant, _
Optional ByVal Month As Integer, Optional Key As Variant)
Dim nDayOfYear As Integer
Dim nAnniversary As Collection
nDayOfYear = zGetDayOfYear(Day, Month)
Set nAnniversary = mAnniversaries(nDayOfYear)
If nAnniversary Is Nothing Then
Set nAnniversary = New Collection
Set mAnniversaries(nDayOfYear) = nAnniversary
End If
nAnniversary.Add Item, Key
End Sub
Die private Hilfsfunktion zGetDayOfYear liefert die benötigte Nummer des Tages im Jahr anhand der übergebenen Parameter.
Private Function zGetDayOfYear(ByVal Day As Variant, _
ByVal Month As Integer)
Select Case True
Case CBool(VarType(Day) = vbDate), _
CBool(VarType(CDate(Day)) = vbDate)
zGetDayOfYear = DatePart("y", CDate(Day))
Case CBool(Month)
zGetDayOfYear = DatePart("y", DateSerial(pYear, Month, Day))
Case Else
zGetDayOfYear = Day
End Select
End Function
Die für einen bestimmten Tag abgelegten Datenelemente erhalten Sie in einer Collection von der Funktion Anniversary geliefert. Die Angaben zu dem betreffenden Tag können Sie auf gleiche Weise wie beim Einfügen übergeben.
Public Function Anniversary(ByVal Day As Variant, _
Optional ByVal Month As Integer) As Collection
Set Anniversary = mAnniversaries(zGetDayOfYear(Day, Month))
End Function
Die wesentliche Funktionalität der Klasse steht damit bereits zur Verfügung. Die weitere Methode MonthAnniversaries liefert Ihnen praktischerweise ein Array mit den Collections für die Tage eines bestimmten Monats.
Public Function MonthAnniversaries(ByVal Month As Integer) _
As Variant
Dim i As Integer
Dim nFirstOfMonth As Date
Dim nAnniversary As Collection
Dim nFirst As Integer
Dim nLast As Integer
Dim nMonthAnniversaries() As Collection
Set MonthAnniversaries = New Collection
nFirstOfMonth = DateSerial(pYear, Month, 1)
nFirst = DatePart("y", nFirstOfMonth)
nLast = DatePart("y", DateAdd("m", 1, nFirstOfMonth) - 1)
ReDim nMonthAnniversaries(nFirst To nLast)
For i = nFirst To nLast
Set nAnniversary = mAnniversaries(i)
If Not (nAnniversary Is Nothing) Then
Set nMonthAnniversaries(i) = nAnniversary
End If
Next 'i
MonthAnniversaries = nMonthAnniversaries
End Function
Der Vollständigkeit halber gibt es schließlich noch die Methode YearAnniversaries, die Ihnen direkt das interne Array mit den Collections jedes Tages zur Verfügung stellt.
Public Function YearAnniversaries() As Variant
YearAnniversaries = mAnniversaries
End Function
|