Remkomplekty.ru

IT Новости из мира ПК
1 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Excel vba многомерные массивы

Excel vba многомерные массивы

Массивы очень упрощают процесс программирования. Без них практически невозможно написать универсальную программу. Например, представьте себе, что вы манипулируете информацией о квартирах жилого дома. Вы объявляете переменные K1 — для первой квартиры, K2 — для второй и так далее. K1=54 будет означать, что площадь первой квартиры 54 кв.м., К2=72 и т.д. Теперь представим, что нам надо подсчитать общую площадь всех квартир в доме. Очевидно, что это что-то типа Total_S = K1+K2+. +Kn. В одном доме у нас 36 квартир, а в другом 144. Представляете бредовость процесса подобного программирования? Если в первом случае я должен буду использовать 36 отдельных переменных для вычисления общей площади, то для второго дома уже 144. Очень быстро вы придёте к мысли, что вам нужна переменная, состоящая из нумерованных ячеек. Тогда обретают смысл все те операторы циклов, входящие в состав любого языка программирования. Но об этом чуть позже.

Что такое массив

Массив — переменная, состоящая из некоторого количества однотипных элементов. У массива, как и у любой другой переменной, есть имя. А доступ к конкретному элементу массива осуществляется через указание в скобках после имени его индекса. Например, A(5) означает, что я обращаюсь к элементу с индексом 5 массива, имеющего имя A.

Типы массивов

Массивы в VBA и во многих других языках программирования делятся на 2 класса:

Фиксированные массивы . Такие массивы состоят из заранее известного количества элементов. Это количество определяется во время объявления массива и уже не может быть изменено в процессе его жизненного цикла. Вы, конечно же, сможете использовать меньшее количество элементов, но не существует способа увеличить количество элементов сверх объявленного.

Динамические массивы . Эти массивы можно «переобъявлять» в процессе жизненного цикла. То есть мы можем управлять количеством элементов динамических масивов в зависимости от наших потребностей. Это очень удобно, так как в подавляющем большинстве случаев программист не может заранее знать, с каким объёмом данных он столкнётся. Если вы собираетесь писать более-менее универсальные программы, то этот тип массивов определенно стоит изучить.

Объявление массивов

Объявление фиксированных массивов

Рекомендация : при объявлении массивов VBA я советую вам давать всем именам префикс » arr «. Я сторонник венгерской нотации.

Как мы видим, тут объявлено 2 одномерных массива arrTemp и arrTest . Одномерные массивы в программировании также часто называют векторами . Типом элементов первого массива является Long , второго массива — String . В этом типе синтаксиса в скобках указан максимальный индекс ( верхняя граница ) элемента массива. А что насчёт минимального индекса ( нижней границы ) массива? По-умолчанию минимальным индексом является ноль. В данном случае стандартное поведение интерпретатора языка VBA можно изменить при помощи оператора option base <0|1>. Option base 1 заставляет VBA считать нижней границей массива — единицу, а не ноль.

Таким образом, по-умолчанию массив arrTemp имеет 11 элементов — от 0 до 10. Но, если в начало модуля, в котором этот массив объявляется, вставить оператор Option Base 1 , то массив arrTemp будет иметь 10 элементов — от 1 до 10.

Помимо вышеуказанного вы вправе использовать следующий синтаксис, который НЕ зависит от option base <0|1>:

таким образом вы в явном виде указываете и нижнюю, и верхнюю границы. Как видите, нижняя граница совершенно не обязательно должна начинаться с 0 или 1. Более того, индексы границ могут принимать и отрицательные значения, главное чтобы нижняя была меньше верхней.

Помимо одномерных массивов, можно объявлять и массивы с размерностью больше единицы.

arrMulti — двумерный массив, а arrData3 — трёхмерный. Первый содержит 11*31=341 элемент, второй — 2*3*10=60 элементов. Теоретически допускается объявлять до 60 размерностей массива.

Какие типы данных могут стать элементами массива? Тут всё, как в шутке про фамилию еврея, — абсолютно любой тип данных годится на роль элемента массива, включая объектные типы, User Data Type , другие массивы (через тип Variant ). Если вы не указываете при объявлении тип данных массива, то предполагается, что этим типом является тип Variant .

