Vedere ad esempio
viewtopic.php?f=26&t=66808
viewtopic.php?f=26&t=67341
Allo scopo ho creato la “funzione” XSTRA che calcola quanto richiesto, anche se in modo piu’ articolato.
Non conoscendo la normativa che c’ e’ dietro, e anche per dare una maggiore flessibilita’ al lavoro, il calcolo viene fatto secondo una definizione a matrice di tipo gg della settimana / fascia oraria, dove all’ intersezione tra questi 2 dati c’ e’ un codice numerico (arbitrario, compreso tra 1 e 16) attribuito a quello straordinario.
La tabella va creata dall’ utente, e ha questo aspetto:
- Codice: Seleziona tutto
DefOrari OrarioStd start1 start2 22:00 24:00 30:00 . . . (vuoto)
1 8:00 N2 N3 1 2 2 . . .
2 8:00 N.. N.. N.. N.. . . .
3 8:00 N.. N.. N.. N.. . . .
4
5
6 00:00 1 1 2 2 3
7 00:00 3 3 4 4 2 . . .
I numeri in verticale da 1 a 7 rappresentano dal Lunedi’ alla Domenica. La colonna “Orario Std” indica le ore “standard” per quel giorno (le ore aggiuntive sono straordinario); ho arbitrariamente scritto 8h dal Lu in poi e 0h per Sa e Dom, ma questi sono paramentri che potete mettere a piacere. Gli Nx o N.. sono numeri da 1 a 16 usati arbitrariamente dall’ utente per raggruppare stessi tipi di straordinario. Start1,2,3,.. sono limiti di orario, e si intende che “fino a quel limite la classe assegnata e’ quella sottostante”; nell’ esempio che ho fatto, lo straordinario tra start2 e le 22:00 e’ classificato di tipo 1 il lunedi’ ma di tipo 4 la domenica.
Si possono definire quante fasce orario si vuole, purche’ non ci siano piu’ di 16 tipi diversi (da 1 a 16); ma questo penso che sia un limite ben superiore al bisogno. Nell’ esempio ho inserito anche le ore 30:00; cosi’ indico in realta’ le ore 6:00 del giorno dopo, giacche’ un turno cominciato oggi puo’ benissimo concludersi domani.
Alla destra della tabella e’ necessario lasciare una colonna libera, che sara’ interpretata come fine della tabella. Come pure l’ angolo in alto a sx deve contenere la stringa DefOrari
La macro richiede 4 celle in orizzontale contigue con le timbrature E/U mattina, E/U pomeriggio; questi dati devono essere introdotti in formato “orario”; se l’ orario e’ continuato si possono solo compilare E/U mattina o E matt + U pom.
Anche il concetto di Matt e Pom e' “largo”, e si intende come “prima parte” e “seconda parte”; ad esempio la seguente sequenza di timbrature e’ gestita correttamente:
21:30 -> 00:30 ; 1:00 -> 4:00 (tot 6 ore).
Per compilare correttamente la tabella del tipo straordinari, si tenga presente che questa timbratura viene trasformata nella macro in questa sequenza:
21:30 24:30 25:00 28:00 (ovviamente 25:00 significa 1:00 del giorno dopo e 28:00=4:00)
Questo e' fatto sia per il calcolo corretto dei delta ore che per consentire di gestire il passaggio da un giorno a un altro; es. dal venerdi’ al Sabato o dal Sabato alla Domenica, come gia’ accennato parlando degli “orari limite” (l’ intestazione della tabella DefOrari.
Uso del codice:
Aprire il vba editor con Alt-F11; Menu /Inserisci /Modulo; copiare il codice e incollarlo nel frame di destra.
Il codice:
- Codice: Seleziona tutto
Function Xstra(Data, InOuTable, DefOrario, TipoXstra, Optional TotH) As Single
'Data=cella contenente la data; InOuTable=prima delle 4 timbrature (E-U, E-U)
'DefOrario=indirizzo tabella con la matrice gg/hh/tipo di straordinario
'TipoXstra= valore del "tipo" richiesto; oppure 0=Ore lavorate
'
Dim GSett As Integer
Dim In1 As Single: Dim In2 As Single: Dim CTy As Single
Dim Out1 As Single: Dim Out2 As Single
Dim WHours As Single
Dim DefCols As Integer: Dim I As Integer: Dim CT As Integer
Dim TabTy(16) As Single: Dim TabTy0 As Single: Dim TabTyOld As Single
If Tipoxsta > 16 Then Exit Function
If DefOrario <> "DefOrari" Then Exit Function
Application.Volatile
GSett = Weekday(Data, vbMonday)
In1 = InOuTable
Out1 = InOuTable.Offset(0, 1).Value + (InOuTable.Offset(0, 1) < In1) * -1
'In2 = InOuTable.Offset(0, 2).Value + (InOuTable.Offset(0, 2) < InOuTable.Offset(0, 1)) * -1
In2 = InOuTable.Offset(0, 2).Value + (InOuTable.Offset(0, 2) < Out1) * -1
Out2 = InOuTable.Offset(0, 3).Value + (InOuTable.Offset(0, 3).Value < In2) * -1
DefCols = DefOrario.End(xlToRight).Column - DefOrario.Column
WHours = Out2 - In2 + Out1 - In1
If TipoXstra = 0 Then
Xstra = WHours: Exit Function
End If
Xstra = WHours - DefOrario.Offset(GSett, 1)
If Xstra < 0 Then
Xstra = 0: Exit Function
End If
For I = DefCols To 2 Step -1
If Out2 > DefOrario.Offset(0, I) Then Exit For
Next I
CalcTy:
CT = DefOrario.Offset(GSett, I + 1)
TabTy0 = Out2 - DefOrario.Offset(0, I)
If In2 >= DefOrario.Offset(0, I) Then TabTy0 = TabTy0 + DefOrario.Offset(0, I) - In2
If Out1 >= DefOrario.Offset(0, I) Then TabTy0 = TabTy0 + Out1 - DefOrario.Offset(0, I)
If In1 >= DefOrario.Offset(0, I) Then TabTy0 = TabTy0 + DefOrario.Offset(0, I) - In1
TabTy0 = TabTy0 - TabTyOld
TabTy(CT) = TabTy0 + TabTy(CT)
TabTyOld = TabTyOld + TabTy0
Xstra = Xstra - TabTy0
If Xstra <= 0 Then
TabTy(CT) = TabTy(CT) + Xstra
Xstra = TabTy(TipoXstra)
Exit Function
End If
I = I - 1
If I > 1 Then GoTo CalcTy
Xstra = "XXX" 'Errore, I=<2 e non ancora completato il calcolo
End Function
Tornare sul foglio excel.
Uso della “funzione” Xstra:
usare Xsta in una formula del tipo
- Codice: Seleziona tutto
=XSTRA(data;timbrature;tabella;tipo)
dove
-Data e’ l’ indirizzo della cella che contiene la data di lavoro, da cui si desume il gg della settimana.
-Timbratura e l’ indirizzo della prima cella con le timbrature;
-Tabella e’ l’ indirizzo della cella con la scritta DefOrari e che punta alla tabella di definizione.
-Tipo e’ il tipo di straordinario che si vuole calcolare; probabilmente userete tante formule in tante colonne diverse quanti sono i “tipi” che avete definito.
Se come Tipo viene usato 0 la funzione restituisce le ore lavorate.
La funzione ovviamente puo’ essere combinata con altre funzioni per eseguire calcoli piu’ complessi, e i suoi parametri possono essere definiti in modo assoluto (globale, su riga, su colonna; tramite l' uso di $) che relativo.
Se la tabella di definizione la mettete su un altro foglio, suggerisco di assegnare un nome alla cella DefOrari e usare quel nome al posto dell’ indirizzo.
Ho fatto un debug decoroso, gli errori piu’ clamorosi penso di averli eliminati; sono rimasti solo i piu’ subdoli che lascio al vostro collaudo...
Se avete problemi con la funzione, per favore scrivete su questo topic.
Ciao.