VBA

Calcolo dei giorni lavorativi

by Andrea Spera

In Microsoft Access non esiste una funzione già pronta per calcolare i giorni lavorativi, escludendo fine settimana e festività. In questa pagina presentiamo un esempio completo di codice VBA che ti permette di effettuare questo calcolo. Il codice considera sia i fine settimana sia un elenco personalizzato di festività, fornendo un modo flessibile per determinare i giorni lavorativi tra due date.
Viene determinato anche il giorno di Pasquetta, particolarmente fastidioso dal punto di vista programmatico.
Codice
Public Function giorni_lavorativi(data_inizio As Variant, data_fine As Variant) As Integer
On Error GoTo Err
Dim gg_solari As Integer
Dim gg_weekend As Integer
Dim data_temp As Variant
gg_solari = DateDiff("d", data_inizio, data_fine)
gg_weekend = 0
If gg_solari < 0 Then
	MsgBox ("Date non sequenziali")
	Exit Function
End If
data_inizio = DateValue(data_inizio)
data_fine = DateValue(data_fine)
data_temp = data_inizio
Do While DateDiff ("d", data_temp, data_fine) >= 0
	If Format(data_temp, "w", 2) = 6 or Format(data_temp, "w", 2) = 7 then
		gg_weekend = gg_weekend + 1
	End If
	data_temp = DateAdd("d", 1, data_temp)
Loop
Dim gg_festivi As Integer
Dim elenco_gg_festivi As Variant
Dim indice As Integer
gg_festivi = 0
elenco_gg_festivi = Array( _
	DateValue("01/01/" & Year(data_fine)), _
	DateValue("06/01/" & Year(data_fine)), _
	DateValue("25/04/" & Year(data_fine)), _
	DateValue("01/05/" & Year(data_fine)), _
	DateAdd("d", 1, DateValue(EasterUSNO(Year(data_fine)))), _
	DateValue("02/06/" & Year(data_fine)), _
	DateValue("15/08/" & Year(data_fine)), _
	DateValue("01/11/" & Year(data_fine)), _
	DateValue("08/12/" & Year(data_fine)), _
	DateValue("25/12/" & Year(data_fine)), _
	DateValue("26/12/" & Year(data_fine)) _
	)
DimensioneArray = UBound(elenco_gg_festivi) - LBound(elenco_gg_festivi) + 1
indice = 0
While indice < DimensioneArray
	If Format(elenco_gg_festivi(indice), "w", 2) <> 6 And _
		Format(elenco_gg_festivi(indice), "w", 2) <> 7 And _
		DateDiff("d", data_inizio, elenco_gg_festivi(indice)) >= 0 And _
		DateDiff("d", elenco_gg_festivi(indice), data_fine) >= 0 Then
		gg_festivi = gg_festivi + 1
	End If
	indice = indice + 1
Wend
giorni_lavorativi = gg_solari - gg_weekend - gg_festivi + 1
Exit Function
Err:
MsgBox (Err.Description)
End Function
 
Public Function EasterUSNO(YYYY As Integer) As Date
'adapted, from: http://www.cpearson.com/excel/easter.aspx
Dim C As Long
Dim N As Long
Dim K As Long
Dim I As Long
Dim J As Long
Dim L As Long
Dim M As Long
Dim D As Long
C = YYYY \ 100
N = YYYY - 19 * (YYYY \ 19)
K = (C - 17) \ 25
I = C - C \ 4 - (C - K) \ 3 + 19 * N + 15
I = I - 30 * (I \ 30)
I = I - (I \ 28) * (1 - (I \ 28) * (29 \ (I + 1)) * ((21 - N) \ 11))
J = YYYY + YYYY \ 4 + I + 2 - C + C \ 4
J = J - 7 * (J \ 7)
L = I - J
M = 3 + (L + 40) \ 44
D = L + 28 - 31 * (M \ 4)
EasterUSNO = Format(DateSerial(YYYY, M, D), "mm/dd/yyyy")
End Function