Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

123 / PDF / Lekcija._Tipy_dannykh_v_VBA

.pdf
Скачиваний:
13
Добавлен:
10.06.2015
Размер:
186.66 Кб
Скачать

1. ТИПЫ ДАННЫХ В VBA

Язык — это знаковая система для передачи информации. Когда мы говорим о языке программирования, то подразумеваем под информацией строго определенное понятие. В данном случае информация — это данные и процедуры их обработки. В этом ра зделе мы коснемся только первой части настоящего определения, а именно данных.

Данные в VBA характеризуются своими типами, которыеопределяют:

формат представления данных в памяти компьютера;

область возможных значений;

множество допустимых операций, применимых к данным.

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

Итак, начнем с встроенных типов данных. Как и любой язык программирования высокого уровня, VBA содержит все привычные встроенные типы данных: арифметические, строковые и логические, но есть и свои типы, специфические для VBA. Полный перечень встроенных типов данных VBA с соответствующими областями значений и требуемой памятью приведен в табл. 20.2.

Таблица. Встроенные типы данных VBA

 

 

 

 

 

 

 

 

 

 

Тип

 

Описание

 

Область значений

 

Требуемая

 

данных

 

 

 

 

 

 

память

 

 

 

 

 

 

 

 

 

Boolean

 

Логическое значение

 

True (Истина) и

2

байта

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

False (Ложь)

 

 

 

 

 

 

 

 

 

 

 

 

 

Byte

 

Число без знака

 

 

0-255

 

1

байт

 

 

 

 

 

 

 

 

 

 

Currency

 

Десятичные

числа

с

-922 337 203 685

8

байтов

 

 

 

фиксированным

количеством

477,5808 - 922 337 203

 

 

 

 

 

знаков после запятой

 

685 477,5807

 

 

 

 

 

 

 

 

 

 

 

Date

 

Используется для хранения

1.01.0100г.-31.12.9999г.

8

байтов

 

 

 

дат

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Decimal

 

Любое число

 

 

28 знаков

12 байт

 

 

 

 

 

 

 

 

 

Double

 

Числовые значения с пла-

 

-1.7Е308--4.9Е324

8

байтов

 

 

 

 

 

 

 

 

 

 

 

 

вающей точкой двойнойдля

отрицательных

 

 

 

 

 

точности

 

 

чисел и 4.9Е324 —

 

 

 

 

 

 

 

 

1 ,7Е308 для положи-

 

 

 

 

 

 

 

 

тельных чисел

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Тип

Описание

 

Область значений

Требуемая

 

данных

 

 

 

 

 

 

память

 

 

 

 

 

 

Integer

Короткие целые числовые

-32 768 - 32 767

2 байта

 

 

 

 

 

 

 

 

 

 

значения

 

 

 

 

 

 

 

 

 

 

 

 

Long

Длинные целые числовые

-2 147483648-

4 байта

 

 

 

 

 

 

 

 

 

 

значения

 

2147483647

 

 

 

 

 

 

 

 

 

 

 

 

Object

Ссылка на объект

 

 

 

 

4 байта

 

 

 

 

 

 

 

 

 

 

 

1

Single

Числовые значения

-3.4Е38--1.4Е45

4

байта

 

 

 

 

 

 

с плавающей точкой обыч-

для отрицательных

 

 

 

 

 

 

 

 

 

ной точности

чисел

 

 

 

 

 

 

и 1.4Е-45-3.4Е-45

 

 

String

Используется для хранениядля положительных

1

байт на символ

 

строковых значений

Длина строки от 0 до 64

 

 

 

 

 

Кбайт

 

 

 

 

 

 

 

Variant

Может использоваться

Значения любого

16 байт плюс

 

 

 

 

 

 

 

 

для

хранения

всехиз

вышеперечисленных

1

байт на ка ждый

 

вышеперечисленных типов

типов плюс Null, Error,

символ строковых

 

 

 

Empty, Nothing.

зна-

 

 

 

 

 

 

 

 

 

 

 

чений

 

 

 

 

 

 

 

Если такие типы данных, как integer или string не требуют особых комментариев, поскольку они стандартны и просты, то типы данных object и variant следует прокомментировать. Сейчас же рассмотрим уникальный в своем роде тип Variant.