Объявление динамических массивов

Динамические массивы объявляться так:

Однако, использовать их после такого объявления пока ещё нельзя. Необходимо выделить память под массив. Особенность работы с динамическим массивом как раз состоит в том, что программист отвечает за его своевременное расширение (усечение) в памяти. Для этого существует специальный оператор, который имеет следующий синтаксис:

ReDim [Preserve] varname(subscripts) [As Type]

После этого оператора, вы можете использовать элементы массива arrOpen с 0-го по 5-й. Всё, что мы говорили про оператор option base и нижнюю границу, верно и для динамических массивов. Предположим, что вы сохранили информацию в элементах 0-5 и у вас поспела новая порция информации для элементов 6-11. Чтобы разместить в данном массиве новые элементы и не потерять старые, вы должны сделать следующее:

то есть мы тут увеличиваем верхнюю границу массива и используем ключевое слово Preserve , чтобы во время этой операции не потерять текущее содержимое arrOpen , так как в противном случае (без слова Preserve ) массив будет расширен, а память заполнена нулями. Вы также вправе вообще не декларировать массив оператором Dim , а сделать это впервые через ReDim и там же указать лип элементов. Но, если вы в первом ReDim (или Dim ) указали определенный тип элементов, то в последующих операторах ReDim этот тип переопределён быть не может — возникнет ошибка на этапе компиляции проекта.

Изменение элементов массива

Пора бы нам уже научиться пользоваться нашими массивами — то есть записывать информацию в их элементы и считывать её оттуда. Это довольно просто:

Как и с обычными переменными запись информации в элемент массива происходит через оператор присваивания (=), но указанием индекса элемента массива.

Чтение элементов массива

Определение границ массива

В подпрограммах часто приходится иметь дело с массивами, которые переданы вам в качестве параметра (как это сделать показано ниже), поэтому в этом случае очень актуален вопрос определения нижней и верхней границ индекса массива. Для этого в языке предусмотрены 2 функции: LBound и UBound . Первая возвращает нижнюю границу индекса, вторая — верхнюю.

LBound( array [, dimension])

UBound( array [, dimension])

Для одномерных массивов параметр dimension можно не указывать. Для многомерных массивов его указывать необходимо. Кстати, это означает, что, если вы точно не знаете, с каким массивом имеете дело, но необходимо узнать его первую размерность, то лучше использовать вариант UBound(arrTemp,1) , а не UBound(arrTemp) , так как последний вариант вызовет ошибку, если массив окажется многомерным.

Если вы ошибётесь с указанием правильного индекса массива, то возникнет ошибка периода исполнения с кодом 9. Эта же ошибка возникнет, если вы в функции LBound / UBound укажете несуществующую размерность массива (например, 3 для двумерного массива).

Перебор элементов массива

Собственно массивы нужны для того, чтобы хранить в них однотипную информацию и перебирать их в цикле. Как правило, алгоритм делает что-то полезное с одним элементом массива, а цикл повторяет эти типовые действия для всех элементов массива.

Наиболее удобный оператор цикла для перебора элементов массива — это безусловно For . Next .

так же есть способ не заботиться об определении нижней и верхней границ, если алгоритм не требует от нас знания текущего индекса массива:

Вы, конечно, можете перебирать массив и в других типах циклов Do . Loop , но, право, смысла и удобства в этом не много. По крайней мере я не сталкивался, кажется, с ситуациями, когда для перебора массива цикл For не подошёл.

Передача массивов в подпрограммы

Массивы удобнее всего передавать в подпрограммы в виде параметра типа Variant .

Обратите внимание, что функции GetResult в качестве параметра передаются массивы. При чём, в первом случае это массив с типом элементов Long , а во втором — String . За счёт того, что внутри функции используются переменные типа Variant , то сначала функция нам возвращает сумму элементов массива arrIntegers , а во втором результат сложения (конкатенации) строк массива arrStrings . Кроме того, параметр parArray не описан как массив ( parArray As Variant ), но мы внутри функции GetResult ведём себя с ним, как с массивом ( For Each Element In parArray )! Это возможно, так как переменные типа Variant умеют определять, что им присваивается и вести себя далее в соответствии с тем, что они содержат. Если переменной parArray присвоили массив (через вызов функции — строки 17 и 18), то она себя будет вести как массив.

