Comment évaluer la valeur d'une expression mathématique ?
Le programmeur est parfois confronté au problème consistant à devoir évaluer
une expression mathématique, simple ou complexe.
Visual Basic ne dispose pas d'une instruction ou fonction permettant
de traiter directement cette problématique.
Cependant, il y a plusieurs solutions envisageables pour résoudre ce problème:
- Utilisation du ScriptControl
- Utilisation de l'API EbExecuteLine
- Utilisation du moteur Jet
- Utilisation d'une librairie toute faite
- Ecriture de sa propre fonction d'évaluation
Chacune de ces solutions présente des avantages et des inconvénients, exposés dans la suite de cet article.
Le Script Control
A partir de Windows 98 et Windows NT, vous pouvez employer le Script Control
et sa méthode Eval qui permet d'évaluer une expression mathématique. La
première chose à faire sera donc d'ajouter une référence à celui-ci. Pour
ce faire, cliquez sur le menu "Projet/Références..." Et dans la
liste des références disponibles, sélectionnez "Microsoft ScriptControl
1.0."
Vous pouvez ensuite essayer cet exemple :
Option Explicit
Private Sub Form_Load()
Dim sc As ScriptControl Set sc = New ScriptControl
sc.Language = "VBScript" MsgBox "(4 * 9) + 4 = " & sc.Eval("(4 * 9) + 4")
Set sc = Nothing
End Sub
A noter qu'il est aussi possible d'utiliser un autre script engine que VBScript, par exemple JScript.
Pour ces différents scripting engines, une documentation très détaillée est disponible ici :
Le Script Control permet aussi de fournir de nouveaux objets, sous forme de classes. En fait, le Script Control est un contrôle extrêmement puissant, dont les possibilités dépassent de très loin ce qu'il est possible de couvrir ici.
Le lecteur intéressé pourra se référer utilement à cet article qui fournit des explications détaillées ainsi que des exemples concrets de ce qu'il est possible de faire avec ce contrôle : Exploring the Microsoft Script Control
A noter que ce composant doit être redistribué avec votre application. Le redistribuable est disponible ici : Download details : Windows Script Control
API EbExecuteLine
Une autre solution consiste à employer l'API "EbExecuteLine",
interne à Visual Basic. Cette fonction permet d'exécuter n'importe quelle
ligne de code et donc, en particulier, d'évaluer une expression numérique.
Seulement cette fonction n'est ni documentée, ni supportée par Microsoft et ne
fonctionne qu'en mode débuggage. Ajoutez à cela que le fichier VB6.dll n'est
PAS REDISTRIBUABLE. Vous ne pourrez donc utiliser cette technique que sur un
poste possédant Visual Basic. Et ce, à vos risques et périls.
Voici un exemple d'utilisation de cette fonction :
Option Explicit
Public Number1 As Long Public Number2 As Long
Private Declare Function EbExecuteLine _ Lib "vba6.dll" _ ( _ ByVal pStringToExec As Long, _ ByVal Foo1 As Long, _ ByVal Foo2 As Long, _ ByVal fCheckOnly As Long _ ) As Long
Public Function Execute(CodeLine As String, Optional CheckOnly As Boolean = False)
Execute = (EbExecuteLine(StrPtr(CodeLine), 0&, 0&, Abs(CheckOnly)) = 0)
End Function
Public Sub Main()
' Exécute : MsgBox "Ceci est un test" Call Execute("MsgBox ""Ceci est un test""") ' Exécute : Number1 = 1024 Call Execute("Number" & 1 & " = 1024") ' Exécute : Number2 = Number1 + 1024 Call Execute("Number" & 2 & " = Number" & 1 & " + 1024") ' Affiche la somme de Number1 et Number2 (soit 3072) MsgBox Number1 + Number2
End Sub
Note : les variables Number1 et Number2 doivent être déclarées en
Global afin de les rendre accessibles par l'API.
Ce code n'est valable que pour Visual Basic 6.0. Si vous
employer la version 5.0, vous devrez remplacer la déclaration de l'API par :
Private Declare Function EbExecuteLine _ Lib "vba5.dll" _ (ByVal pStringToExec As Long, _ ByVal Foo1 As Long, _ ByVal Foo2 As Long, _ ByVal fCheckOnly As Long) As Long
Enfin, le paramètre "CheckOnly" permet de spécifier s'il faut
exécuter la ligne la ligne de code ou simplement vérifier si celle-ci est
correcte.
Utilisation du moteur Jet
Cette solution est originale tout en étant extrêmement puissante et très simple à mettre en oeuvre.
Elle utilise le fait que le moteur Jet (le moteur de base de données d'Access) permet en lui même
d'évaluer des expressions mathématiques dans un simple SELECT.
Ainsi, une requête telle que : SELECT 3*4+2 FROM TABLE; retourne 14 en tant que résultat.
Pour faire fonctionner ceci, il faut simplement :
- Ajouter au projet une référence à Microsoft DAO 3.51 ou supérieur
- Créer un petit fichier texte, à mettre dans le répertoire de l'application
Le fichier texte pourra être de la forme :
"Pi";"e"
3,1415926535897932384626433832795;2,71828182845905
On peut mettre autant de valeurs que nécessaires, ces valeurs devenant accessibles depuis l'évaluateur.
Le code ensuite est extrêmement simple :
Public Function MyEval(expression As String) As Variant Dim db As Database Dim rs As Recordset
Set db = OpenDatabase(App.Path, False, True, "Text;") Set rs = db.OpenRecordset("SELECT " & expression & " FROM data.dat;") MyEval = rs(0) rs.Close db.Close Set rs = Nothing Set db = Nothing End Function
Pour appeler cette fonction, il suffit de faire (par exemple) :
Private Sub Command1_Click() Dim result As Variant
result = MyEval(Text1.Text) MsgBox result End Sub
On peut maintenant évaluer des expressions telles que:
"3*4+2", "12*Cos(Pi/2)", etc.
A noter que vous devez alors redistribuer le moteur Jet avec votre application. Toutes les informations utiles ainsi que les fichiers à télécharger sont disponibles ici : Obtenir le dernier Service Pack pour Microsoft jet
Note : Si vous utilisez une référence à Microsoft DAO 3.51, l'assistant d'empaquetage et déploiement incluera automatiquemen tous les fichiers nécessaires. Ne pas oublier d'inclure le Driver "text".
Utiliser une solution existante
Si aucune de ces solutions ne vous convient, vous pouvez toujours essayer de
chercher sur Internet une libraire "prête à l'emploi" répondant à votre
problème.
Voici quelques exemples de solutions existantes :
A noter que ces solutions sont peu coûteuses (quelques dizaines de dollars US). Certaines sont même gratuites pour une utilisation personnelle.
Vous trouverez depuis cette page de très nombreux liens présentant des solutions existantes : http://www.programurl.com/software/expression-parser.htm
Créer sa propre fonction d'évaluation
Une autre possibilité consiste à créer votre propre fonction d'évaluation. Ce n'est
pas si compliqué et constitue en soi un exercice amusant. Qui plus est, vous pourrez
alors intégrer à votre évaluateur les spécificités dont vous auriez besoin.
Un autre intérêt d'une solution "propriétaire" est que celle ci vous dispense de prendre en compte des considérations de redistribution de composants tiers. Le dernier avantage (par rapport à une solution "toute faite") est qu'en cas de soucis, vous êtes l'auteur du code et avez donc toutes les facilités pour debugger votre interpréteur.
La réalisation d'un tel interpréteur dépasse le cadre de cet article, mais un article détaillant la création d'un tel évaluateur est en préparation. Cet article sera disponible lors des prochaines mise à jour, dans la section "Algorithmique".
|