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

2 Курс Информатика VBA(ЗО) / Книги / В.Д.Хорев - Самоучитель программирования на VBA в Microsoft Office

.pdf
Скачиваний:
2707
Добавлен:
31.05.2015
Размер:
21.66 Mб
Скачать

Данные VBA: типы данных, переменные и константы 265

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

SvodCount = 2

For A = 1 To PriceA.Range("Наименование").Rows.Count

...

SvodCaunt = SvodCount + 1

...

Next A

Предположим, в результате забывчивости или просто из-за опечатки в цикле было введено имя SvodCaunt вместо SvodCount. Никто ничего не заметит, и программа будет работать. Но работать она будет неправильно, поскольку переменная SvodCaunt будет автоматически создана помимо переменной SvodCount, и начальным значением ее будет число 0, а вовсе не 2. Значение же переменной SvodCount будет оставаться неизменным внутри цикла, хотя предполагалось, что оно будет увеличиваться на 1 в каждом проходе. Когда (и если!) будет обнаружено, что программа работает неправильно, придется искать, в чем же ошибка. Если в программе используется 2-3 переменные, которые упоминаются 2-3 десятка раз, то даже тогда придется немало потрудиться, чтобы найти подобную ошибку. Если же переменных несколько десятков и упоминаются они сотни раз, то, скорее всего, ошибку нельзя будет найти никогда — программу придется переписывать заново. Но это еще не самый худший случай, — возможно, сам факт наличия ошибки не будет обнаружен, и придется пользоваться неправильно работающей программой, пока на ошибку не укажет сама жизнь.

Директива Option Explicit

Для того чтобы Visual Basic перестал “понимать” необъявленные переменные, используют директиву Option Explicit. Эта директива помещается в начале исходного текста и любые переменные, упоминаемые после нее, обязательно должны быть предварительно объявлены. Если рассмотреть предыдущий пример с учетом директивы Option Explicit, то картина разительно переменится. Например:

Option Explicit

...

Dim SvodCount As Integer

Dim A As Integer

...

SvodCount = 2

...

For A = 1 To PriceA.Range("Наименование").Rows.Count

...

SvodCaunt = SvodCount + 1

...

Next A

При попытке запуска программы компилятор Visual Basic обнаружит ошибку и, вместо того, чтобы запустить программу, выдаст сообщение: “Ошибка компиляции: переменная не определена”, выделив при этом в тексте ошибочное имя SvodCaunt (рис. П.1).

266 Приложение. VBA, как язык программирования: данные, синтаксис и функции

Рис. П.1. Компилятор обнаружил необъявленную переменную

Опечатка обнаружена сразу же, а поиск ее не стоил программисту никакого труда.

Если создается простенький макрос “на скорую руку”, то можно не объявлять переменные и не использовать директиву Option Explicit. Но как только программа станет немного сложнее, то придется использовать директиву Option Explicit и заранее объявлять каждую переменную, поскольку в противном случае вряд ли удастся отладить программу, а если и удастся, то никогда нельзя быть уверенным в том, что она работает правильно.

Область видимости и время жизни переменных

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

Предположим, в исходном тексте (это может быть модуль, форма, рабочая книга или документ), объявлены переменные A, B и C:

Public A As Integer Dim B As Integer

...

Sub MySub()

Dim C As Integer

...

End Sub

Глобальная переменная A будет доступна во всех процедурах всех модулей, относящихся к данной рабочей книге или документу.

Переменная B доступна только в пределах модуля, то есть в этом же окне исходного текста. Если где-то в другом модуле объявлена глобальная переменная с таким же именем (Public B), то в процедурах этого модуля будет фактически использована эта переменная B, а в остальных местах под B будет иметься в виду глобальная, то есть Public-переменная B.

Переменная C определена только внутри процедуры MySub. Если переменная с таким же именем объявлена на уровне модуля, то внутри процедуры MySub будет все равно использоваться “своя”, локальная переменная C.

Существует еще область видимости Private — такие переменные доступны в пределах модуля, но недоступны в других модулях. Это область видимости по умолчанию, и ее можно явно не указывать — объявление Dim на уровне модуля (то есть вне текста какой-либо процедуры) подразумевает Private.

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

Данные VBA: типы данных, переменные и константы 267

Public A As Integer Dim B As Integer

...

Sub MySub()

Dim C As Integer A = 10

B = 20