Читать еще:  Vba excel события листа

Массив с элементами типа массив

Продемонстрируем, как можно хранить в качестве элементов массива другие массивы.

Результат отладочной печати:

Функция Array

Данная функция полезна для создания справочных массивов. Она возвращает переменную типа Variant , содержащую одномерный массив с типом элементов Variant .

Array( arglist )

Вызов функции без параметров приведёт к возврату массива нулевой длинны. При этом будет наблюдаться интересный эффект LBound вернёт вам 0, а UBound вернёт -1, то есть верхняя граница окажется меньше нижней границы.

Функция Split

Split возвращает одномерный массив, содержащий подстроки, из строкового выражении с учётом указанного разделителя

Split(expression[, delimiter[, limit[, compare]]])

expression — строковое выражение, содержащая подстроки и разделители. Обязательный параметр.

delimiter — текстовый разделитель. Необязательный параметр. Если опущен, то предполагается, что разделителем является символ пробела.

limit — количество подстрок, которое необходимо вернуть. -1 или отсутствие параметра означает, что вернуть надо все подстроки.

compare — константа, указывающая тип сравнения для символов разделителей. 1 — текстовое сравнение (без учёта регистра), 0 — бинарное сравнение (с учётом регистра).

Результат выглядит так:

Если вы в качестве разделителя укажете пустую строку, то на выходе получите массив, состоящий из одного элемента. Кстати, split всегда возвращает массив с нулевой нижней границей вне всякой зависимости от наличия option base 1 .

Нюансы работы с динамическими массивами

Неинициализированный массив

У динамического массива есть такое промежуточное состояние, когда он уже объявлен, но ещё не содержит никаких элементов.

То есть у переменной динамического массива есть такое состояние, когда мы не можем воспользоваться вспомогательными функциями LBound / UBound для определения его (массива) статуса. Это особенно надо учитывать, когда вы пишите подпрограммы, работающие с массивами. Прежде чем работать (перебирать) массив необходимо убедиться, что он проинициализирован, в противном случае программа вылетит с ошибкой 9.

Для этого я предлагаю пользоваться функцией подобной нижеописанной IsNotEmptyArray :

Расширение массива

Как правило, расширять динамический массив приходится в цикле. Возможны 2 стратегии: расширение на 1 элемент, как только в этом есть необходимость (назовём это эластичным расширением), и расширение авансом, когда вы увеличиваете верхнюю границу скачками, скажем сразу на 100 элементов. Реализовав оба варианта, я для себя сделал вывод, что авансовое расширение получилось и компактнее, и работает быстрее, так как операция расширения, вообще говоря, затратна и, чем реже вызывается, тем лучше.

Авансовый метод вышел даже компактнее

Удаление массива

Существует оператор Erase , который полностью освобождает память из-под динамического массива. Будучи вызванным для статического массива он его обнуляет, а если он строковый, то элементам присваивается пустые строки.

Получение массива на основе диапазона Excel

Самый эффективный по скорости способ получить содержимое диапазона Excel для манипулирования в VBA — это скопировать его в массив с элементами Variant. Делается так:

Даже, если вы передаёте в массив столбец или строку, получаемый массив всегда будет иметь 2 измерения. Измерение 1 отвечает за строки, измерение 2 — за столбцы. То есть ячейка C5 будет в элементе arrTemp(5,3) . Нижняя граница таких массивов всегда будет начинаться с единицы.

Дополнительные источники

В качестве источника дополнительной информации по массивам я могу порекомендовать замечательный, исчерпывающий ресурс Чарльза Пирсона (Charles H. Pearson). Его сайт следует штудировать всем, кто серьёзно осваивает VBA. Конкретно по массивам там огромное количество готовых подпрограмм для работы с ними, исходные коды, снабженные подробнейшими комментариями, продвинутые объяснения для копающих в глубину. Без преувеличения великолепный ресурс!

