Ну, использование массива сэкономит много времени выполнения кода. Но есть некоторые проблемы, которые необходимо понять:
Первое, когда работа в VBA и ваш проект увеличивается, - это правильно объявить ваши переменные. Попробуйте сделать рефлекс, поместив Option Explicit
поверх всех ваших модулей. В случае с массивом, с этой точки зрения, вещь остается такой:
Dim Arr() As variant, arr1 As Variant
Оба объявления работают в Excel . Но второй рекомендуется ( на майский вкус ), , когда вам нужен массив из диапазона . Когда вы хотите создать, скажем, массив результатов, он будет основан на нуле, и вы должны позаботиться о размере диапазона, в котором будут возвращаться значения.
Содержимое массива не может быть найденным точно так же, как вы пытались ответить на ваш вопрос в случае нефиксированного / известного количества элементов. Посмотрите на следующий тестовый код:
Sub testArrays()
Dim sh As Worksheet, rng As Range, arrTest As Variant
Set sh = ActiveSheet
Set rng = sh.Range("A1:F4")
arrTest = rng.value
sh.Range("J1").Resize(UBound(arrTest, 1), UBound(arrTest, 2)).value = arrTest
End Sub
Рекомендуется использовать arrTest = sh.Range("A1:F4").value
. Используя диапазон Value
. Excel может понять, что вам нужно, в соответствии с вашей декларацией, но вам будет полезно как-то отличить его от способа определения диапазона.
Иногда вам необходимо создать массив во время анализа динамических параметров. c диапазон. Если вы не можете знать новые размеры массива и вам нужно Redim (Preserve), может быть изменено только второе измерение массива, и в таком случае должна использоваться функция Transpose
. И, наконец, полученный массив можно правильно загрузить в диапазон, только если вы знаете номер массива строк и столбцов.
Вы можете вывести строку диапазона из строки массива следующим образом: если мы ссылаемся на вышеприведенное
arrTest
, мы знаем, что его первая строка является первой строкой листа и имеет 5 столбцов.
Итак, arrTest(3, 1)
будет sh.Range("A3").Value
, а его строка будет 3.
Тогда arrTest(3, 4)
будет sh.Range("D3").Value
, и его строка будет также 3.
Если ваш массив взят из диапазона, начинающегося с пятой строки, вы должны добавить четыре, чтобы получить строку листа, извлеченную из строки массива ...
Итак, ваш пример может быть преобразован в :
If arrTest(3, 4) ="Pending" then sh.Cells(3, 4).Font.Bold=1 Else sh.Cells(3, 4).Font.Bold=0
Теперь, если вам нужен массив диапазонов, вы не можете сделать это так, как вы пытались. Вы должны использовать адрес диапазонов и построить диапазон в конце:
Sub testArraysBis()
Dim sh As Worksheet, rng As Range, rng1 As Range, lastCol As Long
Dim rng2, arrTest As Variant, arrT As Variant, arrF As Variant
Set sh = ActiveSheet
lastCol = sh.Cells(1, Cells.Columns.Count).End(xlToLeft).column
Set rng = sh.Range(sh.Cells(1, 1), sh.Cells(4, lastCol))
Set rng1 = sh.Range("A5:F6")
arrT = Array(rng.Address, rng1.Address)
arrTest = rng.value
Debug.Print UBound(arrTest), LBound(arrTest)
sh.Range("J1").Resize(UBound(arrTest, 1), UBound(arrTest, 2)).value = arrTest
Set rng2 = sh.Range(arrT(0))
Debug.Print rng2.Address
arrF = sh.Range(arrT(0)).value
Debug.Print UBound(arrF, 2)
End Sub
rng2
диапазон будет построен с использованием строки адреса, извлеченной из * Массив 1065 *. Массив (arrF
) также можно извлечь из первого элемента arrT
...
Epilog: лучший способ, с точки зрения скорости, это загрузить диапазон в массивах, выполнить всю обработку, используя их (в памяти и очень быстро из-за этого аспекта),
, но самая важная проблема - это построить другой массив (или даже диапазон, используя Union
) и извлеките данные в ОДИН РАЗ . Отправка каждого результата частичной обработки в ячейку / диапазон занимает много времени и других ресурсов, для большого размера диапазона ...