Una funzione che mostra come può essere fatto il calcolo delle ore di un cartellino in modo relativamente semplice e facilmente modificabile per adattarsi alle diverse regole dei contratti/aziende.
Uno degli aspetti positivi di una funzione scritta in VBA è che sono molto più visibili i calcoli e le condizioni utilizzate, cose che utilizzzando le formule sul foglio di calcolo sarebbero fatte aggiungento colonne e calcoli intermedi.
La tabella di partenza ha una struttura come quella qui a lato: due entrate e uscite e un eventuale giustificativo, nel caso di turno notturno l'uscita viene registrata nel giorno successivo. |
Il codice della funzione è seprato in 2 parti:
- nella prima vengono effettuati le verifiche e controlli sui tipi di dato, eventuali assenze, risultati non corretti;
- nella seconda il calcolo vero e proprio con i suoi criteri.
Impostandola in questo modo risulta molto più semplice vedere dove e come modificare il tipo di calcolo nel caso di orario di tipo diverso, regole di tipo diverso o parametri modificati.
l'esempio completo é scaricabile da questo link:
Es397.xlsm (a questo link le info per
attivare le macro se risultano bloccate)
Il codice della funzione:
Function OreLavorateGiorno(
Entrata1,
Uscita1,
Entrata2,
Uscita2,
UscitaGgSeg,
Assenza)
As Variant
OreLavorateGiorno = 0
'verifica orari "vuoti"
If (IsEmpty(
Entrata1))
Then Entrata1 = 0
If (IsEmpty(
Uscita1))
Then Uscita1 = 0
If (IsEmpty(
Entrata2))
Then Entrata2 = 0
If (IsEmpty(
Uscita2))
Then Uscita2 = 0
If (IsEmpty(
UscitaGgSeg))
Then UscitaGgSeg = 0
' fine turno nel gg successivo
If (
Entrata1 <> 0 And
Uscita1 = 0 And
UscitaGgSeg <> 0 And
UscitaGgSeg <
Entrata1)
Then
Uscita1 =
UscitaGgSeg + 1
ElseIf (
Entrata2 <> 0 And
Uscita2 = 0 And
UscitaGgSeg <> 0 And
UscitaGgSeg <
Entrata2)
Then
Uscita2 =
UscitaGgSeg + 1
End If
If (
Entrata1 = 0 And
Uscita1 <> 0)
Then
Uscita1 = 0
End If
'verifica dati non numerici
If (
Not (IsNumeric(
Entrata1)) Or
Not (IsNumeric(
Uscita1)) Or
Not (IsNumeric(
Entrata2)) Or
Not (IsNumeric(
Uscita2)))
Then
OreLavorateGiorno = "Errore"
Exit Function
End If
'se c'è una pausa inferiore all'ora lo considera un turno unico
If (
Uscita1 <> 0 And
Entrata2 <> 0 And
Entrata2 -
Uscita1 < 1 / 24)
Then
Uscita1 =
Uscita2 -
Entrata1 +
Uscita1
Entrata2 = 0
Uscita2 = 0
End If
' in caso di assenza mette l'orario di un turno
If (
Assenza <> "")
Then
OreLavorateGiorno = 6 / 24
'in caso manchi un'entrata o un'uscita segnala errore
ElseIf ((
Entrata1 = 0 Xor
Uscita1 = 0) Or (
Entrata2 = 0 Xor
Uscita2 = 0))
Then
OreLavorateGiorno = "Errore"
Else
OreLavorateGiorno = OreLavorateEU(
Entrata1,
Uscita1) + OreLavorateEU(
Entrata2,
Uscita2)
' con dati inseriti in modo scorretto (anche se numerici) può dare risultati insensati
If (
OreLavorateGiorno < 0 Or _
OreLavorateGiorno > 24 / 24)
Then OreLavorateGiorno = "Errore"
End If
End Function
Il calcolo delle ore per singola entrata/uscita:
Function OreLavorateEU(
OraEntrata,
OraUscita)
As Double
Const MinutiAggMax = 15 / 60 / 24
Const Arrotondamento = 5 / 60 / 24
OreLavorateEU = 0
If (
OraEntrata <> 0 And
OraUscita <> 0)
Then
'calcolo orario e arrotondamento
OreLavorateEU =
OraUscita -
OraEntrata
OreLavorateEU =
Int(
OreLavorateEU / Arrotondamento) * Arrotondamento
' tipo di turno
If (7 / 24 <
OraEntrata And
OraEntrata < 9 / 24)
Then
TipoTurno = "M"
ElseIf (13 / 24 <
OraEntrata And
OraEntrata < 15 / 24)
Then
TipoTurno = "P"
ElseIf (19 / 24 <
OraEntrata And
OraEntrata < 21 / 24)
Then
TipoTurno = "N"
End If
'ora massime consentite per turno
Select Case TipoTurno
Case "M": OreMax = 6 / 24 + MinutiAggMax
Case "P": OreMax = 6 / 24 + MinutiAggMax
Case "N": OreMax = 12 / 24 + MinutiAggMax
Case Else: OreMax = 24 / 24
End Select
If (
OreLavorateEU > OreMax)
Then OreLavorateEU = OreMax
End If
End Function
Gli esempi contenuti nel sito sono per uso personale, non é consentito l'uso professionale, commerciale o la riproduzione senza autorizzazione.