Тип variant — это универсальный тип данных, позволяющий программисту не думать о том, каким будет тип переменных. С одной стороны, безусловное удобство: не надо думать при объявлении переменной, с другой — это может привести к ошибкам, которые трудно обнаружить. Более того, на обработку переменных данного типа тратится больше времени, да и память расходуется нерационально (особенно, когда речь идет о статических массивах данного типа).

Мы советуем (особенно начинающим программистам) не злоупотреблять данным типом, хотя ряд приемов его использования заметно упрощает программирование. Например, вы хотите, чтобы пользователь программы ввел целое число (после чего программа нарисует круг соответствующего радиуса) и переменную ввода целого типа. Но что, если пользователь введет вместо целого числа вещественное или, вообще, строковое значение? Произойдет ошибка при попытке присвоения переменной значения не того типа.

Вот тут-то и необходим тип Variant. Если переменная для ввода будет объявлена как variant, ничего страшного не случится: введенное значение будет благополучно присвоено этой переменной, а вы получите возможность проанализировать введенное значение и попросить пользователя повторить ввод, если введенное им значение не отвечает требуемым условиям. Теперь перейдем к разговору о третьей составляющей нашего определения типа данных, об операциях. Операция — это действие, выполняемое над данными.

[Результат =] операнд! <операция> операнд2

Любая операция имеет результат и несколько операндов (как правило, два). Операнд

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

2

преобразование. Например, целое число 3 можно преобразовать в вещественное число 3.0 и значение сохранится, но вещественное число 3.1415926 нельзя преобразовать в целое, не потеряв информацию. Таким образом, учитывая приведения типов, можно однозначно определять тип результата операции по следующему правилу: если операция применяется к операндам различных типов, то операнд, у которого порядок типа ниже, преобразуется к типу операнда, у которого порядок выше и значение операции будет иметь, соответственно, тип высшего порядка.

Существует четыре вида операций:

1.Арифметические (+, - ,*, \, /, ^, mod).

2.Логические (not, and, or, xor, eqv, imp).

3.Строковые (+,&).

4.Операции отношения (=, <>, <, >, <=, >=, Is, Like).

Итак, мы описали встроенные типы данных. Но вспомним, что сам по себе тип — это просто характеристика данных, значимой же величиной являются сами данные. Первым шагом на пути работы с данными будет их объявление и инициализация, о которых сейчас и пойдет речь. После того как были описаны типы данных, необходимо приступать к работе с данными, т. е. к программированию. По существу эта работа делится на два этапа — на объявление переменных и на составление процедур обработки этих переменных.

Массив — это совокупность однотипных индексированных переменных Представьте, что имеется 20 магазинов, которым издательство поставляет книгу "Microsoft Outlook 2002 в подлиннике". Естественным образом хоте лось бы иметь список, в котором было бы указано количество экземпляров, проданных каждому магазину. Данные количества для разных магазинов являются, в принципе, элементами одного типа (а точнее, просто числами). Таким образом, данная совокупность представляет собой массив. Обращение же к элементам массива происходит путем указания имени данного массива и порядкового номера требуемого элемента. Конечно, вы вправе присвоить каждому магазину персональное имя и работать с ними, как с обособленными единицами. Но представьте, что вам надо провести одну и ту же процедуру для каждого магазина, например подсчитать общее количество проданных книг. Не проще ли задать цикл для всего массива магазинов, где изменяется лишь индекс, который однозначно определяет магазин?

Количество же индексов массива в VBA может достигать 60, но это своего рода излишество, как правило, используются массивы с одним, двумя и тремя индексами. О количестве индексов массива говорят как о размерности массива. Массивы с одним индексом называют одномерными, с двумя — двумерными и т. д. Продолжив наш пример, предположим, что издательство выпускает не одну книгу, а множество различных книг, скажем, еще 100. Таким образом, вы имеете дело с двумерным массивом (20x100) и обращение к необходимому элементу становится тривиальным: магазин № 7 книга № 56. Данное обращение покажет количество проданных книг № 56 магазину № 7. Конечно, в языке VBA подобные выражения неприемлемы, но суть остается той же. Как и любой элемент данных, массив необходимо объявлять. Ниже приведен синтаксис объявления массива:

{ Dim I Private | Public | Static} имяМассива (<размер1> [, <размер2>] ...) [Аs типДанных] [, имяМассива (<размер1> [, <размер2>] ... ) [As типДанных]]

3

Итак, опять мы встречаем знакомые конструкции — операторы объявления массива

иимя массива. Размер массива может задаваться тремя способами.

