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?
- Erreur 3000 france tv - Forum Lecteurs et supports vidéo
- Erreur t32 ✓ - Forum Livebox
- Erreur 0x80070643 - Accueil - Windows
- Canon f166 400 - Forum Logiciels
- Meilleur smartphone moins de 400 euros - Guide
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