|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Все про массивы в VBA
Время создания: 12.10.2019 20:24
Раздел: Разные закладки - VBA - Array
Запись: xintrea/mytetra_db_adgaver_new/master/base/1570883844sspzu53dni/text.html на raw.githubusercontent.com
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Автор Дмитрий Якушев На чтение24 мин. Просмотров2.7k. Дональд Кнут Список настолько же силен, как и его самое слабое звено В следующей таблице приведена краткая справка по использованию массивов в VBA. Оставшаяся часть статьи содержит наиболее полное руководство, которое вы найдете о массивах VBA. Содержание
Краткое руководство по массивам VBA
В этой статье подробно рассматриваются массивы на языке программирования Excel VBA. Она охватывает важные моменты, такие как:
В первом разделе мы рассмотрим, что такое массивы и зачем они нужны. Вы можете не понимать часть кода в первом разделе. Это отлично. Я буду разбивать на простые термины в следующих разделах статьи. Иногда коллекции лучше, чем массивы. Вы можете прочитать о коллекциях здесь . Массивы и циклы идут рука об руку. Наиболее распространенными циклами, которые вы используете с массивами, являются циклы For и For Each. Что такое массивы и зачем они нужны? Массив VBA — это тип переменной. Используется для хранения списков данных одного типа. Примером может быть сохранение списка стран или списка итогов за неделю. В VBA обычная переменная может хранить только одно значение за раз. В следующем примере показана переменная, используемая для хранения оценок ученика.
Если мы хотим сохранить оценки другого ученика, нам нужно создать вторую переменную. В следующем примере у нас есть оценки пяти студентов Мы собираемся прочитать эти отметки и записать их в Immediate Window. Примечание. Функция Debug.Print записывает значения в Immediate Window. Для просмотра этого окна выберите View-> Immediate Window из меню (сочетание клавиш Ctrl + G). Как видите в следующем примере, мы пишем один и тот же код пять раз — по одному для каждого учащегося.
Ниже приведен вывод из примера Проблема с использованием одной переменной для каждого учащегося заключается в том, что вам необходимо добавить код для каждого учащегося. Поэтому, если в приведенном выше примере у вас будет тысяча студентов, вам понадобится три тысячи строк кода! К счастью, у нас есть массивы, чтобы сделать нашу жизнь проще. Массивы позволяют нам хранить список элементов данных в одной структуре.
Преимущество этого кода в том, что он будет работать для любого количества студентов. Если нам нужно изменить этот код для работы с 1000 студентами, нам нужно всего лишь изменить (от 1 до 5) на (от 1 до 1000) в декларации. В предыдущем примере нам нужно было добавить примерно пять тысяч строк кода. Давайте проведем быстрое сравнение переменных и массивов. Сначала мы сравним декларацию.
Далее мы сравниваем присвоение значения
Наконец, мы смотрим на запись значений
Как видите, использование переменных и массивов очень похоже. Важным является тот факт, что массивы используют индекс (также называемый нижним индексом) для доступа к каждому элементу. Это означает, что мы можем легко получить доступ ко всем элементам в массиве, используя цикл For. Теперь, когда у вас есть представление о том, почему массивы полезны, давайте пройдемся по ним шаг за шагом. В VBA есть два типа массивов:
Разница между этими массивами в основном в том, как они создаются. Доступ к значениям в обоих типах массивов абсолютно одинаков. В следующих разделах мы рассмотрим оба типа. Статический массив объявляется следующим образом
Как видите, размер указывается при объявлении статического массива. Проблема в том, что вы никогда не можете быть заранее уверены, какой размер вам нужен. Каждый раз, когда вы запускаете макрос, у вас могут быть разные требования к размеру. Если вы не используете все расположения массива, ресурсы тратятся впустую. Если вам нужно больше мест, вы можете использовать ReDim, но это по сути создает новый статический массив. Динамический массив не имеет таких проблем. Вы не указываете размер, когда объявляете. Поэтому вы можете расти и уменьшаться по мере необходимости.
Динамический массив не выделяется, пока вы не используете оператор ReDim. Преимущество в том, что вы можете подождать, пока не узнаете количество элементов, прежде чем устанавливать размер массива. Со статическим массивом вы должны указать размер заранее. Привожу пример. Представьте, что вы читали листы студенческих оценок. С помощью динамического массива вы можете сосчитать студентов на рабочем листе и установить массив для этого размера. Со статическим массивом вы должны установить размер максимально возможного числа студентов. Чтобы присвоить значения массиву, вы используете номер местоположения. Вы присваиваете значение для обоих типов массивов одинаково.
Номер места называется индексом. Последняя строка в примере выдаст ошибку «Индекс вне диапазона», так как в примере массива нет местоположения 4. Использование функций Array и Split Вы можете использовать функцию Array для заполнения массива списком элементов. Вы должны объявить массив как тип Variant. Следующий код показывает, как использовать эту функцию.
Массив, созданный функцией Array, начнется с нулевого индекса, если вы не используете Option Base 1 в верхней части вашего модуля. Затем он начнется с первого индекса. В программировании, как правило, считается плохой практикой иметь ваши реальные данные в коде. Однако иногда это полезно, когда вам нужно быстро протестировать некоторый код. Функция Split используется для разделения строки на массив на основе разделителя. Разделитель — это символ, такой как запятая или пробел, который разделяет элементы. Следующий код разделит строку на массив из трех элементов.
Функция Split обычно используется, когда вы читаете из файла, разделенного запятыми, или из другого источника, который предоставляет список элементов, разделенных одним и тем же символом. Использование циклов с массивами Использование цикла For обеспечивает быстрый доступ ко всем элементам массива. Вот где сила использования массивов становится очевидной. Мы можем читать массивы с десятью значениями или десятью тысячами значений, используя те же несколько строк кода. В VBA есть две функции: LBound и UBound. Эти функции возвращают самый маленький и самый большой индекс в массиве. В массиве arrMarks (от 0 до 3) LBound вернет 0, а UBound вернет 3. В следующем примере случайные числа присваиваются массиву с помощью цикла. Затем он печатает эти числа, используя второй цикл.
Функции LBound и UBound очень полезны. Их использование означает, что наши циклы будут работать правильно с любым размером массива. Реальное преимущество заключается в том, что если размер массива изменяется, нам не нужно менять код для печати значений. Цикл будет работать для массива любого размера, пока вы используете эти функции. Вы можете использовать цикл For Each с массивами. Важно помнить, что он доступен только для чтения. Это означает, что вы не можете изменить значение в массиве. В следующем коде значение метки изменяется, но оно не меняет значение в массиве.
Цикл For Each отлично подходит для чтения массива. Как видите, лучше писать специально для двумерного массива .
Функция Erase может использоваться для массивов, но она работает по-разному в зависимости от типа массива. Для статического массива функция Erase сбрасывает все значения по умолчанию. Если массив состоит из целых чисел, то все значения устанавливаются в ноль. Если массив состоит из строк, то все строки устанавливаются в «» и так далее. Для динамического массива функция удаления стирает память. То есть он удаляет массив. Если вы хотите использовать его снова, вы должны использовать ReDim для выделения памяти. Давайте рассмотрим пример статического массива. Этот пример аналогичен примеру ArrayLoops в последнем разделе с одним отличием — мы используем Erase после установки значений. Когда значение будет распечатано, все они будут равны нулю.
Теперь мы попробуем тот же пример с динамикой. После того, как мы используем Erase, все места в массиве были удалены. Нам нужно использовать ReDim, если мы хотим использовать массив снова. Если мы попытаемся получить доступ к членам этого массива, мы получим ошибку «Индекс вне диапазона».
Если мы используем ReDim для существующего массива, то массив и его содержимое будут удалены. В следующем примере второй оператор ReDim создаст совершенно новый массив. Исходный массив и его содержимое будут удалены.
Если мы хотим расширить размер массива без потери содержимого, мы можем использовать ключевое слово Preserve. Когда мы используем Redim Preserve, новый массив должен начинаться с того же начального размера, например Мы не можем сохранить от (0 до 2) до (от 1 до 3) или до (от 2 до 10), поскольку они являются различными начальными размерами. В следующем коде мы создаем массив с использованием ReDim, а затем заполняем массив типами фруктов. Затем мы используем Preserve для увеличения размера массива, чтобы не потерять оригинальное содержимое.
Из приведенных ниже снимков экрана видно, что исходное содержимое массива было «сохранено». Предостережение: в большинстве случаев вам не нужно изменять размер массива, как мы делали в этом разделе. Если вы изменяете размер массива несколько раз, то вам захочется рассмотреть возможность использования коллекции . Использование Preserve с 2-мерными массивами Preserve работает только с верхней границей массива. Например, если у вас есть двумерный массив, вы можете сохранить только второе измерение, как показано в следующем примере:
Если мы попытаемся использовать Preserve на нижней границе, мы получим ошибку «Индекс вне диапазона». В следующем коде мы используем Preserve для первого измерения. Запуск этого кода приведет к ошибке «Индекс вне диапазона»:
Когда мы читаем из диапазона в массив, он автоматически создает двумерный массив, даже если у нас есть только один столбец. Применяются те же правила сохранения. Мы можем использовать Preserve только на верхней границе, как показано в следующем примере:
В VBA нет функции для сортировки массива. Мы можем отсортировать ячейки листа, но это медленно, если данных много. Функция быстрой сортировки ниже может использоваться для сортировки массива.
Вы можете использовать эту функцию так:
Передача массива в Sub или функцию Иногда вам нужно будет передать массив в процедуру. Вы объявляете параметр, используя круглые скобки, аналогично тому, как вы объявляете динамический массив. Переход к процедуре с использованием ByRef означает, что вы передаете ссылку на массив. Таким образом, если вы измените массив в процедуре, он будет изменен, когда вы вернетесь.
Возвращение массива из функции Важно помнить следующее. Если вы хотите изменить существующий массив в процедуре, вы должны передать его как параметр, используя ByRef (см. Последний раздел). Вам не нужно возвращать массив из процедуры. Основная причина возврата массива — это когда вы используете процедуру для создания нового. В этом случае вы присваиваете возвращаемый массив массиву в вызывающей программе. Этот массив не может быть уже выделен. Другими словами, вы должны использовать динамический массив, который не был выделен. Следующие примеры показывают это:
Массивы, на которые мы смотрели до сих пор, были одномерными. Это означает, что массивы представляют собой один список элементов. Двумерный массив — это список списков. Если вы думаете об одной строке электронной таблицы как об одном измерении, то более одного столбца является двухмерным. На самом деле электронная таблица является эквивалентом двумерного массива. Он имеет два измерения — строки и столбцы. Следует отметить одну маленькую вещь: Excel обрабатывает одномерный массив как строку, если вы записываете его в электронную таблицу. Другими словами, массив arr (от 1 до 5) эквивалентен arr (от 1 до 1, от 1 до 5) при записи значений в электронную таблицу. На следующем рисунке показаны две группы данных. Первый — это одномерный макет, а второй — двухмерный. Чтобы получить доступ к элементу в первом наборе данных (одномерном), все, что вам нужно сделать, это дать строку, например. 1,2, 3 или 4. Для второго набора данных (двумерного) вам нужно указать строку И столбец. Таким образом, вы можете думать, что 1-мерное — это несколько столбцов, а одна строка и двухмерное — это несколько строк и несколько столбцов. Примечание. В массиве может быть более двух измерений. Это редко требуется. Если вы решаете проблему с помощью 3+-мерного массива, то, вероятно, есть лучший способ сделать это. Вы объявляете двумерный массив следующим образом:
В следующем примере создается случайное значение для каждого элемента в массиве и печатается значение в Immediate Window.
Видите, что мы используем второй цикл For внутри первого цикла, чтобы получить доступ ко всем элементам. Результат примера выглядит следующим образом: Этот макрос работает следующим образом:
Заметьте, что LBound и UBound имеют второй аргумент 2. Это указывает, что это верхняя или нижняя граница второго измерения. Это начальное и конечное местоположение для j. Значение по умолчанию 1, поэтому нам не нужно указывать его для цикла i. Использование For Each лучше использовать при чтении из массива.
Теперь давайте перепишем его, используя цикл For Each. Как видите, нам нужен только один цикл, и поэтому гораздо проще написать:
Использование цикла For Each дает нам массив только в одном порядке — от LBound до UBound. В большинстве случаев это все, что вам нужно. Чтение из диапазона ячеек в массив Если вы читали мою статью о ячейках и диапазонах , то вы знаете, что VBA имеет чрезвычайно эффективный способ чтения из диапазона ячеек в массив и наоборот.
Динамический массив, созданный в этом примере, будет двухмерным массивом. Как видите, мы можем прочитать весь диапазон ячеек в массив всего за одну строку. В следующем примере будут считаны примеры данных студента ниже из C3: E6 Лист1 и распечатаны в Immediate Window.
Как видите, первое измерение (доступное через i) массива — это строка, а второе — столбец. Чтобы продемонстрировать это, взглянем на значение 44 в Е4 данных образца. Это значение находится в строке 2 столбца 3 наших данных. Вы можете видеть, что 44 хранится в массиве в StudentMarks (2,3). Как заставить ваши макросы работать на суперскорости Если ваши макросы работают очень медленно, этот раздел будет очень полезным. Особенно, если вы имеете дело с большими объемами данных. В VBA это держится в секрете. Обновление значений в массивах происходит экспоненциально быстрее, чем обновление значений в ячейках. В последнем разделе вы увидели, как мы можем легко читать из группы ячеек в массив и наоборот. Если мы обновляем много значений, то мы можем сделать следующее
Например, следующий код будет намного быстрее, чем код ниже:
Назначение из одного набора ячеек в другой также намного быстрее, чем с помощью копирования и вставки.
Ниже приводится краткое изложение основных моментов этого поста.
Источник |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Так же в этом разделе:
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|