Встроенные типы данных

   VBA располагает множеством встроенных типов данных. Условно эти типы можно разделить на численные типы, строки, ссылки, типы для хранения даты и времени, объектные ссылки, массивы и особый тип для хранения значения любого типа, именуемый Variant.
Численные типы данных
   Основные характеристики численных типов VBA приведены в табл. 1.2.
Таблица 1.2. Численные типы данных VBA
   Примечание
   Численный тип Decimal как самостоятельный тип на сегодняшний день не поддерживается. Однако его можно использовать в пределах типа Variant (о типе Variant будет рассказано далее).
Строки
   Для хранения символьных данных в VBA реализована поддержка типа данных String (строка). В переменных этого типа могут храниться отдельные символы и большие фрагменты текста. Строки в VB А бывают двух видов: фиксированной и переменной длины. Разница между этими двумя типами строк понятна из их названий.
   Строки фиксированной длины применяются, когда длина текста, который хранится в них, постоянна или не может превышать известный предел (например, для хранения отдельных символов). Строки фиксированной длины в ряде случаев обрабатываются быстрее строк переменной длины. Максимальный размер строки фиксированной длины – около 65 400 символов.
   Строки переменной длины являются более гибким инструментом обработки текста в программах на VBA. Длина этих строк может динамически изменяться в зависимости от длины хранимого в них текста. Максимальная длина таких строк – около 2 млрд символов.
Дата и время
   Для удобства работы со значениями даты и времени в VBA введен тип данных Date. Он позволяет задавать значения времени и даты в формате, удобном для восприятия, а также упрощает вычисления с временными интервалами. Этот тип данных, естественно, используется и в таблицах Excel.
   Нужно заметить, что тип Date не является внутренним типом, используемым VBA для хранения даты и времени. Вместо него применяется тип Single (число с плавающей точкой). Целая часть этого числа – количество суток, прошедших с 30 декабря 1899 года, дробная – прошедшая часть текущих суток.
Тип данных Variant
   В VBA предусмотрен один универсальный тип данных – Variant. Переменная этого типа может хранить значение любого поддерживаемого VBA типа (в том числе и ссылки на объекты, о которых будет рассказано ниже).
   Однако при обработке переменных типа Variant тратится дополнительное время на определение и преобразование типа данных в этих переменных – самый универсальный тип данных VBA оказывается и самым медленным. Поэтому следует избегать слишком частого и неоправданного использования переменных этого типа (например, в качестве целочисленных итераторов, счетчиков и т. д.).
   Когда переменная типа Variant пуста (ей не присвоено никакого значения), она заполняется специальным значением Empty.
Ссылки. Тип данных Object
   Важно понимать, что в VBA переменные, предоставляющие доступ к объектам, являются только ссылками на эти объекты. В данном языке программирования невозможно получить сам объект (его двоичный код). Все операции по созданию, удалению объектов и манипулированию ими, осуществляются только с использованием ссылок.
   Объекты, доступные из VBA, существуют, пока на них установлена хотя бы одна ссылка. Первая ссылка на объект устанавливается при его создании. В процессе работы можно как устанавливать новые ссылки на объект, так и удалять их с использованием специальной инструкции Set. Пусть objRef – ссылка на некоторый объект. Тогда операция установления новой ссылки будет иметь такой вид:
   Set objNewRef = objRef
   Теперь objNewRef ссылается на тот же объект, что и objRef. Операция же удаления ссылок будет выглядеть следующим образом:
   Set objRef = Nothing
   Set objNewRef = Nothing
   Если на объект не было других ссылок, кроме этих, то он будет удален.
   Для доступа к объектам в VBA предусмотрен тип данных Object. Он является универсальным, так как может быть ссылкой на объект любого типа.

