VBA"任何"逻辑运算符

时间:2016-11-17 15:09:29

标签: vba

是否有VBA运算符检查是否有任何参数的计算结果为true?我不喜欢为多个参数多次写AndOr的语法,特别是对于有" select all / deselect all"功能类型。

实施例

If checkbox1 = True Or checkbox2 = True or ... checkbox10 = True Then

这可以更简洁地写成

If Any(checkbox1, checkbox2 , ..., checkbox10) Then

此外,编写如此长的if语句是否有任何性能考虑因素?我注意到在添加此宏或VBA代码后,我的Access表单加载速度变慢,不知道它是否与此有关。

修改

我尝试测试下面建议的代码

Public Sub text_x()
Dim a, b, c, d, e, f, g, h, i, result As Boolean
Dim t1, t2 As Single

a = False
b = False
c = False
d = False
e = False
f = False
g = False
h = False
i = True

t2 = Timer
For i = 1 To 10000000
    result = False
    If a Or b Or c Or d Or e Or f Or g Or h Or i Then
            result = True
    Else
            result = False
    End If
Next
t2 = Timer - t2


t1 = Timer
For i = 1 To 10000000
    result = False
    Select Case True
        Case a, b, c, d, e, f, g, h, i
            result = True
        Case Else
            result = False
    End Select
Next
t1 = Timer - t1


MsgBox ("Timer1 " & t1 & vbCrLf & "Timer2 " & t2)
End Sub

然而,时间取决于我在代码(t1或t2)中首先放置的那个。这是为什么?

3 个答案:

答案 0 :(得分:3)

滚动你自己很容易。请注意,Any是一个关键字,因此是函数名称。

Private Function AnyTrue(ParamArray args() As Variant) As Boolean
    Dim i As Long
    For i = LBound(args) To UBound(args)
        If CBool(args(i)) Then
            AnyTrue = True
            Exit Function
        End If
    Next
End Function

Sub SampleUse()
    Debug.Print AnyTrue(False, False, True, False)
    Debug.Print AnyTrue(False, False, False)
End Sub

答案 1 :(得分:3)

我只是实现它。除非您不能将其命名为Any,因为这是保留的,所以如何:

Public Function IsAnyTrue(ParamArray values()) As Boolean
    Dim i As Long
    For i = LBound(values) To UBound(values)
        If CBool(values(i)) Then
            IsAnyTrue = True
            Exit Function
        End If
    Next
End Function

虽然我们正在努力:

Public Function IsAllTrue(ParamArray values()) As Boolean
    Dim result As Boolean
    result = True
    Dim i As Long
    For i = LBound(values) To UBound(values)
        result = result And CBool(values(i))
        If Not result Then Exit Function
    Next
    IsAllTrue = result
End Function

逻辑运算符(AndOr,...)在VBA中不会短路(在VB.NET中,它们添加了短路AndAlso和{{1对于那个),所以如果你正在评估20个条件,例如:

OrElse

即使If expr1 And expr2 And expr3 And ... And exprN Then 评估为expr1,VBA仍会评估<{1}}以外的所有内容,以确定布尔表达式的结果。

但是这样:

False

一旦你知道一个人exprN,就会拯救你,并且这个:

If IsAnyTrue(expr1, expr2, expr3, ..., exprN) Then

一旦你知道True,就会拯救你,这会提高效果。

...看起来比If IsAllTrue(expr1, expr2, expr3, ..., exprN) Then 块更整洁。

答案 2 :(得分:2)

您可以使用Case开关进行近似,例如:

Select Case True
    Case CheckBox1, CheckBox2, CheckBox3, ... CheckBox10 '# Be sure to enumerate ALL of the CheckBoxes here 
        MsgBox "any"
    Case Else
        MsgBox "not"
End Select

它比一个巨大的IF语句更容易阅读/维护,但在本地VBA中没有任何等效的Any函数。

(你可以用它来测试它)

Sub x()
Dim a, b, c

a = False
b = True
c = False


Select Case True
    Case a, b, c
        MsgBox "any"
    Case Else
        MsgBox "not"
End Select

End Sub