VBA“;任何;逻辑运算符
是否有VBA运算符检查任何参数的计算结果是否为true?我不喜欢为多个参数多次编写VBA“;任何;逻辑运算符,vba,Vba,是否有VBA运算符检查任何参数的计算结果是否为true?我不喜欢为多个参数多次编写和或或的语法,尤其是对于具有“全选/全选”功能类型的按钮 前 这可以写得更简洁吗 If Any(checkbox1, checkbox2 , ..., checkbox10) Then ? 另外,编写这么长的if语句是否有性能方面的考虑?我注意到,在添加了这个宏或VBA代码之后,我的Access窗体加载速度变慢了,我不知道这是否与此有关 编辑 我试着测试下面建议的代码 Public Sub text_x() Di
和
或或
的语法,尤其是对于具有“全选/全选”功能类型的按钮
前
这可以写得更简洁吗
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)。这是为什么?您可以使用一个
案例
开关来近似计算,例如:
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中没有任何等效的函数
(您可以使用它来测试它)
您可以使用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
是一个关键字,因此是函数名
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
你很容易就能自己动手。请注意,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
我会实施它。除非您不能将其命名为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
逻辑运算符(和
,或
,…)在VBA中不会短路(在VB.NET中,他们为此添加了短路和短路和或短路),因此如果您正在评估20个条件,例如:
If expr1 And expr2 And expr3 And ... And exprN Then
即使expr1
的计算结果为False
,VBA仍将计算所有直到exprN
的值,以确定布尔表达式的结果
然而,在这方面:
If IsAnyTrue(expr1, expr2, expr3, ..., exprN) Then
If IsAllTrue(expr1, expr2, expr3, ..., exprN) Then
一旦你知道其中一个是真的
,你就要退出了,并且:
If IsAnyTrue(expr1, expr2, expr3, ..., exprN) Then
If IsAllTrue(expr1, expr2, expr3, ..., exprN) Then
当您知道其中一个是False
时,您将立即退出,这将提高性能
…而且看起来比一个选择案例
块更整洁。我只想实现它。除非您不能将其命名为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
逻辑运算符(和
,或
,…)在VBA中不会短路(在VB.NET中,他们为此添加了短路和短路和或短路),因此如果您正在评估20个条件,例如:
If expr1 And expr2 And expr3 And ... And exprN Then
即使expr1
的计算结果为False
,VBA仍将计算所有直到exprN
的值,以确定布尔表达式的结果
然而,在这方面:
If IsAnyTrue(expr1, expr2, expr3, ..., exprN) Then
If IsAllTrue(expr1, expr2, expr3, ..., exprN) Then
一旦你知道其中一个是真的
,你就要退出了,并且:
If IsAnyTrue(expr1, expr2, expr3, ..., exprN) Then
If IsAllTrue(expr1, expr2, expr3, ..., exprN) Then
当您知道其中一个是False
时,您将立即退出,这将提高性能
…看起来比选择框
块更整洁。放下=
部分。你也可以将它们存储在数组中。你可以将控件存储在数组中?是的,为什么不呢?是的,你可以将控件存储在数组、集合、字典、数组列表中…关于计时,Select Case
会使计算短路。如果
语句没有,则删除=
部分。你也可以将它们存储在数组中。你可以将控件存储在数组中?是的,为什么不呢?是的,你可以将控件存储在数组、集合、字典、数组列表中…关于计时,Select Case
会使计算短路。If
语句没有。我试图测试这段代码的计时(上面编辑过),但出于某种原因,其中一段或另一段的计时更快,这取决于我先放的是哪一段(它们都编译成相同的代码?)@AllenWang-如果你把它作为一个新问题发布,我可以解释一下。@Comintern ok will doI我试着测试这段代码的计时(上面编辑过),但出于某种原因,根据我先放的是哪一段(它们都编译成相同的代码?)@AllenWang-如果你把它作为一个新问题发布,我可以解释一下。@Comintern ok will Dow第二个函数中CBool的作用是什么,为什么要用result=result和CBool(values(I))
设置逻辑比较,而不是像第一个函数中那样设置它?难道你不能只做如果不是CBool(值(i)),那么result=False;退出函数
?CBool
将显式转换为布尔值
;由于ParamArray
,所有项都是隐式的Variant
——我喜欢显式的类型转换。感谢ping,我在答案框中写了这些,没有测试,第二个根本没有返回(已修复)。我发现result=result和CBool(values(I))
更明确地说明了正在发生的事情-我会像IsAllTrue
所暗示的那样“如果一切都是真的,则返回真的”,而不是“如果一个人是假的,则返回假的”,这实际上是等效的。做任何事都没有一个真正的方法!第二个函数中的CBool有什么意义?为什么要用result=result和CBool(values(i))
设置逻辑比较,而不是像第一个函数中那样设置?难道你不能只做如果不是CBool(值(i)),那么result=False;退出函数
?CBool
将显式转换为布尔值
;由于ParamArray
,所有项都是隐式的Variant
——我喜欢显式的类型转换。感谢ping,我在答案框中写了这些,没有测试,第二个根本没有返回(已修复)。我发现result=result和CBool(值(I))
更多