martedì 7 ottobre 2014

Calcolo dei turni teorici per reparto.

Ora devo conoscere, per fare i calcoli opportuni sulla scrittura dei turni alternati come ho fatto finora:
  • il numero totale dei turni disponibili
  • il numero dei medici di ciascun reparto
turniTot è il numero di turni totali disponibili.
medCar è il numero di medici della cardiologia.
medMed è il numero di medici della medicina.
turniCar è il numero di turni della cardiologia.
turniMed è il numero di turni della medicina.
turniTot / (medCar + medMed) = numero dei turni per ciascun medico.
Moltiplicando il numero di turni per ciascun medico per il numero di medici di ciascun reparto ottengo il numero di turni per ciascun reparto.

turniCar = turniTot / (medCar + medMed) * medCar

turniMed = turniTot / (medCar + medMed) * medMed
Calcoliamoli...
Sub main()
    Dim d As Date, nomeFoglio As String
    
    d = DateAdd("m", 1, Date)      'attribuisce alla variabile locale d il valore del mese successivo alla data attuale
    nomeFoglio = MonthName(Month(d)) & " " & Year(d)    'attribuisce alla stringa nomeFoglio mese e anno della variabile locale d
    
    Sheets.Add          'aggiunge un nuovo foglio
    On Error GoTo x     'gestisce l'errore di tentata rinominazione del foglio
    ActiveSheet.Name = nomeFoglio   'rinomina il foglio con la stringa nomeFoglio.
    ActiveSheet.Move after:=Sheets(Sheets.Count) 'sposta alla fine della cartella il nuovo foglio

        
    formattaFoglio Month(d), Year(d)  'formatta il foglio secondo lo schema
    attribuzioneTurni
    Exit Sub
x:     'gestione dell'errore di tentata rinominazione del foglio: elimina il foglio senza suscitare avvisi di eliminazione.
    Application.DisplayAlerts = False
    ActiveSheet.Delete
    Application.DisplayAlerts = True
End Sub

Private Sub attribuzioneTurni()
Dim reparti(1) As String
Dim n As Integer
Dim f As Integer
Dim tCar, tMed As Integer

reparti(0) = "CAR"
reparti(1) = "MED"
 
n = Int(Rnd() * 2)
Range("Reparto").Cells(1, 1).Formula = reparti(n)
If reparti(n) = "CAR" Then
    tCar = tCar + 1
Else
    tMed = tMed + 1
End If

For k = 2 To Range("Reparto").Rows.Count
    If n = 0 Then
        n = 1
    Else
        n = 0
    End If
    Range("Reparto").Cells(k, 1).Formula = reparti(n)
    If reparti(n) = "CAR" Then
        tCar = tCar + 1
    Else
        tMed = tMed + 1
    End If
    
    If festivo(Range("Reparto").Cells(k, 1).Offset(0, -2).Formula) Then
        If Range("Reparto").Cells(k, 1).Formula = "MED" Then
            Range("Reparto").Cells(k, 1).Formula = "CAR - MED"
            tCar = tCar + 1
        Else
            Range("Reparto").Cells(k, 1).Formula = "MED - CAR"
            tMed = tMed + 1
        End If
        f = f + 1
    End If
Next k
Debug.Print "turni attribuiti card " & tCar
Debug.Print "turni attribuiti med " & tMed


Dim turniTot As Integer
Dim medCar, medMed As Integer
Dim turniCar, turniMed As Integer
turniTot = k - 1 + f
medCar = 7
medMed = 6

turniCar = turniTot / (medCar + medMed) * medCar
turniMed = turniTot / (medCar + medMed) * medMed
Debug.Print "turni teorici card " & turniCar
Debug.Print "turni teorici med " & turniMed
End Sub
Risultato
turni attribuiti card 18
turni attribuiti med 17
turni teorici card 18,8461538461538
turni teorici med 16

Ecco, questo è il calcolo completo (quello marcato in rosso), ma c'è qualcosa che non va: il fatto che i turni siano espressi in una cifra decimale, essendo indivisibili.
Per giunta, la somma non combina, essendo espresso uno solo in frazioni di turno.
Sicuramente non sono appropriate le variabili che ho usato per immagazzinarne il valore.
Rifeccio:
Dim turniTot As Integer
Dim medCar, medMed As Integer
Dim turniCar, turniMed As Double
turniTot = k - 1 + f
medCar = 7
medMed = 6

turniCar = turniTot / (medCar + medMed) * medCar
turniMed = turniTot / (medCar + medMed) * medMed
Debug.Print "turni teorici card " & turniCar
Debug.Print "turni teorici med " & turniMed
Proviamo:
turni attribuiti card 17
turni attribuiti med 18
turni teorici card 18,8461538461538
turni teorici med 16,1538461538462
Perfetto! Si tratta di numeri periodici, per cui la verifica non darà mai il risultato esatto, comunque la somma fra i due mi restituisce 34,99999999..... che si può considerare esatto! I turni totali sono infatti 35.
Adesso dobbiamo vedere come liberarci delle frazioni di turno...
Intanto devo correggere un errore di codice che ho commesso: il motivo per cui uno dei risultati era frazionario e l'altro no è stato che io ho dichiarato le variabili in questo modo:
Dim turniCar, turniMed As Integer
credendo, in quanto non ricordavo bene questo aspetto della sintassi del VBA, che anche turniCar sarebbe stata dichiarata come Integer, mentre invece in realtà questa veniva dichiarata come Variant, e quindi mi dava un risultato decimale.
Correggendo la cosa...
Dim turniCar As Integer, turniMed As Integer
ottengo:
turni attribuiti card 17
turni attribuiti med 18
turni teorici card 19
turni teorici med 16
La somma è sempre 35, ma il risultato viene arrotondato.

Sarebbe il caso di vedere come VBA arrotonda... Mi costruisco un programmino dedicato.

Nessun commento:

Posta un commento