循环变量数组时不能使用具有多个条件 (AND/OR) 的 If 语句?
Cannot use an If-statement with multiple conditions (AND/OR) when looping through variant array?
背景:
在使用一些变体数组根据条件将数据排序到多个位置时,我注意到每次使用带有多个标记为 false 的条件的 if 语句。这被用来创建一个字典,尽管它从未进入字典方面,因为仅在变量数组中循环时出现错误响应。
我将它们移动到两个单独的 if 语句中,一切都按预期工作。
问题:
为什么在变体数组中循环数据时无法使用多条件 if 语句?
有问题的代码:
生成变体数组的通用代码:
Public ex_arr As Variant, ex_lr As Long, ex_lc As Long
Public dc As Scripting.Dictionary
Private Sub capture_export_array()
With Sheets("export")
ex_lc = .Cells(1, .Columns.Count).End(xlToLeft).Column
ex_lr = .Cells(.Rows.Count, ex_lc).End(xlUp).Row
ex_arr = .Range(.Cells(1, 1), .Cells(ex_lr, ex_lc)).Value
End With
End Sub
导致 False
条件的代码(立即 window print = 0):
Private Sub find_unique_items()
Set dc = New Scripting.Dictionary
Dim i As Long
For i = LBound(ex_arr) To UBound(ex_arr)
If InStr(ex_arr(i, ex_lc), "CriteriaA") And InStr(ex_arr(i, 4), "CriteriaB") Then dc(ex_arr(i, 2)) = ex_arr(i, 3)
Next i
Debug.Print dc.Count
End Sub
产生所需输出的代码(立即 window 打印 > 0):
Private Sub find_unique_items()
Set dc = New Scripting.Dictionary
Dim i As Long
For i = LBound(ex_arr) To UBound(ex_arr)
If InStr(ex_arr(i, ex_lc), "CriteriaA") Then
If InStr(ex_arr(i, 4), "CriteriaB") Then dc(ex_arr(i, 2)) = ex_arr(i, 3)
End If
Next i
Debug.Print dc.Count
End Sub
InStr
returns一个索引。作为一个逻辑运算符,And
想要有Boolean
个操作数。给定 Integer
个操作数,And
运算符是一个 按位运算符 - 说实话,这些运算符 总是 按位;当操作数为 Boolean
.
时,我们将它们称为 "logical" 运算符
If InStr(ex_arr(i, ex_lc), "CriteriaA") Then
此条件隐含地将返回的索引强制转换为 Boolean
表达式,利用任何非零值都将转换为 True
.
的事实
当您将 logical/bitwise 运算符带入等式时,问题就开始了。
If InStr(ex_arr(i, ex_lc), "CriteriaA") And InStr(ex_arr(i, 4), "CriteriaB") Then dc(ex_arr(i, 2)) = ex_arr(i, 3)
说第一个InStr
returns2
,第二个returns1
。 If
表达式变为 If 2 And 1 Then
,因此 0
。那是零,所以条件是假的。
等等,什么?
想想 2 与 1 的二进制表示:
2: 0010
1: 0001
AND: 0000
按位与产生 0
,因为 none 个位对齐。
停止滥用隐式类型转换,并明确说明您的真正意思。你的意思是这样的:
If (InStr(ex_arr(i, ex_lc), "CriteriaA") > 0) And (InStr(ex_arr(i, 4), "CriteriaB") > 0) Then dc(ex_arr(i, 2)) = ex_arr(i, 3)
(多余的括号仅供说明之用)
现在计算两个 Boolean
表达式,对两个值应用按位与,并按预期正确工作。
True: 1111
True: 1111
AND: 1111
背景:
在使用一些变体数组根据条件将数据排序到多个位置时,我注意到每次使用带有多个标记为 false 的条件的 if 语句。这被用来创建一个字典,尽管它从未进入字典方面,因为仅在变量数组中循环时出现错误响应。
我将它们移动到两个单独的 if 语句中,一切都按预期工作。
问题:
为什么在变体数组中循环数据时无法使用多条件 if 语句?
有问题的代码:
生成变体数组的通用代码:
Public ex_arr As Variant, ex_lr As Long, ex_lc As Long
Public dc As Scripting.Dictionary
Private Sub capture_export_array()
With Sheets("export")
ex_lc = .Cells(1, .Columns.Count).End(xlToLeft).Column
ex_lr = .Cells(.Rows.Count, ex_lc).End(xlUp).Row
ex_arr = .Range(.Cells(1, 1), .Cells(ex_lr, ex_lc)).Value
End With
End Sub
导致 False
条件的代码(立即 window print = 0):
Private Sub find_unique_items()
Set dc = New Scripting.Dictionary
Dim i As Long
For i = LBound(ex_arr) To UBound(ex_arr)
If InStr(ex_arr(i, ex_lc), "CriteriaA") And InStr(ex_arr(i, 4), "CriteriaB") Then dc(ex_arr(i, 2)) = ex_arr(i, 3)
Next i
Debug.Print dc.Count
End Sub
产生所需输出的代码(立即 window 打印 > 0):
Private Sub find_unique_items()
Set dc = New Scripting.Dictionary
Dim i As Long
For i = LBound(ex_arr) To UBound(ex_arr)
If InStr(ex_arr(i, ex_lc), "CriteriaA") Then
If InStr(ex_arr(i, 4), "CriteriaB") Then dc(ex_arr(i, 2)) = ex_arr(i, 3)
End If
Next i
Debug.Print dc.Count
End Sub
InStr
returns一个索引。作为一个逻辑运算符,And
想要有Boolean
个操作数。给定 Integer
个操作数,And
运算符是一个 按位运算符 - 说实话,这些运算符 总是 按位;当操作数为 Boolean
.
If InStr(ex_arr(i, ex_lc), "CriteriaA") Then
此条件隐含地将返回的索引强制转换为 Boolean
表达式,利用任何非零值都将转换为 True
.
当您将 logical/bitwise 运算符带入等式时,问题就开始了。
If InStr(ex_arr(i, ex_lc), "CriteriaA") And InStr(ex_arr(i, 4), "CriteriaB") Then dc(ex_arr(i, 2)) = ex_arr(i, 3)
说第一个InStr
returns2
,第二个returns1
。 If
表达式变为 If 2 And 1 Then
,因此 0
。那是零,所以条件是假的。
等等,什么?
想想 2 与 1 的二进制表示:
2: 0010
1: 0001
AND: 0000
按位与产生 0
,因为 none 个位对齐。
停止滥用隐式类型转换,并明确说明您的真正意思。你的意思是这样的:
If (InStr(ex_arr(i, ex_lc), "CriteriaA") > 0) And (InStr(ex_arr(i, 4), "CriteriaB") > 0) Then dc(ex_arr(i, 2)) = ex_arr(i, 3)
(多余的括号仅供说明之用)
现在计算两个 Boolean
表达式,对两个值应用按位与,并按预期正确工作。
True: 1111
True: 1111
AND: 1111