0

I'm hoping someone can help answer my question, perhaps with an idea of where to go or whether what I'm trying to do is not possible with the way I want to do it.

I've been asked to write a set of rules based on the data held by our ERP form components or variables.

Unfortunately, these components and variables cannot be accessed or used outside of the ERP, so I can't use SQL to query the values and then build some kind of SQL query.

They'd like the ability to put statements like these:

C(MyComponentName) = C(MyOtherComponentName)
V(MyVariableName) > 16
(C(MyComponentName) = "") AND V(MyVariableName) <> "")
((C(MyComponentName) = "") OR C(MyOtherComponentName) = "") AND V(MyVariableName) <> "")

This should be turned into some kind of query which gets the value of MyComponentName and MyOtherComponentName and (in this case) compares them for equality.

They don't necessarily want to just compare for equality, but to be able to determine whether a component / variable value is greaterthan or lessthan etc.

Basically it's a free-form statement that gets converted into something similar to an IF statement.

I've tried this:

Sub TestCondition()
  Dim Condition as string = String.Format("{0} = {1}", _
             Component("MyComponent").Value, Component("MyOtherComponent").Value)

  If (Condition) Then
      ' Do Something
  Else
      ' Do Something Else
  End If
End Sub

Obviously, this does not work and I honestly didn't think it would be so simple.

Ignoring the fact that I'd have to parse the line, extract the required operators, the values from components or variables (denoted by a C or V) - how can I do this?

I've looked at Expression Trees but these were confusing, especially as I'd never heard of them, let alone used them. (Is it possible to create an expression tree for dynamic if statements? - This link provided some detail on expression trees in C#)

I know an easier way to solve this might be to simply populate the form with a multitude of drop-down lists, so users pick what they want from lists or fill in a text box for a specific search criteria.

This wouldn't be a simple matter as the ERP doesn't allow you to dynamically create controls on its forms. You have to drag each component manually and would be next to useless as we'd potentially want at least 1 rule for every form we have (100+).

I'm either looking for someone to say you cannot do this the way you want to do it (with a suitable reason or suggestion as to how I could do it) that I can take to my manager or some hints, perhaps a link or 2 pointing me in the right direction.

Community
  • 1
  • 1
Arkane
  • 3
  • 3
  • Why can't you simply do: `If Component("MyComponent").Value = Component("MyOtherComponent").Value Then` ? – Tim Schmelter Jul 09 '15 at 08:29
  • Can you comment on what the input is, what test you need to perform against it, and what output you're expecting? – Andrew Mortimer Jul 09 '15 at 08:56
  • @TimSchmelter: It's meant to be dynamic. I won't know what they wish to compare before script compilation. The 'entries' they wish to query, would be stored in the ERP itself. – Arkane Jul 09 '15 at 09:23
  • @Mort: The input would be the value of the component/variable, which could be a number or string or both. The test would be whatever the user specifies based on the operator used. The output I expect would be a boolean only. Simply if equates to true, return true etc. Does this help? – Arkane Jul 09 '15 at 09:23
  • 1
    There is no easy solution for this. Short of creating your own expression parser, It should be possible to do what you need by building an expression tree dynamically, as is demonstrated by the link you provided, or you might also consider using CodeDom to dynamically compile a new assembly in memory and then execute it. – Steven Doggart Jul 09 '15 at 10:33
  • @StevenDoggart: Thank you for this. Unfortunately I think this is beyond my current abilities, either in VB .Net or C#. A case of biting off more than I can chew possibly. The expression trees do look interesting though, so might be worth persevering with them. – Arkane Jul 09 '15 at 18:00

2 Answers2

0
If (Condition) Then

This is not possible. There is no way to treat data stored in a string as code. While the above statement is valid, it won't and can't function the way you want it to. Instead, Condition will be evaluated as what it is: a string. (Anything that doesn't boil down to 0 is treated as True; see this question.)

What you are attempting borders on allowing the user to type code dynamically to get a result. I won't say this is impossible per se in VB.Net, but it is incredibly ambitious.

Instead, I would suggest clearly defining what your application can and can't do. Enumerate the operators your code will allow and build code to support each directly. For example:

Public Function TestCondition(value1 As Object, value2 As Object, op as string) As Boolean
    Select Case op
        Case "="
            Return value1 = value2
        Case "<"
            Return value1 < value2
        Case ">"
            Return value1 > value2
        Case Else
            'Error handling
    End Select
End Function

Obviously you would need to tailor the above to the types of variables you will be handling and your other specific needs, but this approach should give you a workable solution.

Community
  • 1
  • 1
Josh
  • 1,088
  • 1
  • 7
  • 16
  • I've found the [NCalc](http://ncalc.codeplex.com/) - which may do most of what I want without having to write my own syntax parser. In any case, if it works or not - will update this comment so it's helpful to others. – Arkane Jul 10 '15 at 09:14
0

For my particular requirements, using the NCalc library has enabled me to do most of what I was looking to do. Easy to work with and the documentation is quite extensive - lots of examples too.

Arkane
  • 3
  • 3