Объявление переменных

   Для объявления переменных элементарных типов (не массивов) в блоке объявлений модуля используется следующая инструкция:
   Public | Private [WithEvents] Имя_переменной [As [New] Имя_-
   типа] _
   [, Имя_переменной [As [New] Имя_типа]]…
   Ключевые слова, записанные до первых квадратных скобок, задают область видимости переменных:
   • Public – позволяет объявлять глобальные переменные и общие переменные-члены класса (о классах будет рассказано позже);
   • Private – позволяет объявлять переменные, доступные только в одном модуле, и частные переменные-члены класса.
   Для объявления переменных элементарных типов (не массивов) в процедурах или функциях используется такая инструкция (локальных переменных):
   Dim | Static [WithEvents] Имя_переменной [As [New] Имя_типа] _
   [, Имя_переменной [As [New] Имя_типа]]…
   Ключевые слова, записанные до первых квадратных скобок, задают время жизни переменных:
   • Dim – используется для объявления локальных переменных, которые уничтожаются после выхода из процедуры;
   • Static – используется для объявления локальных переменных, значения которых сохраняются между вызовами процедуры или функции.
   Ключевое слово WithEvents используется для объявления переменной-обработчика событий объекта.
   Имя_переменной – это идентификатор объявляемой переменной.
   Имя_типа – название типа данных объявляемой переменной.
   Если конструкция [As [New] Имя_типа] не используется, то типом объявляемой переменной автоматически становится тип Variant.
   Если используется ключевое слово New, то создается новый объект. New нельзя использовать совместно с WithEvents, а также при объявлении переменной типа Object и если тип Имя_типа не является объектным.
   Ниже приведены примеры объявления переменных на VBA:
   Public intData As Integer
   Private intCount As Integer, varData
   Dim strText As String
   Static a, b, c
   Dim objRef As Object
   Dim objCtrl As New Control
   Внимание!
   При объявлении в одной строке нескольких переменных слово As относится только к переменной, непосредственно после идентификатора которой оно следует. Например, при объявлении Dim а, Ь, с As Integer переменные а и b будут иметь тип Variant, а переменная с – тип Integer.

Инициализация переменных

   После того как переменная объявлена, VBA производит ее инициализацию указанным ниже образом.
   • Переменным численных типов автоматически присваивается нулевое значение.
   • Строки переменной длины после объявления являются пустыми (с нулевой длиной). Строки фиксированной длины заполняются нулевыми символами.
   • Данные типа Date инициализируются значением 00:00:00 30.12.1899 (это равняется нулю при представлении даты в численном формате, о котором было рассказано выше).
   • Все переменные типа Object и подобные (то есть ссылки на объекты определенного типа) принимают значение Nothing, если при их объявлении не создан новый объект (не использовалось New).

Явное и неявное объявление переменных

   Рассмотренное выше объявление переменных называется явным.
   VBA также поддерживает неявное объявление переменных. Под неявным объявлением подразумевается возможность использования переменной без ее объявления посредством инструкции Dim, Static, Private или Public. При первом обращении к такой переменной для нее автоматически выделяется память и происходит ее инициализация. Следует отметить, что все неявно объявленные переменные имеют тип Variant.
   Использование неявного объявления переменных может как упростить написание программ, так и значительно усложнить процесс их отладки.
   К примеру, можно очень долго разбираться, почему же после вычисления такого выражения, как dblSalaryAccount = dblSalaryAcount * 10. 5, значение переменной dblSararyAccount стало равным нулю, если до этого оно было равно 5.37 5. Все дело в небольшой ошибке в названии идентификатора переменной, в результате которой создается новая переменная dblSalaryAcount, которая инициализируется нулевым значением. В случае использования явного объявления переменных подобных ошибок в программе быть не может, потому что каждый раз при обнаружении необъявленного идентификатора VBA выдает ошибку.
   Для включения требования обязательного объявления переменных используется директива Option Explicit. Чтобы данная директива добавлялась в каждый новый модуль автоматически, нужно с помощью меню Tools → Options (Сервис → Параметры) редактора VBA открыть диалоговое окно Options (Параметры) и на вкладке Editor (Редактор) установить флажок Require Variable Declaration (Явное описание переменных).

Константы

   Как и в любом другом языке программирования, в VBA можно сопоставлять с идентификаторами константные значения. Объявление констант в языке VBA во многом сходно с объявлением переменных. Синтаксис инструкции объявления константы следующий:
   [Public | Private] Const Имя_константы [As Имя_типа] = Значение
   Два ключевых слова в первых скобках задают область видимости константы:
   • Public – используется для объявления глобальных констант;
   • Private – используется для объявления констант, доступных только в том модуле, где они объявлены.
   По умолчанию, то есть когда не употреблены указанные ключевые слова, константа является Private.
   Имя_константы – задает идентификатор константы.
   Значение – константное значение (например, «Строка1», 1.245 ит. д.) либо выражение, в число аргументов которого не входят переменные и функции.
   Если тип константы не задан, то он автоматически выбирается VBA исходя из ее значения. Ниже приводятся примеры объявления констант:
   Const PI As Double = 3.14159265359
   Public Const MyConstString = «MyConst»
   Private Const НазваниеТаблицы As String = «Отчеты»

Операторы

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

