Zum Inhalt dieser Seite

Access - 'Feiertage'

Weiter unten kommen die Anweisungen für das Datumsfeld im Formular, ein Download einer Demo-Datenbank ist durch Klick auf den folgenden Link möglich: (55 kByte) . Falls noch mehr Feiertage kontrolliert werden sollen, so muss das globale Array 'FeierArray' größer dimensioniert werden. Im Augenblick können maximal 16 Feiertage (Index 0 bis 15) eingetragen werden. Außerdem müssen alle Anweisungen, in denen das Array durchlaufen wird (im Augenblick von 0 bis 15), angepasst werden.

Mit folgendem Code (in ein Modul kopieren) kann überprüft werden, ob es sich bei einem Eingabewert in einem Formular um einen Arbeitstag handelt):

Option Compare Database
Option Explicit
'Public Const Arbeitstage = 0 'Feiertage etc. nicht beachten
'Public Const Arbeitstage = 1 'nur Samstag und Sonntag
'Public Const Arbeitstage = 2 'Samstag, Sonntag und
                              'bundesweite Feiertage (ohne regionale)
Public Arbeitstage As Integer
Public FeierArray(15, 2) As Variant
 
 
 
Public Function Feiertage(Optional xJahr As Long)
 
On Error GoTo FeierTage_Err:
 
Dim m As Integer
Dim n As Integer
Dim a As Integer
Dim B As Integer
Dim c As Integer
Dim d As Integer
Dim e As Integer
Dim Tag As Integer
Dim Mon As Integer
Dim TagDerWoche As Integer 'xter Tag der Woche
                           '(Montag = 1, Dienstag = 2 usw.)
Dim FTagName As String
Dim strJahr As String
Dim Datum As Date
Dim ArrayEint As Byte
Dim Fehlermeldung As Integer
Dim datOsterSonntag As Date
 
If IsMissing(xJahr) Then
  strJahr = Format$(Year(Date))
 Else
  strJahr = Format$(xJahr)
End If
 
'bewegliche Feiertage
'Ostersonntag
m = 23
n = 3
 
If xJahr > 1799 Then
  n = 4
End If
 
If xJahr > 1899 Then
  n = n + 1
  m = 24
End If
 
If xJahr > 2099 Then
  n = n + 1
End If
 
a = xJahr Mod 19
B = xJahr Mod 4
c = xJahr Mod 7
d = ((a * 19) + m) Mod 30
e = ((B * 2) + (c * 4) + (d * 6) + n) Mod 7
Tag = d + e + 22
 
If Tag > 31 Then
  Tag = Tag - 31
  If (Tag = 26) Or ((Tag = 25) And (d = 28) And (a > 10)) Then
    Tag = Tag - 7
  End If
  Mon = 4
 Else
  Mon = 3
End If
 
Datum = CDate(Format$(Tag) & "." & Format$(Mon) & ". " & strJahr)
datOsterSonntag = Datum
FTagName = "Ostersonntag"
ArrayEint = EintragFeiertag(3, Datum, FTagName, True)
 
'Karfreitag
Datum = datOsterSonntag - 2
FTagName = "Karfreitag"
ArrayEint = EintragFeiertag(2, Datum, FTagName, True)
 
'Ostermontag
Datum = datOsterSonntag + 1
FTagName = "Ostermontag"
ArrayEint = EintragFeiertag(4, Datum, FTagName, True)
 
'Pfingstsonntag
Datum = datOsterSonntag + 49
FTagName = "Pfingstsonntag"
ArrayEint = EintragFeiertag(7, Datum, FTagName, True)
 
'Pfingstmontag
Datum = datOsterSonntag + 50
FTagName = "Pfingstmontag"
ArrayEint = EintragFeiertag(8, Datum, FTagName, True)
 
'Chr.Himmelfahrt
Datum = datOsterSonntag + 39
FTagName = "Christi Himmelfahrt"
ArrayEint = EintragFeiertag(6, Datum, FTagName, True)
 
'Frohnleichnam
Datum = datOsterSonntag + 60
FTagName = "Frohnleichnam"
ArrayEint = EintragFeiertag(9, Datum, FTagName, False)
 
'Buß+Bettag
Datum = CDate("1.11." & strJahr)
Do
  TagDerWoche = CInt(Format$(Datum, "w", vbMonday))
  Select Case TagDerWoche
   Case 3              'Mittwoch
    Datum = Datum + 14
   Case Else           'anderer Wochentag (nicht Mittwoch)
    Datum = Datum + 1
  End Select
Loop While TagDerWoche <> 3
If Day(Datum) < 16 Then
  Datum = Datum + 7
End If
FTagName = "Buß und Bettag"
ArrayEint = EintragFeiertag(13, Datum, FTagName, False)
 
'feste Feiertage
Datum = CDate("1.1." & strJahr)
FTagName = "Neujahr"
ArrayEint = EintragFeiertag(0, Datum, FTagName, True)
 
