每个循环的动态数组中的元素数量不正确

时间:2012-01-02 00:12:08

标签: arrays vba for-loop

我不明白为什么当我使用动态数组时,vba中的每个循环都不会返回良好数量的元素。

例如,我的数组大小为4,每次循环我都有5次迭代......

Public Sub test()

Dim t_direction() As String
Dim t_nextDirection() As String
Dim myDirection As Variant
Dim test As Integer
Var = 0

ReDim t_direction(4)

t_direction(0) = "N"
t_direction(1) = "S"
t_direction(2) = "E"
t_direction(3) = "W"

t_nextDirection = randomizeArray(t_direction)

For Each myDirection In t_nextDirection
    Var = Var + 1
Next myDirection

MsgBox (UBound(t_nextDirection))
MsgBox (Var)

End Sub

Public Function randomizeArray(ByVal t_array As Variant) As String()
Dim i As Integer
Dim j As Integer

Dim tmp As String
Dim numItems As Integer

numItems = UBound(t_array) - 1

    ' Randomize the array.
    For i = 0 To numItems
        ' Pick a random entry.
        j = Rand(0, numItems)

        ' Swap the numbers.
        tmp = t_array(i)
        t_array(i) = t_array(j)
        t_array(j) = tmp
    Next i
    'MsgBox (UBound(t_array))
    randomizeArray = t_array

End Function

Public Function Rand(ByVal Low As Long, _
                     ByVal High As Long) As Integer
  Rand = Int((High - Low + 1) * Rnd) + Low
End Function

2 个答案:

答案 0 :(得分:4)

目前您正在使用
创建一个5元素数组 ReDim t_direction(4)
因为第一个元素出现在t_direction(0)

你应该

  • 创建一个4元素数组ReDim t_direction(3)(即0到3),然后使用与此一致的numItems,或
  • 创建一个基数为1(即1到4)的4元素数组ReDim t_direction,然后使用与其一致的numItems(即numItems = UBound(t_array))。下面的Option Base 1强制第一个元素为1(然后使用ReDim t_direction(1 To 4)确保任何元素

以下代码使用后面的方法。它返回4和4而不是当前的4和5

Option Base 1
Public Sub test()

Dim t_direction() As String
Dim t_nextDirection() As String
Dim myDirection As Variant
Dim test As Integer
Var = 0

ReDim t_direction(1 To 4)

t_direction(1) = "N"
t_direction(2) = "S"
t_direction(3) = "E"
t_direction(4) = "W"

t_nextDirection = randomizeArray(t_direction)

For Each myDirection In t_nextDirection
    Var = Var + 1
Next myDirection

MsgBox (UBound(t_nextDirection))
MsgBox (Var)

End Sub

Public Function randomizeArray(ByVal t_array As Variant) As String()
Dim i As Integer
Dim j As Integer

Dim tmp As String
Dim numItems As Integer

numItems = UBound(t_array)

    ' Randomize the array.
    For i = 1 To numItems
        ' Pick a random entry.
        j = Rand(1, numItems)

        ' Swap the numbers.
        tmp = t_array(i)
        t_array(i) = t_array(j)
        t_array(j) = tmp
    Next i
    'MsgBox (UBound(t_array))
    randomizeArray = t_array

End Function

Public Function Rand(ByVal Low As Long, _
                     ByVal High As Long) As Integer
  Rand = Int((High - Low + 1) * Rnd) + Low
End Function

答案 1 :(得分:2)

ReDim t_direction(4)实际上将t_direction声明为0 To 4

最好明确:

ReDim t_direction(0 To 3)

如果没有指定的下限(使用To子句),则使用默认的下限。
在模块级别使用0可将此默认设置设为1Option Base {0|1} 如果没有Option Base,则默认默认值为0

注意:

在VBA中,您不限于01作为下限,您可以使用任何您想要的值。

迭代数组使用

For i = LBound(arr) To UBound(arr)

要计算数组中项目的数量,请使用

numItems = UBound(arr) - LBound(arr) + 1

这样你就不会对下限是什么做出任何假设