Results 1 to 30 of 30

Thread: How Can I let a user create formulas? Can’t change a textbox 2 formula…

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    May 2002
    Posts
    230

    How Can I let a user create formulas? Can’t change a textbox 2 formula…

    I am trying to allow the user to be able to create or edit formulas used in a program. The way I have it set up is that there are different command buttons that have different variables that are used as well as buttons for each # 0-9 and + - / * and ( and ) so they build a formula and it shows it in the textbox. The thing is I am trying to test the formula but it just shows it as text. Or it will just put a 0 if I use Val(TestFormula.text) How can I turn the Textbox text into a formula. So this TestVal = “(Area + 2000)/2” turns to TestVal= (Area + 2000/2)

  2. #2

    Thread Starter
    Addicted Member
    Join Date
    May 2002
    Posts
    230
    Ok how about just this... Say you have a textbox that a user enters this text:

    (2 * 3) + 1

    How would you code a cmd button so that it will tell you the answer of 7? I just get 0 when I do val(text1.text)

  3. #3
    Fanatic Member BillBoeBaggins's Avatar
    Join Date
    Jan 2003
    Location
    in your database, dropping your tables.
    Posts
    628
    You might want to build a "Formula builder" part to your project are as an activeX control, so you can control the flow of what is entered into the formula.
    You can't far as I am aware take text from anything and insert into a variable for it to do computations on it. You can do some heavy string manipulation to decipher their formula and then control the way it is processed, but this is very difficult and time consuming. What are you trying to let them build formulas for? Is it a math program?


  4. #4

    Thread Starter
    Addicted Member
    Join Date
    May 2002
    Posts
    230
    I am making a program that is used to calculate road meterials and cost. I just wanted the people with the program to be able to add new things down the road without me having to hard code it into the program itself. Also if there ever was a change in a formula they can edit it by themself... I just thought this would be a good option for the program since the formulas aren't really that hard. But now I don't see any easy way of doing this.

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    May 2002
    Posts
    230
    here are some of the formulas:

    PrimeCoatCoverSand = SquareYards * 0.1 ' gallons
    Oil = 0.5 * SquareYards 'gallons
    Aggregate = (25 * SquareYards) / 2000 'tons
    Dirt = (CubicYards * 2800) / 2000 'tons
    Sand = (CubicYards * 3000) / 2000 'tons
    Asphalt = (CubicFeet * 145) / 2000
    Concrete = (CubicFeet * 145 / 2000)


    I wanted to be able to store the formula info into a database so if they added another item say Item2 they would be able to make the formula and then that option would show up on the options list and if they picked it then it would calculate out...

  6. #6

  7. #7

    Thread Starter
    Addicted Member
    Join Date
    May 2002
    Posts
    230
    where is the Microsoft Script Control? I looked in the list of components and don't see it. Is it under something else?

  8. #8

  9. #9

    Thread Starter
    Addicted Member
    Join Date
    May 2002
    Posts
    230
    Ok I got that to work but what if I want to use variable names in the formula.

    Like this

    Area = 25

    Text1.Text = Area * 4

    MsgBox ScriptControl1.Eval(Text1.text .Text) would = 100

    the way I have it now it gives me 0.

  10. #10

  11. #11
    New Member KingMoogle's Avatar
    Join Date
    Jan 2003
    Posts
    15
    If i understand your question right, then you could try making a function to to insert the values in for the variables you specify before evaluating the expression.

    Kind of like this:
    Code:
    Public Function setVar(expression As String, var As String, val As Double)
        Dim i As Integer
        setVar = ""
        For i = 1 To Len(expression) - Len(var) + 1
            If Mid(expression, i, Len(var)) <> var Then
                setVar = setVar + Mid(expression, i, 1)
            Else
                setVar = setVar + CStr(val)
                i = i + Len(var) - 1
            End If
        Next i
        setVar = setVar + Right(expression, Len(expression) - i + 1)
    End Function
    Then you could use the original expression, variable name, and variable value for the arguments "expression", "var", and "val" respectively, and evaluate what it returns. (or use it again for multiple variables)
    Last edited by KingMoogle; Jan 27th, 2003 at 11:59 PM.

  12. #12

    Thread Starter
    Addicted Member
    Join Date
    May 2002
    Posts
    230
    What I am trying to do is this:

    A person enters in (this will always change)
    Length
    Width
    Depth

    From these values I can get:

    SquareFeet = Length * Width
    CubicFeet = Length * Width * Depth
    SquareYards = SquareFeet / 9
    CubicYards = CubicFeet / 27

    I want to be able to enter in the value of these into a formula that the user creates.

    So how I find out how much dirt is needed for the Area you would use this formula:

    Dirt = (CubicYards *2800) / 2000

    This would give you that amount in tons

    So I want a user to be able to enter in a new Item like Dirt and write the formula for it and it would be saved in a database.

    I just can’t get the variables to work… It saves the formula correct but it puts “ “ around it. Or if I use the ScriptControl1.Eval(Text1.Text) it only works with numbers. It will not calculate the value of SquareFeet or any other variable it gives them a 0.
    So the Dirt formula would calculate out like this (0 *2800) / 2000
    I attached the file that I just started on so maybe that will help show what I am talking about…
    Attached Files Attached Files

  13. #13

    Thread Starter
    Addicted Member
    Join Date
    May 2002
    Posts
    230
    Just a note... For the testing I just put in the values of CubicYards, CubicFeet ect in the code... No L x W x D on this yet... that was 2 come after I got this to work.

  14. #14
    New Member KingMoogle's Avatar
    Join Date
    Jan 2003
    Posts
    15
    If your only problem is geting the variables to work right with it, then the function i posted earlier could be used as in the attachment on this post.

    If that's not the problem though, then i'm unclear as to your problem.

    (BTW, why does it keep making me add the Script control every time i open the file?)
    Attached Files Attached Files

  15. #15
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    I would suggest U write Ur own "Evaluate" function. It is easier to manage and debug.

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  16. #16
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    An example. Have a command button name "Command1" and text box named "Text1". This code does not have any Error Handling code. Step through (F8) the code to see how this code works

    VB Code:
    1. Private Type MyVariables
    2.     strVarName As String * 10
    3.     lngVarValue As Double
    4. End Type
    5.  
    6. Dim myVar() As MyVariables
    7.  
    8. 'We use a ByRef argument so that we can return the
    9. 'new variable's name as well in addition to the
    10. 'result of the Evaluation
    11. Private Function Evaluate(strExpression As String, ByRef LeftHandSide As String) As Double
    12. Dim tmpString() As String
    13. Dim LHS As String, RHS As String
    14. Dim RHSBegin As Long
    15. Dim lngLoop As Long
    16. Dim tmpResult As Double
    17.  
    18. 'Find out where in the Expression the Right Hand Side begins
    19. RHSBegin = InStr(1, strExpression, "=", vbBinaryCompare)
    20.  
    21. 'Sperate the Left Hand Side and Right Hand Side
    22. LHS = Trim(Mid(strExpression, 1, RHSBegin - 1))
    23. RHS = Trim(Mid(strExpression, RHSBegin))
    24.  
    25. 'Split the RHS into blocks separated by
    26. 'a space
    27. tmpString = Split(RHS, " ", -1, vbBinaryCompare)
    28.  
    29. 'First take the second value (the first value
    30. 'is the = sign) in the RHS and
    31. 'assign it to the temorary result
    32.  
    33. tmpResult = Assign_Values_for_Variables(tmpString(LBound(tmpString) + 1))
    34.  
    35. 'Do a loop from the third element to perform the evaluation
    36. 'If we encounter a Variable like "SqFt"
    37. 'then we take the value from the array
    38. 'which we have populated earlier by calling
    39. 'the Assign_Values_for_Variables function
    40.  
    41. For lngLoop = LBound(tmpString) + 2 To UBound(tmpString)
    42.     Select Case tmpString(lngLoop)
    43.         Case Is = "+"
    44.             tmpResult = tmpResult + CDbl(Assign_Values_for_Variables(tmpString(lngLoop + 1)))
    45.             lngLoop = lngLoop + 1
    46.         Case Is = "-"
    47.             tmpResult = tmpResult - CDbl(Assign_Values_for_Variables(tmpString(lngLoop + 1)))
    48.             lngLoop = lngLoop + 1
    49.         Case Is = "*"
    50.             tmpResult = tmpResult * CDbl(Assign_Values_for_Variables(tmpString(lngLoop + 1)))
    51.             lngLoop = lngLoop + 1
    52.         Case Is = "/"
    53.             tmpResult = tmpResult / CDbl(Assign_Values_for_Variables(tmpString(lngLoop + 1)))
    54.             lngLoop = lngLoop + 1
    55.     End Select
    56. Next lngLoop
    57.  
    58. LeftHandSide = LHS
    59. Evaluate = tmpResult
    60. tmpResult = 0
    61. LHS = ""
    62. End Function
    63.  
    64. Private Function Assign_Values_for_Variables(uVariable As String) As Double
    65. Select Case uVariable
    66.         Case Is = "SqFt"
    67.             Assign_Values_for_Variables = myVar(3).lngVarValue
    68.         Case Is = "CubicFt"
    69.             Assign_Values_for_Variables = myVar(4).lngVarValue
    70.         Case Is = "SqYd"
    71.             Assign_Values_for_Variables = myVar(5).lngVarValue
    72.         Case Is = "CubicYd"
    73.             Assign_Values_for_Variables = myVar(6).lngVarValue
    74.         Case Else
    75.             If IsNumeric(uVariable) Then
    76.                 Assign_Values_for_Variables = CDbl(uVariable)
    77.             Else
    78.                 MsgBox "Handle  exceptions here"
    79.             End If
    80. End Select
    81. End Function
    82.  
    83. Private Sub Assign_And_Calculate_Area(Length As Long, Width As Long, Depth As Long)
    84. 'Assign Length, Width & Depth
    85. 'and calculate Areas using the following formulae
    86. 'SquareFeet = Length * Width
    87. 'CubicFeet = Length * Width * Depth
    88. 'SquareYards = SquareFeet / 9
    89. 'CubicYards = CubicFeet / 27
    90.  
    91. myVar(0).lngVarValue = Length
    92. myVar(1).lngVarValue = Width
    93. myVar(2).lngVarValue = Depth
    94.  
    95. 'Calculate and store Sq Feet
    96. myVar(3).lngVarValue = myVar(0).lngVarValue * myVar(1).lngVarValue
    97. 'Calculate and store Cubic Feet
    98. myVar(4).lngVarValue = myVar(0).lngVarValue * myVar(1).lngVarValue * myVar(2).lngVarValue
    99. 'Calculate and store Sq Yards
    100. myVar(5).lngVarValue = myVar(3).lngVarValue / 9
    101. 'Calculate and store Cubic Yards
    102. myVar(6).lngVarValue = myVar(4).lngVarValue / 27
    103.  
    104. End Sub
    105.  
    106. Private Sub Command1_Click()
    107. Dim NewVar As String
    108. Dim EquationResult As Double
    109.  
    110. Assign_And_Calculate_Area 100, 50, 25
    111.  
    112. Text1.Text = "Dirt = CubicFt * 2800 / 2000"
    113. EquationResult = Evaluate(Text1.Text, NewVar)
    114. MsgBox NewVar & " = " & EquationResult
    115. End Sub
    116.  
    117. Private Sub Form_Load()
    118. 'load and assign the variable names
    119. ReDim myVar(6) As MyVariables
    120.     myVar(0).strVarName = "Length"
    121.     myVar(1).strVarName = "Width"
    122.     myVar(2).strVarName = "Depth"
    123.     myVar(3).strVarName = "SqFt"
    124.     myVar(4).strVarName = "CubicFt"
    125.     myVar(5).strVarName = "SqYd"
    126.     myVar(6).strVarName = "CubicYd"
    127. End Sub

    HTH

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  17. #17
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    take a look here

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  18. #18
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    Tsur, the attachment here is the form U posted in the other thread. It works ok, I don't get any error except when brackets are used. I shall keep u posted on any progress made.

    regards

    kayjay
    Attached Files Attached Files

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  19. #19
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    I have updated the Class Module here

    U should be able to use brackets as well now.

    HTH

    Regards KayJay

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  20. #20
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687
    Don't give up on the Script Control just yet..... I use it in our app to let the user build some extremely complex formulas. The trick is in how the functions get built. The Script Control has Code modules that you can add code to and then execute. Two words of warning... the code has to be added, there's no way to save/load directly to a file (you would have to do that yourself) And 2, it uses VBScript, so there are somethings that are not available, like the IIF function....

    Here's what you do, build a string that has all of the code, incl any constants, and functions you want to use.
    so that it looks something like this:
    VB Code:
    1. function CalcSqrFeet(Length, Width)
    2.   CalcSqrFeet= Length * Width
    3. end function
    4.  
    5. function CalcCubicFeet(Length, Width, Depth)
    6.   CalcCubicFeet = Length * Width * Depth
    7. end function
    8.  
    9. function CalcSquareYards(SquareFeet)
    10.   CalcSquareYards = SquareFeet / 9
    11. end function
    12.  
    13. function CalcCubicYards(CubicFeet)
    14.   CalcCubicYards = CubicFeet / 27
    15. end function

    Then, using the Script Control, create a CodeModule, give it what ever name you want (maybe "AreaFunctions").
    Then Add the string as the CodeModule's code.
    VB Code:
    1. mobjScript.Modules("AreaFunctions").AddCode strFunctions
    Then when you want to calculate the functions, run the Eval method, passing in the name of the function you want to run:
    VB Code:
    1. dblRetValue = mobjScript.Modules("AreaFunctions").Eval("CalcSqrFeet")
    You'll need to do a bit of checking to find out how to pass in parameters (I think it's just an array passed in after the function name) as I don't do that in my code.
    Hope this helps
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  21. #21
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    Did not know that was possible with the Script control.

    Thanx for the info.

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  22. #22
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687
    And once you've "loaded" the VBCode into a CodeModule, as long as you don't destroy the object, the formulas will remain there, to be used over and over and over again......
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  23. #23
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    Tsur:

    Check the attached form. Its the one U had atached earlier. I have changed it to use the Class Module.

    HTH

    Regards

    KayJay
    Attached Files Attached Files

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  24. #24
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    Originally posted by techgnome
    Don't give up on the Script Control just yet..... I use it in our app to let the user build some extremely complex formulas. The trick is in how the functions get built. The Script Control has Code modules that you can add code to and then execute. Two words of warning... the code has to be added, there's no way to save/load directly to a file (you would have to do that yourself) And 2, it uses VBScript, so there are somethings that are not available, like the IIF function....

    Here's what you do, build a string that has all of the code, incl any constants, and functions you want to use.
    so that it looks something like this:
    VB Code:
    1. function CalcSqrFeet(Length, Width)
    2.   CalcSqrFeet= Length * Width
    3. end function
    4.  
    5. function CalcCubicFeet(Length, Width, Depth)
    6.   CalcCubicFeet = Length * Width * Depth
    7. end function
    8.  
    9. function CalcSquareYards(SquareFeet)
    10.   CalcSquareYards = SquareFeet / 9
    11. end function
    12.  
    13. function CalcCubicYards(CubicFeet)
    14.   CalcCubicYards = CubicFeet / 27
    15. end function

    Then, using the Script Control, create a CodeModule, give it what ever name you want (maybe "AreaFunctions").
    Then Add the string as the CodeModule's code.
    VB Code:
    1. mobjScript.Modules("AreaFunctions").AddCode strFunctions
    Then when you want to calculate the functions, run the Eval method, passing in the name of the function you want to run:
    VB Code:
    1. dblRetValue = mobjScript.Modules("AreaFunctions").Eval("CalcSqrFeet")
    You'll need to do a bit of checking to find out how to pass in parameters (I think it's just an array passed in after the function name) as I don't do that in my code.
    Hope this helps
    I did a little bit of research on the Scripting Control. You were right. It really is quite extendable, though being VB Script, there are some restrictions. The best of all its functionalities is its ExecuteStatement method. Here is a sample of what it can do.

    Required; a Scripting control, named "SC", a TextBox, "Text1" with its Multiline property set to "True", copy the attached text file into the application's path, a command button "Command1" and paste the following code
    VB Code:
    1. Private Sub Command1_Click()
    2. Dim result
    3. SC.AddCode Text1.Text
    4. 'Execute a Function
    5. result = SC.Run("Avg", "10,2,51,89,48")
    6. MsgBox result
    7.  
    8. 'Assign the result to a variable in the script
    9. SC.ExecuteStatement ("SomeVar = " & result)
    10. 'Display the script's variable's value
    11. MsgBox SC.Run("GetSomeVar")
    12. 'Change that variable's value from this code
    13. SC.ExecuteStatement ("Call SetSomeVar(1024)")
    14. 'Verify that it has actually changed in the Script
    15. MsgBox SC.Run("GetSomeVar")
    16.  
    17. 'Use the new value to assign a value to another variable
    18. SC.ExecuteStatement ("Call SetSomeOtherVar(GetSomeVar + 6)")
    19. 'Display the value of the Script's second variable
    20. MsgBox SC.Run("GetSomeOtherVar")
    21.  
    22. 'Perform separate operations on the two variables
    23. SC.ExecuteStatement "SomeVar = CalcOnVar(GetSomeOtherVar)"
    24. SC.ExecuteStatement "Msgbox DoWorkOnVar(GetSomeVar)"
    25. End Sub
    26.  
    27. Private Sub Form_Load()
    28. Dim strCode As String
    29. Open App.Path & "\SCRIPTS.TXT" For Binary As #1
    30.     strCode = Space(LOF(1))
    31.     strCode = Input(LOF(1), 1)
    32. Close #1
    33. Text1.Text = strCode
    34. End Sub
    Attached Files Attached Files

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  25. #25
    Lively Member neodatatype's Avatar
    Join Date
    Aug 2002
    Location
    Italy
    Posts
    103

    Re: How Can I let a user create formulas? Can’t change a textbox 2 formula…

    I am trying to allow the user to be able to create or edit formulas used in a program.
    Use a math parser.

    Use MY math parser

    you find it in signature, it's flexible and faster than Microsoft Script Control
    > NeoDataType.net <

    Try my Free .Net Reporting Tool!

  26. #26
    Frenzied Member dis1411's Avatar
    Join Date
    Mar 2001
    Posts
    1,048
    Originally posted by TSur
    Ok I got that to work but what if I want to use variable names in the formula.

    Like this

    Area = 25

    Text1.Text = Area * 4

    MsgBox ScriptControl1.Eval(Text1.text .Text) would = 100

    the way I have it now it gives me 0.
    didn't read the rest but seems like
    VB Code:
    1. Text1.Text = Area & " * 4"
    would work

  27. #27
    Frenzied Member
    Join Date
    Aug 2000
    Location
    O!
    Posts
    1,177
    Originally posted by TSur
    Ok how about just this... Say you have a textbox that a user enters this text:

    (2 * 3) + 1

    How would you code a cmd button so that it will tell you the answer of 7? I just get 0 when I do val(text1.text)
    The attached demo app will do that for you. It is actually an example of LALR parsing. It has no look ahead capability at the moment. I may get around to adding it one of these days.
    Attached Files Attached Files

  28. #28
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687
    Originally posted by KayJay
    I did a little bit of research on the Scripting Control. You were right. It really is quite extendable, though being VB Script, there are some restrictions. The best of all its functionalities is its ExecuteStatement method.
    Was there any doubt.

    We use this method in our product, where we let the user build formulas (using a set of menus and a grid) then at run-time, convert the data into a VBScript that we then stuff into the script control. The biggest limitation is that because it is VBScript (but you can load other languages, but I have not been able to figure out how - I think the method is LoadLanguage, or something like that) it doesn't have IIF... but you can build your own and add it if you need it.

    TG
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  29. #29
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    Was there any doubt.
    None at all. Most certainly not after a liitle more than a full year

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  30. #30
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687
    Originally posted by KayJay
    None at all. Most certainly not after a liitle more than a full year
    Oh my fork... has it been that long?

    Sometimes seems like it's been longer than that.

    TG
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width