Me ne sono andato in crisi profondissima di fronte al modo in cui VBA Excel opera gli arrotondamenti.
Poi, andando in crisi, non riesco più a ragionare lucidamente, e non riuscendo a ragionare lucidamente me ne vado ancora più in crisi, fin quando collasso completamente e mi ci sento male da un punto di vista emotivo.
Meglio sempre razionalizzare per iscritto, altrimenti mi imprigiono dentro queste "strutture emotive patologiche" che mi paralizzano del tutto.
In fondo, è per questo che ho deciso di tenere un diario, solo che poi non lo compilo perché ho paura di essere troppo prolisso su argomenti banali e di appesantirlo.
Ecco.
Quello che mi serve è approssimare per difetto le frazioni da 0,1 a 0,4 e per eccesso quelle da 0.5 a 0.9.
Aiutandomi con spunti che ho trovato in rete, ecco la conclusione cui sono arrivato.
Mi creo un codice apposta per sperimentare la cosa.
Sub main()
Dim n As Double
For n = 1 To 5 Step 0.1
Debug.Print n & " -----> " & Int(n + 0.5)
Next n
End Sub
1 -----> 1
1,1 -----> 1
1,2 -----> 1
1,3 -----> 1
1,4 -----> 1
1,5 -----> 2
1,6 -----> 2
1,7 -----> 2
1,8 -----> 2
1,9 -----> 2
2 -----> 2
2,1 -----> 2
2,2 -----> 2
2,3 -----> 2
2,4 -----> 2
2,5 -----> 3
2,6 -----> 3
2,7 -----> 3
2,8 -----> 3
2,9 -----> 3
3 -----> 3
3,1 -----> 3
3,2 -----> 3
3,3 -----> 3
3,4 -----> 3
3,5 -----> 4
3,6 -----> 4
3,7 -----> 4
3,8 -----> 4
3,9 -----> 4
4 -----> 4
4,1 -----> 4
4,2 -----> 4
4,3 -----> 4
4,4 -----> 4
4,5 -----> 5
4,6 -----> 5
4,7 -----> 5
4,8 -----> 5
4,9 -----> 5
5 -----> 5
Sembra che risponda egregiamente ai miei piani. Era così banale, ma nel circolo vizioso in cui mi ero messo non ci avevo pensato: sono stato spiazzato dal metodo apparentemente assurdo di approssimazione che Excel opera, convertendo 0.5 ora nell'intero superiore ora in quello inferiore a seconda che la parte intera sia pari o dispari (Banker, pare che si chiami, ossia metodo "del banchiere"...)
Adesso applichiamolo alla bisogna.
Io ho un numero di turni da attribuire a due reparti che hanno rispettivamente un numero variabile di medici.
Faccio prima senza approssimazione:
Sub main()
Dim turni As Integer
Dim medCar As Integer, medMed As Integer
Dim turniCar As Double, turniMed As Double
Dim turniPerMedico As Double
turni = 15
medCar = 4
medMed = 5
turniPerMedico = turni / (medCar + medMed)
turniCar = turniPerMedico * medCar
turniMed = turniPerMedico * medMed
Debug.Print turniCar
Debug.Print turniMed
End Sub
6,66666666666667
8,33333333333333
Vario le cifre:
medCar = 5
medMed = 5
7,5
7,5
medCar = 6
medMed = 5
8,18181818181818
6,81818181818182
Adesso introduciamo un arrotondamento come quello che ho ricavato.
Sub main()
Dim turni As Integer
Dim medCar As Integer, medMed As Integer
Dim turniCar As Double, turniMed As Double
Dim turniPerMedico As Double
turni = 15
medCar = 4
medMed = 5
turniPerMedico = turni / (medCar + medMed)
turniCar = Int(turniPerMedico * medCar + 0.5)
turniMed = Int(turniPerMedico * medMed + 0.5)
Debug.Print turniCar
Debug.Print turniMed
End Sub
7
8
medCar = 5
medMed = 5
8
8
medCar = 6
medMed = 5
8
7
Facciamo un confronto con i risultati che avevo ottenuto senza approssimazione:
- Primo caso: 4 e 5:
Senza arrotondamento:
6,66666666666667
8,33333333333333
Con arrotondamento:
7
8
somma: 15
- Secondo caso: 5 e 5:
Senza arrotondamento:
7,5
7,5
Con arrotondamento:
8
8
somma:16
- Terzo caso: 6 e 5:
Senza arrotondamento:
8,18181818181818
6,81818181818182
Con arrotondamento:
8
7
somma:15
Solo nel caso in cui i due gruppi siano uguali, dal momento che la cifra decimale è 0.5, viene arrotondata in alto in ambedue, "creando" un turno in più: in tutti gli altri casi, essendo le cifre decimali diverse e necessariamente una al di sopra di 0.5 e l'altra al di sotto, i turni vengono divisi bene con l'arrotondamento, venendo attribuiti al gruppo cui ne "spetterebbe" la parte maggiore.
Dunque dal momento che l'unica situazione in cui la somma dei turni per reparto non corrisponde al totale dei turni pare sia questa, bisogna trovare un modo per normalizzare la cosa.