我需要在VBA中评估字符串布尔表达式,例如:" 1和(0或0或1)" (这应评估为" 1"。)
我正在寻找像Python" eval"功能。使用VBA有一种简单的方法吗?谢谢!
答案 0 :(得分:0)
您可以调用.Eval()
ActiveX的ScriptControl
方法以避免任何字符串预处理:
Sub TestEvaluateExpression()
Dim varResult As Variant
Dim strEvalContent As String
strEvalContent = "1 and (0 or 0 or 1)"
varResult = Eval(strEvalContent)
MsgBox varResult
End Sub
Function Eval(strEvalContent As String) As Variant
With CreateObject("ScriptControl")
.Language = "VBScript"
Eval = .Eval(strEvalContent)
End With
End Function
答案 1 :(得分:0)
除了omegastripes的回答,请注意脚本控制是32位。随着64位成为常态,我不愿意使用任何只有32位的解决方案。
对于64位脚本控制选项,请参阅:
Microsoft Script Control 64 bit?
但这仍然是一个尴尬的解决方案,我不会推荐它。它要求用户安装新的DLL,并要求VBA程序员调用JavaScript,即使JS确实具有相对安全的“eval”功能。从安全角度来看,这可能不是最佳方法,并且由于Microsoft没有64位版本,因此不推荐使用32位版本,或者至少弃用。
以下是我更喜欢的其他一些方法:
How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops
但是,RegEx在字符串方面的效果要比使用数字方式好得多。 (如果你想将它与数字一起使用,那么你可以尝试类似于我在下面演示的内容,即单独进行数字评估。)
添加图层的最简单建议是将每个短数字表达式括在括号中并在传递之前对其进行评估。下面,我展示了一个简单的例子来评估这些括号内的表达式(在本例中为“[[”和“]]”),因此用户可以将自定义表达式写为“[[(20>(15+) 1))]]和([[7> 2]]或[[5 = 4]])“。
因此,=BacketEval("[[(20 > (15+1) )]] AND ([[7>2]] OR [[5=4]])")
只会将其简化为“(True)AND(True或False)”,您可以将其插入到布尔解析器中。类似的方法适用于其他解析器。
Function BracketEval(BoolExp As String, Optional OpenBracket = "[[", Optional CloseBracket = "]]") As String
Dim BoolStartPos As Integer
Dim BoolEndPos As Integer
Dim BoolToEval As String
Dim BoolEvaled As String
BoolStartPos = InStr(BoolExp, OpenBracket)
BracketEval = BoolExp
Do While BoolStartPos <> 0
BoolEndPos = InStr(BoolStartPos + 1, BracketEval, CloseBracket)
BoolToEval = Mid(BracketEval, BoolStartPos + Len(OpenBracket), BoolEndPos - BoolStartPos - Len(CloseBracket))
BoolEvaled = CStr(Application.Evaluate(BoolToEval))
BracketEval = Left(BracketEval, BoolStartPos - 1) _
& BoolEvaled _
& Right(BracketEval, Len(BracketEval) - BoolEndPos - Len(CloseBracket) + 1)
BoolStartPos = InStr(BoolStartPos + Len(OpenBracket) - 1, BracketEval, OpenBracket)
Loop
End Function
一个完整的解析器,甚至是一个可以为VBA风格的表达式添加括号的解析器,超出了我想要的范围,已经是一个冗长的(虽然不是很受欢迎!)的答案,这太复杂了,虽然我已经涉足过那些。
这里提出了一些不寻常的解决方案:
Evaluate Excel VBA boolean condition (not a formula)
其中最好的是:
你也可以:
对于某些人来说,下面可能是最快和最优雅的答案,特别是如果你想使用更快的引擎来淘汰其中一些:
从那里开始,可用的选择在质量上有所下降。
如果您只有几个要评估的表达式,并且它们是静态的,那么您可以将它们转换为标准的Excel电子表格语言。但是如果你想说接受用户的表达式,那么要求他们使用Excel在其常规函数语言中使用的笨拙的括号AND,OR和NOT是非常笨拙的。 VBA自己对表达式的评估看起来很正常,但是VBA不能轻易地将代码作为字符串传递给自己(这通常是一件好事)。
答案 2 :(得分:0)
请参阅 stdVBA
项目的 stdLambda
:
Debug.Print stdLambda.Create("1 and (0 or 0 or 1)").Run '=> True
通常您会传入有效参数而不是实际创建字符串,例如
set lambda = stdLambda.Create("$1.a and ($1.b < 10 or $1.c < 10 or $1.d < 100)")
Debug.Print lambda.Run(myObj)