Erreur 400, trop de calculs?
Résolu
ezor
Messages postés
190
Statut
Membre
-
ezor Messages postés 190 Statut Membre -
ezor Messages postés 190 Statut Membre -
Bonjour,
je cherche à créer une petite macro qui donne la probabilité de victoire pour un jeu aléatoire à deux joueurs. Je rentre le score et le nombre de question restante pour chacun, et je suppose que pour chaque question, il y a 1/4 de réussite.
Le problème est le suivant : Dans certain cas, lorsque je lance la macro depuis la feuille, j'ai "erreur 400" et quand je le fais depuis l'éditeur, j'ai "impossible de lire la propriété combin de la classe WorksheetFunction"
La majorité du temps, ça se passe plutot bien, mais parfois j'ai ces erreurs.
je vous met le code ci dessous
Comme vous pouvez le voire, j'ai aussi essayer de créer ma propre fonction "combinaison" pour remplacer COMBIN. Voici comment j'ai fait
mais dans ce cas, j'ai une erreur "dépassement de capacité" au niveau de l'arguement de "combinaison".
j'ai bien l'impression que le problème vient d'un nombre trop grand de calcul à effectuer, mais je ne sais pas comment vérifier ça.
J'espère avoir été à peu près clair dans mes explications.
Je voudrais comprendre d'où viennent vriament ces deux types d'erreurs et si possible comment les régler.
merci d'avance,
PS : voici un exemple de conditions initiales qui entrainent une erreur
Cells(4, 3) = "2"
Cells(4, 4) = "0"
Cells(5, 3) = "15"
Cells(5, 4) = "18"
ezor
je cherche à créer une petite macro qui donne la probabilité de victoire pour un jeu aléatoire à deux joueurs. Je rentre le score et le nombre de question restante pour chacun, et je suppose que pour chaque question, il y a 1/4 de réussite.
Le problème est le suivant : Dans certain cas, lorsque je lance la macro depuis la feuille, j'ai "erreur 400" et quand je le fais depuis l'éditeur, j'ai "impossible de lire la propriété combin de la classe WorksheetFunction"
La majorité du temps, ça se passe plutot bien, mais parfois j'ai ces erreurs.
je vous met le code ci dessous
Dim a As Long
Dim x As Long
Dim b As Long
Dim y As Long
Dim res As Double 'proba de victoire de A
Dim nul As Double 'proba de faire match nul
Dim som As Double
Dim k As Long
Dim i As Long
Sub calcul()
a = Range("C4").Value 'Score du joueur A
x = Range("C5").Value 'nombre de question restante pour le joueur A
b = Range("D4").Value 'Score du joueur B
y = Range("D5").Value 'nombre de question restante pour le joueur B
nul = 0
res = 0
If a + x < b Then
res = 0 'cas trivial où A est sur de perdre
ElseIf a > b + y Then
res = 1 'cas trivial où A est sur de gagner
ElseIf a > b Then
'Calcul de la victoire de A
res = 0
som = 0
k = 0
'Cas où A gagne quelques soit les réponses qu'il fait
For k = 0 To (a - b - 1)
res = res + proba(k, y)
Next k
'Autres cas
k = a - b
While k <= y
som = 0
For i = k - (a - b) + 1 To x
som = som + proba(i, x)
Next i
res = res + proba(k, y) * som
k = k + 1
Wend
'Calcul du match nul
k = 0
While a - b + k <= y
nul = nul + proba(k, x) * proba(a - b + k, y)
k = k + 1
Wend
ElseIf a < b Then
res = 0
nul = 0
k = 0
While k <= a - b + x - 1
som = 0
For i = (b - a + 1 + k) To x
som = som + proba(i, x)
Next i
res = res + proba(k, y) * som
k = k + 1
Wend
'Calcul du match nul
k = 0
While b - a + k <= x
nul = nul + proba(k, y) * proba(b - a + k, x)
k = k + 1
Wend
'cas d'égalité
ElseIf a = b Then
res = 0
nul = 0
If x = y Then
For i = 0 To x
nul = nul + (proba(i, x) ^ 2)
Next i
res = (1 - nul) / 2
Else 'si a=b mais x =/= y
Dim min As Integer
min = Application.WorksheetFunction.min(x, y)
For k = 0 To min
som = 0
For i = (k + 1) To x
som = som + proba(i, x)
Next i
res = res + proba(k, y) * som
Next k
End If
Else
MsgBox "j'ai oublié un cas"
End If
'écritude du résultat
Cells(4, 6) = res * 100 & " .%" 'probabilité de victoire de A
Cells(7, 6) = nul * 100 & " .%" 'probabilité de match nul
Cells(10, 6) = (1 - res - nul) * 100 & " .%" 'probabilité de victoire de B
Range("F4").NumberFormat = "General"
Range("F7").NumberFormat = "General"
Range("F10").NumberFormat = "General"
res = 0
nul = 0
box = MsgBox("Terminé", vbInformation, "")
End Sub
Public Function proba(nb_juste As Long, restant As Long) As Double
Dim r As Long
Dim n As Long
r = restant
n = nb_juste
proba = (Application.WorksheetFunction.combin(r, n) * 3 ^ (r - n)) / (4 ^ r)
'proba = (combinaison(n,r) * 3 ^ (r - n)) / (4 ^ r)
End Function
Comme vous pouvez le voire, j'ai aussi essayer de créer ma propre fonction "combinaison" pour remplacer COMBIN. Voici comment j'ai fait
'fonction factorielle
Public Function fact(ByVal n As Long) As Long
If n < 0 Then
MsgBox "erreur : argument factorielle négatif "
Exit Function
ElseIf n = 0 Then
fact = 1
Else
If n = 1 Then
fact = 1
Else
fact = n * fact(n - 1)
End If
End If
End Function
'fonction combinaison
Public Function combinaison(ByVal p As Integer,ByVal n As Integer)
If p > n Then
combinaison = 0
Else
combinaison = fact(n) / (fact(p) * fact(n - p))
End If
End Function
mais dans ce cas, j'ai une erreur "dépassement de capacité" au niveau de l'arguement de "combinaison".
j'ai bien l'impression que le problème vient d'un nombre trop grand de calcul à effectuer, mais je ne sais pas comment vérifier ça.
J'espère avoir été à peu près clair dans mes explications.
Je voudrais comprendre d'où viennent vriament ces deux types d'erreurs et si possible comment les régler.
merci d'avance,
PS : voici un exemple de conditions initiales qui entrainent une erreur
Cells(4, 3) = "2"
Cells(4, 4) = "0"
Cells(5, 3) = "15"
Cells(5, 4) = "18"
ezor
A voir également:
- Erreur 400, trop de calculs?
- Barbara veut calculer automatiquement son budget dans un tableau. citez un des logiciels lui permettant de faire des calculs sur des tableaux de nombres (tableur). - Forum Excel
- Erreur t32 ✓ - Forum Livebox
- Meilleur smartphone moins de 400 euros - Guide
- Erreur 0x80070643 - Accueil - Windows
- Erreur de lecture reconnecté en 3s - Forum TV & Vidéo
4 réponses
bonjour,
Déjà, remplace "integer" par "long", essaies et tu nous dis
Michel
Déjà, remplace "integer" par "long", essaies et tu nous dis
Michel
ezor
Messages postés
190
Statut
Membre
11
merci pour ta réponse, effectivement, c'est plus "prudent" avec Long, mais le problème reste le même.
Bonjour
Utilises plutôt la fonction combin de la feuille de calcul, qui évitera les factorielles trop grandes, mais tu vas quand même être limité
à 2 147 483 647
Salut à michel en passant
Cdlmnt
Utilises plutôt la fonction combin de la feuille de calcul, qui évitera les factorielles trop grandes, mais tu vas quand même être limité
à 2 147 483 647
Dim c As Long, n As Long, p As Long
n = 5
p = 3
c = Application.WorksheetFunction.Combin(n, p)
Salut à michel en passant
Cdlmnt
Idée 1. Récupères les valeurs dans des variables et regardes leur valeur lorsque ça plante
Idée 2. as tu bien n >= p
Idée 3. Cells(5, 4) = "18" si tu as laissé les guillemets, ça plante
Sinon, envoies la partie concernée de ton fichier via cjoint.com avec les exemples qui plantent
Cdlmnt
Idée 2. as tu bien n >= p
Idée 3. Cells(5, 4) = "18" si tu as laissé les guillemets, ça plante
Sinon, envoies la partie concernée de ton fichier via cjoint.com avec les exemples qui plantent
Cdlmnt
dans le sens inverse ;) :
idée 3 : avec ou sans " " pas de changement
idée 2 : je n'ai pas l'impression que le problème vienne de là. J'ai un cas "if p>n" dans ma routine combinaison pour gérer ça
idée 1 : je vais tenter de faire ça, mais il y a beaucoup de variables, ça va me prendre du temps. Je te dis si jamais ça s'approche dangereusement de 9 223 372 036 854 775 807 (le maximum pour un Long!)
PS : 18! < max d'un Long
idée 3 : avec ou sans " " pas de changement
idée 2 : je n'ai pas l'impression que le problème vienne de là. J'ai un cas "if p>n" dans ma routine combinaison pour gérer ça
idée 1 : je vais tenter de faire ça, mais il y a beaucoup de variables, ça va me prendre du temps. Je te dis si jamais ça s'approche dangereusement de 9 223 372 036 854 775 807 (le maximum pour un Long!)
PS : 18! < max d'un Long
Bon, pour une raison que j'ignore, j'ai une solution qui semble fonctionner même pour des nombres relativement grands. J'ai utilisé ma propre fonction "combinaison" avec pour le calcul des factorielles, Application.fact() ce qui donne le code suivant
Je ne sais pas pourquoi c'est mieux ainsi. J'avais testé avec Application.combin(n,p) et en recodant la fonction factorielle par récursivité.
Je présume que le FACT() de excel est plus optimisé que le miens ou celui dans COMBIN()
Si quelqu'un à une explication je suis preneur.
EDIT : pour info, je peux aller jusqu'à "nombre de question restante" égale à 170 environ. Au dela, j'ai un message d'erreur "Incompatibilité de type". Ça doit dépasser la capactité d'un Long
ezor
'fonction combinaison Public Function combinaison(ByVal p As Long, ByVal n As Long) If p > n Then combinaison = 0 Else combinaison = Application.fact(n) / (Application.fact(p) * Application.fact(n - p)) End If End Function
Je ne sais pas pourquoi c'est mieux ainsi. J'avais testé avec Application.combin(n,p) et en recodant la fonction factorielle par récursivité.
Je présume que le FACT() de excel est plus optimisé que le miens ou celui dans COMBIN()
Si quelqu'un à une explication je suis preneur.
EDIT : pour info, je peux aller jusqu'à "nombre de question restante" égale à 170 environ. Au dela, j'ai un message d'erreur "Incompatibilité de type". Ça doit dépasser la capactité d'un Long
ezor