Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Type Lavoratore
- nome As String
- DisponibileGiorni() As Boolean ' Array di 7 elementi (uno per ogni giorno della settimana)
- OrariDisponibili() As Integer ' Array di 10 elementi (uno per ogni fascia oraria)
- End Type
- Sub PianificaTurni()
- Dim lavoratori() As Lavoratore
- Dim numLavoratori As Integer
- Dim i As Integer
- Dim j As Integer
- Dim k As Integer
- Dim turnoSettimanale() As String
- Dim turnoGiornaliero() As String
- Dim oreDisponibili As Integer
- Dim personeDisponibili() As Lavoratore
- Dim numPersoneDisponibili As Integer
- Dim oreGiornaliere(1 To 5) As Integer
- Dim giorniLavorativi(1 To 7) As Boolean
- Dim oreMinime(1 To 5) As Integer
- Dim oreMassime(1 To 5) As Integer
- Dim turnoInserito As Boolean
- Dim nomeTurno As String
- ' Popola l'array di lavoratori
- Call PopolaLavoratori
- lavoratori = PopolaLavoratori
- ' Inizializza l'array di turni settimanali
- ReDim turnoSettimanale(1 To 5, 1 To 4)
- ' Inizializza l'array di turni giornalieri
- ReDim turnoGiornaliero(1 To 5, 1 To 4)
- ' Popola l'array di turni settimanali con i nomi dei giorni lavorativi
- turnoSettimanale(1, 1) = "Lunedi"
- turnoSettimanale(2, 1) = "Martedi"
- turnoSettimanale(3, 1) = "Mercoledi"
- turnoSettimanale(4, 1) = "Giovedi"
- turnoSettimanale(5, 1) = "Venerdi"
- ' Inizializza l'array di giorni lavorativi
- For i = 1 To 7
- giorniLavorativi(i) = False
- Next i
- ' Pianifica il turno del lunedi
- giorniLavorativi(2) = True
- giorniLavorativi(3) = True
- numPersoneDisponibili = 0
- oreDisponibili = 0
- For i = 1 To numLavoratori
- If lavoratori(i).DisponibileGiorni(2) And lavoratori(i).DisponibileGiorni(3) And lavoratori(i).OrariDisponibili(3) <= 3 And lavoratori(i).OrariDisponibili(4) >= 2 Then
- ReDim Preserve personeDisponibili(1 To numPersoneDisponibili + 1)
- personeDisponibili(numPersoneDisponibili + 1) = lavoratori(i)
- numPersoneDisponibili = numPersoneDisponibili + 1
- oreDisponibili = oreDisponibili + (lavoratori(i).OrariDisponibili(4) - lavoratori(i).OrariDisponibili(3) + 1)
- End If
- Next i
- If numPersoneDisponibili >= 5 Then
- ' Se ci sono abbastanza persone disponibili, assegna il turno
- For i = 1 To 5
- turnoGiornaliero(i, 1) = personeDisponibili(i).nome
- personeDisponibili(i).TurniSettimanali(1) = turnoGiornaliero(i, 1)
- personeDisponibili(i).OreLavorateGiornaliere(2) = personeDisponibili(i).OreLavorateGiornaliere(2) + (personeDisponibili(i).OrariDisponibili(4) - personeDisponibili(i).OrariDisponibili(3) + 1)
- giorniLavorativi(2) = True
- giorniLavorativi(3) = True
- Next i
- Else
- ' Altrimenti, scegli i lavoratori con il maggior numero di ore disponibili
- Do While numPersoneDisponibili < 5 And oreDisponibili > 0
- Dim maxOre As Integer
- maxOre = 0
- For i = 1 To numLavoratori
- If lavoratori(i).DisponibileGiorni(2) And lavoratori(i).DisponibileGiorni(3) And lavoratori(i).OrariDisponibili(3) <= 3 And lavoratori(i).OrariDisponibili(4) >= 2 And lavoratori(i).OreLavorateGiornaliere(2) < oreMassime(2) Then
- If lavoratori(i).OreLavorateGiornaliere(2) >= maxOre Then
- If lavoratori(i).OreLavorateGiornaliere(2) > maxOre Then
- numPersoneDisponibili = 0
- oreDisponibili = 0
- ReDim personeDisponibili(1 To 5)
- maxOre = lavoratori(i).OreLavorateGiornaliere(2)
- End If
- numPersoneDisponibili = numPersoneDisponibili + 1
- oreDisponibili = oreDisponibili + (lavoratori(i).OrariDisponibili(4) - lavoratori(i).OrariDisponibili(3) + 1)
- personeDisponibili(numPersoneDisponibili) = lavoratori(i)
- End If
- End If
- Next i
- Loop
- If numPersoneDisponibili >= 5 Then
- ' Se ci sono abbastanza persone disponibili, assegna il turno
- For i = 1 To 5
- turnoGiornaliero(i, 1) = personeDisponibili(i).nome
- personeDisponibili(i).TurniSettimanali(1) = turnoGiornaliero(i, 1)
- personeDisponibili(i).OreLavorateGiornaliere(2) = personeDisponibili(i).OreLavorateGiornaliere(2) + (personeDisponibili(i).OrariDisponibili(4) - personeDisponibili(i).OrariDisponibili(3) + 1)
- giorniLavorativi(2) = True
- giorniLavorativi(3) = True
- Next i
- Else
- ' Altrimenti, il turno viene saltato
- For i = 1 To numPersoneDisponibili
- personeDisponibili(i).OreLavorateGiornaliere(2) = personeDisponibili(i).OreLavorateGiornaliere(2) + (personeDisponibili(i).OrariDisponibili(4) - personeDisponibili(i).OrariDisponibili(3) + 1)
- Next i
- Else
- ' Altrimenti, il turno viene saltato
- For i = 1 To numPersoneDisponibili
- personeDisponibili(i).OreLavorateGiornaliere(2) = personeDisponibili(i).OreLavorateGiornaliere(2) + (personeDisponibili(i).OrariDisponibili(4) - personeDisponibili(i).OrariDisponibili(3) + 1)
- personeDisponibili(i).TurniSettimanali(1) = "Riposo"
- Next i
- End If
- ' Assegna il turno del pomeriggio
- numPersoneDisponibili = 0
- oreDisponibili = 0
- ReDim personeDisponibili(1 To 5)
- If numLavoratori >= 5 Then
- ' Se ci sono abbastanza lavoratori, scegli casualmente 5 persone
- Dim index As Integer
- Dim usedIndices As New Collection
- Do While numPersoneDisponibili < 5
- index = Int(Rnd() * numLavoratori) + 1
- If Not usedIndices.Contains(index) And lavoratori(index).DisponibileGiorni(2) And lavoratori(index).DisponibileGiorni(3) And lavoratori(index).OrariDisponibili(3) <= 3 And lavoratori(index).OrariDisponibili(4) >= 2 And lavoratori(index).OreLavorateGiornaliere(3) < oreMassime(3) Then
- numPersoneDisponibili = numPersoneDisponibili + 1
- oreDisponibili = oreDisponibili + (lavoratori(index).OrariDisponibili(6) - lavoratori(index).OrariDisponibili(5) + 1)
- personeDisponibili(numPersoneDisponibili) = lavoratori(index)
- usedIndices.Add (index)
- End If
- Loop
- ' Se ci sono abbastanza persone disponibili, assegna il turno
- For i = 1 To 5
- turnoGiornaliero(i, 2) = personeDisponibili(i).nome
- personeDisponibili(i).TurniSettimanali(2) = turnoGiornaliero(i, 2)
- personeDisponibili(i).OreLavorateGiornaliere(3) = personeDisponibili(i).OreLavorateGiornaliere(3) + (personeDisponibili(i).OrariDisponibili(6) - personeDisponibili(i).OrariDisponibili(5) + 1)
- giorniLavorativi(2) = True
- giorniLavorativi(3) = True
- Next i
- Else
- ' Altrimenti, scegli i lavoratori con il maggior numero di ore disponibili
- Do While numPersoneDisponibili < 5 And oreDisponibili > 0
- Dim maxOre As Integer
- maxOre = 0
- For i = 1 To numLavoratori
- If lavoratori(i).DisponibileGiorni(2) And lavoratori(i).DisponibileGiorni(3) And lavoratori(i).OrariDisponibili(3) <= 3 And lavoratori(i).OrariDisponibili(4) >= 2 Then
- Dim oreDisponibiliPersona As Integer
- oreDisponibiliPersona = (lavoratori(i).OrariDisponibili(6) - lavoratori(i).OrariDisponibili(5) + 1) - lavoratori(i).OreLavorateGiornaliere(3)
- If oreDisponibiliPersona > maxOre Then
- maxOre = oreDisponibiliPersona
- End If
- Next i
- If maxOre > 0 Then
- For i = 1 To numLavoratori
- If lavoratori(i).DisponibileGiorni(2) And lavoratori(i).DisponibileGiorni(3) And lavoratori(i).OrariDisponibili(3) <= 3 And lavoratori(i).OrariDisponibili(4) >= 2 And (lavoratori(i).OrariDisponibili(6) - lavoratori(i).OrariDisponibili(5) + 1) - lavoratori(i).OreLavorateGiornaliere(3) = maxOre And oreDisponibili > 0 Then
- numPersoneDisponibili = numPersoneDisponibili + 1
- oreDisponibili = oreDisponibili - maxOre
- personeDisponibili(numPersoneDisponibili) = lavoratori(i)
- End If
- Next i
- Else
- Exit Do
- End If
- Loop
- If numPersoneDisponibili = 5 Then
- ' Se ci sono abbastanza persone disponibili, assegna il turno
- For i = 1 To 5
- turnoGiornaliero(i, 2) = personeDisponibili(i).nome
- personeDisponibili(i).TurniSettimanali(2) = turnoGiornaliero(i, 2)
- personeDisponibili(i).OreLavorateGiornaliere(3) = personeDisponibili(i).OreLavorateGiornaliere(3) + maxOre
- giorniLavorativi(2) = True
- giorniLavorativi(3) = True
- Next i
- Else
- ' Altrimenti, il turno viene saltato
- For i = 1 To numPersoneDisponibili
- personeDisponibili(i).OreLavorateGiornaliere(3) = personeDisponibili(i).OreLavorateGiornaliere(3) + (personeDisponibili(i).OrariDisponibili(6) - personeDisponibili(i).OrariDisponibili(5) + 1)
- personeDisponibili(i).TurniSettimanali(2) = "Riposo"
- Next i
- End If
- End If
- ' Assegna il turno del venerdi sera
- numPersoneDisponibili = 0
- oreDisponibili = 0
- ReDim personeDisponibili(1 To 3)
- If numLavoratori >= 3 Then
- ' Se ci sono abbastanza lavoratori, scegli casualmente 3 persone
- Dim index As Integer
- Dim usedIndices As New Collection
- Do While numPersoneDisponibili < 3
- index = Int(Rnd() * numLavoratori) + 1
- If Not usedIndices.Contains(index) And lavoratori(index).DisponibileGiorni(5) And lavoratori(index).DisponibileGiorni(6) And lavoratori(index).OrariDisponibili(5) <= 5 And lavoratori(index).OrariDisponibili(6) >= 4 Then
- numPersoneDisponibili = numPersoneDisponibili + 1
- personeDisponibili(numPersoneDisponibili) = lavoratori(index)
- usedIndices.Add index
- End If
- Loop
- Else
- ' Altrimenti, cerca tra i lavoratori disponibili chi ha più ore a disposizione
- Dim maxOre As Integer
- maxOre = 0
- Do While oreDisponibili > 0
- maxOre = 0
- For i = 1 To numLavoratori
- Dim oreDisponibiliPersona As Integer
- oreDisponibiliPersona = (lavoratori(i).OrariDisponibili(6) - lavoratori(i).OrariDisponibili(5) + 1) - lavoratori(i).OreLavorateGiornaliere(4)
- If oreDisponibiliPersona > maxOre Then
- maxOre = oreDisponibiliPersona
- End If
- Next i
- If maxOre > 0 Then
- For i = 1 To numLavoratori
- If lavoratori(i).DisponibileGiorni(5) And lavoratori(i).DisponibileGiorni(6) And lavoratori(i).OrariDisponibili(5) <= 5 And lavoratori(i).OrariDisponibili(6) >= 4 And (lavoratori(i).OrariDisponibili(6) - lavoratori(i).OrariDisponibili(5) + 1) - lavoratori(i).OreLavorateGiornaliere(4) = maxOre And oreDisponibili > 0 Then
- numPersoneDisponibili = numPersoneDisponibili + 1
- oreDisponibili = oreDisponibili - maxOre
- personeDisponibili(numPersoneDisponibili) = lavoratori(i)
- End If
- Next i
- Else
- Exit Do
- End If
- Loop
- If numPersoneDisponibili = 3 Then
- ' Se ci sono abbastanza persone disponibili, assegna il turno
- For i = 1 To 3
- turnoGiornaliero(i + 4, 2) = personeDisponibili(i).nome
- personeDisponibili(i).TurniSettimanali(5) = turnoGiornaliero(i + 4, 2)
- personeDisponibili(i).OreLavorateGiornaliere(4) = personeDisponibili(i).OreLavorateGiornaliere(4) + maxOre
- giorniLavorativi(5) = True
- giorniLavorativi(6) = True
- Next i
- Else
- ' Altrimenti, il turno viene saltato
- For i = 1 To numPersoneDisponibili
- personeDisponibili(i).OreLavorateGiornaliere(4) = personeDisponibili(i).OreLavorateGiornaliere(4) + (personeDisponibili(i).OrariDisponibili(6) - personeDisponibili(i).OrariDisponibili(5) + 1)
- personeDisponibili(i).TurniSettimanali(5) = "Riposo"
- Next i
- End If
- ' Giovedì
- numPersoneDisponibili = 0
- ReDim personeDisponibili(numLavoratori)
- If giorniLavorativi(4) Then
- ' Se ci sono lavoratori disponibili il giovedì, cerca prima quelli che lavorano fino alle 18:00
- For index = 1 To numLavoratori
- If lavoratori(index).DisponibileGiorni(4) And lavoratori(index).OrariDisponibili(6) >= 5 And lavoratori(index).OreLavorateGiornaliere(5) < (lavoratori(index).OrariDisponibili(6) - lavoratori(index).OrariDisponibili(5) + 1) And Not usedIndices.Contains(index) And giorniLavorativi(4) Then
- numPersoneDisponibili = numPersoneDisponibili + 1
- personeDisponibili(numPersoneDisponibili) = lavoratori(index)
- usedIndices.Add index
- End If
- Next index
- ' Se non ci sono abbastanza lavoratori disponibili fino alle 18:00, cerca quelli che hanno almeno 4 ore libere
- Dim oreDisponibili As Integer
- oreDisponibili = 8
- For i = 1 To numLavoratori
- oreDisponibili = oreDisponibili - lavoratori(i).OreLavorateGiornaliere(5)
- Next i
- If oreDisponibili >= 4 Then
- For index = 1 To numLavoratori
- If lavoratori(index).DisponibileGiorni(4) And (lavoratori(index).OrariDisponibili(6) - lavoratori(index).OrariDisponibili(5) + 1) - lavoratori(index).OreLavorateGiornaliere(5) >= 4 And Not usedIndices.Contains(index) And giorniLavorativi(4) Then
- numPersoneDisponibili = numPersoneDisponibili + 1
- personeDisponibili(numPersoneDisponibili) = lavoratori(index)
- usedIndices.Add index
- End If
- Next index
- End If
- ' Se ancora non ci sono abbastanza lavoratori disponibili, cerca quelli che possono lavorare il giovedì
- Do While numPersoneDisponibili < 4 And oreDisponibili > 0
- For index = 1 To numLavoratori
- If lavoratori(index).DisponibileGiorni(4) And (lavoratori(index).OrariDisponibili(6) - lavoratori(index).OrariDisponibili(5) + 1) - lavoratori(index).OreLavorateGiornaliere(5) > 0 And Not usedIndices.Contains(index) And giorniLavorativi(4) Then
- numPersoneDisponibili = numPersoneDisponibili + 1
- oreDisponibili = oreDisponibili - 1
- personeDisponibili(numPersoneDisponibili) = lavoratori(index)
- lavoratori(index).OreLavorateGiornaliere(5) = lavoratori(index).OreLavorateGiornaliere(5) + 1
- usedIndices.Add index
- End If
- Next index
- Loop
- If numPersoneDisponibili = 4 Then
- ' Se ci sono abbastanza persone disponibili, assegna il turno
- For i = 1 To 5
- turniGiornalieri(4, 1) = personeDisponibili(1).nome
- turniGiornalieri(4, 2) = personeDisponibili(2).nome
- turniGiornalieri(4, 3) = personeDisponibili(3).nome
- turniGiornalieri(4, 4) = personeDisponibili(4).nome
- Else
- ' Se non ci sono abbastanza persone disponibili, segnala l'errore
- MsgBox "Impossibile pianificare il turno del giovedì", vbCritical, "Errore"
- End If
- Else
- ' Se il giovedì non è un giorno lavorativo, lascia vuoti i turni
- For i = 1 To 4
- turniGiornalieri(4, i) = ""
- Next i
- End If
- ' Venerdì
- numPersoneDisponibili = 0
- ReDim personeDisponibili(numLavoratori)
- If giorniLavorativi(5) Then
- ' Se ci sono lavoratori disponibili il venerdì, cerca quelli che lavorano fino alle 18:00
- For index = 1 To numLavoratori
- If lavoratori(index).DisponibileGiorni(5) And lavoratori(index).OrariDisponibili(6) >= 5 And lavoratori(index).OreLavorateGiornaliere(6) < (lavoratori(index).OrariDisponibili(6) - lavoratori(index).OrariDisponibili(5) + 1) And Not usedIndices.Contains(index) And giorniLavorativi(5) Then
- numPersoneDisponibili = numPersoneDisponibili + 1
- personeDisponibili(numPersoneDisponibili) = lavoratori(index)
- usedIndices.Add index
- End If
- Next index
- ' Se non ci sono abbastanza lavoratori disponibili fino alle 18:00, cerca quelli che hanno almeno 4 ore libere
- Dim oreDisponibili As Integer
- oreDisponibili = 8
- For i = 1 To numLavoratori
- oreDisponibili = oreDisponibili - lavoratori(i).OreLavorateGiornaliere(6)
- Next i
- If oreDisponibili >= 4 Then
- For index = 1 To numLavoratori
- If lavoratori(index).DisponibileGiorni(5) And (lavoratori(index).OrariDisponibili(6) - lavoratori(index).OrariDisponibili(5) + 1) - lavoratori(index).OreLavorateGiornaliere(6) >= 4 And Not usedIndices.Contains(index) And giorniLavorativi(5) Then
- numPersoneDisponibili = numPersoneDisponibili + 1
- personeDisponibili(numPersoneDisponibili) = lavoratori(index)
- usedIndices.Add index
- End If
- Next index
- End If
- ' Se ancora non ci sono abbastanza lavoratori disponibili, cerca quelli che possono lavorare il venerdì
- Do While numPersoneDisponibili < 3 And oreDisponibili > 0
- For index = 1 To numLavoratori
- If lavoratori(index).DisponibileGiorni(5) And (lavoratori(index).OrariDisponibili(6) - lavoratori(index).OrariDisponibili(5) + 1) - lavoratori(index).OreLavorateGiornaliere(6) >= 1 And Not usedIndices.Contains(index) And giorniLavorativi(5) Then
- numPersoneDisponibili = numPersoneDisponibili + 1
- personeDisponibili(numPersoneDisponibili) = lavoratori(index)
- usedIndices.Add index
- oreDisponibili = oreDisponibili - 1
- End If
- Next index
- Loop
- ' Se ci sono abbastanza persone disponibili, pianifica i turni
- If numPersoneDisponibili >= 3 Then
- ' Inserisce le persone disponibili
- turniGiornalieri(5, 1) = personeDisponibili(1).nome
- turniGiornalieri(5, 2) = personeDisponibili(2).nome
- turniGiornalieri(5, 3) = personeDisponibili(3).nome
- Else
- ' Se non ci sono abbastanza persone disponibili, segnala l'errore
- MsgBox "Impossibile pianificare il turno del venerdì", vbCritical, "Errore"
- End If
- Else
- ' Se il venerdì non è un giorno lavorativo, lascia vuoti i turni
- For i = 1 To 3
- turniGiornalieri(5, i) = ""
- Next i
- End If
- ' Sabato e Domenica
- For i = 6 To 7
- For j = 1 To 3
- turniGiornalieri(i, j) = ""
- Next j
- Next i
- ' Riempie i dati nella tabella
- For i = 1 To 35
- ' Nome del lavoratore
- Sheets("Planning").Cells(i + 9, 9).Value = turniGiornalieri(i Mod 5, 1)
- Sheets("Planning").Cells(i + 9, 10).Value = turniGiornalieri(i Mod 5, 2)
- Sheets("Planning").Cells(i + 9, 11).Value = turniGiornalieri(i Mod 5, 3)
- ' Orario di lavoro
- Sheets("Planning").Cells(i + 9, 12).Value = orarioGiornaliero(i Mod 5, 1)
- Sheets("Planning").Cells(i + 9, 13).Value = orarioGiornaliero(i Mod 5, 2)
- Sheets("Planning").Cells(i + 9, 14).Value = orarioGiornaliero(i Mod 5, 3)
- ' Giorno della settimana
- Sheets("Planning").Cells(i + 9, 15).Value = giorniSettimana(i Mod 5)
- ' Data
- Sheets("Planning").Cells(i + 9, 16).Value = dataInizio.AddDays(i - 1)
- Next i
- ' Segnala che la pianificazione è stata completata
- MsgBox "Pianificazione completata!", vbInformation, "Completato"
- Else
- ' Se non è stata selezionata una data di inizio, segnala l'errore
- MsgBox "Seleziona una data di inizio!", vbCritical, "Errore"
- End If
- Else
- ' Se non sono stati inseriti i lavoratori nel database, segnala l'errore
- MsgBox "Inserisci almeno un lavoratore nel database!", vbCritical, "Errore"
- End If
- End Sub
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement