Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2019 Problème calcul % sur calculatrice

  • Initiateur de la discussion Initiateur de la discussion Nathe
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Nathe

XLDnaute Junior
Bonjour à toutes et tous,

Je suis en train d'essayer de monter un projet calculatrice sur excel mais je peine sur l'adaptation du calcul du pourcentage,
Si une personne saurai comment effectué le code qui irai bien.

Merci à tous
Nathe

 

Pièces jointes

Bon alors
Bonjour @Nathe , @jurassic pork,@rheeem,etc...
j'ai repris le truc 5 minutes afin de réduire le code de réduction (développement)de l'operation avec des parenthèses en veux tu en voilà
c'est devenu un code tout simple
Pour afficher ce contenu, nous aurons besoin de votre consentement pour définir des cookies tiers.
Pour plus d'informations, consultez notre page sur les cookies.
je livre le userform d'essai
je pense que c'est une bonne base pour pouvoir travailler après sur les règles de priorité(unfois qu'il n'y a plus ces parenthèses

patrick
 

Pièces jointes

Bonjour,
Merci pour votre persévérance, toutefois j'ai essayé à plusieurs reprise, votre est presque juste, mais merci pour votre travail.

L'affichage de l'ordre d’évaluation de cette expression n'est pas correcte, c'est l'expression (45x2.8) qui doit être evaluer en premier ,
Regarde dans code que j'ai fourni dans un poste précédent
En plus le code calcule correctement le % :
20+10+30%
Donc affiche 39
 
Dernière édition:
Hello,
je suis en train d'étudier Lex yacc qui sont des outils utiles si vous voulez créer un compilateur, un transpiler ou si vous voulez simplement interpréter un langage formel. On part de deux fichiers de description :
1 fichier de description des jetons (.lex) qui sont spécifiés par des expressions régulières :
exemple (partie) :
C#:
Eol             (\r\n?|\n)
NotWh           [^ \t\r\n]
Space           [ \t]
Digit   [0-9]
Integer {Digit}+
Ndigit  (\-)?{Digit}+
Float      {Digit}+(\.){Digit}+
Exponent ({Digit}+|{Float}+)(E|e){Ndigit}+
OpPlus            \+
OpMinus            \-
OpMult            \*
OpDiv            \/
OpMod           \%
POpen            \(
PClose            \)
et un fichier de description de la grammaire (.y)
exemple (partie) :
C#:
%token INTEGER, FLOAT, OP_PLUS, OP_MINUS, OP_MULT, OP_DIV, OP_MOD, P_OPEN, P_CLOSE

%%

line   : exp                            { Console.WriteLine("result is {0}\n", $1.n);}
       ;

exp    : term                           { $$.n = $1.n;            Console.WriteLine("Rule -> exp: {0}", $1.n); }
       | exp OP_PLUS term               { $$.n = $1.n + $3.n;    Console.WriteLine("Rule -> exp: {0} + {1}", $1.n, $3.n); }
       | exp OP_MINUS term              { $$.n = $1.n - $3.n;    Console.WriteLine("Rule -> exp: {0} - {1}", $1.n, $3.n); }
       ;

term   : factor                            {$$.n = $1.n;            Console.WriteLine("Rule -> term: {0}", $1.n); }
       | term OP_MULT factor            {$$.n = $1.n * $3.n;    Console.WriteLine("Rule -> term: {0} * {1}", $1.n, $3.n); }
       | term OP_DIV factor             {$$.n = $1.n / $3.n;    Console.WriteLine("Rule -> term: {0} / {1}", $1.n, $3.n); }
       ;

factor : float                          {$$.n = $1.n;            Console.WriteLine("Rule -> factor: {0}", $1.n); }
       | P_OPEN exp P_CLOSE             {$$.n = $2.n;            Console.WriteLine("Rule -> factor: ( {0} )", $3.n);}
       ;

number :
       | NUMBER                            { Console.WriteLine("Rule -> number: {0}", $1.n); }
       ;
float  :
       | FLOAT                            { Console.WriteLine("Rule -> float: {0}", $1.n); }
       ;
