VBA 检查整行多维变体是否为空且无循环
VBA check if whole row of multidimensional variant is empty without loops
有没有快速检查变体整行是否为空的方法?
我的多维数组/变体有 n 行和 m 列。
我能想到的唯一方法是遍历(特定行的)列并使用 IsEmpty() 函数来确定单元格是否为空。
变体只包含字符串。
你知道更快的方法吗?也许是这样的伪代码:IsEmpty(myarr(1,*))
此伪代码意味着检查第一行的所有列是否为空。
您可以尝试类似的方法:
Sub Test()
Dim myarr() As Variant, indx As Long
myarr = Range("A8:C20").Value 'Or however you initialize your array.
indx = 1 'Or whichever row you would want to check.
With Application
Debug.Print Join(.Index(myarr, indx, 0), "") <> ""
End With
End Sub
不确定它是否会比循环更快,因为我们调用了工作表应用程序。
不,没有更快的方法,特别是考虑到 VBA 中的数组按列存储在内存中。单行上的值不会像列值那样相邻存储在内存中 - 您可以通过 运行 数组上的 For Each
循环轻松测试这一点。
话虽这么说,您或许应该考虑使用 Function
检查特定行是否为空,以便您可以重复调用它,并在需要时检查空字符串。例如,一系列返回“”的公式不会为空,但您可能希望能够将它们视为空。
例如,您可以这样使用:
Public Function Is2DArrayRowEmpty(ByRef arr As Variant _
, ByVal rowIndex As Long _
, Optional ByVal ignoreEmptyStrings As Boolean = False _
) As Boolean
Const methodName As String = "Is2DArrayRowEmpty"
'
If GetArrayDimsCount(arr) <> 2 Then
Err.Raise 5, methodName, "Array is not two-dimensional"
ElseIf rowIndex < LBound(arr, 1) Or rowIndex > UBound(arr, 1) Then
Err.Raise 5, methodName, "Row Index out of bounds"
End If
'
Dim j As Long
Dim v As Variant
'
For j = LBound(arr, 2) To UBound(arr, 2)
v = arr(rowIndex, j)
Select Case VBA.VarType(v)
Case VbVarType.vbEmpty
'Continue to next element
Case VbVarType.vbString
If Not ignoreEmptyStrings Then Exit Function
If LenB(v) > 0 Then Exit Function
Case Else
Exit Function
End Select
Next j
'
Is2DArrayRowEmpty = True 'If code reached this line then row is Empty
End Function
Public Function GetArrayDimsCount(ByRef arr As Variant) As Long
If Not IsArray(arr) Then Exit Function
'
Const MAX_DIMENSION As Long = 60
Dim dimension As Long
Dim tempBound As Long
'
'A zero-length array has 1 dimension! Ex. Array() returns (0 to -1)
On Error GoTo FinalDimension
For dimension = 1 To MAX_DIMENSION
tempBound = LBound(arr, dimension)
Next dimension
Exit Function
FinalDimension:
GetArrayDimsCount = dimension - 1
End Function
请注意,我没有检查 IsObject
,因为您的值来自 Excel 的范围,但在一般情况下您通常会检查它。
您的伪代码 IsEmpty(myarr(1,*))
可以翻译为:
Is2DArrayRowEmpty(myarr, 1, False) 'Empty strings would not be considered Empty
或
Is2DArrayRowEmpty(myarr, 1, True) 'Empty strings would be considered Empty
有没有快速检查变体整行是否为空的方法?
我的多维数组/变体有 n 行和 m 列。
我能想到的唯一方法是遍历(特定行的)列并使用 IsEmpty() 函数来确定单元格是否为空。
变体只包含字符串。
你知道更快的方法吗?也许是这样的伪代码:IsEmpty(myarr(1,*))
此伪代码意味着检查第一行的所有列是否为空。
您可以尝试类似的方法:
Sub Test()
Dim myarr() As Variant, indx As Long
myarr = Range("A8:C20").Value 'Or however you initialize your array.
indx = 1 'Or whichever row you would want to check.
With Application
Debug.Print Join(.Index(myarr, indx, 0), "") <> ""
End With
End Sub
不确定它是否会比循环更快,因为我们调用了工作表应用程序。
不,没有更快的方法,特别是考虑到 VBA 中的数组按列存储在内存中。单行上的值不会像列值那样相邻存储在内存中 - 您可以通过 运行 数组上的 For Each
循环轻松测试这一点。
话虽这么说,您或许应该考虑使用 Function
检查特定行是否为空,以便您可以重复调用它,并在需要时检查空字符串。例如,一系列返回“”的公式不会为空,但您可能希望能够将它们视为空。
例如,您可以这样使用:
Public Function Is2DArrayRowEmpty(ByRef arr As Variant _
, ByVal rowIndex As Long _
, Optional ByVal ignoreEmptyStrings As Boolean = False _
) As Boolean
Const methodName As String = "Is2DArrayRowEmpty"
'
If GetArrayDimsCount(arr) <> 2 Then
Err.Raise 5, methodName, "Array is not two-dimensional"
ElseIf rowIndex < LBound(arr, 1) Or rowIndex > UBound(arr, 1) Then
Err.Raise 5, methodName, "Row Index out of bounds"
End If
'
Dim j As Long
Dim v As Variant
'
For j = LBound(arr, 2) To UBound(arr, 2)
v = arr(rowIndex, j)
Select Case VBA.VarType(v)
Case VbVarType.vbEmpty
'Continue to next element
Case VbVarType.vbString
If Not ignoreEmptyStrings Then Exit Function
If LenB(v) > 0 Then Exit Function
Case Else
Exit Function
End Select
Next j
'
Is2DArrayRowEmpty = True 'If code reached this line then row is Empty
End Function
Public Function GetArrayDimsCount(ByRef arr As Variant) As Long
If Not IsArray(arr) Then Exit Function
'
Const MAX_DIMENSION As Long = 60
Dim dimension As Long
Dim tempBound As Long
'
'A zero-length array has 1 dimension! Ex. Array() returns (0 to -1)
On Error GoTo FinalDimension
For dimension = 1 To MAX_DIMENSION
tempBound = LBound(arr, dimension)
Next dimension
Exit Function
FinalDimension:
GetArrayDimsCount = dimension - 1
End Function
请注意,我没有检查 IsObject
,因为您的值来自 Excel 的范围,但在一般情况下您通常会检查它。
您的伪代码 IsEmpty(myarr(1,*))
可以翻译为:
Is2DArrayRowEmpty(myarr, 1, False) 'Empty strings would not be considered Empty
或
Is2DArrayRowEmpty(myarr, 1, True) 'Empty strings would be considered Empty