C = 100

...

End Sub

После того, как процедура MySub завершит свою работу, переменная C “исчезнет” вместе со своим значением, и снова она возникнет уже со значением 0 в момент следующего вызова процедуры MySub. А переменные A и B сохранят присвоенные им значения. Причем значение A сможет прочитать процедура любого модуля, а значение B будет доступно только в пределах текущего модуля. Благодаря глобальным переменным процедуры могут передавать друг другу, или, скорее, оставлять друг для друга сохраненные данные.

Существует возможность сохранять значения локальных переменных. Если объявить переменную внутри процедуры с использованием зарезервированного слова Static, то она будет продолжать существовать и после завершения процедуры, сохраняя свое значение. Например:

Sub MySub()

Static C As Integer

...

End Sub

Массивы

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

Const MaxWords = 3000

Const WordsInDictionary = 200

Dim Words(0 To MaxWords) As String

Dim WordFrq(0 To MaxWords) As Integer

Если нижняя граница индекса не указана, то по умолчанию она принимается равной 0. При помощи директивы Option Base значение нижней границы по умолчанию можно изменить, например Option Base 1 задаст отсчет нижней границы по умолчанию с 1.

Таким образом, массив Words, например, можно было бы определить, как

Dim Words(3000) As String

Если бы требовалось использовать две размерности в массиве, достаточно было бы указать два набора границ:

Dim Words(0 To 30, 0 To 100) As String

Динамические массивы

В Visual Basic поддерживаются динамические массивы, то есть массивы, размерность которых меняется при выполнении программы. Например, можно было бы не указывать размерность массива Words при его объявлении:

268 Приложение. VBA, как язык программирования: данные, синтаксис и функции

Dim Words() As String

Но затем, перед первым обращением к элементам такого массива, необходимо будет задать его размерность при помощи оператора ReDim:

ReDim Words(0 To 3000)

При необходимости изменить размерность, ее снова можно переопределить:

ReDim Words(0 To 4000)

Если новая размерность больше старой, в массиве просто появятся дополнительные пустые элементы, в данном случае строки. Если новая размерность меньше старой размерности, то значения части элементов будет утеряны.

При помощи функций LBound и UBound можно получить текущие значения нижней и верхней границ динамического массива соответственно. Операторы

MsgBox LBound(Words)

MsgBox UBound(Words)

выведут на экран значения 0 и 4000.

Объектные переменные

Объектную переменную можно объявить, как абстрактный объект (тип Object), или указать

для нее определенный объектный тип. Переменная типа Object (ссылка на объект) может указы-

вать на объект любого типа.

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

Присваивание объектного значения (точнее, ссылки на объект) производится при помощи зарезервированного слова Set:

Dim MyParagraph As Paragraph

Dim MyDocument As Document

...

Set MyDocument = Documents.Add

Set MyParagraph = MyDocument.Paragraphs.Add

С таким же успехом можно объявить обе переменные, как объект, и присвоить им в качестве значения объекты типа “документ” и “абзац”, …

Dim MyParagraph As Object

Dim MyDocument As Object

...

Set MyDocument = Documents.Add

Set MyParagraph = MyDocument.Paragraphs.Add

… или наоборот:

Set MyParagraph = Documents.Add

Set MyDocument = MyDocument.Paragraphs.Add

В любом случае при этом произойдет так называемое “позднее связывание” и фактический тип объектов MyDocument и MyParagraph определится уже в процессе выполнения программы. Такой способ работы с объектами связан с определенными сложностями, и использовать его следует только в тех случаях, когда тип возвращаемого объекта действительно заранее неизвестен.

Данные VBA: типы данных, переменные и константы 269

Определить тип объекта, ссылка на который получена откуда-то извне (например, как возвращаемое значение какой-то функции), можно при помощи оператора TypeOf и операции Is:

Dim MyObject As Object

...

Set MyObject = MyFunction()

...

If TypeOf MyObject Is Document Then

MyObject.Paragrahps.Add

...

End If

If TypeOf MyObject Is Workbook Then

MyObject.WorkSheets.Add

...

End If

Типы данных

Все данные, которыми оперирует VBA-код, относятся к определенному типу. Тип переменной можно не указывать при ее объявлении, но это не значит, что она не будет относиться ни к какому типу: просто неявным образом будет использован универсальный тип по умолчанию, именуемый

Variant.