Les deux fichiers dans un premier temps vont être compilés et générer des fichiers source du langage ( dans mon cas c'est du dotnet) dans lequel on doit faire l'analyse d'une ligne source (équivalent existe en python, java, c mais pas en vba) .

Voici ce que j'obtiens en mettant comme source :
Code:
(45.0*2.8)/((1.0*1.04)/(0.8*(1.1-0.3)))

je ne maîtrise pas encore tout (par exemple je ne sais pas pour l'instant mixer des entiers et des flottants , c'est pour cela que ma ligne
source n'est composée que de flottants.

Ami calmant, J.P
 
Dernière édition:
re
Bonjour @jurassic pork tu m'a l'air bien parti
moi je cherche la logique vba pour mettre des parenthèses en fonction des priorités
par exemple j'ai "3*2*8*2"
et je dois lui mettre les parenthèses en fonction des priorités
pour pouvoir la repasser par mon moteur html
une ébauche
VB:
Sub test()
    chaine = "3*2*8*2"
    chaine = Replace(chaine, "*", "|*")
     Do While InStr(chaine, "*") > 0
      t = Split(chaine, "|")
     For i = 1 To UBound(t)
            If InStr(t(i), "*") Then t(i - 1) = "(" & t(i - 1):  t(i - 1) = t(i - 1) & Replace(t(i), "*", "x") & ")": t(i) = "": Exit For
        Next
        chaine = Replace(Join(t, ""), "*", "|*")
   Debug.Print chaine
   Loop
MsgBox chaine
End Sub
resultat dans la console

(3x2)|*8|*2
((3x2)x8)|*2
(((3x2)x8)x2)
ca me parait bon vous me direz
 
allez plus compliqué dites moi si les parenthèses dans la console sont bien représentatives des priorités
VB:
Sub test()
    chaine = "3*2*8+10*2-4*2"
    Debug.Print chaine
    Debug.Print "--------------------"
    For Each elem In Array("+", "-", "*", "/"): chaine = Replace(chaine, elem, "|" & elem): Next
    Do While InStr(chaine, "*") > 0
        t = Split(chaine, "|")
        For i = 1 To UBound(t)
            If InStr(t(i), "*") Then t(i - 1) = "(" & t(i - 1): t(i - 1) = t(i - 1) & Replace(t(i), "*", "x") & ")": t(i) = "": Exit For
        Next
        chaine = Replace(Replace(Replace(Join(t, ""), "*", "|*"), "+", "|+"), "-", "|-")
        Debug.Print chaine
    Loop
    chaine = Replace(Replace(chaine, "(|+", "+("), "(|-", "-(")
    Debug.Print chaine
    MsgBox chaine
End Sub
la console
3*2*8+10*2-4*2
--------------------
(3x2)|*8|+10|*2|-4|*2
((3x2)x8)|+10|*2|-4|*2
((3x2)x8)(|+10x2)|-4|*2
((3x2)x8)(|+10x2)(|-4x2)
((3x2)x8)+(10x2)-(4x2)
si c'est bon je compile ça en fonction au propre
 
3*2*8+10*2-4*2
--------------------
(3x2)|*8|+10|*2|-4|*2
((3x2)x8)|+10|*2|-4|*2
((3x2)x8)(|+10x2)|-4|*2
((3x2)x8)(|+10x2)(|-4x2)
((3x2)x8)+(10x2)-(4x2)

si c'est bon je compile ça en fonction au propre
Hello Patrick,
j'ai soumis ton expression à mon analyseur, apparemment on arrive au même résultat :
 
Bonjour @jurassic pork
bon on est bons alors
maintenant on essaie une division dans le lot
VB:
Sub test()
    chaine = "3*2*8*4.5+10/1.5*2-4*2"
    Debug.Print chaine
    Debug.Print "--------------------"
    For Each elem In Array("+", "-", "*", "/"): chaine = Replace(chaine, elem, "|" & elem): Next
    Do While InStr(chaine, "*") > 0
        t = Split(chaine, "|")
        For i = 1 To UBound(t)
            If InStr(t(i), "*") Then t(i - 1) = "(" & t(i - 1): t(i - 1) = t(i - 1) & Replace(t(i), "*", "x") & ")": t(i) = "": Exit For
        Next
        chaine = Replace(Replace(Replace(Replace(Join(t, ""), "*", "|*"), "+", "|+"), "-", "|-"), "/", "|/")
        Debug.Print chaine
    Loop
    chaine = Replace(Replace(Replace(chaine, "(|+", "+("), "(|-", "-("), "(|/", "/(")
    chaine = Replace(chaine, "|", "")
    Debug.Print chaine
    MsgBox chaine
End Sub
resultat dans la console
3*2*8*4.5+10/1.5*2-4*2
--------------------
(3x2)|*8|*4.5|+10|/1.5|*2|-4|*2
((3x2)x8)|*4.5|+10|/1.5|*2|-4|*2
(((3x2)x8)x4.5)|+10|/1.5|*2|-4|*2
(((3x2)x8)x4.5)|+10(|/1.5x2)|-4|*2
(((3x2)x8)x4.5)|+10(|/1.5x2)(|-4x2)
(((3x2)x8)x4.5)+10/(1.5x2)-(4x2)
c'est bon ou il faut faire comme pour "X"
 
J'ai soumis les expressions à mon analyseur :
expression de départ résultat : 221,333333333333
dernière expression console résultat : 211,333333333333
si tu veux voir les décompositions des 2 expressions dis moi le
 
Dernière édition:
re j'ai fini par trouver mon astuce
VB:
Sub test()
    chaine = "3*2*8*4.5+10/1.5*2-4*2"
    Debug.Print chaine
    Debug.Print "--------------------"
    Debug.Print PutPrioritySegment(chaine)
End Sub
Function PutPrioritySegment(chaine)
    Dim elem, i&, t
    For Each elem In Array("+", "-", "*", "/"): chaine = Replace(chaine, elem, "|" & elem): Next
    chaine = Replace(chaine, "/", "*/")
    Do While InStr(chaine, "*") > 0
        t = Split(chaine, "|")
        For i = 1 To UBound(t)
            If InStr(t(i), "*") Then t(i - 1) = "(" & t(i - 1): t(i - 1) = t(i - 1) & Replace(t(i), "*", "x") & ")": t(i) = "": Exit For
        Next
        chaine = Replace(Replace(Replace(Replace(Join(t, ""), "*", "|*"), "+", "|+"), "-", "|-"), ":", "|:")
        Debug.Print chaine
    Loop
    chaine = Replace(Replace(Replace(chaine, "(|+", "+("), "(|-", "-("), "(|:", "/(")
    chaine = Replace(chaine, "(+", "+(")
    chaine = Replace(chaine, "x/", "/")
    chaine = Replace(chaine, "|", "")
    PutPrioritySegment = chaine
End Function





 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
17
Affichages
802
Réponses
9
Affichages
345
  • Question Question
Microsoft 365 Formulaire
Réponses
2
Affichages
117
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…