Массивы в VBA

Массивы используются в большинстве языков программирования и VBA, как язык высокого уровня, тоже не мог обойтись без них. Данный материал расскажет о создании массивов, их применении, а так же вы здесь найдете примеры использования массивов. Для начала разберем синтаксис определения массивов.

Объявление массивов

Пример 1. Создание (объявление) одномерного массива выполняется, так:

В данном примере объявляются: одномерный массив Arr1, содержащий ячейки с 0-й до 10-й типа Integer, массив Arr2, содержащий ячейки с 5-й до 10-й типа String и динамический массив Arr3.

Прежде чем использовать динамический массив, его необходимо «инициализировать», т.е. выделить для него необходимую память. Менять размер динамического массива можно много раз в программе, даже в цикле, если хотите. Правда учитывайте, что выделение памяти для массива — ресурсно-затратная операция, поэтому не стоит менять размер массива очень часто, это сильно замедлит программу.

Пример 2. Инициализация динамического массива и изменение его размеров

В данном примере мы сначала с помощью ReDim задали размер динамического массива в 11 элементов (c 0-го по 10-й), а затем снова увеличили размер до 21-го элемента. Кроме того, использовали ключевое слово Preserve — означающее, что нужно сохранить уже имеющиеся элементы с их значениями (без этого ключевого слова массив обнуляется).

Примечание: изменение размеров функцией ReDim возможно только для динамических массивов. Если размер массива был изначально задан, то его размер уже не будет меняться функцией.

Пример 3. Объявление многомерного массива

Arr4 — двумерных массив 11х11 элементов, а массив Arr5 — трехмерный.

Пример 4. Создание массива массивов

В следующем примере массив Arr2 будет содержать элементы другого массива Arr1

Определение нижней и верхней границы массива

Чтобы узнать какой самый наименьший индекс у массива и какой самый максимальный индекс массива, нужно использовать функции LBound для определения нижней границы и UBound для определения верхней границы.

Пример 5. Определение границ массива

Чтобы определить границы многомерных массивов, нужно просто использовать второй параметр функций UBound и LBound.

Задание нижней границы по-умолчанию

Иногда бывает очень не удобно, что VBA начинает нумерацию элементов массивов с нуля (0), это часто может привести к путанице и усложнению кода программы. Для решения этой проблемы есть специальный оператор Option Base , аргумент которого может быть 0 или 1. Указав значение 1, индексация массивов будет начинаться с 1, а не с 0.

Пример 6. Указание нижней границы по-умолчанию.

В данном примере я намеренно использовал процедуру, чтобы показать, что Option Base нужно применять не внутри процедур и функций, а в разделе «Declarations». В результате выполнения процедуры Test будет отображено сообщение с индексом нижней границы массива, т.е. «1».

Примечание: Оператор Option Base так же влияет на функцию Array и не влияет на функцию Split (будут рассмотрены ниже), что означает, что при задании «Option Base 1», функция Array вернет массив с индексацией с 1-цы, а функция Split вернет массив с индексацией с 0.

Запись данных в массивы

Для сохранения каких-либо значений в массив, можно воспользоваться несколькими способами. С помощью примеров, покажу эти способы.

Пример 7. Запись данных в массив в цикле.

Пример 8. Запись заранее известных данных с помощью Array

Функция Array возвращает массив из перечисленных данных типа Variant. При этом, массив, который будет содержать значения, должен быть динамическим, т.е. без указания его размеров и границ.

Пример 9. Получение массива из строки с разделителями

Обход элементов массива

Обычно, массивы используются для хранения большого кол-ва данных, а не 1-2 значений, поэтому чтобы получить все эелементы и использовать их для чего-то, обычно используют циклы. Наиболее удобны в этом плане циклы For и For Each .

Пример 10. Обход элементов массива циклом For.

Пример 11. Обход элементов массива циклом For Each.

Иногда, бывает необходимость работы с массивом внутри других типов циклов, но получение значение элемента, всё-равно в них будет таким же, как и в цикле For, т.е. через индекс элемента.