Объявляется только верхняя граница, при этом нижняя граница по умолчанию принимает значение, равное 0. Синтаксис подобного объявления прост: { верхняяГраница}

Объявляется нижняя и верхняя граница изменения индекса: (нижняяГраница То верхняяГраница)

Размер массива вообще не объявляется, размерность массива неизвестна: ( )

Приведем ряд примеров, поясняющих использование синтаксических конструкций. В первом из них объявляется одномерный массив типа variant с использованием ключевого слова Dim, причем индексация производится от -14 до — 1. Данная индексация имеет смысл, например, в случае с метеорологическими данными, представляющими средние дневные температуры за последние две недели. В таком случае temperature (-2) будет соответствовать позавчерашней температуре. Во втором примере показано объявление двумерного массива магазинов с использованием константных аргументов, и инициализация элемента (7, 56).

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

{Первый пример}

Dim temperature( - 14 То -1) temperature(-2) = -10 {Второй пример}

Const numbShop As Integer = 20, numbBook As Integer = 100 Dim numbBookSale (1 To numbShop, 1 To numbBook) As Integer numbBookSale(7, 56) = 300

В приведенных примерах речь все время шла о массивах фиксированного размера, количество элементов в которых явно указано во время описания в операторе Dim. Такие массивы называются статическими. Но иногда количество элементов массива изначально не известно. Например, вы не знаете точного количества магазинов (возможно, появятся еще несколько магазинов, с которыми издательство будет сотрудничать). Как быть? Не стопорить же сбыт продукции до выявления конечного числа магазинов.

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

ReDim имяМассива (размер1[, размер2 ...])

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

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

4

[Private | Public] Enum имяTипа

имяЗначения [ = Константа] имяЗначения [ = Константа]

End Enum

Синтаксис довольно прост. Операторы Private и Public объявляют область видимости для типа (кстати, перечисляемые типы могут описываться только на уровне модуля, т. е. нельзя описать перечисляемый тип внутри процедуры). Затем следует ключевое слово Enum и имятипа, после чего — перечисление значений типа (по одному на строчке). По умолчанию все значения типа перенумеровываются целыми числами, начиная с 0, но вы можете самостоятельно указать константное целое значение для значений типа.

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

Enum Week Monday Tuesday Wednesday Thursday Friday Saturday

Sunday End Enum Sub Weekend() Dim day As Week

Day = Saturday End Sub

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

Например, мы могли бы описать человека при помощи массива целых чисел: Dim Person () As Integer, где Person (1) задает рост, Person (2) — Вес, Person(3) — объем грудной клетки и т. д. Но это все элементы одного типа integer, а как же быть когда мы захотим определить не менее важный параметр человека — его имя, имеющее тип string, или дату рождения типа Date? Решением является создание записи. В нашем случае это будет выглядеть следующим образом: мы создаем пользовательский тип данных Person, элементами которого являются значения разных типов. Обращение же к таким переменным строится следующим образом: Person->Weight или Person->Name

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

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

[Private |Public] Type имяТипа

имяПоля [([<размер>]}] As типДанных [имяПоля [ ( [<размер>] ) ] Аs типДанных]

End Type

Исходя из синтаксической конструкции, сразу можно сказать, что тип определяется либо на уровне модуля, либо на уровне приложения. Далее идет ключевое слово туре и

5

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

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

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

Туре Заяц Волк Аs Заяц

End Type

В приведенной ниже программе мы объявляем тип Person, имеющий поля name (имя) и birthday (дата рождения) простых типов. Далее мы объявляем тип Book, имеющий поле author определенного выше типа Person, поле title (название книги) типа string и поле content (названия глав книги), представляющее собой динамический массив типа string. После объявления типов мы объявляем одномерный массив типа Book и полностью инициализируем второй элемент массива, используя для доступа к полям записей точечную нотацию. Небольшой нюанс при инициализации поля content: поскольку это динамический массив, его необходимо переопределить. В конце просто выводится название одной из глав книги.

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

Public Type Person name As String

birthday As Date End Type

Public Type Book author As Person title As String content () as String End Type

Sub TypeExample() Dim arrBook(l) As Book

arrBpok(1).author.name = "Федор Новиков" arrBook(l).author.birthday = #10/10/1951# arrBook(l).title = "Microsoft Office 2001 в целом" ReDim arrBook(1).content(0 To 1) arrBook(1).content(0) = "Введение"

MsgBox (arrBook(1).content(0)) End Sub

6

Соседние файлы в папке PDF