Datum = CDate("6.1." & strJahr)
FTagName = "Heilige drei Könige"
ArrayEint = EintragFeiertag(1, Datum, FTagName, False)
 
Datum = CDate("1.5." & strJahr)
FTagName = "Tag der Arbeit"
ArrayEint = EintragFeiertag(5, Datum, FTagName, True)
 
Datum = CDate("3.10." & strJahr)
FTagName = "Tag der deutschen Einheit"
ArrayEint = EintragFeiertag(11, Datum, FTagName, True)
 
Datum = CDate("15.8." & strJahr)
FTagName = "Mariä Himmelfahrt"
ArrayEint = EintragFeiertag(10, Datum, FTagName, False)
 
Datum = CDate("1.11." & strJahr)
FTagName = "Allerheiligen"
ArrayEint = EintragFeiertag(12, Datum, FTagName, False)
 
Datum = CDate("25.12." & strJahr)
FTagName = "1. Weihnachtstag"
ArrayEint = EintragFeiertag(14, Datum, FTagName, True)
 
Datum = CDate("26.12." & strJahr)
FTagName = "2. Weihnachtstag"
ArrayEint = EintragFeiertag(15, Datum, FTagName, True)
 
'nur für Debug-Zwecke
'zeige = ZTage()
 
Feiertage_Exit:
  Exit Function
 
FeierTage_Err:
  If Err.Number = 13 Then
    Fehlermeldung = MsgBox("Die eingegebene Jahreszahl '" & CStr(xJahr) _
                    & "' ist zu gross. Gültige Jahreswerte " _
                    & "bewegen sich zwischen '0' und '9999'", _
                    vbExclamation, "Fehler in der Funktion 'Feiertage'")
   Else
    MsgBox Err.Description
  End If
  Resume Feiertage_Exit:
 
End Function
 
 
 
Public Function EintragFeiertag(iArray, WDatum, TName, Bundesweit) As Byte
 
FeierArray(iArray, 0) = WDatum
FeierArray(iArray, 1) = TName
FeierArray(iArray, 2) = Bundesweit
 
End Function
 
 
 
Public Function ZTage()
 
'nur für Debug-Zwecke
'kann im Direktfenster mit ?ZTage() aufgerufen werden,
'nachdem Feiertage mit ?Feiertage() eingelesen wurden.
 
Dim i As Byte
Dim LEintrag As Integer
 
For i = 0 To 15
  LEintrag = Len(FeierArray(i, 1))
  'Debug.Print FeierArray(i, 0) & "  " & FeierArray(i, 1) _
               & Space(27 - LEintrag) & FeierArray(i, 2)
  ZTage = ZTage & FeierArray(i, 0) & "  " & FeierArray(i, 1) _
          & Space(27 - LEintrag) & FeierArray(i, 2) & Chr(13) & Chr(10)
Next i
 
End Function
 
 
 
Public Function IstArbeitstag(WDatum As Date)
 
Dim Meldetext1 As String, Meldetext2 As String
Dim Welchertag As String, Trenner As String
Dim RGabe As String, Zusatz As String
Dim ITemp As Boolean
Dim DJahr As Long, AJahr As Long
Dim i As Byte
Dim ArrayNeu, ArrayDatum, ArrayBeschr, ArrayBWeit
 
Welchertag = GibWotag(WDatum)
Meldetext1 = "Bei dem eingegebenen Datum '"
Meldetext2 = "' handelt es sich um einen"
Trenner = Chr(13) & Chr(10)
ITemp = True
 