Читать еще:  Vba excel address

Массивы в VBA: как работать с массивами

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

Объявление массивов

Массивы объявляются так же, как объявлена переменная, за исключением того, что объявление переменной массива использует скобки. В следующем примере размер массива указан в скобках.

  • Хотя размер массива указывается как 5, он может содержать 6 значений, поскольку индекс массива начинается с ZERO.
  • Индекс массива не может быть отрицательным.
  • Массивы VBScript могут хранить любой тип переменной в массиве. Следовательно, массив может хранить целое число, строку или символы в одной переменной массива.

Назначение значений массиву

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

Добавьте кнопку и добавьте следующую функцию.

Когда вы выполняете вышеуказанную функцию, она производит следующий вывод.

Value stored in Array index 0 : 1
Value stored in Array index 1 : VBScript
Value stored in Array index 2 : 100
Value stored in Array index 3 : 2.45
Value stored in Array index 4 : 7/10/2013
Value stored in Array index 5 : 12:45:00 PM

Многомерные массивы

Массивы не ограничиваются одним измерением, однако они могут иметь максимум 60 измерений. Двумерными массивами являются наиболее часто используемые.

В следующем примере многомерный массив объявляется с тремя строками и четырьмя столбцами.

Когда вы выполняете вышеуказанную функцию, она производит следующий вывод.

Value stored in Array index : 0 , 1 : Orange
Value stored in Array index : 2 , 2 : coffee

Объявление ReDim

Оператор ReDim используется для объявления переменных динамического массива и распределения или перераспределения пространства для хранения.

Синтаксис ReDim [Preserve] varname(subscripts) [, varname(subscripts)]
Параметр Описание

  • Preserve — необязательный параметр, используемый для сохранения данных в существующем массиве при изменении размера последнего измерения.
  • Varname — обязательный параметр, который обозначает имя переменной, которое должно соответствовать стандартным соглашениям об именах.
  • Subscript — требуемый параметр, который указывает размер массива.

пример

В следующем примере массив был переопределен, а затем значения сохранялись при изменении существующего размера массива.

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

Когда вы выполняете вышеуказанную функцию, она производит следующий вывод.

Методы массива

В VBScript есть встроенные функции, которые помогают разработчикам эффективно обрабатывать массивы. Все методы, которые используются вместе с массивами, перечислены ниже. Чтобы узнать об этом, нажмите на имя метода.

Функции для работы с массивами

LBound

Функция LBound возвращает наименьший индекс указанного массива.Следовательно, LBound массива — ZERO.

Синтаксис LBound(ArrayName[,dimension])
Параметы и Описание

  • ArrayName — обязательный параметр. Этот параметр соответствует имени массива.
  • Размер — необязательный параметр. Это принимает целочисленное значение, соответствующее размеру массива. Если это «1», то он возвращает нижнюю границу первого измерения;если это «2», то он возвращает нижнюю границу второго измерения и так далее.

пример

Добавьте кнопку и добавьте следующую функцию.

Когда вы выполняете вышеуказанную функцию, она производит следующий вывод.

The smallest Subscript value of the given array is : 0
The smallest Subscript of the first dimension of arr2 is : 0
The smallest Subscript of the Second dimension of arr2 is : 0

Функция, которая возвращает целое число, соответствующее наименьшему индексу данных массивов.

UBound

Функция UBound возвращает наибольший индекс указанного массива.Следовательно, это значение соответствует размеру массива.

Синтаксис UBound(ArrayName[,dimension])
Параметры и Описание

  • ArrayName — обязательный параметр. Этот параметр соответствует имени массива.
  • Размер — необязательный параметр. Это принимает целочисленное значение, соответствующее размеру массива. Если это «1», то он возвращает нижнюю границу первого измерения;если он равен «2», то он возвращает нижнюю границу второго измерения и т. д.

пример

Добавьте кнопку и добавьте следующую функцию.

Когда вы выполняете вышеуказанную функцию, она производит следующий вывод.

The Largest Subscript value of the given array is : 5
The Largest Subscript of the first dimension of arr2 is : 3
The Largest Subscript of the Second dimension of arr2 is : 2

