Зубчатые массивы в VBA

Итак, я хочу создать массив массивов, и, насколько я понимаю, мне нужен зубчатый массив.

У меня есть массив x(i,j), который определяет квадратную матрицу целых чисел nxn. Для каждой итерации k два целых значения внутри этого массива меняются местами, чтобы попытаться улучшить матрицу x(i,j). Мне нужно создать массив, в котором хранится эта матрица x(i,j) после каждой итерации k.

Чтобы уточнить, скажите, есть ли у меня

1  2  3
4  5  6
7  8  9

И я выполняю итерацию, меняя местами два элемента внутри массива:

7  2  3
4  5  6
1  8  9

Я хочу иметь возможность хранить эти массивы внутри массива, чтобы их можно было вызывать в любое время. Я попытался решить здесь:

Dim y() As Variant 'Declare as a variant to contain arrays
ReDim y(1 To IterationLimit) 'This will be the jagged array

For k = 1 To IterationLimit
'Some code goes here for the swap
    y(k) = x(i,j)
next k

Теперь скажем, я хочу 85-ю итерацию. Я хочу иметь возможность ввести y(85) [или аналогичный], чтобы вывести матрицу x(i,j) за это конкретное время.

Надеюсь, я объяснил это достаточно хорошо. Любая помощь приветствуется, я действительно застрял в этом.

редактировать: удаленный код


person Matt    schedule 27.04.2013    source источник
comment
когда вы говорите, что у вас есть массив x(i,j), i и j представляют границы этого массива? Или x представляет собой массив массивов, один из дочерних массивов которого идентифицируется индексом (i,j)?   -  person David Zemens    schedule 27.04.2013
comment
я и j действительно представляют границы да. Итак, для приведенного выше примера, я думаю, будет x (от 1 до 3, от 1 до 3)   -  person Matt    schedule 27.04.2013
comment
Чтобы дать вам немного больше информации, если бы я должен был сослаться на x (2,2) из ​​приведенной выше матрицы, это приняло бы значение во второй строке и втором столбце, то есть 5. Не уверен, поможет это или нет.   -  person Matt    schedule 27.04.2013
comment
Итак, когда вы выполняете y(k) = x(i,j), происходит то, что вы ТОЛЬКО сохраняете y(k) как одно значение (элемент, представленный координатами i/j в массиве x).   -  person David Zemens    schedule 27.04.2013
comment
Если вы хотите получить весь массив за y(k), вы просто делаете y(k) = x во время итерации.   -  person David Zemens    schedule 27.04.2013
comment
Да, теперь в моем макросе есть фрагмент кода, который выводит матрицу [Cells(20 + i, 20 + j).Value = y(20)], и значение везде одинаковое. Но я не знаю, как обойти это.   -  person Matt    schedule 27.04.2013
comment
Я попробовал это, поэтому у меня есть y (k) = x. Затем вне моего цикла у меня есть Cells(20 + i, 20 + j).Value = y(20) (где y(20) — 20-я итерация). Но это по-прежнему отображает одно и то же значение во всех массивах...   -  person Matt    schedule 27.04.2013
comment
Да, и, кстати, i и j по-прежнему являются границами матрицы.   -  person Matt    schedule 27.04.2013
comment
Если вы посмотрите на окно Locals в VBE‹, как выглядит y(20)? Кроме того, всегда полезно опубликовать весь код, а не только его часть. Как бы то ни было, проблема может быть где-то еще в вашем коде, который я не вижу. Я приведу пример, показывающий, что я имею в виду...   -  person David Zemens    schedule 27.04.2013
comment
Хм, хорошо, я могу сделать это сейчас, если хочешь? Однако он достаточно длинный. Мне просто отредактировать свой первый пост?   -  person Matt    schedule 27.04.2013
comment
Хорошо, я разместил саб в своем первом посте. Если вам нужно какое-либо объяснение чего-либо, я буду рад помочь! Изменить: кстати, не обращайте слишком много внимания на аннотации, поскольку я использую их, чтобы помочь мне больше, чем объяснить прямо сейчас   -  person Matt    schedule 27.04.2013
comment
ОК, да, это довольно длинно, и у меня нет формы файла/пользователя и т. д. Я опубликую предложенный ответ с VBE, показывающим вам, как просматривать ваши переменные массива, так как кажется, что вы что-то не так с ними делают.   -  person David Zemens    schedule 27.04.2013


Ответы (1)


ХОРОШО. Я думаю, вы просто неправильно назначаете массивы y. Как я упоминал в комментариях:

