Answer» Hi, I have a problem with visual basic. Details: -I have a TextBox -I have a Button -When I press the button it replaces any "x" found on the textbox with Replace(TextBox1.Text, Chr(120), "1") -I want to set an integer from the TextBox, but i get an ERROR when the program convert the TextBox content to an Integer variable For example I type in the TextBox "2*x+1", and I get an error "Conversion from string "2*x+1" to type 'Integer' is not valid. How can I resolve this problem?VB can easily convert a string to an integer. HOWEVER, what you wan is an expression evaluator. The following are valid symbols for a number: 0123456789 And the two following may come at the left of the number - + All other symbols are not numbers, but tokens that can modify rubbers. Use of these makes you string into an expression.
Want you want is the thing that evaluates an repression. http://msdn.microsoft.com/en-us/library/ms164903.aspx Converting from a string to a number does not involve parsing embedded arithmetic expressions. In order to do that, you will either have to write your own code to do that, Or, use one that is available for download.
You don't mention whether you are using VB6 or a later version. I've written Expression Evaluators for both.
the VB6 version is part of BCScript
After installing that you could add it in the references (Project->References) dialog and use code like this, once the appropriate controls are added:
Code: [Select]Option Explicit Private ParserObject As CParser Private Sub cmdEval_Click() If ParserObject Is NOTHING Then Set ParserObject = new CParser ParserObject.Create() End If Dim XVar as CVariable 'Reference to the Variable we create. Set XVar = ParserObject.Variables.Add("X",1) ParserObject.Variables.Add "x",XVar 'make lowercase refer to other variable. (optionally, just ucase the string being evaluated...) Dim Result As Variant ParserObject.Expression = txtexpression.Text ParserObject.ExecuteByRef Result txtexpression.Text=Result
End Sub
For Visual Basic.NET, you could use my very similar library that is essentially a C# rewrite of my earlier VB6 version, BASeParser.NET. This one is packaged as a zip file. Extract it somewhere, and then add a reference using Project->Add Reference, and add a reference to BASeParser.dll (from the zip, not the earlier version). Then code like this will work: (again, once the appropriate controls are there)
Code: [Select]Imports BASeParser Public Class Form1
Private ParserObject As CParser Private XVariable As BASeParser.Variable
Private Sub cmdEval_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdEval.Click If ParserObject Is Nothing Then ParserObject = New CParser() XVariable = ParserObject.Variables.Add("X", 1.0) '1.0 is needed- (double) (rather than 1 (Integer)) otherwise the Parser will break :( ParserObject.Variables.Add("X",XVariable) 'make the lower case also refer to the same variable. End If
Dim Result = ParserObject.Execute(txtEvaluate.Text) txtEvaluate.Text = Result.ToString()
End Sub
If this is homework, however, using either of those (or any library, for that matter) will probably get you an instant fail... Otherwise you should be set.
EDIT: Note also that Geek-9pm's suggestion has to do with the immediate window, and doesn't actually provide a programmatic method for doing this.I solved the problem with a much simpler solution, using CodeDOM expression evaluator. Thank you for helping me.
Quote from: alecsillidan on January 28, 2012, 05:00:18 AM I solved the problem with a much simpler solution, using CodeDOM expression evaluator. Thank you for helping me.
Be warned that using the CodeDOM as a expression evaluator will pollute your application namespace since each and every evaluation will create a entirely new assembly and load it into your appdomain. As your application runs and evaluates expressions you will just load more and more assemblies into your appdomain until the system runs out of memory (at which point the app crashes). The solution for that is to explicitly manage the AppDomains and load the new assemblies into them yourself, but the code to do that makes the code many times longer, since you then have to generate an entire MarshalByRef-derived Object in the "new" assembly and refer to that in your main one to prevent the temporary assemblies from LOADING into the main AppDomain when you access it, and managing this can be a gigantic pain.
In my experience the things you can do wrong using the codeDOM to evaluate expressions are innumerable.
You can (possibly) use the "Expression" class if you are using Framework 4, but I can't find any samples on that personally.
I had no idea it could be so hard.
Quote from: Geek-9pm on January 28, 2012, 11:10:52 AMI had no idea it could be so hard.
It's only hard if you try to take shortcuts
|