Функция, которая возвращает целое число, соответствующее самому большому индексу данных массивов.

Split

Функция Split возвращает массив, который содержит определенное количество значений, разделенных на основе разделителя.

Синтаксис Split(expression [,delimiter[, count[, compare]]])
Параметры и Описание

  • Выражение — требуемый параметр. Строковое выражение, которое может содержать строки с разделителями.
  • Разделитель — необязательный параметр. Параметр, который используется для преобразования в массивы на основе разделителя.
  • Count — необязательный параметр. Количество подстрок, которые нужно вернуть, и если указано как -1, то возвращаются все подстроки.
  • Compare — Необязательный параметр. Этот параметр указывает, какой метод сравнения следует использовать.
  • = vbBinaryCompare — выполняет двоичное сравнение
  • 1 = vbTextCompare — выполняет текстовое сравнение

пример

Добавьте кнопку и добавьте следующую функцию.

Когда вы выполняете вышеуказанную функцию, она производит следующий вывод.

The value of array in 0 is :Red
The value of array in 1 is : Blue
The value of array in 2 is : Yellow

Функция, которая возвращает массив, содержащий указанное количество значений. Разделить на разделитель.

Это функция, которая возвращает строку, содержащую указанное количество подстрок в массиве. Это полная противоположная функция метода разделения.

Синтаксис Join(List[,delimiter])
Параметры и Описание

  • Список — требуемый параметр. Массив, содержащий подстроки, которые должны быть соединены.
  • Разделитель — необязательный параметр. Символ, который используется как разделитель при возврате строки. По умолчанию разделителем является Space .

пример

Добавьте кнопку и добавьте следующую функцию.

Когда вы выполняете вышеуказанную функцию, она производит следующий вывод.

The value of b is :Red Blue Yellow
The Join result after using delimiter is : Red$Blue$Yellow

Функция, которая возвращает строку, содержащую указанное количество подстрок в массиве. Это полная противоположная функция метода разделения.

Filter

Функция фильтра, которая возвращает массив на основе нуля, который содержит подмножество массива строк на основе определенных критериев фильтра.

Синтаксис Filter(inputstrings, value[, include [,compare]])
Параметры и Описание

  • Inputstrings — обязательный параметр. Этот параметр соответствует массиву строк для поиска.
  • Значение — требуемый параметр. Этот параметр соответствует строке для поиска по параметру inputstrings.
  • Include — необязательный параметр. Это логическое значение, которое указывает, следует ли возвращать подстроки, которые включают или исключают.
  • Compare — Необязательный параметр. Этот параметр описывает, какой метод сравнения строк должен использоваться.
  • = vbBinaryCompare — выполняет двоичное сравнение
  • 1 = vbTextCompare — выполняет текстовое сравнение

пример

Добавьте кнопку и добавьте следующую функцию.

Когда вы выполняете вышеуказанную функцию, она производит следующий вывод.p The Filter result 1: Blue
The Filter result 2: Red
The Filter result 2: Blue
The Filter result 2: Yellow
The Filter result 3: Yellow

Функция, которая возвращает массив с нулевым основанием, который содержит подмножество массива строк на основе определенных критериев фильтра.

IsArray

Функция IsArray возвращает логическое значение, указывающее, является ли указанная входная переменная переменной или переменной NOT переменной массива.

Синтаксис IsArray(variablename)
пример

Добавьте кнопку и добавьте следующую функцию.

Когда вы выполняете вышеуказанную функцию, она производит следующий вывод.

The IsArray result 1 : True
The IsArray result 2 : False

Функция, возвращающая логическое значение, указывающее, является ли входная переменная массивом.

Erase

Функция Erase используется для сброса значений массивов фиксированного размера и освобождения памяти динамических массивов.Он ведет себя в зависимости от типа массивов.

Синтаксис Erase ArrayName

  • Фиксированный числовой массив, каждый элемент в массиве сбрасывается до нуля.
  • Исправлен строковый массив, каждый элемент в массиве сбрасывается до нулевой длины «».
  • Массив объектов, каждый элемент в массиве сбрасывается до специального значения Nothing .