Операторы для работы с численными значениями

   Информация обо всех операторах для работы с численными значениями приведена в табл. 1.3.
Таблица 1.3. Операторы для работы с численными значениями
   Примечание
   Оператор «+» может использоваться и для соединения строк. Однако bVBA существует специальный оператор «&», выполняющий эту функцию. Рекомендуется использовать для соединения строк именно оператор «&», так как это способствует легкому визуальному отделению операций над строками от операций над другими типами данных, что, в свою очередь, улучшает читаемость кода.

Операторы сравнения

   Результатом выполнения всех операторов сравнения является значение типа Boolean. Если операнды какого-либо оператора удовлетворяют его условию, то возвращается значение True, иначе возвращается значение False. Все операторы сравнения, поддерживаемые VBA, приведены в табл. 1.4.
Таблица 1.4. Операторы сравнения
 
   Описанные операторы сравнения могут принимать в качестве операндов значения выражений любого типа, то есть фактически оперируют с типом данных Variant. Если один из операндов равен Empty, то результатом выполнения операторов будет специальное значение NULL. Если операнды несравнимы, то при выполнении описанных выше операторов генерируется ошибка: «Несоответствие типа».
   Режим сравнения строковых значений можно задать с помощью директивы Option Compare. Для Excel работают два варианта данной директивы: Option Compare Text (текст сравнивается без учета регистра символов) и Opt ion Compare Binary (сравниваются бинарные коды символов, при этом автоматически учитывается их регистр). По умолчанию сравнение строк происходит согласно директиве Option Compare Binary.
   В VBA реализованы два специфических оператора Like и Is, которые тоже относятся к операторам сравнения. Они также возвращают значение типа Boolean как результат сравнения.
   Оператор I s используется для определения, являются ли две ссылки ссылками на один и тот же объект. Этот оператор допускает использование в качестве операндов только ссылки на объекты. Формат данного оператора такой:
   Результат = Ссылка1 Is Ссылка2
   Оператор Like используется для проверки, удовлетворяет ли текст в строке заданному шаблону. Формат этого оператора следующий:
   Результат = Строка Like Шаблон
   Перечень символов, которые могут употребляться в строке шаблона, приведен в табл. 1.5.
