我正在尝试获取数组的长度,但我一直收到此错误:
需要对象
我做错了吗?
Exception calling "ExecuteNonQuery" with "0" argument(s): "Violation of PRIMARY KEY constraint 'PK_Group_Stats'. Cannot insert duplicate key in object 'dbo.Group_Stats'.
答案 0 :(得分:75)
数组的长度:
UBound(columns)-LBound(columns)+1
UBound
不是获取每个数组长度的最佳方法,因为VBA中的数组可以从不同的索引开始,例如Dim arr(2 to 10)
UBound
才会返回正确的结果(例如Dim arr(1 to 10)
开始索引。在任何其他情况下,它将返回错误的结果,例如Dim arr(10)
有关VBA阵列的更多信息 in this VBA Array tutorial。
答案 1 :(得分:19)
<强>功能强>
Public Function ArrayLen(arr As Variant) As Integer
ArrayLen = UBound(arr) - LBound(arr) + 1
End Function
<强>用法强>
Dim arr(1 To 3) As String ' Array starting at 1 instead of 0: nightmare fuel
Debug.Print ArrayLen(arr) ' Prints 3. Everything's going to be ok.
答案 2 :(得分:3)
如果变量为空,则将引发错误。防弹代码如下:
Public Function GetLength(a As Variant) As Integer
If IsEmpty(a) Then
GetLength = 0
Else
GetLength = UBound(a) - LBound(a) + 1
End If
End Function
答案 3 :(得分:1)
当我们有一个未初始化的动态数组时,UBound 和 LBound 不起作用。
我没有找到解决方案,所以,我处理了错误。现在它适用于我所有的脚本情况:
Public Function SizeOf(arr As Variant) As Integer
On Error GoTo IsEmpty
SizeOf = UBound(arr) - LBound(arr) + 1
Exit Function
IsEmpty:
SizeOf = 0
End Function
答案 4 :(得分:0)
尝试“ CountA”
Dim myArray(1 to 10) as String
Dim arrayCount as String
arrayCount = Application.CountA(myArray)
Debug.Print arrayCount
答案 5 :(得分:0)
到处编译答案,这是一整套用于完成工作的arr工具:
Function getArraySize(arr As Variant)
' returns array size for a n dimention array
' usage result(k) = size of the k-th dimension
Dim ndims As Long
Dim arrsize() As Variant
ndims = getDimensions(arr)
ReDim arrsize(ndims - 1)
For i = 1 To ndims
arrsize(i - 1) = getDimSize(arr, i)
Next i
getArraySize = arrsize
End Function
Function getDimSize(arr As Variant, dimension As Integer)
' returns size for the given dimension number
getDimSize = UBound(arr, dimension) - LBound(arr, dimension) + 1
End Function
Function getDimensions(arr As Variant) As Long
' returns number of dimension in an array (ex. sheet range = 2 dimensions)
On Error GoTo Err
Dim i As Long
Dim tmp As Long
i = 0
Do While True
i = i + 1
tmp = UBound(arr, i)
Loop
Err:
getDimensions = i - 1
End Function
答案 6 :(得分:0)
复制/意大利面解决方案:
最常见的答案是:
UBound(myItems) - LBound(myItems) + 1
虽然它在 +90% 的时间里工作,但当客户端/用户运行它时,另外 10% 会因严重的计划外错误而失败。这是因为该解决方案没有涵盖许多边缘情况。
通用解决方案:
下面的解决方案涵盖了我迄今为止发现的所有边缘情况。它消除了客户端/用户运行时的所有运行时故障。
'Generic solution using Variant
Public Const SIZE_NOT_ARRAY As Long = -1
Public Const SIZE_EMPTY As Long = 0
'Return Value:
' -1 - Not an Array
' 0 - Empty
' > 0 - Defined
Public Function size( _
ByVal values As Variant _
, Optional ByVal dimensionOneBased As Long = 1 _
) As Long
Dim result As Long: result = SIZE_NOT_ARRAY 'Default to not an Array
Dim lowerBound As Long
Dim upperBound As Long
On Error GoTo NormalExit
If (IsArray(values) = True) Then
result = SIZE_EMPTY 'Move default to Empty
lowerBound = LBound(values, dimensionOneBased) 'Possibly generates error
upperBound = UBound(values, dimensionOneBased) 'Possibly generates error
If (lowerBound < upperBound) Then
result = upperBound - lowerBound + 1 'Size greater than 1
Else
If (lowerBound = upperBound) Then
result = 1 'Size equal to 1
End If
End If
End If
NormalExit:
size = result
End Function
Public Function isEmpty( _
ByVal values As Variant _
, Optional ByVal dimensionOneBased As Long = 1 _
) As Boolean
isEmpty = size(values, dimensionOneBased) = 0
End Function
Public Function isDefined( _
ByVal values As Variant _
, Optional ByVal dimensionOneBased As Long = 1 _
) As Boolean
isDefined = size(values, dimensionOneBased) > 0
End Function
警告:
虽然上述“通用”解决方案有效且稳健,但它并不是最高效的。 IOW,如果知道有人正在使用 Dim strings() As String
,那么更具体的解决方案可以快很多倍。
更快的解决方案:
下面的 Array
解决方案的 String
比上面的“通用解决方案”快很多倍。为什么?因为额外的指令(默认为 SIZE_NOT_ARRAY
、IsArray
、IsEmpty
等)以及从 Variant
到 Array
的转换似乎带来了相当大的成本。在我的测试中,下面的解决方案可以快 10 倍以上。
'Specifically Typed solution for String
Public Const SIZE_EMPTY As Long = 0
'Return Value:
' -1 - Not an Array
' 0 - Empty
' > 0 - Defined
Public Function size( _
ByRef r_values() As String _
, Optional ByVal dimensionOneBased As Long = 1 _
) As Long
Dim result As Long: result = SIZE_EMPTY 'Default to Empty
Dim lowerBound As Long
Dim upperBound As Long
On Error GoTo NormalExit
lowerBound = LBound(r_values, dimensionOneBased) 'Possibly generates error
upperBound = UBound(r_values, dimensionOneBased) 'Possibly generates error
If (lowerBound < upperBound) Then
result = upperBound - lowerBound + 1 'Size greater than 1
Else
If (lowerBound = upperBound) Then
result = 1 'Size equal to 1
End If
End If
NormalExit:
size = result
End Function
Public Function isEmpty( _
ByRef r_values() As String _
, Optional ByVal dimensionOneBased As Long = 1 _
) As Boolean
isEmpty = size(r_values, dimensionOneBased) = 0
End Function
Public Function isDefined( _
ByRef r_values() As String _
, Optional ByVal dimensionOneBased As Long = 1 _
) As Boolean
isDefined = size(r_values, dimensionOneBased) > 0
End Function