пример

Добавьте кнопку и добавьте следующую функцию.

Когда вы выполняете вышеуказанную функцию, она производит следующий вывод.

The value at Zeroth index of NumArray is
The value at First index of NumArray is
The value at Second index of NumArray is
The value at Third index of NumArray is

Функция, которая восстанавливает выделенную память для переменных массива.

Читать еще:  Vba excel имя листа

Массивы в Visual Basic for Application

Массивы в Visual Basic for Application – это структуры, которые обычно хранят наборы взаимосвязанных переменных одного типа. Доступ к записям массива осуществляется по их числовому индексу.

Например, есть команда из 20 человек, имена которых нужно сохранить для дальнейшего использования в коде VBA. Можно было бы просто объявить 20 переменных для хранения каждого имени, вот так:

Но можно использовать гораздо более простой и организованный способ – сохранить список имён членов команды в массиве из 20 переменных типа String:

В строке, показанной выше, мы объявили массив. Теперь запишем значение в каждый из его элементов, вот таким образом:

Дополнительное преимущество хранения данных в массиве, по сравнению с использованием отдельных переменных, становится очевидным, когда возникает необходимость выполнить одно и то же действие над каждым элементом массива. Если бы имена членов команды были сохранены в 20 отдельных переменных, то потребовалось бы каждый раз записывать 20 строк кода, чтобы выполнить одинаковое действие с каждым из них. Однако, если имена сохранены в массиве, то выполнить нужное действие с каждым из них можно при помощи простого цикла.

Как это работает продемонстрировано ниже на примере кода, который выводит имена каждого члена команды последовательно в ячейки столбца A активного рабочего листа Excel.

Очевидно, что работа с массивом, в котором сохранено 20 имён, значительно менее громоздка и более аккуратна, чем использование 20 отдельных переменных. А что, если этих имён не 20, а 1000? А если, вдобавок, требуется сохранить отдельно фамилии и отчества?! Ясно, что вскоре станет совершенно невозможно справиться с таким объёмом данных в коде VBA без помощи массива.

Многомерные массивы в Excel Visual Basic

Массивы Visual Basic, о которых шла речь выше, считаются одномерными. Это означает, что они хранят простой список имён. Однако, массивы могут иметь множество измерений. Например, двумерный массив можно сравнить с сеткой значений.

Предположим, что нужно сохранить ежедневные показатели продаж за январь для 5 разных команд. Для этого потребуется двумерный массив, состоящий из 5 наборов показателей для 31 дня. Объявим массив таким образом:

Для того, чтобы получить доступ к элементам массива Jan_Sales_Figures, нужно использовать два индекса, указывающих день месяца и номер команды. Например, адрес элемента, содержащего показатели продаж для 2-ой команды за 15-ое января будет записан так:

Таким же образом можно объявить массив с 3-мя и более измерениями – достаточно добавить дополнительные измерения в объявление массива и использовать дополнительные индексы для ссылки на элементы этого массива.

Объявление массивов в Excel Visual Basic

Ранее в этой статье мы уже рассмотрели несколько примеров объявления массивов в VBA, но эта тема заслуживает более подробного рассмотрения. Как было показано, одномерный массив можно объявить вот так:

Такое объявление сообщает компилятору VBA, что массив Team_Members состоит из 20 переменных, к которым можно обратиться по индексам от 1 до 20. Однако, нам может прийти в голову пронумеровать наши переменные массива числами от 0 до 19, и в таком случае массив должен быть объявлен вот так:

На самом деле, по умолчанию нумерация элементов массива начинается с 0, и в объявлении массива начальный индекс может быть не указан вовсе, вот так:

Такую запись компилятор VBA расценит, как объявление массива из 20 элементов с индексами от 0 до 19.

Эти же правила действуют при объявлении многомерных массивов Visual Basic. Как уже было показано в одном из примеров, при объявлении двумерного массива индексы его измерений разделяются запятой:

Однако, если не указывать начальный индекс для обоих измерений массива и объявить его вот так:

