Kalendertag oder Arbeitstag

15.12.2006 von Lorenz  Hölscher
Die Funktion DateDiff erlaubt es, von einem Anfangsdatum aus eine bestimmte Anzahl von Kalendertagen weiterzuzählen. Wenn Sie jedoch in einer Tabelle Anfangstermine speichern und zum Beispiel zehn Tage später einen Endetermin vorgeben wollen, sind oft Arbeitstage gemeint.

Um diese Aufgabenstellung umzusetzen, schreiben Sie in einem Standardmodul eine Funktion, welche nach Belieben nur Arbeitstage von Montag bis Freitag berücksichtigt. In Listing 1 sehen Sie die Funktion FindeEnde, welche ein Startdatum und eine Anzahl von Arbeitstagen als Argumente erhält.

Function FindeEnde(datStart As Variant, intDauer As Variant) As Variant
Dim intZaehler As Integer
Dim intAnzTage As Integer
If Not IsNull(datStart) And Not IsNull(intDauer) Then
intZaehler = 0
Do Until intZaehler >= intDauer
intAnzTage = intAnzTage + 1
Select Case Weekday(datStart + intAnzTage, vbMonday)
Case 6, 7
Case Else: intZaehler = intZaehler + 1
End Select
Loop
FindeEnde = datStart + intAnzTage
Else
FindeEnde = ""
End If
End Function

Der Rückgabewert der Funktion ist ebenso variant wie die Argumente, damit sie vor allem robust gegenüber Nullwerten sind.

Solange nicht beide Argumente Daten enthalten, wird ein Leerstring zurückgegeben. Dann ist eine Berechnung nicht möglich.

In Bild 1 wird diese Funktion für das berechnete Feld EndeDatum benutzt, indem dort als Steuerelementinhalt =FindeEnde([PStartDatum]; [PDauer]) eingetragen wurde. PStartDatum und PDauer sind Felder in der zugrundeliegenden Tabelle.

Bild 1: Berechnetes EndeDatum für Arbeitstage nach PStartDatum.

Wie bei Artikel schreiben in Bild 1 zu sehen ist, liegt genau fünf Arbeitstage nach Freitag, dem 9.6.2006 wieder ein Freitag.

Nicht immer zählen

Der eigentliche Trick der Funktion besteht in der Tatsache, dass die darin benutzte Weekday-Funk- tion zu jedem Werktag eine Zahl zurückgibt.

Der Prüfzähler intZaehler wird nur dann erhöht, wenn es sich um die Tageszahlen 1-5, also Montag bis Freitag handelt. Der Do-Loop-Zähler intAnzTage wird hingegen immer weiter um 1 erhöht, bis intZaehler die gewünschte intDauer erreicht hat. Die Variable intAnzTage wird also so lange hochgezählt, bis sich ausreichend Tage in intZaehler gesammelt haben.

Feiertage berücksichtigen

Da diese Technik sehr einfach ist und zeitlich unbegrenzt funktioniert, ließe sie sich auch noch verbessern.

Die Funktion lässt sich erweitern, indem man für das jeweilige Endedatum (aus datStart + intAnzTage) per DLookup prüft, ob es in einer Tabelle als Feiertag oder Urlaubstag hinterlegt wurde. Und wenn intZaehler dann nicht erhöht wird, berücksichtigt die Funktion sogar nur noch echte Arbeitstage.