Зачем нужно объявлять тип?

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

Первая причина заключается в том, что за свободу в обращении с типами приходится платить эффективностью. Если требуется переменная I для хранения целочисленных значений, то можно объявить ее с явным указанием целочисленного типа Integer:

Dim I As Integer

или же просто, как

Dim I

или, что то же самое,

Dim I As Variant

Как уже указывалось, если тип не указан, то по умолчанию используется тип Variant. Так можно делать, и программа будет нормально работать. Если таких переменных немного и обращение к ним происходит небольшое число раз, то никакой разницы программа “не почувствует”. Но разница все же есть. Переменная типа Variant занимает в несколько раз больше места в памяти

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

Вторая причина для явного указания типов всех переменных заключается во все тех же опечатках и ошибках, которые неизбежно случаются при работе с исходным текстом. Если тип переменной I, которая упоминалась выше, не указан явным образом, то можно присвоить ей любое значение, например строковое:

I = “Строковое значение”

270Приложение. VBA, как язык программирования: данные, синтаксис и функции

Втакой возможности кроется неиссякаемый источник ошибок. Например, выражение

I = “1” + “1”

никоим образом не эквивалентно выражению

I = 1 + 1

В первом случае переменная I получит строковое значение “11”, а во втором — числовое значение 2. Если тип I не указан явным образом, то оба варианта одинаково правомерны. Но если I

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

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

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

Boolean

Может принимать только значения True (Истина) или False (Ложь). Переменные типа Boolean используются главным образом при организации циклов и ветвлений — обычно они играют роль флажков, сигнализирующих о состоянии программы. Например, можно сохранить в Boolean-переменной результат логической операции, скажем, результат сравнения двух чисел:

Result As Boolean

Dim N1 As Integer

Dim N2 As Integer

...

N1 = 10

N2 = 5

...

Result = N1 > N2

...

If Result=True Then

MsgBox “Первое число больше второго!”

End If

Integer

Этим переменным можно присваивать только целочисленные значения. Наименьшее значение: –32768 Наибольшее значение: +32767

Integer-переменные отличаются малым объемом занимаемой памяти и высокой скоростью обращения. Часто их используют в качестве счетчика цикла:

Dim Counter As Integer

...

For Counter = 1 to 1000

...

Next Counter

Long

Этим переменным также можно присваивать только целочисленные значения. От Integer этот тип отличается более широким диапазоном значений.

Наименьшее значение: –2147483648

Данные VBA: типы данных, переменные и константы 271

Наибольшее значение: +2147483647

Long-переменные отличаются высокой скоростью обращения, и наилучшим образом подходят для задач целочисленной арифметики. Например:

Dim MyDistance As Long

Dim MyTotalTime As Long Dim MySpeed As Long

...

MySpeed = 2521 MyTotalTime = 811

MyDistance = MySpeed * MyTotalTime

см. об еще одном способе объявления Long-переменных в раздел “Операции со строками” этой главы.

Single

Этот тип используется для вычислений с плавающей точкой. Single-переменные обеспечивают точность до 6-го знака после десятичной точки.

Наименьшее отрицательное значение: –3.402823E+38 Наибольшее отрицательное значение: –1.401298E–45 Наименьшее положительное значение: 1.401298E–45 Наибольшее положительное значение: 3.402823E+38

Например, с помощью переменных типа Single можно выполнять вычисления с дробями:

Dim MyWeight As Single

Dim MyPrice As Single

Dim PriceToWeight As Single

...

MyWeight = 3.1

MyPrice = 121.77

PriceToWeight = MyPrice / MyWeight

Double

Этот тип также используется для вычислений с плавающей точкой. Double-переменные обеспечивают точность до 14-го знака после десятичной точки.

Наименьшее отрицательное значение: –1.79769313486232E+308 Наибольшее отрицательное значение: –4.94065645841247E–324 Наименьшее положительное значение: 4.94065645841247E–324 Наибольшее положительное значение: 1.79769313486232E+308

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

Dim MyPI As Double Dim MyRadius As Double Dim MySquare As Double

...

MyPI = 3.14159265358979 MyRadius = 9.79921235715865 MySquare = MyPI * MyRadius * 2

Currency

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

272 Приложение. VBA, как язык программирования: данные, синтаксис и функции

арифметике обычной. Если речь идет о денежных суммах, то корректность арифметических операций будет обеспечена только при использовании специального денежного типа Currency.

