Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender

Forumthread: Nettoarbeitstage in VBA

Nettoarbeitstage in VBA
24.11.2014 14:18:06
Werner
Hallo Excel-Freunde
ich habe schon seit langem folgenden Code (Quelle unbekannt)
der mir zwischen 2 Datumsangaben die Nettoarbeitstage berechnet.
Der funktioniert auch wunderbar - nur leider macht er einen kleinen Fehler
Ist das Start-Datum = End-Datum, berechnet er mir immer den Wert 0
(und nicht 1, wenn der Tag ein normaler Arbeitstag ist)
Wir nutzen diese Formeln, da unser Admin das entspr Analyse-AddIn gesperrt hat.
Hat jemand einen Tip, diesen "Mini-Fehler" zu korrigieren ?
Besten Gruss
Werner
hier der Code:
Option Explicit
Public Function ArbTag(Datum As Range, Optional ArbeitsTage As Range, Optional FreieTage As  _
Range)
'Auflistung Arbeitstage mit Berücksichtigung der Feiertage + optional zusätzliche ArbeitsTage
'und / oder zusätzliche freie Tage!
Dim i%
Application.Volatile
If IsDate(Datum) Then
If ArbeitsTage Is Nothing And FreieTage Is Nothing Then
For i = 1 To 5
If ATag(Datum + i) = 1 Then
Exit For
End If
Next
ElseIf ArbeitsTage Is Nothing Then
For i = 1 To 1000
If ATag(Datum + i) = 1 And Application.IsNumber(Application.Match(CLng(Datum + i),  _
FreieTage, 0)) = False Then
Exit For
End If
Next
ElseIf FreieTage Is Nothing Then
For i = 1 To 1000
If ATag(Datum + i) Or Application.IsNumber(Application.Match(CLng(Datum + i), ArbeitsTage, _
0)) Then
Exit For
End If
Next
Else
For i = 1 To 1000
If ATag(Datum + i) And Application.IsNumber(Application.Match(CLng(Datum + i), FreieTage,  _
0)) = False _
Or Application.IsNumber(Application.Match(CLng(Datum + i), ArbeitsTage, 0)) Then
Exit For
End If
Next
End If
End If
ArbTag = Datum + i
End Function

Public Function NettoArbTage(Beginn As Date, Ende As Date, Optional ArbeitsTage As Range,  _
Optional FreieTage As Range)
'Berechnung NettoArbeitstage mit Berücksichtigung der Feiertage + optional zusätzliche  _
ArbeitsTage
'und / oder zusätzliche freie Tage!
Application.Volatile
If IsDate(Beginn) And IsDate(Ende) And Beginn 

Public Function ATag(Datum As Date) As Integer
'!!! Achtung :   Feiertage, bitte anpassen !!!
Dim Feiertage(13) As Date
Dim Jahr%, WTag%, i&
Jahr = CInt(Format(Datum, "yyyy"))
WTag = CInt(Weekday(Datum, 2))
ATag = 1
If WTag > 5 Then
ATag = 0
Else
' Feiertage
' Karfreitag
Feiertage(0) = (Ostersonntag(Jahr)) - 2
' Ostermontag
Feiertage(1) = (Ostersonntag(Jahr)) + 1
' Christi Himmelfahrt
Feiertage(2) = (Ostersonntag(Jahr)) + 39
' Pfingstmontag
Feiertage(3) = (Ostersonntag(Jahr)) + 50
' Fronleichnam
Feiertage(4) = (Ostersonntag(Jahr)) + 60
' Neujahr
Feiertage(5) = CDate("01.01." & Jahr)
' 1.Mai
Feiertage(6) = CDate("01.05." & Jahr)
' Maria Himmelfahrt > kein Feiertag
'Feiertage(7) = CDate("15.08." & Jahr)
' Tag der deutschen Einheit
If Jahr  kein Feiertag
'Feiertage(9) = CDate("01.11." & Jahr)
' Weihnachtstag
Feiertage(10) = CDate("24.12." & Jahr)
' 1. Weihnachtstag
Feiertage(11) = CDate("25.12." & Jahr)
' 2.Weihnachtstag
Feiertage(12) = CDate("26.12." & Jahr)
' Sylvester
Feiertage(13) = CDate("31.12." & Jahr)
' Ist das Datum ein Feiertag?
For i = 0 To 13
If Datum = Feiertage(i) Then
ATag = 0
Exit For
End If
Next i
End If
End Function
Function Ostersonntag(Jahr As Integer) As Date
Dim intA As Integer, intB As Integer, intC As Integer, intD As Integer
Dim intE As Integer, intF As Integer, intG As Integer, intH As Integer
Dim intI As Integer, intK As Integer, intL As Integer, intM As Integer
Dim intN As Integer, intP As Integer
Application.Volatile
Select Case Jahr
Case Is >= 1900
intA = Jahr Mod 19
intB = Int(Jahr / 100)
intC = Jahr Mod 100
intD = Int(intB / 4)
intE = intB Mod 4
intF = Int((intB + 8) / 25)
intG = Int((intB - intF + 1) / 3)
intH = (19 * intA + intB - intD - intG + 15) Mod 30
intI = Int(intC / 4)
intK = intC Mod 4
intL = (32 + 2 * intE + 2 * intI - intH - intK) Mod 7
intM = Int((intA + 11 * intH + 22 * intL) / 451)
intN = Int((intH + intL - 7 * intM + 114) / 31)
intP = (intH + intL - 7 * intM + 114) Mod 31
Ostersonntag = DateSerial(Jahr, intN, intP + 1)
End Select
End Function

