количество элементов которых при описании не фиксируются, но могут быть определены непосредственно при выполнении программы. Синтаксис объявления динамического массива отличается от объявления статического тем, что после имени массива в нем стоят лишь пустые скобки. Однако перед тем как использовать массив, нужно выполнить оператор ReDim, который задаст размерность и диапазоны изменения индексов динамического массива.
ReDim имяМассива (размер1 [, размер2 . . . ])
Более того, вы можете неоднократно использовать оператор ReDim для изменения размерности одного и того же массива. Но данная возможность требует небольшого пояснения. Дело в том, что при изменении размеров массива ему заново выделяется память, и текущие значения его элементов теряются. Чтобы их не потерять при переопределении размерности, используется ключевое слово Preserve. Но учтите, что при использовании ключевого слова preserve вы можете поменять только последний аргумент, задающий размерность массива.
В приведенном ниже примере мы рассматриваем массив прошлого примера, только в этом случае мы объявили его как динамический и проинициализировали элемент authorList(7,2). А затем представили, будто количество полей увеличилось до 10, и добавили эти параметры к уже существующему массиву. Причем, заметьте, без потери информации, благодаря ключевому слову Preserve. Это проверяется посредством функции
MsgBox.
Листинг. Объявление динамических массивов
Sub examples()
Dim authorList() As String
ReDim authorList(1 To 100, 1 To 2) authorList(7, 2) = "Усаров"
ReDim Preserve authorList(1 To 100, 1 To 10)
53
MsgBox(authorList(7, 2))
End Sub
3.6. Перечисляемый тип
При всем обилии встроенных типов данных часто возникает желание ввести новый тип данных, содержащий некоторые определенные значения. Такой тип называется в VBA перечисляемым типом. Синтаксис довольно прост:
[Private | Public] Enum имяТипа имяЗначения [ = Константа] имяЗначения [ = Константа] ….
End Enum
Ключевые слова Private и Public объявляют область видимости для типа (кстати, перечисляемые типы могут описываться только на уровне модуля, т. е. нельзя описать перечисляемый тип внутри процедуры). Затем следует ключевое слово Enum и имяТипа. После этого идет перечисление значений типа (по одному на строчке). По умолчанию все значения типа пронумеровываются целыми числами, начиная с 0, но вы можете самостоятельно указать константное целое число для значений типа.
Поясним сказанное на типичном примере. Мы хотим ввести тип "неделя". Элементами данного типа будут только обозначения дней недели, и, соответственно, область значений будет изменяться от понедельника до воскресенья.
Листинг. Перечисляемый тип
Private Enum Week Monday
Tuesday Wednesday Thursday Friday
54
Saturday
Sunday
End Enum
Sub Weekend()
Dim day As Week day = Saturday
End Sub
3.7. Тип, определяемый пользователем
После описания простейшего структурного типа данных (массива) перейдем к более сложному типу, определяемому пользователем. Так как массив представляет собой совокупность однотипных переменных, хотелось бы создать объединение элементов разных типов (запись).
Запись - это структурированный тип данных, компоненты которого обычно называются полями, имеют имя и могут принадлежать к различным типам данных.
[Private | Public] Type имяТипа
имя Поля [ ([<размер>]) ] Аs типДанных [имяПоля [ ([<размер>])] As типДанных ] ….
End Type
Исходя из синтаксической конструкции, сразу можно сказать, что тип определяется либо на уровне модуля, либо на уровне приложения. Далее идет ключевое слово туре и собственно имя типа. После этого идет объявление полей нового типа. Это могут быть простые переменные и массивы встроенных типов, а также переменные и массивы уже определенных типов пользователя, которые в свою очередь могут также иметь вышеуказанную структуру.
Для тех, кого последнее предложение заставило задуматься - небольшое пояснение. Определение записи можно рассматривать как дерево. Корень - это имя типа, а вершины - имена полей, которые могут являться корнями подобного же дерева. Не допускается использование рекурсивных определений, т. е. нельзя объявить тип следующим образом:
55
Туре Заяц Волк Аs Заяц
End Type
3.8. Преобразование данных VBA
Зависимость преобразований, выполняемых VBA, от типа данных и оператора представлена в табл.3.7.
|
Таблица 3.7 |
|
|
Преобразования данных VBA |
|
Выраже- |
Описание и тип результата |
|
ние |
||
|
||
Num + Str |
Создает ошибку несовпадения типов, когда Num |
|
|
объявляется как численный тип, а Str — как тип |
|
|
String. Выполняется строковая конкатенация, ко- |
|
|
гда Num является Variant, a Str объявляется как |
|
|
тип String; результат является типом String |
|
|
|
|
Num + Str |
Выполняется арифметическое сложение, когда |
|
|
Num объявляется как численный тип, а Str— как |
|
|
Variant, или когда и Num, и Str являются типом |
|
|
Variant; результат - численный тип |
|
|
|
|
Num +«3» |
Вызывает ошибку несовпадения типов, если Num |
|
|
объявлен численным типом. |
|
|
Выполняется строковая конкатенация, если Num |
|
|
является типом Variant; результат имеет тип |
|
|
String |
|
|
|
|
3 + Str |
Вызывает ошибку несовпадения типов, если Str |
|
|
объявлен как тип String. Выполняется арифмети- |
|
|
ческое сложение, если Str является типом Variant; |
|
|
результат является численным типом. (Заметьте, |
|
|
что это выражение никогда не имеет результатом |
|
|
строковую конкатенацию) |
|
|
|
56
Продолжение табл. 3.7
Num & Str Всегда выполняет строковую конкатенацию, независимо от типов переменных; результатом является тип String. Это выражение никогда не вызывает ошибки несовпадения типов
Преобразования численных типов. VBA обычно пре-
образует все численные типы данных в выражении в тип наибольшей точности, а затем дает этот тип результату выражения. Например, если выражение содержит численные значения с типами Integer и Single, результат выражения является типом Single — тип наибольшей точности в этом выражении.
Если вы присваиваете результат численного выражения переменной с наименьшей точностью, чем фактический тип результата выражения, VBA округляет результат выражения до тех пор, пока его точность не совпадет с ожидаемым типом. Например, если вы присваиваете численное выражение, имеющее результатом число типа Double, переменной типа Integer, VBA округляет число двойной точности до типа Integer.
Преобразования строк и чисел. При преобразовании числа в строку VBA создает строку, содержащую все цифры этого числа и десятичный знак (если число имеет его). Число 3413.72, например, преобразуется в строку «3413,72». Если число очень большое или очень маленькое, VBA может создать строковое представление числа в экспоненциальной записи; например, число 0.0000000004927 преобразуется в строку
«4,927Е-11».
VBA может преобразовывать строку в число, если только эта строка содержит символьное представление числа в десятичном формате или экспоненциальном. Строки «988,б», «812», «-186,7», «1,ЗЕ10» представляют числа, и VBA может преобразовать их в числа. Строки «1.045», «$74.550» и «С добрым утром!» не могут быть преобразованы в числа.
Преобразования значений типа Boolean. Когда VBA
преобразует значения типа Boolean в числа, значение True преобразуется в 1, а значение False — в 0. Когда VBA преобра-
57