Таблица 1.5. Перечень возможных символов в строке шаблона
 
   В качестве примера определим, является ли строка «15 26 ОА» номером автомобиля серии ОА или ОО. Значение строки-шаблона для этого случая будет равно «## ## О[AО]», а результатом применения оператора «15 26 ОА» Like «## ## О[АО]» будет значение True.
   Для задания непрерывного диапазона символов в квадратных скобках можно воспользоваться знаком «минус» (-). При этом символы необходимо указывать в возрастающем порядке (по номеру в алфавите): [A-Z], а не [Z-A].
   Примечание
   Если нужно, чтобы в шаблоне присутствовали специальные символы, приведенные в табл. 1.5, то необходимо заключить соответствующие знаки в скобки: ([), (]), (#), (?), (*).

Логические операторы

   В VBA введены операторы, которые используются в составе логических выражений (например, условие в инструкции If-Then-Else, которая будет рассмотрена позже). Формат логических операторов VBA (кроме импликации) и их описание приведены в табл. 1.6 (все выражения, используемые в операторах, – логические, принимающие значение True или False).
Таблица 1.6. Логические операторы VBA

Массивы

   При создании программ часто приходится оперировать большими количествами данных одного типа и имеющих одинаковый смысл. Для хранения таких данных используются массивы. Массив – это совокупность значений одного типа, объединенных в одной переменной.
   Язык VBA предоставляет широкие возможности для использования массивов. В нем работа с массивами значительно упрощена. Например, при выполнении программы автоматически контролируется выход за пределы массива. Также VBA-программисту при работе с массивами не нужно заботиться о выделении и освобождении памяти.

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

   Для объявления массивов в VBA используются инструкции, формат которых приведен ниже:
   Public | Private Имя_массива ([Размерность])[As Имя_типа] _
   [, Имя_массива ([Размерность]) [As Имя_типа]]…
   или
   Dim | Static Имя_массива ([Размерность])[As Имя_типа] _
   [, Имя_массива ([Размерность]) [As Имя_типа]]…
   Первая инструкция используется для объявления массивов на уровне модуля, вторая – для объявления массива в процедуре или функции (все аналогично объявлению переменных).
   Объявление массива отличается от объявления любой другой переменной тем, что при объявлении массива после идентификатора переменной указывается размерность. Если размерность не указана, то создается динамический массив, размер которого можно изменять во время выполнения программы. Для динамического массива инструкция объявления является формальной: чтобы этот массив можно было использовать, к нему необходимо применить инструкцию ReDim (об этой инструкции будет рассказано далее).
   При указании размерности массива необходимо учитывать, что элемент Размерность имеет следующий формат:
   Нижняя_граница To Верхняя_граница | Количество_элементов _
   [,Нижняя_граница To Верхняя_граница | Количество_элементов]…
   В VBA разрешено создавать многомерные массивы с количеством измерений не более 60. Размерности измерений массива разделяются запятой.
   При задании размерности в виде Нижняягранща То Верхняягранща нужно явно указывать нижнюю и верхнюю границы измерения массива (например, 50 То 100).
   При задании размерности можно также просто указывать требуемое количество элементов в данном измерении массива. При таком задании в качестве нижней границы измерения используется значение по умолчанию (об изменении этого значения будет рассказано далее).
   Ниже приведены примеры объявлений массивов (переменного размера, двух одномерных и двух многомерных):
   Dim avarValues()
   Dim astrValues(1 To 10) As String, astrValues2(10) As String
   Dim aintValues(1 To 10, 1 To 3) As Integer, aintValues(10, 3)
   As Integer

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

   Как было сказано ранее, при указании размерности измерения массива может использоваться значение нижней границы по умолчанию. Для задания нижней границы, используемой по умолчанию, предназначена директива Option Base. Существуют только два варианта данной директивы:
   Option Base 0
   и
   Option Base 1
   Первый вариант устанавливает нижнюю границу равной нулю (используется по умолчанию), а второй – единице.

Изменение размера массива

   Язык VBA позволяет изменять размер динамического массива во время выполнения программы. Кроме того, VBA дает возможность изменять количество измерений такого массива. Для этого используется инструкция ReDim, формат которой следующий:
   ReDim [Preserve] Имя_массива ([Размерность])[As Имя_типа] _
   [, Имя_массива ([Размерность]) [As Имя_типа]]…
   Назначение элементов данной инструкции полностью аналогично назначению одноименных элементов инструкции Dim (при использовании ее для объявления массивов). Тип элементов массива можно указывать только в том случае, если Имямассива – это идентификатор переменной типа Variant.
   При выполнении инструкции ReDim без использования ключевого слова Preserve значения всех элементов, которые ранее были в массиве, теряются. Ниже приведены примеры таких инструкций:
   ReDim astrValues(1 To 10), aintValues(10, 20)
   ReDim varArray(2 To 4) As Boolean
   Использование Preserve позволяет изменять размер массива, не теряя значений его элементов. Однако использование данного ключевого слова налагает некоторые ограничения на возможности манипулирования массивами:
   • нельзя изменять количество измерений массива;
   • нельзя изменять размерности измерений массива, кроме размерности последнего измерения;
   • можно изменять только верхнюю границу последнего измерения массива.
   Давайте рассмотрим пример использования инструкции ReDim с ключевым словом Preserve:
   ' Первая инструкция ReDim для динамического массива
   ReDim astrValues(1 To 5, 1 To 10)
   …
   ' Увеличение размера массива
   ReDim Preserve astrValues(1 To 5, 1 To 25)
   …
   ' Уменьшение размера массива
   ReDim Preserve astrValues(1 To 5, 1 To 15)

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

   Так как VBA позволяет задавать произвольную нижнюю границу массива, при написании программ крайне удобно наличие возможности узнать границы массива во время выполнения программы. Для этой цели в VBA введены две функции, формат которых следующий:
   LBound(Имя_массива[, Номер_измерения])
   RBound(Имя_массива[, Номер_измерения])
   Функция LBound позволяет получить нижнюю границу массива, a RBound – верхнюю. Обе функции принимают в качестве аргументов идентификатор массива и номер измерения, границу которого нужно получить. Нумерация измерений начинается с единицы. Если параметр Номеризмерения опущен, то его значение принимается равным единице. Обе функции возвращают значение типа Long.
   Ниже приведен пример получения нижней и верхней границ первого измерения массива avarValues (значения сохраняются в переменных типа Long):
   lngLBound = LBound(avarValues)
   lngRBound = RBound(avarValues)

Доступ к элементам массива

   Для доступа к элементам массива в VBA используется указание номера этого элемента в круглых скобках после идентификатора переменной массива. При этом номера измерений массива разделяются запятыми. Например (для одномерного и трехмерного массивов):
   intNum = aintValues(16)
   intNum = aintValues(12, 32, 3)

Использование переменной Variant при работе с массивами

   Язык VBA поддерживает универсальный тип данных Variant, которому находится применение и при работе с массивами. Переменной этого типа можно присваивать массив. В результате этой операции в переменной Variant формируется копия массива. Далее с такой переменной можно работать либо как с обычной переменной, либо как с массивом (использовать доступ к элементам), например:
   Dim aintValues(1 To 3) As Integer
   Dim varArray
   ' Присвоение массива переменной типа Variant
   varArray = aintValues
   ' Доступ к элементам массива
   varArray(1) = 1
   varArray(2) = 2
   varArray(3) = 3
   Возможность присвоения массива переменной типа Variant на самом деле широко используется в VBA при передаче массивов в функции и процедуры, а также при возврате функциями массивов.
   Для определения того, содержит ли переменная типа Variant массив, можно использовать функцию IsArray, имеющую следующий формат:
   IsArray(Переменная)
   Данная функция возвращает значение типа Boolean: True – если в переменной с именем Переменная содержится массив, и False – в противном случае.

Использование функции Array для заполнения массива

   В VBA имеется возможность быстрого заполнения массива значениями. Эта возможность реализована в функции Array. Ее формат такой:
   Array(Список_элементов)
   В качестве аргументов функция принимает список значений, разделенных запятой. Возвращает она заполненный заданными значениями массив, сохраненный в переменной типа Variant. Ниже приведен пример использования функции Array:
   Dim varArray
   ' Заполнение массива значениями
   varArray = Array(1, 2, 3, 4, 5)

Коллекции

   Коллекции (они же семейства и множества) – это объекты, которые позволяют хранить произвольное количество элементов любого типа. Элементы в коллекции идентифицируются уникальным ключом, которым может быть не только номер элемента в коллекции, но и значение строкового или другого типа. При программировании на VBA различные коллекции используются очень часто. Например, к коллекции Workbooks нужно обращаться для получения ссылки на объект Workbook нужной рабочей книги, к коллекции Worksheets – для получения ссылки на объект Worksheet нужного рабочего листа и т. д.
   В VBA коллекции реализованы во встроенном классе Collection. Создание объекта Collection ничем не отличается от создания объекта другого типа:
   Dim col As New Collection
   или
   Dim col As Collection
   Set col = New Collection

Добавление элементов

   Для добавления элементов в коллекции реализован метод Add, имеющий следующий формат:
   Ссылка. Add Элемент [, Ключ][, Добавить_перед][, Добавить_после]
   Единственным обязательным параметром метода Add является значение добавляемого элемента. Элемент может быть константой или переменной любого типа, кроме типа, определенного пользователем. При добавлении элемента можно указать ключ, который будет однозначно идентифицировать элемент в коллекции. Ключ – это любое значение типа Variant.
   По умолчанию новые элементы добавляются в конец коллекции. Для изменения порядка добавления элементов используются параметры Добавить_перед и Добавить_после, с помощью которых указывается номер или ключ того элемента, перед которым или после которого нужно вставить новый элемент. Нумерация элементов в коллекции начинается с единицы.
   Ниже приведены примеры инструкций, добавляющих новые элементы в коллекцию:
   col.Add «Value1», «Key1»
   col.Add «Value2», «Key2»
   col.Add «Value0»,"Key1"

Количество элементов в коллекции

   Для определения количества элементов в коллекции используется свойство только для чтения Count. При его получении возвращается значение типа Long. Пример получения количества элементов коллекции приведен ниже:
   lngCount = col.Count

Удаление элементов из коллекции

   Для удаления элементов из коллекции используется метод Remove:
   Ссылка. Remove Номер
   Единственным параметром метода Remove является номер элемента в коллекции или его ключ. Например, для удаления значения «Value2», добавленного в коллекцию при рассмотрении метода Add, можно использовать инструкцию
   col.Remove 3
   или
   col.Remove «Кеу2»

Доступ к элементам коллекций

   Для получения значений элементов коллекции используется метод Item, который возвращает значение соответствующего элементу типа:
   Ссылка. Item (Номер)
   Единственным параметром метода I tern является Номер – это ключ элемента или его порядковый номер в коллекции. Например, для получения значения элемента с ключом «Keyl» (или номером 2) можно использовать следующие инструкции:
   val = col.Item(«Key1»)
   val = col.Item(2)
   Следует отметить, что Item является для объекта Collection методом по умолчанию, поэтому значения элемента с ключом «Key 1» можно получать и таким образом: