
Option Explicit
Sub colorize()
Dim my_range As Range, my_row As Range, cell As Range, col As Integer
Dim next_cell As Range, next_next_cell As Range
Dim rip_cell As Range, rip As Integer
Application.ScreenUpdating = False
'normalizza l'intera tabella, bordi compresi
set_color Range("T12:AK47"), xlAutomatic, 2, True, True
'considera alcune condizioni di ALLERTA (celle in ARANCIONE)
'-----------------------------------------------------------
Set my_range = Range("U13:AA46,AD13:AJ46") 'prende in esame ognuno dei due quadranti setitmanali
For Each my_row In my_range.Rows 'scorre riga per riga
'non possono esserci più di due riposi infrasettimanali in una settimana
'(non si applica se uno dei riposi è festivo, RFI)
If (count_of(my_row, "R") > 2) And (count_of(my_row, "RFI") = 0) Then
For Each cell In my_row.Cells
If Not (Left(cell, 1) Like "[Rr]") Then
set_color cell, xlAutomatic, 46, True, True
End If
Next
End If
'non può esserci solo un riposo in una settimana a meno che in settimana non ci sia *S o *F
'(tutta la settimana diventa ARANCIONE, tranne la cella con il codice di riposo)
If (count_of(my_row, "R") = 1) And (count_of(my_row, "S") + count_of(my_row, "F") = 0) Then
For Each cell In my_row.Cells
If Not (Left(cell, 1) Like "[Rr]") Then set_color cell, xlAutomatic, 46, True, True
Next
End If
Next
'non possono esserci comunque mai 7 turni consecutivi, contando anche le celle del secondo quadrante
'(salta la regola con *S, *F o RFI)
Set my_range = Range("U13:AJ46")
For Each my_row In my_range.Rows 'scorre riga per riga dei due quadranti unificati
col = 0: rip = 0
For Each cell In my_row.Cells
col = col + 1
If col < 8 Or col > 9 Then 'salta le due colonne centrali (relativamente a my_range)
If cell = "RO" Or cell = "RC" Then
rip = 0
Set rip_cell = cell
Else
rip = rip + 1
End If
If rip > 6 Then 'non possono esserci più di 6 turni consecutivi, colora di ARANCIONE dall'ultimo riposo fino al prossimo
set_color Range(Cells(rip_cell.Row, rip_cell.Column + 1), Cells(rip_cell.Row, rip_cell.Column + rip + IIf(col > 9, 2, 0))), xlAutomatic, 46, True, True
'rip = 0
'Exit For
End If
End If
Next
Next
'applica le regole normali, casi speciali e condizioni di ERRORE
Call apply_rules(Range("U13:AJ46"))
Range("AK12:AK47, AB13:AC46").Interior.ColorIndex = 2
Application.ScreenUpdating = True
Range("U13:AJ46").FormatConditions.Delete
Range("AB13:AC46").Font.italic = False
MsgBox "VERIFICA ULTIMATA"
End Sub
Private Sub apply_rules(r As Range)
Dim my_row As Range, cell As Range, col As Integer
Dim next_cell As Range, next_next_cell As Range
'applica le regole normali
For Each my_row In r.Rows 'scorre riga per riga
col = 0
For Each cell In my_row.Cells 'scorre ogni riga dalla prima alla terz'ultima cella e considera cella per cella
col = col + 1
If col < 8 Or col > 9 Then 'salta le due colonne centrali (relativamente a my_range)
Select Case my_row.Cells(col)
Case "C+", "C**", "CS", "C+S", "C*S", "C**S", "CF", "C+F", "C*F", "C**F"
set_color cell, 2, 3, True, False
Case "1+", "1S", "1+S", "1*S", "1**S", "1F", "1+F", "1*F", "1**F"
set_color cell, 2, 3, True, False
Case "2+", "2S", "2+S", "2*S", "2**S", "2F", "2+F", "2*F", "2**F"
set_color cell, 2, 3, True, False
Case "3+", "3**", "3S", "3+S", "3*S", "3**S", "3F", "3+F", "3*F", "3**F"
set_color cell, 2, 3, True, False
Case "RO", "RC", "RFI":
set_color cell, 3, 36, True, False
Case "F", "DISP":
set_color cell, 3, 34, True, False
Case "M":
set_color cell, 2, 30, True, False
Case "DS":
set_color cell, 2, 32, True, False
End Select
Set next_cell = cell.Offset(, 1)
Set next_next_cell = cell.Offset(, 2)
'se siamo nella penultima colonna del primo quadrante:
'la cella successiva è stata impostata, ma la cella dopo è la prima del secondo quadrante
If col = 6 Then
Set next_next_cell = cell.Offset(, 4)
End If
'se siamo nell'ultima colonna del primo quadrante
'la cella successiva è la prima del secondo quadrante, quella dopo ancora è la seconda
If col = 7 Then
Set next_cell = cell.Offset(, 3)
Set next_next_cell = cell.Offset(, 4)
End If
'controlla condizioni di ERRORE (in ROSSO)
'-----------------------------------------
'ignora condizioni di errore legate al 3 se si esamina l'ultima colonna del secondo quadrante
If col < 16 Then
'altrimenti considera alcune condizioni di ERRORE
Select Case Left(cell, 1)
Case "3"
'un 3 non può essere seguito da un 2 o da un 1
If next_cell Like "2*" Or next_cell Like "1*" Then set_color next_cell, xlAutomatic, 3, True, True
'un 3 deve essere seguito da due celle R* oppure da un altro 3
If Left(next_cell, 1) Like "[Rr]" And Not (Left(next_next_cell, 1) Like "[Rr]") Then
set_color next_next_cell, xlAutomatic, 3, True, True
End If
Case "2"
'un 2 non può essere seguito da un 1
If next_cell Like "1*" Then set_color next_cell, xlAutomatic, 3, True, True
End Select
End If
End If
Next
Next
End Sub
Private Sub set_color(this_cell As Range, foreground As Integer, background As Integer, bold, italic)
With this_cell
With .Font
.bold = True
.italic = True
.ColorIndex = foreground
End With
If this_cell.Cells.Count = 1 Then
If .Interior.ColorIndex <> 46 Then
.Interior.ColorIndex = background
End If
Else
.Interior.ColorIndex = background
End If
End With
End Sub
Private Function count_of(ByVal r As Range, what As String)
Dim vect() As Variant, v As Variant, i As Integer, s As String
ReDim vect(1 To r.Cells.Count)
For Each v In r.Cells
i = i + 1
vect(i) = v
Next
s = Join(vect, vbNullChar) & vbNullChar
count_of = Len(Replace(s, what, what & "*")) - Len(s)
End Function |
Range("AK12:AK47, AB13:AC46").Interior.ColorIndex = 2
Range("AL12:AZ50").Interior.ColorIndex = xlNone '<<<<<< normalizza l'area esterna ai quadranti
Application.ScreenUpdating = True
Range("U13:AJ46").FormatConditions.Delete
Range("AB13:AC46").Font.italic = False
MsgBox "VERIFICA ULTIMATA" |
Option Explicit
Sub colorize()
Dim my_range As Range, my_row As Range, cell As Range, col As Integer
Dim next_cell As Range, next_next_cell As Range
Dim rip_cell As Range, rip As Integer
Application.ScreenUpdating = False
'normalizza l'intera tabella, bordi compresi
set_color Range("T12:AK47"), xlAutomatic, 2, True, True
'considera alcune condizioni di ALLERTA (celle in ARANCIONE)
'-----------------------------------------------------------
Set my_range = Range("U13:AA46,AD13:AJ46") 'prende in esame ognuno dei due quadranti setitmanali
For Each my_row In my_range.Rows 'scorre riga per riga
'non possono esserci più di due riposi infrasettimanali in una settimana
'(non si applica se uno dei riposi è festivo, RFI)
If (count_of(my_row, "R") > 2) And (count_of(my_row, "RFI") = 0) Then
For Each cell In my_row.Cells
If Not (Left(cell, 1) Like "[Rr]") Then
set_color cell, xlAutomatic, 46, True, True
End If
Next
End If
'non può esserci solo un riposo in una settimana a meno che in settimana non ci sia *S o *F
'(tutta la settimana diventa ARANCIONE, tranne la cella con il codice di riposo)
If (count_of(my_row, "R") = 1) And (count_of(my_row, "S") + count_of(my_row, "F") = 0) Then
For Each cell In my_row.Cells
If Not (Left(cell, 1) Like "[Rr]") Then set_color cell, xlAutomatic, 46, True, True
Next
End If
Next
'non possono esserci comunque mai 7 turni consecutivi, contando anche le celle del secondo quadrante
'(salta la regola con *S, *F o RFI)
Set my_range = Range("U13:AJ46")
For Each my_row In my_range.Rows 'scorre riga per riga dei due quadranti unificati
col = 0: rip = 0
For Each cell In my_row.Cells
If Trim(cell) <> "" Then
col = col + 1
If col < 8 Or col > 9 Then 'salta le due colonne centrali (relativamente a my_range)
If cell = "RO" Or cell = "RC" Then
rip = 0
Set rip_cell = cell
Else
rip = rip + 1
End If
If rip > 6 Then 'non possono esserci più di 6 turni consecutivi, colora di ARANCIONE dall'ultimo riposo fino al prossimo
set_color Range(Cells(rip_cell.Row, rip_cell.Column + 1), Cells(rip_cell.Row, rip_cell.Column + rip + IIf(col > 9, 2, 0))), xlAutomatic, 46, True, True
End If
End If
End If
Next
Next
'applica le regole normali, casi speciali e condizioni di ERRORE
Call apply_rules(Range("U13:AJ46"))
Range("AK12:AK47, AB13:AC46").Interior.ColorIndex = 2
Application.ScreenUpdating = True
Range("U13:AJ46").FormatConditions.Delete
Range("AB13:AC46").Font.italic = False
MsgBox "VERIFICA ULTIMATA"
End Sub
Private Sub apply_rules(r As Range)
Dim my_row As Range, cell As Range, col As Integer
Dim next_cell As Range, next_next_cell As Range
'applica le regole normali
For Each my_row In r.Rows 'scorre riga per riga
col = 0
For Each cell In my_row.Cells 'scorre ogni riga dalla prima alla terz'ultima cella e considera cella per cella
col = col + 1
If col < 8 Or col > 9 Then 'salta le due colonne centrali (relativamente a my_range)
Select Case my_row.Cells(col)
Case "C+", "C**", "CS", "C+S", "C*S", "C**S", "CF", "C+F", "C*F", "C**F"
set_color cell, 2, 3, True, False
Case "1+", "1S", "1+S", "1*S", "1**S", "1F", "1+F", "1*F", "1**F"
set_color cell, 2, 3, True, False
Case "2+", "2S", "2+S", "2*S", "2**S", "2F", "2+F", "2*F", "2**F"
set_color cell, 2, 3, True, False
Case "3+", "3**", "3S", "3+S", "3*S", "3**S", "3F", "3+F", "3*F", "3**F"
set_color cell, 2, 3, True, False
Case "RO", "RC", "RFI":
set_color cell, 3, 36, True, False
Case "F", "DISP":
set_color cell, 3, 34, True, False
Case "M":
set_color cell, 2, 30, True, False
Case "DS":
set_color cell, 2, 32, True, False
End Select
Set next_cell = cell.Offset(, 1)
Set next_next_cell = cell.Offset(, 2)
'se siamo nella penultima colonna del primo quadrante:
'la cella successiva è stata impostata, ma la cella dopo è la prima del secondo quadrante
If col = 6 Then
Set next_next_cell = cell.Offset(, 4)
End If
'se siamo nell'ultima colonna del primo quadrante
'la cella successiva è la prima del secondo quadrante, quella dopo ancora è la seconda
If col = 7 Then
Set next_cell = cell.Offset(, 3)
Set next_next_cell = cell.Offset(, 4)
End If
'controlla condizioni di ERRORE (in ROSSO)
'-----------------------------------------
'ignora condizioni di errore legate al 3 se si esamina l'ultima colonna del secondo quadrante
If col < 16 Then
'altrimenti considera alcune condizioni di ERRORE
Select Case Left(cell, 1)
Case "3"
'un 3 non può essere seguito da un 2 o da un 1
If next_cell Like "2*" Or next_cell Like "1*" Then set_color next_cell, xlAutomatic, 3, True, True
'un 3 deve essere seguito da due celle R* oppure da un altro 3
If Left(next_cell, 1) Like "[Rr]" And Not (Left(next_next_cell, 1) Like "[Rr]") Then
set_color next_next_cell, xlAutomatic, 3, True, True
End If
Case "2"
'un 2 non può essere seguito da un 1
If next_cell Like "1*" Then set_color next_cell, xlAutomatic, 3, True, True
End Select
End If
End If
Next
Next
End Sub
Private Sub set_color(this_cell As Range, foreground As Integer, background As Integer, bold, italic)
With this_cell
With .Font
.bold = True
.italic = True
.ColorIndex = foreground
End With
If this_cell.Cells.Count = 1 Then
If .Interior.ColorIndex <> 46 Then
.Interior.ColorIndex = background
End If
Else
.Interior.ColorIndex = background
End If
End With
End Sub
Private Function count_of(ByVal r As Range, what As String)
Dim vect() As Variant, v As Variant, i As Integer, s As String
ReDim vect(1 To r.Cells.Count)
For Each v In r.Cells
i = i + 1
vect(i) = v
Next
s = Join(vect, vbNullChar) & vbNullChar
count_of = Len(Replace(s, what, what & "*")) - Len(s)
End Function
|
Option Explicit
Sub colorize()
Dim my_range As Range, my_row As Range, cell As Range, col As Integer
Dim next_cell As Range, next_next_cell As Range
Dim rip_cell As Range, rip As Integer
Application.ScreenUpdating = False
'normalizza l'intera tabella, bordi compresi
set_color Range("T12:AK47"), xlAutomatic, 2, True, True
'considera alcune condizioni di ALLERTA (celle in ARANCIONE)
'-----------------------------------------------------------
Set my_range = Range("U13:AA46,AD13:AJ46") 'prende in esame ognuno dei due quadranti setitmanali
For Each my_row In my_range.Rows 'scorre riga per riga
'non possono esserci più di due riposi infrasettimanali in una settimana
'(non si applica se uno dei riposi è festivo, RFI)
If (count_of(my_row, "R") > 2) And (count_of(my_row, "RFI") = 0) Then
For Each cell In my_row.Cells
If Not (Left(cell, 1) Like "[Rr]") Then
set_color cell, xlAutomatic, 46, True, True
End If
Next
End If
'non può esserci solo un riposo in una settimana a meno che in settimana non ci sia *S o *F
'(tutta la settimana diventa ARANCIONE, tranne la cella con il codice di riposo)
If (count_of(my_row, "R") = 1) And (count_of(my_row, "S") + count_of(my_row, "F") = 0) Then
For Each cell In my_row.Cells
If Not (Left(cell, 1) Like "[Rr]") Then set_color cell, xlAutomatic, 46, True, True
Next
End If
Next
'non possono esserci comunque mai 7 turni consecutivi, contando anche le celle del secondo quadrante
'(salta la regola con *S, *F o RFI)
Set my_range = Range("U13:AJ46")
For Each my_row In my_range.Rows 'scorre riga per riga dei due quadranti unificati
col = 0: rip = 0
For Each cell In my_row.Cells
col = col + 1
If col < 8 Or col > 9 Then 'salta le due colonne centrali (relativamente a my_range)
If Trim(cell) <> "" Then
If cell = "RO" Or cell = "RC" Then
rip = 0
Set rip_cell = cell
Else
rip = rip + 1
End If
If rip > 6 Then 'non possono esserci più di 6 turni consecutivi, colora di ARANCIONE dall'ultimo riposo fino al prossimo
set_color Range(Cells(rip_cell.Row, rip_cell.Column + 1), Cells(rip_cell.Row, rip_cell.Column + rip + IIf(col > 9, 2, 0))), xlAutomatic, 46, True, True
End If
End If
End If
Next
Next
'applica le regole normali, casi speciali e condizioni di ERRORE
Call apply_rules(Range("U13:AJ46"))
Range("AK12:AK47, AB13:AC46").Interior.ColorIndex = 2
Application.ScreenUpdating = True
Range("U13:AJ46").FormatConditions.Delete
Range("AB13:AC46").Font.italic = False
MsgBox "VERIFICA ULTIMATA"
End Sub
Private Sub apply_rules(r As Range)
Dim my_row As Range, cell As Range, col As Integer
Dim next_cell As Range, next_next_cell As Range
'applica le regole normali
For Each my_row In r.Rows 'scorre riga per riga
col = 0
For Each cell In my_row.Cells 'scorre ogni riga dalla prima alla terz'ultima cella e considera cella per cella
col = col + 1
If col < 8 Or col > 9 Then 'salta le due colonne centrali (relativamente a my_range)
Select Case my_row.Cells(col)
Case "C+", "C**", "CS", "C+S", "C*S", "C**S", "CF", "C+F", "C*F", "C**F"
set_color cell, 2, 3, True, False
Case "1+", "1S", "1+S", "1*S", "1**S", "1F", "1+F", "1*F", "1**F"
set_color cell, 2, 3, True, False
Case "2+", "2S", "2+S", "2*S", "2**S", "2F", "2+F", "2*F", "2**F"
set_color cell, 2, 3, True, False
Case "3+", "3**", "3S", "3+S", "3*S", "3**S", "3F", "3+F", "3*F", "3**F"
set_color cell, 2, 3, True, False
Case "RO", "RC", "RFI":
set_color cell, 3, 36, True, False
Case "F", "DISP":
set_color cell, 3, 34, True, False
Case "M":
set_color cell, 2, 30, True, False
Case "DS":
set_color cell, 2, 32, True, False
End Select
Set next_cell = cell.Offset(, 1)
Set next_next_cell = cell.Offset(, 2)
'se siamo nella penultima colonna del primo quadrante:
'la cella successiva è stata impostata, ma la cella dopo è la prima del secondo quadrante
If col = 6 Then
Set next_next_cell = cell.Offset(, 4)
End If
'se siamo nell'ultima colonna del primo quadrante
'la cella successiva è la prima del secondo quadrante, quella dopo ancora è la seconda
If col = 7 Then
Set next_cell = cell.Offset(, 3)
Set next_next_cell = cell.Offset(, 4)
End If
'controlla condizioni di ERRORE (in ROSSO)
'-----------------------------------------
'ignora condizioni di errore legate al 3 se si esamina l'ultima colonna del secondo quadrante
If col < 16 Then
'altrimenti considera alcune condizioni di ERRORE
Select Case Left(cell, 1)
Case "3"
'un 3 non può essere seguito da un 2 o da un 1
If next_cell Like "2*" Or next_cell Like "1*" Then set_color next_cell, xlAutomatic, 3, True, True
'un 3 deve essere seguito da due celle R* oppure da un altro 3
If Left(next_cell, 1) Like "[Rr]" And Not (Left(next_next_cell, 1) Like "[Rr]") Then
set_color next_next_cell, xlAutomatic, 3, True, True
End If
Case "2"
'un 2 non può essere seguito da un 1
If next_cell Like "1*" Then set_color next_cell, xlAutomatic, 3, True, True
End Select
End If
End If
Next
Next
End Sub
Private Sub set_color(this_cell As Range, foreground As Integer, background As Integer, bold, italic)
With this_cell
With .Font
.bold = True
.italic = True
.ColorIndex = foreground
End With
If this_cell.Cells.Count = 1 Then
If .Interior.ColorIndex <> 46 Then
.Interior.ColorIndex = background
End If
Else
.Interior.ColorIndex = background
End If
End With
End Sub
Private Function count_of(ByVal r As Range, what As String)
Dim vect() As Variant, v As Variant, i As Integer, s As String
ReDim vect(1 To r.Cells.Count)
For Each v In r.Cells
i = i + 1
vect(i) = v
Next
s = Join(vect, vbNullChar) & vbNullChar
count_of = Len(Replace(s, what, what & "*")) - Len(s)
End Function
|
