得到数组的长度?

时间:2015-06-01 13:27:28

标签: excel vba ms-access

我正在尝试获取数组的长度,但我一直收到此错误:

  

需要对象

我做错了吗?

Exception calling "ExecuteNonQuery" with "0" argument(s): "Violation of PRIMARY KEY constraint 'PK_Group_Stats'. Cannot insert duplicate key in object 'dbo.Group_Stats'. 

7 个答案:

答案 0 :(得分:75)

数组的长度:

UBound(columns)-LBound(columns)+1

单独

UBound不是获取每个数组长度的最佳方法,因为VBA中的数组可以从不同的索引开始,例如Dim arr(2 to 10)

仅当数组从1开始时,

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_ARRAYIsArrayIsEmpty 等)以及从 VariantArray 的转换似乎带来了相当大的成本。在我的测试中,下面的解决方案可以快 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