y(k) = x(i,j) ТОЛЬКО сохраняет значение, представленное координатами i/j в массиве x.

Чтобы y(k) ссылался на весь массив x в то время, вы должны сделать:

y(k) = x

Если это все еще не работает, возможно, что-то еще не так. Вот пример, где у меня есть массив 2x2 (база 0) с именем baseArray, который я явно заполняю некоторыми значениями. Я итерирую от i = 0 to itLimit, и в каждой итерации я перебираю элементы в массиве, умножая значения на 2 и сохраняя в переменной массива tmpArray. После преобразования значений я сохраняю их в arrContainer и перехожу к следующей For i = 0 to itLimit итерации.

Sub FunWithArrays()
Dim itLimit As Integer  '## Iteration limit.'
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim baseArray(2, 2) As Variant '## an example array.'

    '## Put some dummy data in this array.'
    baseArray(0, 0) = 1
    baseArray(0, 1) = 65
    baseArray(0, 2) = 13
    baseArray(1, 0) = 14
    baseArray(1, 1) = 29
    baseArray(1, 2) = 44
    baseArray(2, 0) = 9
    baseArray(2, 1) = 16
    baseArray(2, 2) = 33

Dim tmpArray(2, 2) As Variant '## This will temporarily hold values as we transform them.'
Dim arrContainer() As Variant '## an array of arrays, to store the iteration arrays.'

    itLimit = 2  '## set a max iteration.'

    For i = 0 To itLimit
        '## Transform the base array somehow'
        For j = LBound(baseArray, 1) To UBound(baseArray, 1)
            For k = LBound(baseArray, 2) To UBound(baseArray, 2)
                tmpArray(j, k) = baseArray(j, k) * 2
            Next
        Next
        ReDim Preserve arrContainer(i)
        arrContainer(i) = tmpArray
    Next

    Dim y As Variant
    '## Now, refer to a single iteration stored in the arrContainer variable:

    y = arrContainer(2)

End Sub

На этом первом снимке экрана я использую окно Locals для просмотра переменных и того, что они содержат. После первой итерации вы можете видеть, что tmpArray было заполнено и имеет те же размеры, что и baseArray, но значения в нем были умножены на 2.

Снимок экрана после первой итерации

Изучив переменную arrContainer, мы видим, что она имеет только 1 элемент, и этот элемент представляет собой массив, равный tmpArray, который мы создали на итерации выше.

Снимок экрана arrContainer после первой итерации

После последней итерации мы можем просмотреть arrContainer и увидеть, что он содержит 3 элемента (от 0 до 2, согласно нашему циклу For i to itLimit). Каждый массив внутри arrContainer равен одному из массивов, созданных на предыдущей итерации.

Скриншот массива массивов arrContainer после всех итераций

Теперь мы можем ссылаться на эти элементы, например:

Dim y as Variant y = arrContainer(2) '# or any in bounds index could be used instead of "2"'

И, наконец, использование окна VBE Locals для просмотра y:

Последний снимок экрана, относящийся к одному элементу массива в arrContainer

person David Zemens    schedule 27.04.2013
comment
@David Zemens О, это отлично, это работает! Окно местных жителей — это то, что я никогда раньше не использовал, но оно оказалось действительно полезным! А для вывода в ячейки я использовал Cells(20 + i, 20 + j).Value = ArrContainer(80)(i, j) [внутри цикла i и j For]. Всего один вопрос! Какова цель ReDim Preserve? Чем занимается заповедник? - person Matt; 27.04.2013
comment
@Matt ReDim позволяет повторно объявить и/или изменить размер массива. Preserve сохранить существующие значения. Разница между ReDim arrContainer(3) и ReDim Preserve arrContainer(3) заключается в том, что первый оператор задает размер массива с верхней границей = 3, но стирает его содержимое, тогда как последний задает размер массива с верхней границей = 3, сохраняя при этом его содержимое. - person David Zemens; 28.04.2013
comment
@Matt Далее: мы изначально определили размер arrContainer as Variant без ограничений, поэтому такое утверждение, как arrContainer(0) = "blah", приведет к ошибке. Каждая итерация ReDim Preserve увеличивает размер массива (для размещения нового значения) и сохраняет существующее содержимое. Вы можете ReDim arrContainer(itLimit-1) после установки itLimit, что создаст массив правильного размера. Но при работе с циклами часто размер заранее неизвестен, поэтому я предпочитаю ReDim Preserve внутри цикла. - person David Zemens; 28.04.2013