Наименьшее значение: –922'337'203'685'477.5808 Наибольшее значение: +922'337'203'685'477.5807

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

Вот как, например, следует выполнять вычисления с денежными суммами в пересчете на валюту по курсу:

Dim MySum As Currency Dim Kurs As Currency Dim MyUSDSum As Currency

...

MySum = 123.45 Kurs = 6.77

MyUSDSum = MySum / Kurs

Date

Данные типа Date служат для операций со значениями даты-времени. Наименьшее значение: 1 января 100 года Наибольшее значение: 31 декабря 9999 года

Значения даты и времени ограничиваются символами #...# или "...", например:

MyDate = "04/02/1962"

или

MyDate = #17/04/1972#

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

Dim BirthDay As Date

Dim TodayDay As Date

Dim DaysAge As Long

BirthDay = "17/04/1972"

TodayDay = #26/01/2001#

DaysAge = TodayDay - BirthDay

MsgBox DaysAge

String

Для выполнения действий с текстовыми строками используют переменные типа String. Максимальная длина строки: 2 миллиарда символов. Строковые значения необходимо заключать в кавычки:

Dim MyString As String

MyString = "Строковое значение"

Данные VBA: типы данных, переменные и константы 273

Специальным видом строки является строка фиксированной длины. Ее максимальная длина равняется 65536 символов (конкретная длина указывается при объявлении). Обращение со строками фиксированной длины отличается некоторыми особенностями. Например:

Dim MyString1 As String

Dim MyString2 As String *30

MyString1 = "Строковое значение1"

MyString2 = "Строковое значение2"

В результате переменная MyString1 содержит строку “Строковое значение1”, состоящую ровно из 19 символов, а в переменной MyString2 содержится строка длиной ровно 30 символов. При этом первые 19 символов — это “Строковое значение2”, а следующие 11 позиций заполнены пробелами. На операции со строками фиксированной длины накладывается ряд ограничений, поэтому их используют только в специальных случаях.

Variant

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

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

Dim MyFloat As Variant

Dim MyInteger As Variant

Dim MyText As Variant

MyInteger = 19

MyFloat = 2.001

MyText = MyInteger * MyFloat & " попугаев"

В результате в переменной MyText окажется строковое значение “38,019 попугаев”, причем строка “38,019” получилась неявным образом из числа 38,019, которое, в свою очередь, получено в результате операции умножения целого числа 19 и числа с плавающей точкой 2.001.

Типы данных, определяемые пользователем

Определяемые пользователем типы данных называют также записями или структурами. Такой тип представляет собой некую совокупность типов (простых или определенных ранее), объединенных общим именем. Если затем объявить переменную, принадлежащую к вновь определенному типу, то доступ к ее компонентам можно будет осуществлять по имени переменной и, отделенному точкой, имени компоненты, каким оно было задано при объявлении типа. В отличие от массивов такой механизм позволяет объединять в единую структуру переменные разных типов.

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

Private Type Sotrudnik

PersNum As Long

Name As String

274 Приложение. VBA, как язык программирования: данные, синтаксис и функции

BirthDay As Date

Salary As Currency

End Type

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

Dim MySotrudnik1 As Sotrudnik

Dim MySotrudnik2 As Sotrudnik

Для того чтобы присвоить значения компонентам переменной MySotrudnik1, необходимо через точку указывать имя соответствующей компоненты:

MySotrudnik1.PersNum = 121

MySotrudnik1.Name = "Евгения"

MySotrudnik1.BirthDay = "26/01/2000"

MySotrudnik1.Salary = 7900.11

Далее можно обращаться с переменной MySotrudnik1, как с единым целым. Например, присвоить ее значение переменной такого же типа:

MySotrudnik2 = MySotrudnik1

В результате выражение MySotrudnik2.BirthDay вернет значение даты "26/01/2000".

Синтаксические конструкции языка VBA

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

Выражения и операции

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

Под выражением в Visual Basic понимают другую переменную, функцию, свойство некоторого объекта или значение (числовое, строковое и т.д.), или результат разрешенных над соответствующими типами данных операций. Конечно, тип операндов и результата должен быть совместимым с типом переменной.

Арифметические операции

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

ТАБЛИЦА П.1. АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ VBA

Операция Описание

+Сложение

Вычитание или перемена знака

/Деление

*Умножение

^Возведение в степень

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