Select Case Arbeitstage
 
 Case Is = 0         'Feiertage etc. nicht beachten
  RGabe = ITemp
 
 Case Is = 1         'nur Samstag und Sonntag
  If Welchertag = "Samstag" Or Welchertag = "Sonntag" Then
    ITemp = False
    RGabe = Meldetext1 & WDatum & Meldetext2 & Trenner & Welchertag & "."
   Else
    RGabe = ITemp
  End If
 
 Case Is = 2         'Samstag,Sonntag und nur bundesweite Feiertage
  RGabe = ITemp
  DJahr = CLng(Year(WDatum))
  If Not IsNull(FeierArray(0, 0)) Then
    AJahr = Year(CVDate(FeierArray(0, 0)))
   Else
    AJahr = Null
  End If
  If DJahr <> AJahr Then
    ArrayNeu = Feiertage(CLng(Year(WDatum)))
  End If
  For i = 0 To 15
    ArrayDatum = CVDate(FeierArray(i, 0))
    ArrayBeschr = FeierArray(i, 1)
    ArrayBWeit = FeierArray(i, 2)
    If ArrayDatum = WDatum And ArrayBWeit = True Then
      ITemp = False
      RGabe = Meldetext1 & CStr(WDatum) & Meldetext2 & Trenner _
              & "bundesweiten Feiertag (" & ArrayBeschr & ")."
      i = 15
    End If
  Next i
  If ITemp = True And (Welchertag = "Samstag" _
  Or Welchertag = "Sonntag") Then
    ITemp = False
    RGabe = Meldetext1 & CStr(WDatum) & Meldetext2 _
            & Trenner & Welchertag & "."
   Else
    RGabe = RGabe
  End If
 
 Case Is = 3         'Samstag,Sonntag und alle Feiertage
  RGabe = ITemp
  DJahr = CLng(Year(WDatum))
  If Not IsNull(FeierArray(0, 0)) Then
    AJahr = Year(CVDate(FeierArray(0, 0)))
   Else
    AJahr = Null
  End If
  If DJahr <> AJahr Then
    ArrayNeu = Feiertage(CLng(Year(WDatum)))
  End If
  For i = 0 To 15
    ArrayDatum = CVDate(FeierArray(i, 0))
    ArrayBeschr = FeierArray(i, 1)
    ArrayBWeit = FeierArray(i, 2)
    If ArrayDatum = WDatum Then
      ITemp = False
      If ArrayBWeit = True Then
        Zusatz = "bundesweiten"
       Else
        Zusatz = "regionalen"
      End If
      RGabe = Meldetext1 & CStr(WDatum) & Meldetext2 & Trenner _
              & Zusatz & " Feiertag (" & ArrayBeschr & ")."
      i = 15
    End If
  Next i
  If ITemp = True And (Welchertag = "Samstag" Or Welchertag = "Sonntag") Then
    ITemp = False
    RGabe = Meldetext1 & CStr(WDatum) & Meldetext2 _
            & Trenner & Welchertag & "."
   Else
    RGabe = RGabe
  End If
 
End Select
 
IstArbeitstag = RGabe
 
End Function
 
 
 
Public Function GibWotag(WDatum As Date)
 
Dim DayofWeek As Byte
Dim GTemp As String
 
DayofWeek = Weekday(WDatum)
 
Select Case DayofWeek
 Case 1
  GTemp = "Sonntag"
 Case 2
  GTemp = "Montag"
 Case 3
  GTemp = "Dienstag"
 Case 4
  GTemp = "Mittwoch"
 Case 5
  GTemp = "Donnerstag"
 Case 6
  GTemp = "Freitag"
 Case 7
  GTemp = "Samstag"
End Select
 
GibWotag = GTemp
 
End Function
 
 
 
Public Function Kontrolle(KDAtum As Date, _
                          QuietMode As Boolean, Richtung As Integer)
 
Dim LDat As Date
Dim Neudat As Date
Dim ZWert As Date
Dim MeldeDat As String, tDat As String, Zusatz As String
Dim Antwort As Integer
Dim i As Byte
 
LDat = KDAtum
 
MeldeDat = IstArbeitstag(LDat)
 
If Left(MeldeDat, 3) = "Bei" Then
  For i = 0 To 7
    tDat = IstArbeitstag(LDat)
    If Left(tDat, 3) <> "Bei" Then
      Neudat = LDat
      If Richtung = 1 Then
        i = 7
       Else
        If LDat < KDAtum Then
         Neudat = LDat
         i = 7
        End If
      End If
    End If
    LDat = LDat + 1 * Richtung
  Next i
  If Richtung = 1 Then
    Zusatz = "nächsten"
   Else
    Zusatz = "vorigen"
  End If
  If QuietMode = True Then
    Antwort = vbYes
   Else
    Antwort = MsgBox(MeldeDat & Chr(13) & Chr(10) _
              & "Soll das Datum auf den " & Zusatz & " Arbeitstag (" _
              & Neudat & ") gestellt werden ?", vbYesNo + vbInformation, _
              "Datumskontrolle (handelt es sich um einen Werktag ?)")
  End If
  If Antwort = vbYes Then
    ZWert = Neudat
   Else
    ZWert = KDAtum
  End If
End If
 
If Left(CStr(ZWert), 2) = "00" Then
  ZWert = KDAtum
End If
 
Kontrolle = ZWert
 
End Function

Anweisungen für das Formular (in das Modul des Formulars kopieren) :
(zu kontrollierendes Feld heisst im Formular 'Datumsfeld')

Option Compare Database
Option Explicit
Dim k As Date
 
 
 
Private Sub Datumsfeld_AfterUpdate()
 
'für -Datumsfeld- muss der tatsächliche Name des Feldes im
'Formular eingesetzt werden.
'die untenstehende Anweisung kontrolliert, ob es sich bei dem
'eingegebenen Datum (Parameter 1) um einen Werktag handelt.
'Wenn nicht, wird nachgefragt (Parameter 2), ob der nächstfolgende
'Arbeitstag eingesetzt werden soll (Parameter 3).
 
k = Kontrolle(Me!Datumsfeld, False, 1)
'Ohne Nachfrage müsste das so aussehen:
'k = Kontrolle(Me!Datumsfeld, True, 1)
Me!Datumsfeld = k
 
End Sub