Vba работа с массивами: Все про массивы в VBA читать в пошаговом руководстве по Excel
Содержание
Функции VBA и массивы значений
Возможности Excel »
Макросы »
Функции и массивы значений
В этой статье разберем примеры, которые раскроют тему создания функций с неограниченным количеством аргументов и тему создания функций, возвращающих массив значений.
Скачать
Создание функций с бесконечным количеством аргументов
В предыдущих примерах мы создавали функции, в которых в качестве аргументов выступало одно значение. Но есть функции, у которых в качестве переменной выступает массив значений. Примерами таких функций встроенных в Excel служат функции СУММ, ВПР, МАКС, СРЗНАЧ и так далее. Давайте теперь создадим свою похожую функцию.
Далее приведен код функции, которая суммирует все четные значения.
Function СуммаЧетных(Диапазон As Range) As Double Dim r As Range Dim S As Double For Each r In Диапазон If r.Value Mod 2 = 0 Then S = S + r.Value Next СуммаЧетных = S End Function
В первой строке данной функции можно увидеть, что переменной Диапазон мы присвоили тип Range (Диапазон As Range). Таким образом, в качестве аргумента функции мы можем использовать диапазон ячеек. Применим эту функцию на рабочем листе Excel.
Как видно из рисунка, мы не перечисляли каждое значение, а использовали диапазон ячеек A2:A11.
Теперь немного разберем код. Мы использовали цикл For Each — Next. Его задача пройтись по каждой ячейке нашего диапазона. Предварительно мы объявили еще одну переменную r типа Range. Она будет хранить значение каждой ячейки.
For Each r In Диапазон
Далее идет проверка значения ячейки и если оно кратно 2, то мы суммируем результат во временную переменную S.
If r.Value Mod 2 = 0 Then S = S + r.Value
В конце, после цикла, мы присваиваем функции СуммаЧетных значение просуммированных элементов S.
Создание функций с неопределенным количеством аргументов
Предыдущая функция имеет недостаток — если вы попытаетесь использовать в качестве переменной несмежный диапазон ячеек, то получите ошибку. Иногда требуется более универсальная функция, так как на старте мы можем не знать количество аргументов, которые будут использоваться. Например, всем известная функция СУММ может принимать неограниченное количество аргументов =СУММ(A1;B1:B5;1;2;3), функция все рано вернет верный результат.
Вы можете создать свою аналогичную функцию в VBA, указав к последнему (или единственному) аргументу ключевое слово ParamArray.
ParamArray — данный модификатор применяется только к последнему аргументу. Аргумент с данным модификатором всегда должен иметь тип данных Variant и всегда является необязательным, ключевое слов Optional не указывается дополнительно
Теперь давайте создадим функцию, которая может принимать произвольное количество аргументов/ А в качестве результата возвращать всю туже сумму нечетных значений.
Function СуммаЧетных2(ParamArray Значения() As Variant) As Double Dim v As Variant Dim S As Double For Each v In Значения If v Mod 2 = 0 Then S = S + v Next СуммаЧетных2 = S End Function
Данная функция может принимать любое количество аргументов, однако аргументы не могут быть многомерные, это означает, что мы не можем указывать диапазоны, а должны перечислить все значения или все ячейки. Как это показано на рисунке далее.
Что же делать, если необходимо использовать различные диапазоны ячеек, а не перечислять каждый элемент отдельно. Рассмотрим следующий код функции, который реализует эту возможность.
Function СуммаЧетных3(ParamArray Диапазоны() As Variant) As Double Dim v As Variant Dim r As Variant Dim S As Double For Each v In Диапазоны For Each r In v If r Mod 2 = 0 Then S = S + r Next Next СуммаЧетных3 = S End Function
У нас добавился еще один цикл For Each — Next. Т.е. сначала мы проходим по всем аргументам (диапазонам ячеек), а после проходим по всем ячейкам этих диапазонов.
Этот код тоже далек от идеала: если мы будем использовать вместо диапазонов значения, то получим ошибку. Поэтому если необходимо создать идеальную функцию, например как СУММ (она может обработать любые типы аргументов), то придется потрудится и дополнительно проверять тип аргументов. Но об это уже поговорим в другой раз. Перейдем к созданию еще одного типа функций.
Создание функции, возвращающих массив значений
Надеюсь вы знаете, как использовать формулы массивов в Excel. Эти функции вводятся на рабочий лист Excel с помощью сочетания клавиш Ctrl + Shift + Enter. Сейчас мы создадим функцию, которая возвратит массив значений. Например, выведет нам список всех месяцев.
Function СписокМесяцев() СписокМесяцев = Array("Январь", "Февраль", "Март", "Апрель", _ "Май", "Июнь", "Июль", "Август", _ "Сентябрь", "Октябрь", "Ноябрь", "Декабрь") End Function
Если мы введем функцию в одну ячейку, то увидим, что результатом будет только Январь. Чтобы понять как работает функция необходимо выделить 12 ячеек по горизонтали, ввести =СписокМесяцев() и нажать сочетание клавиш Ctrl + Shift + Enter.
Если необходимо вывести список месяцев по вертикали, то можно дополнительно использовать функцию =ТРАНСП(СписокМесяцев()).
Возможно покажется, что функции, возвращающие массив достаточно бесполезны. Однако это не так, да они реже используются на рабочем листе Excel, но я надеюсь что они будут незаменимой вещаю в ваших будущих программах на VBA.
Скачать
Рекомендуем к прочтению
Как записать макрос в Excel? Пошаговая инструкция
Создаем свою первую функцию в Excel
Аргументы функции на VBA
Как получить список файлов в Excel с помощью VBA
Комментарии:
Please enable JavaScript to view the comments powered by Disqus.comments powered by Disqus
«Массивы и циклы VBA Excel», цена 650 руб.
— видеокурсы «Смотри Учись»
Инструктор
Роберт Киракосян
ИТ менеджер и тренер
Работаю в области ИТ более 20 лет, закончил Московский институт электронной техники. Работал начальником управления информационных технологий в компании «Группа ГАЗ», «EN+ менеджмент». Руководил проектом по внедрению SAP
Описание курса
Работая с большими объемами информации, мы решаем несколько сложных задач одновременно. Как сделать так, чтобы работа выполнялась автоматически? Роберт Киракосян, IT-специалист с 20-летним стажем, рекомендует использовать динамические массивы VBA Excel и функции массивов VBA Excel, которые обрабатывают группу данных и выдают итог.
Все станет проще! Например, чтобы подсчитать все книги в доме, вы назначаете переменные: K1 – объем книг на одной полке, K2 – на второй… Ваша библиотека — это K1+K2+…+Kn. Абсурдное программирование, правда? Меж тем, вам нужна переменная из нумерованных ячеек (полки) — и операторы циклов тут же обретут смысл. Причем это актуально для любого языка программирования.
Курс посвящен работе с динамическими массивами VBA Excel, их отличию от фиксированных массивов и циклам VBA Excel. Он полезен всем, кто работает с большими объемами информации: студентам, аналитикам, финансистам.
Учебный план
Раздел 1: Массивы |
|||
Лекция 1.1 | Понятие массива | 3:16 | |
Назначение и типы массивов. |
|||
Лекция 1.2 | Фиксированные массивы | 9:31 | |
Описание фиксированных массивов. |
|||
Лекция 1. |
Динамические массивы | 8:33 | |
Объявление динамических массивов, их расширение, как не потерять уже введённые в динамический массив данные. |
|||
Тест 1.1 | Объявление массивов | 1:30 | |
Раздел 2: Циклы и массивы |
|||
Лекция 2.1 | Фиксированные массивы и циклы | 21:52 | |
Совместное использование фиксированных массивов и цикла FOR. |
|||
Лекция 2.2 | Динамический массив и текущая область | 8:44 | |
Запоминаем текущую область в двумерный динамический массив. |
|||
Лекция 2.3 | Увеличение размера динамического массива | 9:19 | |
Увеличение размера динамического массива, использование Preserve и цикл While. |
|||
Тест 1 | Вопросы к курсу | 2:30 |
Отзывы
Отзывов пока нет
Акция | |
Промокод | |
Итого к оплате | |
Списать со счёта |
|
Сумма к оплате |
Доступно бонусов: 0
Оплата деньгами производится через сервис ROBOKASSA, принимающий платежи самыми разными способами
(карты VISA/MasterCard, электронные кошельки и другие).
После оплаты, пожалуйста, нажмите на кнопку «Вернуться в магазин» для возврата на наш сайт. Защищенное соединение.
Оплата деньгами производится через сервис PayAnyWay,
принимающий платежи самыми разными способами (карты VISA/MasterCard, электронные кошельки и другие).
PayAnyWay не передает данные Вашей карты магазину и иным третьим лицам.
Безопасность платежей с помощью банковских карт обеспечивается технологиями защищенного соединения HTTPS и двухфакторной аутентификации пользователя 3D Secure.
После оплаты, пожалуйста, нажмите на кнопку «Вернуться в магазин» для возврата на наш сайт.
К сожалению, мы не можем принять платеж из Вашей страны
Курс в подарок для:
Смотри. Учись.
Для оформления чека согласно 54-ФЗ, пожалуйста, введите E-mail
Нажимая на кнопку Оплатить, вы даете свое согласие на выдачу чека в электронном формате и
обработку персональных данных,
а также подтверждаете достоверность предоставленных данных
Подтвердите покупку в рассрочку
У вас уже есть карта рассрочки?
Необходимо заполнить данные
Для покупки данного необходимо заполнить данные в разделе Выдача диплома.
Перейти
Покупка
Нажимая на кнопку «Купить», вы соглашаетесь с соглашением об оказании образовательных услуг и принимаете, что выдача диплома установленного образца произойдет только после предоставления Вами скана копии вашего паспорта.
До конца акции
—:—:—
Новый курс
Это Ваш курс
Оплатить бонусами
Оплатить бонусами
Сертификат об окончании
Информация о курсе
- Продолжительность 1 ч
- 6 лекций, 2 теста, 3 доп. материала
…
Я принимаю условия
публичной оферты
на участие в реферальной программе
…
Узнать больше
Выберите пакет
Цена курсов по отдельности
Скидка на пакет | |
Промокод | |
Итого к оплате | |
Списать со счёта |
|
Сумма к оплате |
Оплата деньгами производится через сервис ROBOKASSA, принимающий платежи самыми разными способами
(карты VISA/MasterCard, электронные кошельки и другие).
После оплаты, пожалуйста, нажмите на кнопку «Вернуться в магазин» для возврата на наш сайт. Защищенное соединение.
Оплата деньгами производится через сервис PayAnyWay,
принимающий платежи самыми разными способами (карты VISA/MasterCard, электронные кошельки и другие).
PayAnyWay не передает данные Вашей карты магазину и иным третьим лицам.
Безопасность платежей с помощью банковских карт обеспечивается технологиями защищенного соединения HTTPS и двухфакторной аутентификации пользователя 3D Secure.
После оплаты, пожалуйста, нажмите на кнопку «Вернуться в магазин» для возврата на наш сайт.
К сожалению, мы не можем принять платеж из Вашей страны
Для оформления чека согласно 54-ФЗ, пожалуйста, введите E-mail
Нажимая на кнопку Оплатить, вы даете свое согласие на выдачу чека в электронном формате и
обработку персональных данных,
а также подтверждаете достоверность предоставленных данных
Подтвердите покупку в рассрочку
У вас уже есть карта рассрочки?
Необходимо заполнить данные
Для покупки данного необходимо заполнить данные в разделе Выдача диплома.
Перейти
Покупка
Нажимая на кнопку «Купить», вы соглашаетесь с соглашением об оказании образовательных услуг и принимаете, что выдача диплома установленного образца произойдет только после предоставления Вами скана копии вашего паспорта.
Похожие курсы в данной категории:
Работа с массивами
Как вы, наверное, знаете, массив — это набор последовательно проиндексированных элементов, имеющих один и тот же тип данных.
Каждый элемент массива имеет уникальный идентификационный номер индекса. Массивы VBA очень быстрые, поэтому используются повсеместно.
Массивы гибки: они могут иметь несколько измерений и могут использоваться для реализации списков, матриц или более абстрактных пространств данных.
В качестве примера вы можете создать простой массив strWords ниже.
В этом случае у нас есть простой массив фиксированной длины или статический массив (динамические массивы более гибкие, но статический — это простая отправная точка).
Первому элементу массива strWords присваивается значение «Hello», второму — «World».
Итак, у нас есть переменная strWords, представляющая 9Список 0005.
Наконец, цикл For Each используется для записи элементов списка в
Сразу окно.
Dim strWords (от 0 до 1) как строка стрВордс(0) = "Привет" стрВордс(1) = "Мир" Dim str как вариант Для каждой строки в строке strWords Debug.Print ул. Далее
Основываясь на базовой функциональности, пользователи написали функции, которые выполняют над ними все виды операций.
Они доступны в надстройке Code VBA в модуле modArrayPreconditions.
который автоматически добавляется в ваш проект, когда вы используете одну из функций, включенных в раздел 9.0011 VBA » Массив » Фрагменты подменю.
Обратите внимание, что вы можете расширить коллекцию фрагментов своими собственными процедурами и фрагментами кода.
Эта страница знакомит вас с основами массива. Кроме того, дается информация о наиболее часто используемых функциях массива,
специальные процедуры для списков, матриц, массивов с объектами, предварительные условия тестирования и многое другое находятся на отдельных страницах.
- Объявление переменных массива и присвоение значений
- Использование динамических массивов
- Функция массива
- Функция разделения
- Установить размер динамического массива ReDim Preserve
- Цикл по массиву, LBound и UBound
- Передать массив между процедурами
- Проверка предварительных условий входного массива
- Переменный массив
- Является динамическим массивом
- Массив выделен или пуст
- Количество измерений массива
- Количество элементов в массиве
Объявление переменных массива и присвоение значений
Чтобы иметь возможность работать с переменной-массивом, мы должны сначала объявить ее.
В дополнение к присвоению ему имени и выбору типа данных, которые он будет хранить, мы можем претендовать на фиксированное пространство — статическое.
или оставьте размер открытым, полагаясь на процесс, который назначает данные для его обработки.
Статический массив
Статический массив — это массив, размер которого указан в операторе Dim, объявляющем массив. Например.
Dim arrNumbers (от 1 до 10) As Long аррнумберс (1) = 1 arrNumbers(2)=10 'и так далее'
Вы не можете изменить размер статического массива, что ограничивает использование такого типа массива ситуациями
где вы заранее знаете, сколько предметов будет храниться.
Использование динамических массивов
Динамический массив — это массив, размер которого не указан в операторе Dim. Dim arrNumbers() как целое число
объявляет имя и указывает тип, размеры определяются либо процедурой заполнения массива, например, приведенными ниже,
или используя ReDim
.
Заполнение динамического массива с помощью функции Array
Удобный способ заполнить динамический массив заданным списком значений — использовать функцию Array, например.
Dim varWeekDays() как вариант varWeekDays = Array("Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс")
Примечания
- В приведенном выше примере varWeekDays(2) (при условии, что значение по умолчанию Option Base 0) содержит «Среда» — индекс начинается с 0.
- Эта изящная функция не работает, если вы объявили статический массив, такой как
Dim varWeekDays(1 to 7) As Variant
.
В таком случае вы получаете ошибку времени компиляции «Невозможно назначить массиву». - Массив объявлен
как Variant
. Вы также можете составить список других типов, кроме строк, таких как числа, массив (1,2,3)
или даты - Элементы разделяются запятой.
.
Заполнение динамического массива строк с помощью функции разделения
Много входных данных поступает к нам в виде String
. Функция Split
может преобразовать строку в такой массив:
Dim strWeekDays() как строка strWeekDays = Split(Expression:="Пн,Вт,Ср,Чт,Пт,Сб,Вс", Разделитель:=",")
Более подробную информацию об использовании функции разделения можно найти здесь.
Установить размер динамического массива ReDim Preserve
Динамический массив — это массив, размер которого не указан в операторе Dim. Вместо этого он определяется оператором ReDim. Например,
Dim DynamicArray() As Long ReDim DynamicArray (от 1 до 10)
Вы можете изменить размер динамического массива, но не тип данных.
Чтобы сохранить данные, уже содержащиеся в массиве, вы должны использовать ключевое слово Preserve:
Резерв ReDim DynamicArray (от 1 до 12)
Когда вы стираете динамический массив, память, выделенная для массива, освобождается.
Вы должны изменить размер массива, чтобы использовать его после того, как он был стерт.
Цикл по массиву
Существует два способа зацикливания массивов. Наиболее распространенной практикой является использование For i = LBound to UBound массива; в
Цикл For Each element можно использовать только с одномерными массивами.
Для i LBound to UBound массива
Обычной практикой для зацикливания массивов является использование функций нижней и верхней границы:
LBound
дает наименьшее значение индекса массива, UBound
наибольшее значение.
Начальная (базовая) точка индекса массива определяется несколькими факторами, которые разрешаются с помощью этих функций.
Dim i как целое число Для i = LBound(strWords) в UBound(strWords) Debug.Print strWords(i) Далее
Чтобы просмотреть список в обратном порядке, используйте
Для i = UBound(strWords) To LBound(strWords) Шаг -1
Для каждого элемента в массиве
Альтернативой распространенной практике зацикливания массивов с использованием For i LBound to UBound
является использование For Each
.
Это имеет преимущество в большей интуитивности; при зацикливании списка мы не заботимся об индексах и границах.
Однако у каждого есть недостатков : во-первых, вы не можете пройтись по списку в обратном направлении,
во-вторых, порядковый номер недоступен в явном виде, хотя в некоторых случаях он может понадобиться вам в вашем процессе,
наконец, вам не разрешено указывать тип выбранного элемента, вы должны использовать Как вариант
, который менее информативен.
ул. Дим Как вариант Для каждой строки в строке strWords Debug.Print ул. Далее
Передача массива между процедурами
Массивы, передаваемые между процедурами с использованием аргументов, обычно имеют тип Как Variant
, например:
Public Sub ReverseArrayInPlace (InputArray As Variant)
Причина в том, что случай, когда вы знаете точный тип или размер, вряд ли когда-либо произойдет.
Проверка предварительных условий входного массива
Как правило, вы знаете детали типа переменной Variant, например. является ли id=массивом, если он динамический и т.д.
-если ваша программа предоставляет переменное содержимое.
Однако, если вы создали общие процедуры, которые используются другими,
или вы зависите от другого процесса в качестве поставщика значения, рекомендуется добавить в процедуру некоторые базовые проверки.
Такие проверки часто называют «предварительными условиями», и для массивов они включены в модуль modArrayPreconditions.
который автоматически добавляется в ваш проект при выборе одной из функций, включенных в
VBA » Массив » Фрагменты подменю, в котором отображаются материалы, связанные с массивом, во фрагментах надстройки Code VBA.
Переменный массив
Первая проверка в случае такого ввода типа Variant
состоит в том, чтобы увидеть, действительно ли это массив.
Для этого мы можем использовать встроенную функцию IsArray
. На самом деле, вы можете использовать встроенную функцию TestVariantIsArray
что вызывает исключение в таком случае, чтобы ваша программа обрабатывала ошибки в дальнейшем в качестве хорошей практики
Public Sub TestVariantIsArray (переменная в виде варианта, необязательное имя переменной в виде строки, необязательная процедура в виде строки, необязательный модуль в виде строки) Если IsArray(Variable) = False Then Err.Raise mclngErrNumberNotAnArray, Module & IIf(IsMissing(Module), "", ".") & procedure, VariableName & " is not a array" Конец суб
Является динамическим массивом
Если процедура предназначена для определения или изменения количества элементов ошибки, мы должны убедиться, что массив является динамическим.
Для этого адаптирована версия Процедура IsArrayDynamic
Чипа Пирсона добавлена в коллекцию фрагментов массива.
Массив выделен или пуст
Выделяется массив, если он является статическим или динамическим массивом, размер которого был изменен с помощью инструкции ReDim.
Статические массивы всегда выделены и никогда не бывают пустыми.
Вы можете проверить, выделена ли переменная с помощью IsArrayAllocated
, включенного в фрагменты массива.
Наоборот, там же можно найти функцию IsEmpty
. Опять же, обе включенные процедуры адаптированы из книги Чипа Пирсона.
Количество измерений массива
Некоторые процедуры, такие как приведенные выше, работают с любым массивом, независимо от количества измерений. Некоторые работают только для массивов списков или матричных массивов.
Чтобы убедиться, что процедура уместна там, где вы хотите ее использовать, используйте функцию NumberOfArrayDimensions
.
Публичная функция NumberOfArrayDimensions (Arr As Variant) как целое число 'Эта функция возвращает количество измерений массива.'Нераспределенный динамический массив имеет 0 измерений. 'Это условие также можно проверить с помощью IsArrayEmpty. 'Адаптировано из modArraySupport Чипа Пирсона. Dim Ndx как целое число Dim Res как целое число При ошибке Возобновить Далее ' Цикл, увеличивающий размерный индекс Ndx, пока не возникнет ошибка. ' Произойдет ошибка, когда Ndx превысит количество измерений ' в массиве. Возврат Ndx-1. Делать Ndx = Ndx + 1 Res = UBound(Arr, Ndx) Цикл до Err.Number 0 NumberOfArrayDimensions = Ndx - 1 Завершить функцию
Количество элементов в массиве
Если вам нужно узнать количество элементов в определенном измерении массива, вы можете использовать функцию NumElements
.
Общедоступная функция NumElements (Arr As Variant, необязательное измерение = 1) As Long ' Возвращает количество элементов в указанном измерении (Dimension) массива в ' обр. Если вы опустите Dimension, будет использовано первое измерение. Функция вернется '0 при следующих обстоятельствах: ' Arr не является массивом или ' Arr - нераспределенный массив, или ' Размерность больше, чем число размерностей Arr, или 'Размер меньше 1.' ' Эта функция не поддерживает массивы пользовательских переменных Type. 'Адаптировано из modArraySupport Чипа Пирсона. Dim NumDimensions As Long 'Предварительные условия - эти функции вызывают ошибку, когда условие не выполняется TestVariantIsArray Переменная: = Arr, VariableName: = "Arr", Процедура: = "NumElements", Модуль: = mcstrThisModule ' если массив не распределен, вернуть 0 и выйти. Если IsArrayEmpty(Arr) = True Тогда Количество элементов = 0 Выход из функции Конец, если ' убедитесь, что размерность не меньше 1. Если размер
Ячейки и диапазоны Excel — Работа с массивами
Excel > Ячейки и диапазоны
Перенос между массивами с диапазонами
Перенос значений ячеек в массив, а затем обратно после некоторых манипуляций является чрезвычайно распространенным явлением.
Может оказаться более эффективным загрузить значения из диапазона в массив, обработать данные и затем записать их обратно, чем обращаться к каждой ячейке по отдельности.
Dim arMyArray() As Variant
arMyArray = Range("A1:D5"). ЗначениеRange("A1:D5").Value = arMyArray
Заполнение массива
Самый простой способ заполнить диапазон значениями Variant тип данных
Вам не нужно определять размер массива перед его заполнением.
Это возможно, только если переменная определена как Variant.
'оба этих объявления будут работать
Dim arTesting As Variant
Dim arTesting() As VariantarTesting = Range("A1:A12").Value
Это создаст следующий тип массива:
Обратите внимание, что этот массив является двумерным и начинается с 1, а не с 0.
Этот массив всегда двумерный, даже если вы имеете в виду одну строку или столбец.
В этом массиве всегда сначала столбцы, а затем строки (проверьте !!) с SS
Заполнение диапазона
Самый быстрый способ заполнить диапазон содержимым массива — определить значение, равное массиву.
Обратите внимание, что это создаст горизонтальный массив , который заполнит строку на листе.
Dim arTesting As Variant
arTesting = VBA.Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
Range("A1:L1").Value = arTesting
Это создаст таблицу на листе.
Если вы хотите создать вертикальный массив , который будет заполнять столбец вниз по рабочему листу, вы должны транспонировать массив, прежде чем назначать его диапазону.
Dim arTesting As Variant
arTesting = VBA.Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
arTesting = Application.WorksheetFunction.Transpose(arTesting)
Range ("A1:A12").Value = arTesting
Это создаст таблицу вниз по рабочему листу.
Пустое значение
Dim aMyArray As Variant
aMyArray = Range("A1"). Значение
aMyArray имеет значение Empty, если ячейка «A1» пуста
aMyArray") = Range("A1").![]()