用VBA计算字符串布尔表达式 [英] Evaluate a string boolean expression with VBA

查看:22
本文介绍了用VBA计算字符串布尔表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在VBA中计算一个字符串布尔表达式,例如:"1 and(0 Or 0 Or 1)" (计算结果应为"1"。)

我正在寻找类似于Python"val"函数的东西。有没有一种使用VBA实现这一点的简单方法?谢谢!

推荐答案

除了omegastripe的回答之外,请注意脚本控制是32位的。随着64位成为标准,我将不愿使用任何仅为32位的解决方案。

有关64位脚本控件替代方案,请参阅:

Microsoft Script Control 64 bit?

但这仍然是一个尴尬的解决方案,我不建议这样做。它要求用户安装一个新的DLL,并要求VBA程序员调用JavaScript,即使JS确实有一个相对安全的"val"函数。从安全角度来看,这可能不是最好的方法,而且由于Microsoft没有64位版本,32位版本已被弃用,或者至少已弃用。

以下是我更喜欢的一些其他方法:

  1. 更喜欢使用RegEx:

How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops

但是,RegEx处理字符串要比处理数字好得多。(如果您想对数字使用它,那么您可以尝试类似于我下面演示的方法,即分别进行数字计算。)

  1. 使用处理布尔表达式的VBA脚本,例如this one用于来自Ashley Harris的搜索字符串。Harris的函数适用于文本或纯布尔值(带有True和False的表达式)。如果您需要计算数字,则必须尝试其他方法,或添加一个层。

我添加一个层的最简单建议是将每个短数表达式放在方括号中,并在传递之前对其求值。下面,我展示了一个计算这种方括号内的表达式的简单示例(在本例中为"[["and"]]""),因此用户可以将其自定义表达式编写为类似于"[[(20>(15+1)]AND([[7>2]OR[[5=4]])。

因此,=BacketEval("[[(20 > (15+1) )]] AND ([[7>2]] OR [[5=4]])")只是将其简化为"(True)and(True Or 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风格的表达式添加括号的解析器,已经超出了我想要的范围(尽管不是很欣赏!)答案,这太复杂了,尽管我已经试过了。

Harris的布尔解析器是我见过的最好的VBA解析器,非常聪明,但请注意,如果它不喜欢输入,它可能会冻结。在他的软件的the page处,我添加了一些关于如何避免这种情况的评论:基本上,添加一个计数器,如果它运行得太高,则退出。

接下来,这里提供了一些不同寻常的布尔解析解决方案:

Evaluate Excel VBA boolean condition (not a formula)

其中最好的是:

  1. 如果安装了Access,则通过Access对象在VBA中计算表达式。如果您只需要计算几个表达式,并且知道用户将具有访问权限,则这是一个漂亮而简单的解决方案。

您还可以:

  1. Create an Internet Explorer browser object,并通过JavaScript计算布尔值。再说一次,也许不是非常优雅,但这里的好处是,大多数Windows电脑确实安装了IE。(如果您碰巧遇到自动化问题,请尝试创建一个InternetExplorerMedium对象,而不是普通的旧InternetExplorer。)

对于某些人来说,以下可能是最快、最优雅的答案,特别是如果你想使用更快的引擎来处理这些问题:

  1. 您可以从另一个脚本引擎调用外部脚本,比如Python、AutoHotkey、R、PHP或类似的东西。PowerShell可能是有意义的,只是调整它的安全设置可能会让一些用户感到讨厌。最快的(计算)可能是调用外部脚本,然后直接从该脚本中访问Excel电子表格对象(以获取表达式),执行所有必要的计算,然后关闭该脚本。

从那时起,可用的选择在质量上就减少了。

  1. 同样如上面的链接所述,如果您愿意降低Excel的安全设置,则可以通过暴力VBA代码注入来计算表达式。这几乎可以肯定是一个糟糕的想法,但如果你只使用一个电子表格,从不使用互联网,不与任何人共享代码,和/或是一个天生的叛逆者,不像莱因霍尔德法官那样,拒绝"照本宣科",那么它很可能是最快的。如果你使用这种方法(你这个坏奶妈),我甚至可能准备在你的杀毒软件中禁用启发式扫描!(如果这还不能让你相信这是个坏主意,我想没有什么能说服你了。)

如果只有几个表达式需要计算,并且它们是静态的,那么只需将它们转换为标准的Excel电子表格语言即可。但是,如果您想说接受用户的表达式,那么要求他们使用Excel在其常规函数式语言中使用的笨拙的括号、OR和NOT是非常笨拙的。VBA自己的表达式计算看起来要正常得多,但VBA不能轻松地将代码作为字符串传递给自己(这通常是一件好事)。

这篇关于用VBA计算字符串布尔表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