неверный номер элемента в динамическом массиве для каждого цикла - PullRequest
1 голос
/ 02 января 2012

Я не понимаю, почему для каждого цикла в 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 ]

4 голосов
/ 02 января 2012

В данный момент вы создаете массив из 5 элементов с
ReDim t_direction(4)
как первый элемент встречается как t_direction(0)

Вы должны либо

  • создайте массив из 4 элементов ReDim t_direction(3) (т. Е. От 0 до 3) и затем используйте numItems в соответствии с этим или
  • создайте массив из 4 элементов ReDim t_direction с основанием 1 (т. Е. От 1 до 4) и затем используйте 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
2 голосов
/ 02 января 2012

ReDim t_direction(4) фактически объявляет t_direction как 0 To 4

Лучше быть точным:

ReDim t_direction(0 To 3)

При отсутствии указанной нижней границы (с использованием предложения To) используется нижняя граница по умолчанию.
Это значение по умолчанию может быть установлено на 0 или 1 с помощью Option Base {0|1} на уровне модуля.
При отсутствии Option Base по умолчанию используется значение по умолчанию 0

Примечания:

В VBA вы не ограничены 0 или 1 в качестве нижней границы, вы можете использовать любое значение.

Для перебора массива используйте

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

Для вычисления количества элементов в массиве используйте

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

Таким образом, вы не делаете никаких предположений относительно нижней границы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...