то эта запись будет расценена, как двумерный массив, первое измерение которого содержит 32 элемента с индексами от 0 до 31, а второе измерение массива содержит 6 элементов с индексами от 0 до 5.

Динамические массивы

Все массивы в рассмотренных выше примерах имеют фиксированное количество измерений. Однако, во многих случаях мы не знаем заранее, какого размера должен быть наш массив. Можно выйти из ситуации, объявив огромный массив, размер которого будет наверняка больше, чем нужно для нашей задачи. Но такое решение потребует много лишней памяти и может замедлить работу программы. Есть решение лучше. Мы можем использовать динамический массив – это такой массив, размер которого может быть установлен и изменён сколько угодно раз в процессе выполнения макроса.

Динамический массив объявляется с пустыми скобками, вот так:

Далее нужно будет объявить измерение массива в процессе выполнения кода при помощи выражения ReDim:

И если в процессе выполнения кода потребуется снова изменить размер массива, то можно использовать выражение ReDim снова:

Нужно иметь в виду, что изменение размера динамического массива таким способом приведёт к потере всех значений, хранившихся в массиве. Для того, чтобы сохранить данные, уже находящиеся в массиве, нужно использовать ключевое слово Preserve, как показано ниже:

К сожалению, ключевое слово Preserve можно использовать только, чтобы изменить верхнюю границу измерения массива. Нижнюю границу массива таким образом изменить нельзя. Кроме того, если массив имеет несколько измерений, то, используя ключевое слово Preserve, можно изменить размер только последнего измерения массива.

Массивы в Excel VBA

В данной статье подробно рассматриваются массивы на языке программирования Excel VBA. Рассматриваются различные вопросы и схемы применения, такие как:

  • Зачем нужны массивы
  • Когда нужно применять массивы
  • Типы массивов
  • Использования многомерных массивов
  • Объявление массивов
  • Добавление значений
  • Просмотр всех элементов
  • Эффективный способ чтения диапазонов (Range) в массив

Типы массивов VBA

В VBA есть два типа массивов:
Статический – массив фиксированного размера.
Динамический – массив, в котором размер задается во время выполнения.
Разница между этими массивами в основном в том, как они создаются. Доступ к значениям в обоих типах массивов абсолютно одинаков. В следующих разделах мы рассмотрим оба типа.

Объявление массива

Статический массив объявляется следующим образом

Как видите, при объявлении статического массива указывается его размер. Но проблема в том, что вы никогда не можете заранее знать, какой размер вам нужен. Каждый раз при запуске макроса у вас могут быть разные требования к размеру массива

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

Динамические массивы не имеют таких проблем. Размер массивы не указывается при объявлении. Поэтому его размер может расти и уменьшаться по мере необходимости

Динамический массив не создается, пока вы не используете оператор ReDim. Преимущество в том, что вы можете подождать, пока не узнаете количество элементов, прежде чем устанавливать размер массива. Со статическим массивом вы должны указать размер заранее.

Чтение из диапазона ячеек в массив

VBA имеет очень эффективный способ чтения из диапазона ячеек в массив и наоборот

Динамический массив, созданный в этом примере, будет двухмерным массивом. Как видите, мы можем прочитать весь диапазон ячеек в массив всего за одну строку.

В следующем примере будут считаны данные из диапазона C3: E6 листа Sheet1 и отображены в окне Immediate Window.

Как сделать выполнение ваших макросов супер скоростным

Если ваши макросы работают очень медленно, этот метод может оказаться очень полезным. Особенно если вы имеете дело с большими объемами данных.

Обновление значений в массивах происходит гораздо быстрее, чем обновление значений в ячейках.

В последнем разделе вы увидели, как мы можем легко читать из группы ячеек в массив и наоборот. Если мы обновляем много значений, мы можем сделать следующее

  1. Копируем данные из ячеек в массив.
  2. Изменяем данные в массиве.
  3. Копируем обновленные данные из массива обратно в ячейки.

Например, следующий код будет намного быстрее, чем код ниже

Назначение из одного множества ячеек в другой также намного быстрее, чем с помощью копирования и вставки

Ссылка на основную публикацию
Adblock
detector