Important alert: (current site time 9/18/2014 1:18:12 AM EDT)
 

VB icon

Evaluate Formula

Email
Submitted on: 1/20/2008 11:30:06 PM
By: Taher A. Taher 
Level: Intermediate
User Rating: By 1 Users
Compatibility: VB.NET
Views: 3462
author picture
 
     This code evaluates a formula in a string and return the result for that formula in decimal. This use recursive calls to evaluate the formula. To use this sample you will need Microsoft Framework 2.0 I took this code from another post: http://www.planet-source-code.com/vb/scripts/showcode.asp?txtCodeId=1424&lngWid=10 It was so nice. I made two modifications: 1. It couldn't execute this "(15/2)+(30/3)" it could only execute formulas like "(15/2)+10". Now it can. 2. I replaced the "*" with the "x" for usability. Again, thanks to Rogério B. Villas Boas
 
code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
 
Terms of Agreement:   
By using this code, you agree to the following terms...   
  1. You may use this code in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
  2. You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
  3. You may link to this code from another website, but ONLY if it is not wrapped in a frame. 
  4. You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.
				
//**************************************
// Name: Evaluate Formula
// Description:This code evaluates a formula in a string and return the result for that formula in decimal. This use recursive calls to evaluate the formula. To use this sample you will need Microsoft Framework 2.0
I took this code from another post:
http://www.planet-source-code.com/vb/scripts/showcode.asp?txtCodeId=1424&lngWid=10
It was so nice.
I made two modifications:
1. It couldn't execute this "(15/2)+(30/3)" it could only execute formulas like "(15/2)+10". Now it can.
2. I replaced the "*" with the "x" for usability.
Again, thanks to Rogério B. Villas Boas
// By: Taher A. Taher
//
// Inputs:String
(Just call the 'ExecuteFormula' function)
//
// Returns:Decimal
//
//This code is copyrighted and has// limited warranties.Please see http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=6301&lngWId=10//for details.//**************************************

Module Core
#Region " Formula Executer "
Private Function InternalExecuteFormula(ByVal strFormula As String) As Double
Dim intPos As Integer
Dim intQtdParentesis As Long
Dim intPosParOpen As Integer
Dim intQtdParOpen As Long
Dim intPosParClose As Integer
Dim intQtdParClose As Long
Dim strFormulaTemp As String
Dim strOperator1 As String
Dim strOperator2 As String
Dim dblResultTemp As Double
'Excludes the spaces
strFormula = strFormula.Replace(" ", "")
'Excludes the digits grouping symbol
strFormula = strFormula.Replace(Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator, "")
'Prepares the negative numbers
strFormula = strFormula.Replace("+-", "+#")
strFormula = strFormula.Replace("--", "-#")
strFormula = strFormula.Replace("x-", "x#")
strFormula = strFormula.Replace("/-", "/#")
strFormula = strFormula.Replace("^-", "^#")
If strFormula.IndexOf("-") = 0 Then strFormula = "#" & strFormula.Substring(1)
'Gets the amount of opening parentesis
intQtdParOpen = 0
intPos = strFormula.IndexOf("(")
intPosParOpen = intPos
Do While intPos > -1
intQtdParOpen += 1
intPos = strFormula.IndexOf("(", intPos + 1)
Loop
'Gets the amount of closing parentesis
intQtdParClose = 0
intPos = strFormula.IndexOf(")")
intPosParClose = intPos
Do While intPos > -1
intQtdParClose += 1
intPosParClose = intPos
intPos = strFormula.IndexOf(")", intPos + 1)
Loop
'Check if the amount of parentesis are equal
If intQtdParOpen <> intQtdParClose Then
Throw New System.Exception("The amount of parentheses is different in the formula.")
End If
'Executes the formula
If intPosParOpen > -1 Then
strFormulaTemp = strFormula.Substring(intPosParOpen + 1, intPosParClose - intPosParOpen - 1)
dblResultTemp = InternalExecuteFormula(strFormulaTemp)
strFormulaTemp = strFormula.Replace("(" & strFormulaTemp & ")", dblResultTemp.ToString)
Return InternalExecuteFormula(strFormulaTemp)
ElseIf strFormula.IndexOf("+") > -1 Then
'Addition
intPos = strFormula.IndexOf("+")
strOperator1 = strFormula.Substring(0, intPos)
strOperator2 = strFormula.Substring(intPos + 1)
Return InternalExecuteFormula(strOperator1) + InternalExecuteFormula(strOperator2)
ElseIf strFormula.IndexOf("-") > -1 Then
'Subtraction
intPos = strFormula.IndexOf("-")
strOperator1 = strFormula.Substring(0, intPos)
strOperator2 = strFormula.Substring(intPos + 1)
Return InternalExecuteFormula(strOperator1) - InternalExecuteFormula(strOperator2)
ElseIf strFormula.IndexOf("x") > -1 Then
'Multiplication
intPos = strFormula.IndexOf("x")
strOperator1 = strFormula.Substring(0, intPos)
strOperator2 = strFormula.Substring(intPos + 1)
Return InternalExecuteFormula(strOperator1) * InternalExecuteFormula(strOperator2)
ElseIf strFormula.IndexOf("/") > -1 Then
'Division
intPos = strFormula.IndexOf("/")
strOperator1 = strFormula.Substring(0, intPos)
strOperator2 = strFormula.Substring(intPos + 1)
Return InternalExecuteFormula(strOperator1) / InternalExecuteFormula(strOperator2)
ElseIf strFormula.IndexOf("^") > -1 Then
'Exponentiation
intPos = strFormula.IndexOf("^")
strOperator1 = strFormula.Substring(0, intPos)
strOperator2 = strFormula.Substring(intPos + 1)
Return InternalExecuteFormula(strOperator1) ^ InternalExecuteFormula(strOperator2)
Else
'Returns the negative numbers
strFormula = strFormula.Replace("#", "-")
'Check if the value is numeric
If Not IsNumeric(strFormula) Then
Throw New System.Exception("One of the operators in the formula is not numeric.")
End If
'Returns the value
Return CDbl(strFormula)
End If
End Function
Public Function ExecuteFormula(ByVal value As String) As Decimal
'((3*4)+(5*7))-89+(3*2)
'(12+35)-89+6
'47-89+6
'-36
Dim part_text As String
Dim part_value As Decimal
Do While value.IndexOf("(") <> -1
part_text = GetFirstFullPer(value)
part_value = InternalExecuteFormula(part_text)
value = value.Replace(part_text, part_value)
Loop
Return InternalExecuteFormula(value)
End Function
Private Function GetFirstFullPer(ByVal value As String) As String
Dim i, i_Next_Open, i_Next_Close, intPosParOpen As Integer
i = value.IndexOf("(")
intPosParOpen = i
i_Next_Open = value.IndexOf("(", intPosParOpen + 1)
i_Next_Close = value.IndexOf(")", intPosParOpen + 1)
If i_Next_Close = -1 Then
Return "X"
ElseIf (i_Next_Open = -1) OrElse i_Next_Close < i_Next_Open Then
Return Strings.Mid(value, intPosParOpen + 1, i_Next_Close - intPosParOpen + 1)
Else
Return GetFirstFullPer(Strings.Right(value, value.Length - i_Next_Open))
End If
End Function
#End Region
End Module


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this code (in the Intermediate category)?
(The code with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments


 There are no comments on this submission.
 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular code, please click here instead.)
 

To post feedback, first please login.