Anzeige

8
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Nettoarbeitstage in VBA
24.11.2014 14:22:58
Hajo_Zi
mal auf den Betreff geantwortet.
WorksheetFunction.NetworkDays

und wieder mal ....
24.11.2014 14:31:15
Rudi
... den Beitrag nicht gelesen.
Wir nutzen diese Formeln, da unser Admin das entspr Analyse-AddIn gesperrt hat.

...und die XlVersion! Gruß owT
24.11.2014 15:08:52
Luc:-?
:-?

Anzeige
AW: Nettoarbeitstage in VBA > ohne AddInnAktiv
25.11.2014 05:25:16
Werner
Hallo
wie von Rudi und Luc:-? geschrieben
Das Analyse-AddInn kann nicht aktiviert werden
und wir verwenden (leider) noch XL2003
Deshalb: Thread noch offen
Freu mich, wenn jemand den VBA-Code checken / anpassen kann.
Besten Gruss
Werner

AW: Nettoarbeitstage in VBA > ohne AddInnAktiv
25.11.2014 10:17:38
Rudi
Hallo,
rein für Nettoarbeitstage habe ich was kürzeres.
Zusätzliche AT haben Vorrang vor Feiertagen und Wochenenden.
Function NettoArbTage(dteStart As Date, _
dteEnde As Date, _
Optional rngZusatz As Range, _
Optional rngFrei As Range)
Dim xDatum As Date, bolFrei As Boolean, bolZusatz As Boolean
For xDatum = dteStart To dteEnde
If Not rngFrei Is Nothing Then
bolFrei = WorksheetFunction.CountIf(rngFrei, xDatum) > 0
bolFrei = bolFrei Or istFeiertag(xDatum)
Else
bolFrei = istFeiertag(xDatum)
End If
If Not rngZusatz Is Nothing Then
bolZusatz = WorksheetFunction.CountIf(rngZusatz, xDatum)  0
Else
bolZusatz = False
End If
If bolZusatz Then
NettoArbTage = NettoArbTage + 1
Else
If Not bolFrei Then
If xDatum Mod 7 > 1 Then
NettoArbTage = NettoArbTage + 1
End If
End If
End If
Next
End Function
Function istFeiertag(datum) As Boolean
Dim d As Integer, iJahr As Integer, OSo As Date
iJahr = Year(datum)
d = (((255 - 11 * (iJahr Mod 19)) - 21) Mod 30) + 21
OSo = DateSerial(iJahr, 3, 1) + d + (d > 48) + 6 _
- ((iJahr + iJahr \ 4 + d + (d > 48) + 1) Mod 7)
Select Case datum
Case OSo - 2, _
OSo + 1, _
OSo + 39, _
OSo + 50, _
OSo + 60, _
DateSerial(iJahr, 1, 1), _
DateSerial(iJahr, 5, 1), _
DateSerial(iJahr, 10, 3), _
DateSerial(iJahr, 11, 1), _
DateSerial(iJahr, 12, 25), _
DateSerial(iJahr, 12, 26)
istFeiertag = True
End Select
'Karfreitag=Ostersonntag-2
'Ostermontag=Ostersonntag+1
'Chr.Himmelfahrt=Ostersonntag+39
'Pfingstmontag=Ostersonntag+50
'Fronleichnam=Ostersonntag+60
End Function

Gruß
Rudi

Anzeige
THX ! Zusätzliche AT haben Vorrang ?
25.11.2014 10:34:49
Werner
Hi Rudi
many Thx - funktioniert perfekt !
... musste nur noch den 24.12 als Feiertag definieren *g*
Wie verstehe Deinen Satz
"Zusätzliche AT haben Vorrang vor Feiertagen und Wochenenden" ?
Gruss
Werner

AW: THX ! Zusätzliche AT haben Vorrang ?
25.11.2014 12:41:06
Rudi
Hallo,
ganz einfach: Wenn du einen Tag als Feiertag und als zusätzlichen AT definierst, ist das ein Arbeitstag und kein Feiertag. Dito bei den autom. FT.
Gruß
Rudi

Anzeige
AW: THX ! Zusätzliche AT haben Vorrang ?
25.11.2014 20:18:25
Werner
Hi Rudi,
erst einmal THX für deine Antwort :) .. und
sorry, dass ich nochmal nachfrag:
WO definiere ich denn einen zusätzlichen AT ?
... als Feiertag im Code - soweit OK .. nur zusätzlichen AT ?
Steh ich gerad mächtig auf dem Schlauch ?
... hat das kalte Wetter mir den Kopf zu sehr gekühlt, dass ich die Antw net versteh ?
ebenso der Hinweis auf "Dito bei den autom. FT"
Besten AbendGruss
Werner
Besten Gruss
Werner
Anzeige
;
Anzeige

