Saut de If à Else malgré condition vérifiée
Résolu
Destmobil
Messages postés
12
Date d'inscription
Statut
Membre
Dernière intervention
-
Destmobil Messages postés 12 Date d'inscription Statut Membre Dernière intervention -
Destmobil Messages postés 12 Date d'inscription Statut Membre Dernière intervention -
Bonjour à Toutes et à Tous,
et bien entendu un GRAND MERCI à toutes celles et à ceux qui nous rendent de fiers services en répondant à nos questions de tous niveaux grâce à CCM.
Je programme actuellement en VBA un petit fichier pour gérer mes dépenses.
Seulement voilà, avant d'écrire dans la dernière cellule de mon tableau, j'ai besoin de vérifier l'égalité entre deux sommes de cellules différentes
Plus précisément l'égalité entre la somme des cellules de la dernière colonne de mon tableau et
et la somme des cellules de la dernière ligne du même tableau
Dim Total_A as Double
Dim Total_B as Double
Total_A = la première somme
Total_B = la seconde somme
If Total_A = Total_B Then
j'écris dans ma dernière cellule
Else
je fais autre chose
End if
ET VOICI LE PROBLEME!!!
Les valeurs de Total_A et Total_B sont rigoureusement identiques (-663.36 dans mon cas) donc Total_A = Total_B
et pourtant la macro passe directement à Else comme si ma condition Total_A = Total_B n'était pas vérifiée.
J'ai même taper les sommes sur ma calculette, elles sont justes, strictement identiques ET sans arrondi.
Est-ce que quelqu'un à déjà été confronté à ce problème?
Existe-t-il un moyen de forcer VBA à nous indiquer les différences qu'il trouve entre mes variables?
Pour les puristes, voici mon bout de code qui déconne:
(les variables i et col sont parfaitement renseignées)
'Total_A = Somme colonne 14
Total_A = Application.WorksheetFunction.Sum(Range(Cells(5, col), Cells(i, col)))
'Total_B = Somme ligne i+1
Total_B = Application.WorksheetFunction.Sum(Range(Cells(i + 1, 2), Cells(i + 1, 13)))
If Total_A = Total_B Then
ActiveSheet.Cells(i + 1, col).Value = Total_A
Else
ActiveSheet.Cells(i + 1, col).Value = "ERREUR"
End If
Personnellement, je n'y comprends plus rien, les valeurs à comparer (-663.36) sont assez simples avec très peu de caractères.
Lors de l'exécution, j'ai placé un espion sur mes deux variables.
Les valeurs sont rigoureusement les mêmes et sont obtenues avec aucune approximation.
Il n'y a en apparence, AUCUNE raison de ne pas rentrer dans la boucle If.
J'espère que vous arriverez à voir ce qui m'échappe, car je suis complètement désarmé devant ce problème.
VBA serait-il en panne au point de ne plus pouvoir gérer correctement une If?
Merci d'avoir lu jusqu'au bout, vous n'avez pas perdu votre temps.... Ou pas, faut voir....
et bien entendu un GRAND MERCI à toutes celles et à ceux qui nous rendent de fiers services en répondant à nos questions de tous niveaux grâce à CCM.
Je programme actuellement en VBA un petit fichier pour gérer mes dépenses.
Seulement voilà, avant d'écrire dans la dernière cellule de mon tableau, j'ai besoin de vérifier l'égalité entre deux sommes de cellules différentes
Plus précisément l'égalité entre la somme des cellules de la dernière colonne de mon tableau et
et la somme des cellules de la dernière ligne du même tableau
Dim Total_A as Double
Dim Total_B as Double
Total_A = la première somme
Total_B = la seconde somme
If Total_A = Total_B Then
j'écris dans ma dernière cellule
Else
je fais autre chose
End if
ET VOICI LE PROBLEME!!!
Les valeurs de Total_A et Total_B sont rigoureusement identiques (-663.36 dans mon cas) donc Total_A = Total_B
et pourtant la macro passe directement à Else comme si ma condition Total_A = Total_B n'était pas vérifiée.
J'ai même taper les sommes sur ma calculette, elles sont justes, strictement identiques ET sans arrondi.
Est-ce que quelqu'un à déjà été confronté à ce problème?
Existe-t-il un moyen de forcer VBA à nous indiquer les différences qu'il trouve entre mes variables?
Pour les puristes, voici mon bout de code qui déconne:
(les variables i et col sont parfaitement renseignées)
'Total_A = Somme colonne 14
Total_A = Application.WorksheetFunction.Sum(Range(Cells(5, col), Cells(i, col)))
'Total_B = Somme ligne i+1
Total_B = Application.WorksheetFunction.Sum(Range(Cells(i + 1, 2), Cells(i + 1, 13)))
If Total_A = Total_B Then
ActiveSheet.Cells(i + 1, col).Value = Total_A
Else
ActiveSheet.Cells(i + 1, col).Value = "ERREUR"
End If
Personnellement, je n'y comprends plus rien, les valeurs à comparer (-663.36) sont assez simples avec très peu de caractères.
Lors de l'exécution, j'ai placé un espion sur mes deux variables.
Les valeurs sont rigoureusement les mêmes et sont obtenues avec aucune approximation.
Il n'y a en apparence, AUCUNE raison de ne pas rentrer dans la boucle If.
J'espère que vous arriverez à voir ce qui m'échappe, car je suis complètement désarmé devant ce problème.
VBA serait-il en panne au point de ne plus pouvoir gérer correctement une If?
Merci d'avoir lu jusqu'au bout, vous n'avez pas perdu votre temps.... Ou pas, faut voir....
A voir également:
- Saut de If à Else malgré condition vérifiée
- Excel cellule couleur si condition texte - Guide
- Comment supprimer une page sur word avec un saut de page ? - Guide
- Saut de colonne word - Guide
- Problème numérotation page word saut de section ✓ - Forum Word
- Saut de ligne html sans <br ✓ - Forum Webmastering
10 réponses
Rien ne t'empêche d'afficher les 2 valeurs avant le test;
Et puis il faut faire attention à une chose... la machine travaille en binaire, rien de surprenant mais un problème sournois se pose quand on a des décimales.
Un exemple:
10,8 en décimal c'est 10 plus exactement 4/5 mais pas en binaire... eh oui 10 c'est dix mais 0.8 ne sera qu'une approximation de sommes de 2 puissance -1, 2 puissance -2, 2 puissance -3.... (0,8 c'est 0,5 + 0,25 + 0,03125 + ...) si bien que 0.8 traduit en binaire ne sera pas exact et si l'on fait '11 - 10,8' en décimal on a un résultat approximatif de 0,2 en binaire, ce je veux dire c'est que d'approximation en approximation, on peut arriver à avoir A=1,999 et B=1,998.
Ai-je été clair?
Et puis il faut faire attention à une chose... la machine travaille en binaire, rien de surprenant mais un problème sournois se pose quand on a des décimales.
Un exemple:
10,8 en décimal c'est 10 plus exactement 4/5 mais pas en binaire... eh oui 10 c'est dix mais 0.8 ne sera qu'une approximation de sommes de 2 puissance -1, 2 puissance -2, 2 puissance -3.... (0,8 c'est 0,5 + 0,25 + 0,03125 + ...) si bien que 0.8 traduit en binaire ne sera pas exact et si l'on fait '11 - 10,8' en décimal on a un résultat approximatif de 0,2 en binaire, ce je veux dire c'est que d'approximation en approximation, on peut arriver à avoir A=1,999 et B=1,998.
Ai-je été clair?
bonjour,
moi j'aimerai bien savoir
le contenu de :
'Total_A = Somme colonne 14
Total_A = Application.WorksheetFunction.Sum(Range(Cells(5, col), Cells(i, col)))
'Total_B = Somme ligne i+1
Total_B = Application.WorksheetFunction.Sum(Range(Cells(i + 1, 2), Cells(i + 1, 13)))
est-ce que le débbogueur affiche la même valeur.
un format d'affichage pourrait masquer une différence minime mais ne remplirai pas la condition.
genre : 1.999 (2.00 affiché)
moi j'aimerai bien savoir
le contenu de :
'Total_A = Somme colonne 14
Total_A = Application.WorksheetFunction.Sum(Range(Cells(5, col), Cells(i, col)))
'Total_B = Somme ligne i+1
Total_B = Application.WorksheetFunction.Sum(Range(Cells(i + 1, 2), Cells(i + 1, 13)))
est-ce que le débbogueur affiche la même valeur.
un format d'affichage pourrait masquer une différence minime mais ne remplirai pas la condition.
genre : 1.999 (2.00 affiché)
Je n'ai pas beaucoup écrit en VBA et il y a bien longtemps.
Au lieu du code suivant:
Au lieu du code suivant:
Dim Total_A as Double Dim Total_B as Double Total_A = la première somme Total_B = la seconde somme If Total_A = Total_B Then j'écris dans ma dernière cellule Else je fais autre chose End ifJ'essaierai
Dim Total_A as Double Dim Total_B as Double Total_A = la première somme Total_B = la seconde somme Total_A = Total_B If Total_A = Total_B Then j'écris dans ma dernière cellule Else je fais autre chose End ifEvidemment 'Total_A = Total_B' parait absurde mais j'aimerai bien savoir si on passe dans le 'if' ou dans le 'else'; moi je parie pour le 'if' car j'ai plutôt confiance, par principe, dans le logiciel.
Sinon, il y a la solution utiliser en calcul scientifique. Nous ne faisons jamais de test d'égalité mais :
if valeur_absolu(A-B)<tolérance
dans ton cas, tu prends une valeur de tolérence de 0,01
if valeur_absolu(A-B)<tolérance
dans ton cas, tu prends une valeur de tolérence de 0,01
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
connait pas VBA, mais je trouve étrange que le signe d'affectation soit le même que celui de comparaison.
en C: a=b; if(a==b);
en Fortran: a=b if(a.eq.b)
en pascal: a:=b if a=b
en C: a=b; if(a==b);
en Fortran: a=b if(a.eq.b)
en pascal: a:=b if a=b
l'écritue est juste le VBA.
Le VB n'est pas aussi "stricte" ou rigoureux que pascal, C, ou python...
mais on ne fait pas la même chose non plus.
Le VB n'est pas aussi "stricte" ou rigoureux que pascal, C, ou python...
mais on ne fait pas la même chose non plus.
Waw, tant de réponses en si peu de temps !!!!!
C'est sympa, je me sens moins seul ;)
Merci à Tous
Je viens d'essayer la technique de Loupious,
c'est à dire taper
Dim Total_A as Double
Dim Total_B as Double
Total_A = la première somme
Total_B = la seconde somme
Total_A = Total_B
If Total_A = Total_B Then
j'écris dans ma dernière cellule
Else
je fais autre chose
End if
Je suis rassuré de voir que la macro rentre bien dans la If et pas dans la Else!
Ce qui prouve que la macro trouve bien deux résultats différents pour Total_A et Total_B
Cependant, voici les valeurs que j'additionne :
Total_A :
-764.78
101.42
0
0
0
0
0
0
0
0
0
0
Total_B :
0
-34.1
-3876.82
-263.2
-165.18
-19.24
-25
0
0
0
-590
315
0
-170
-34.82
700
3500
Faites donc le calcul, le résultat des deux sommes sont identiques et bien égaux à -663.63
Nul besoin d'approximation pour atteindre ce résultat.
Si VBA trouve un résultat différent, c'est qu'il ne sait pas faire une simple addition, et c'est grave!!!!
Vous trouverez ici un zip contenant 3 captures d'écran qui montrent ce que fait la macro avec en bas des images les valeurs indiquées par le débogger.
http://destmobil.neuf.fr/Pb_macro_VBA.zip
Donc, au risque de me répéter et étant donné que la macro considère que mes variables ne sont pas égales,
existe-t-il un moyen de forcer VBA à indiquer les différences entre les deux variables qui m'intéressent?
Personnellement, je suis sur le cul !!!!
Sidéré de buter sur ce problème avec des valeurs aussi simples...
Si les valeurs que j'additionne avaient une infinité de décimales, je comprendrais facilement qu'un problème d'arrondi peut arriver....
Mais là!!!!!!!!!!!!!!!!!
Je n'ai jamais plus de 2 décimales et une addition ne peut pas créer de décimales supplémentaires. C'est mathématiquement impossible!!!!
Ce serait absurde d'avoir un résultat du genre -663.62999999999999999999999 !
Bref,
Au Secouuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuurs
:o)
C'est sympa, je me sens moins seul ;)
Merci à Tous
Je viens d'essayer la technique de Loupious,
c'est à dire taper
Dim Total_A as Double
Dim Total_B as Double
Total_A = la première somme
Total_B = la seconde somme
Total_A = Total_B
If Total_A = Total_B Then
j'écris dans ma dernière cellule
Else
je fais autre chose
End if
Je suis rassuré de voir que la macro rentre bien dans la If et pas dans la Else!
Ce qui prouve que la macro trouve bien deux résultats différents pour Total_A et Total_B
Cependant, voici les valeurs que j'additionne :
Total_A :
-764.78
101.42
0
0
0
0
0
0
0
0
0
0
Total_B :
0
-34.1
-3876.82
-263.2
-165.18
-19.24
-25
0
0
0
-590
315
0
-170
-34.82
700
3500
Faites donc le calcul, le résultat des deux sommes sont identiques et bien égaux à -663.63
Nul besoin d'approximation pour atteindre ce résultat.
Si VBA trouve un résultat différent, c'est qu'il ne sait pas faire une simple addition, et c'est grave!!!!
Vous trouverez ici un zip contenant 3 captures d'écran qui montrent ce que fait la macro avec en bas des images les valeurs indiquées par le débogger.
http://destmobil.neuf.fr/Pb_macro_VBA.zip
Donc, au risque de me répéter et étant donné que la macro considère que mes variables ne sont pas égales,
existe-t-il un moyen de forcer VBA à indiquer les différences entre les deux variables qui m'intéressent?
Personnellement, je suis sur le cul !!!!
Sidéré de buter sur ce problème avec des valeurs aussi simples...
Si les valeurs que j'additionne avaient une infinité de décimales, je comprendrais facilement qu'un problème d'arrondi peut arriver....
Mais là!!!!!!!!!!!!!!!!!
Je n'ai jamais plus de 2 décimales et une addition ne peut pas créer de décimales supplémentaires. C'est mathématiquement impossible!!!!
Ce serait absurde d'avoir un résultat du genre -663.62999999999999999999999 !
Bref,
Au Secouuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuurs
:o)
Bonjour tous,
Les montants que tu donne en exemple sont-il le contenu de cellules ?
Et tes données arrivent d'un fichier texte ?
Si oui...
Quand tu met un texte -34.1 dans une cellule il n'est plus possible de le comptabilisé ni de changer le format.
Seule solution, Changer manuellement le Point par une virgule ou si beaucoup de données faire une macros pour changer le point.
Et les résultat A et B ne SONT PAS IDENTIQUE
A= -663,36000
B= -2568,12
A+
Les montants que tu donne en exemple sont-il le contenu de cellules ?
Et tes données arrivent d'un fichier texte ?
Si oui...
Quand tu met un texte -34.1 dans une cellule il n'est plus possible de le comptabilisé ni de changer le format.
Seule solution, Changer manuellement le Point par une virgule ou si beaucoup de données faire une macros pour changer le point.
Et les résultat A et B ne SONT PAS IDENTIQUE
A= -663,36000
B= -2568,12
A+
Bon et biennn,
m'est avis que Loupius tient le bon bout!
Son explication tient la route et je pense que la solution consiste à traiter le mal par le mal.
C'est à dire, que je vais immédiatement faire en sorte que mes deux variables soient quoiqu'il arrive arrondies au centième.
Ainsi, Total_A et Total_B auront forcément 2 décimales maximum et ma condition Total_A = Total_B sera alors vérifiée!
Sinon j'ai pensé à une seconde solution, multiplier toutes mes valeurs par 100, puis les additionner et enfin comparer les sommes. Je n'aurai ainsi aucun problème de décimale puisque la macro ne verra que des entiers.
Pour répondre à ta question lermite222, les valeurs que je vous ai donné sont exactement celles contenues par les cellules de mon tableau et le Point est le séparateur de décimales sur mon système et Excel les reconnaît bien en tant que valeurs et non en tant que chaînes de caractères. D'autre part, les lignes qui effectuent les additions ne plantent pas (pas d'incompatibilité de type).
Je vous tiens au courant, je pense que ce ne sera pas très long.
A tout à l'heure ;)
m'est avis que Loupius tient le bon bout!
Son explication tient la route et je pense que la solution consiste à traiter le mal par le mal.
C'est à dire, que je vais immédiatement faire en sorte que mes deux variables soient quoiqu'il arrive arrondies au centième.
Ainsi, Total_A et Total_B auront forcément 2 décimales maximum et ma condition Total_A = Total_B sera alors vérifiée!
Sinon j'ai pensé à une seconde solution, multiplier toutes mes valeurs par 100, puis les additionner et enfin comparer les sommes. Je n'aurai ainsi aucun problème de décimale puisque la macro ne verra que des entiers.
Pour répondre à ta question lermite222, les valeurs que je vous ai donné sont exactement celles contenues par les cellules de mon tableau et le Point est le séparateur de décimales sur mon système et Excel les reconnaît bien en tant que valeurs et non en tant que chaînes de caractères. D'autre part, les lignes qui effectuent les additions ne plantent pas (pas d'incompatibilité de type).
Je vous tiens au courant, je pense que ce ne sera pas très long.
A tout à l'heure ;)
Multiplier par cent est une solution tentante... mais...
Considérons le nombre 10,8, oui je sais je me répète. Supposons que ce nombre soit 10,79997 en binaire (peut-être 10,79999999999998 en fonction du nombre de bits représentant ce nombre).
Eh bien, que représente 10,8 * 100 en binaire, on peut dire sommairement: 10,79997 * 100 soit 1079,997 qui seront arrondis à 1079 et non pas à 1080. il faut donc faire (10,8 + 0,001) * 100, c'est un problème bien connu.
A méditer
Considérons le nombre 10,8, oui je sais je me répète. Supposons que ce nombre soit 10,79997 en binaire (peut-être 10,79999999999998 en fonction du nombre de bits représentant ce nombre).
Eh bien, que représente 10,8 * 100 en binaire, on peut dire sommairement: 10,79997 * 100 soit 1079,997 qui seront arrondis à 1079 et non pas à 1080. il faut donc faire (10,8 + 0,001) * 100, c'est un problème bien connu.
A méditer
Euuuuh oui.....
Donc si j'ai bien compris, en binaire, la valeur approximée est toujours légèrement inférieure à la valeur décimale d'origine.
Donc en ajoutant une valeur inférieure à 0,01 à 10,8 (pour reprendre ton exemple), on évite ainsi de se retrouver avec une valeur binaire approximée inférieure à 10,8.
10,801 vaudra en binaire approximativement 10,8009998
On peut alors tranquillement multiplier par 100
STP, dis moi si je me trompe!!!
Je suis bien content que tu ais apporté de telles explications.
J'espère les avoir bien comprises.
Donc si j'ai bien compris, en binaire, la valeur approximée est toujours légèrement inférieure à la valeur décimale d'origine.
Donc en ajoutant une valeur inférieure à 0,01 à 10,8 (pour reprendre ton exemple), on évite ainsi de se retrouver avec une valeur binaire approximée inférieure à 10,8.
10,801 vaudra en binaire approximativement 10,8009998
On peut alors tranquillement multiplier par 100
STP, dis moi si je me trompe!!!
Je suis bien content que tu ais apporté de telles explications.
J'espère les avoir bien comprises.
J'ai mis 0,001 parce que tu proposais de multiplier par cent; si on multiplie par 1000 il faut mettre moins car on risque d'avoir 1 de plus (il y a quand même des nombres décimaux qui sont justes ( par exemple 0,5 ou 0,75 ou 0,875).
Le problème n'est pas facile à résoudre, c'est une question de calcul des erreurs (du style delta(x * y) = delta (x) + delta (y).
Toutefois il est probable que l'utilisation de la fonction Round() soit satisfaisante.
A tester et bon courage.
Le problème n'est pas facile à résoudre, c'est une question de calcul des erreurs (du style delta(x * y) = delta (x) + delta (y).
Toutefois il est probable que l'utilisation de la fonction Round() soit satisfaisante.
A tester et bon courage.
YEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHH
Un grand Merci à Tous, vous avez été Super!!!!!!!
L'explication de Loupius est la bonne!!!!!!!!
Même si en apparence il n'y a aucune raison, il se peut que le résultat ne soit pas tout à fait exact à cause des approximations que fait la macro puisqu'elle travaille en binaire.
Attention aux valeurs annoncées par le débogger!!!!!
Visiblement arrondies mais pas utilisées comme telles!
3 solutions différentes pour rentrer enfin dans la If:
--- Grâce à la fonction Round utilisée juste avant d'arriver sur la If
Total_A = Round(Total_A, 2)
Total_B = Round(Total_B, 2)
Syntaxe :Round(expression [,numdecimalplaces])
--- Ou alors en multipliant par 100, mais il faut que les variables soient des Long et plus des Doubles, sinon ça ne marche pas!!!
Dim Total_A as Long
Dim Total_B as Long
Total_A = Application.WorksheetFunction.Sum(Range(Cells(5, col), Cells(i, col))) * 100
Total_B = Application.WorksheetFunction.Sum(Range(Cells(i + 1, 2), Cells(i + 1, 13))) * 100
--- Dernière solution qui fonctionne (mais c'est bizarre)
lorsque les sommes sont calculées directement par des cellules et non par la macro,
la condition Total_A = Total_B est vérifiée.
Probablement parce que les cellules arrondissent d'elle même les valeurs calculées.
Perso, je vais continuer en utilisant la fonction Round(expression, nombre de décimales)
La syntaxe est très simple et il suffit de la placer juste avant de vérifier une condition quelle qu'elle soit.
While, If
Encore une fois Merci à Tous pour votre aide ;)
A bientôt!!!
Un grand Merci à Tous, vous avez été Super!!!!!!!
L'explication de Loupius est la bonne!!!!!!!!
Même si en apparence il n'y a aucune raison, il se peut que le résultat ne soit pas tout à fait exact à cause des approximations que fait la macro puisqu'elle travaille en binaire.
Attention aux valeurs annoncées par le débogger!!!!!
Visiblement arrondies mais pas utilisées comme telles!
3 solutions différentes pour rentrer enfin dans la If:
--- Grâce à la fonction Round utilisée juste avant d'arriver sur la If
Total_A = Round(Total_A, 2)
Total_B = Round(Total_B, 2)
Syntaxe :Round(expression [,numdecimalplaces])
--- Ou alors en multipliant par 100, mais il faut que les variables soient des Long et plus des Doubles, sinon ça ne marche pas!!!
Dim Total_A as Long
Dim Total_B as Long
Total_A = Application.WorksheetFunction.Sum(Range(Cells(5, col), Cells(i, col))) * 100
Total_B = Application.WorksheetFunction.Sum(Range(Cells(i + 1, 2), Cells(i + 1, 13))) * 100
--- Dernière solution qui fonctionne (mais c'est bizarre)
lorsque les sommes sont calculées directement par des cellules et non par la macro,
la condition Total_A = Total_B est vérifiée.
Probablement parce que les cellules arrondissent d'elle même les valeurs calculées.
Perso, je vais continuer en utilisant la fonction Round(expression, nombre de décimales)
La syntaxe est très simple et il suffit de la placer juste avant de vérifier une condition quelle qu'elle soit.
While, If
Encore une fois Merci à Tous pour votre aide ;)
A bientôt!!!