Infobox / Tutorial

Nettoarbeitstage in VBA berechnen


Schritt-für-Schritt-Anleitung

Um die Nettoarbeitstage zwischen zwei Datumsangaben in Excel mit VBA zu berechnen, kannst du den folgenden Code verwenden. Dieser Code berücksichtigt Feiertage und zusätzliche Arbeitstage:

  1. Öffne Excel und drücke ALT + F11, um den VBA-Editor zu öffnen.
  2. Klicke auf Einfügen > Modul, um ein neues Modul zu erstellen.
  3. Füge den folgenden Code in das Modul ein:
Public Function NettoArbTage(Beginn As Date, Ende As Date, Optional ArbeitsTage As Range, Optional FreieTage As Range) As Long
    Dim xDatum As Date
    Dim ArbeitsTageCount As Long
    For xDatum = Beginn To Ende
        If Not IsDate(xDatum) Then Continue For
        If Not FreieTage Is Nothing Then
            If WorksheetFunction.CountIf(FreieTage, xDatum) = 0 And Not istFeiertag(xDatum) Then
                ArbeitsTageCount = ArbeitsTageCount + 1
            End If
        Else
            If Not istFeiertag(xDatum) Then
                ArbeitsTageCount = ArbeitsTageCount + 1
            End If
        End If
    Next xDatum
    NettoArbTage = ArbeitsTageCount
End Function

Function istFeiertag(datum As Date) As Boolean
    ' Hier kannst du Feiertage definieren
    ' Beispiel: Neujahr
    If datum = DateSerial(Year(datum), 1, 1) Then
        istFeiertag = True
    Else
        istFeiertag = False
    End If
End Function
  1. Schließe den VBA-Editor und gehe zurück zu deinem Excel-Dokument.
  2. Verwende die Funktion in einer Zelle, z.B. =NettoArbTage(A1, B1, D1:D10), wobei A1 das Startdatum, B1 das Enddatum und D1:D10 die Liste zusätzlicher Arbeitstage ist.

Häufige Fehler und Lösungen

  • Fehler: 0 Nettoarbeitstage bei gleichen Datumsangaben

    • Lösung: Stelle sicher, dass das Datum ein Arbeitstag ist. Ändere den Code, um das Datum zu zählen, wenn es mit einem Arbeitstag übereinstimmt.
    If Beginn = Ende And Not istFeiertag(Beginn) Then
      NettoArbTage = 1
      Exit Function
    End If
  • Fehler: Feiertage werden nicht erkannt

    • Lösung: Achte darauf, dass die Feiertage im istFeiertag-Code korrekt definiert sind.

Alternative Methoden

Falls du keine VBA-Lösungen verwenden möchtest, kannst du auch die integrierte Funktion NETWORKDAYS in Excel verwenden. Diese Funktion berechnet die Anzahl der Arbeitstage zwischen zwei Daten, unter Berücksichtigung von Feiertagen:

=NETWORKDAYS(A1, B1, D1:D10)

Dabei ist A1 das Startdatum, B1 das Enddatum und D1:D10 die Liste der Feiertage.


Praktische Beispiele

Hier sind einige Beispiele, wie du die Funktionen in deinem Excel-Dokument verwenden kannst:

  • Beispiel 1: Berechnung der Nettoarbeitstage ohne zusätzliche Feiertage:
=NettoArbTage("01.01.2023", "31.01.2023")
  • Beispiel 2: Berechnung der Nettoarbeitstage mit einer Liste von Feiertagen:
=NettoArbTage("01.01.2023", "31.01.2023", E1:E5)

Tipps für Profis

  • Verwende Application.Volatile in deinen Funktionen, um sicherzustellen, dass sie bei jeder Änderung in der Arbeitsmappe neu berechnet werden.
  • Du kannst die Feiertagsberechnung dynamisch gestalten, indem du sie in eine separate Tabelle auslagerst, um die Wartung zu erleichtern.
  • Teste deine Funktionen mit verschiedenen Datumsformaten, um sicherzustellen, dass sie robust sind.

FAQ: Häufige Fragen

1. Wie kann ich zusätzliche Arbeitstage definieren?
Du kannst zusätzliche Arbeitstage über den optionalen Parameter ArbeitsTage in der Funktion NettoArbTage übergeben.

2. Funktioniert der Code in älteren Excel-Versionen wie 2003?
Ja, dieser VBA-Code sollte auch in Excel 2003 funktionieren, da er keine spezifischen Funktionen verwendet, die in neueren Versionen eingeführt wurden.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Entdecke mehr
Finde genau, was du suchst

Die erweiterte Suchfunktion hilft dir, gezielt die besten Antworten zu finden

Suche nach den besten Antworten
Unsere beliebtesten Threads

Entdecke unsere meistgeklickten Beiträge in der Google Suche

Top 100 Threads jetzt ansehen
Anzeige