Переменные, константы и типы данных
Как и в других языках программирования, в VBA для хранения временных значений, передачи параметров и проведения вычислений используются переменные. Кратко остановимся на основных особенностях описания и использования переменных в VBA.
Обычно перед тем, как использовать переменную, производится ее объявление, т. е. вы заранее сообщаете Visual Basic, какие именно имена переменных вы будете использовать в своей программе, при этом объявляется также тип данных, для хранения которых предназначена эта переменная. В VBA, как и в обычном языке Basic, для этого используется оператор Dim. Вот синтаксис этого оператора:
Dim <имяПеременной> [Аs<типДанных>]
В VBA действуют следующие правила именования переменных. Имя не может быть длиннее 255 символов, оно должно начинаться с буквы, за которой могут следовать буквы, цифры или символ подчеркивания. Оно не должно содержать пробелов, знаков препинания или специальных символов, за исключением самого последнего знака. В конце к имени переменной может быть добавлен еще один из следующих шести специальных символов — описателей типа данных:
! # $ % & @
Эти символы не являются частью имени переменной: если в программе используются одновременно имена stringl$ и stringl, то они ссылаются на одну и ту же строковую переменную. Нельзя использовать одно и то же имя переменной с разными символами определения типа данных или одновременно явное описание типа данных и не соответствующий этому типу данных специальный символ. Мы еще остановимся на этом подробнее при обсуждении типов данных.
Кроме того, не допускается использование в качестве имен переменных ключевых слов VBA и имен стандартных объектов. Именно поэтому рекомендуется начинать имена переменных со строчной, а не с прописной буквы. Поскольку у ключевых слов VBA и имен стандартных объектов первая буква при вводе автоматически преобразуется в прописную, вы будете избавлены от риска нечаянно использовать запрещенное имя переменной.
Допускается использование в именах переменных букв не только латинского алфавита, но и кириллицы, что может оказаться удобным для русских пользователей: при желании можно давать переменным имена на русском языке.
Во многих языках программирования, например в Pascal, переменные должны быть объявлены обязательно, и эти объявления используются компилятором, чтобы зарезервировать память для переменных. В то же время в VBA объявление переменных не яаляется обязательным. Как и в его предшественнике, обычном языке Basic, допускается использование неописанных переменных. Выделение памяти переменным может выполняться динамически, а тип данных, хранящихся в переменной, может определяться по последнему символу имени переменной.
В свое время велись длительные баталии между сторонниками сокращения записи процедур за счет отказа от объявлений переменных и сторонниками обязательного описания всех переменных. Аргументы обеих сторон были достаточно серьезны — действительно, зачастую обязательное описание всех переменных требует изрядной доли занудства при методичном выписывании объявлений типа
Dim i As Integer, j As Integer Dim x As Double
С другой стороны, трудно что-нибудь возразить и против того, что одним из самых опасных источников труднообнаружимых ошибок в языках программирования, допускающих применение неописанных переменных, служат опечатки в написании имен переменных. Такие опечатки истолковываются транслятором как появление еще одной, новой переменной, отличной от ранее использовавшейся, и не воспринимаются как ошибки. Порой для обнаружения такой опечатки требуется время, во много раз превосходящее то, которое потребовааось бы на явное описание всех используемых в программе переменных.
В VBA принято поистине соломоново решение — предоставить разрешение этой дилеммы самому программисту. В этом языке имеется оператор
Option Explicit
Если вы начнете свой модуль с этого оператора (он должен быть расположен в самом начале модуля, до того, как начнется первая процедура этого модуля), то VBA будет требовать обязательного объявления переменных в этом модуле и генерировать сообщения об ошибке всякий раз, как встретит необъявленную переменную. Кроме того, если вы строгий пуританин и хотели бы, чтобы это требование стало обязательным для всех ваших модулей без исключения, вы можете установить параметр Require Variable Declaration (Явное описание переменных) на вкладке Editor (Редактор) диалогового окна Options (Параметры) редактора VBA. (Подробнее об установке параметров редактора VBA будет рассказано в разд. "Среда программирования Access 2002" ниже в данной главе.)
Установка этого параметра приведет к тому, что редактор Visual Basic будет автоматически добавлять оператор Option Explicit в начало каждого вновь создаваемого модуля. Учтите, однако, что этот флажок не влияет на все ранее созданные модули — если вы хотите добавить этот оператор к уже существующим модулям, вам придется проделать это вручную.
Приведем теперь краткую сводку используемых типов данных VBA (табл. 13.1).
Тип данных | Описание |
Array | Массив переменных, для ссылки на конкретный элемент массива используется индекс. |
Boolean | Требуемая память: зависит от размеров массива Принимает одно из двух логических значений: True или False. Требуемая память: 2 байта |
Byte | Число без знака от 0 до 255 Требуемая память: как нетрудно догадаться, 1 байт |
Currency | Используется для произведения денежных вычислений с фиксированным количеством знаков после десятичной запятой, в тех случаях, когда важно избежать возможных ошибок округления. Диапазон возможных значений: от -922 337 203 685 477,5808 до 922 337 203 685 477,5807. Требуемая память: 8 байтов. Символ определения типа по умолчанию: @ |
Date | Используется для хранения дат. Диапазон возможных значений: от 1 января 0100 г. до 31 декабря 9999 г. Требуемая память: 8 байтов |
Double | Числовые значения с плавающей точкой двойной точности. Диапазон возможных значений для отрицательных чисел: от -1 ,797693 13486232Е308 до -4,94065645841 247Е-324. Диапазон возможных значений для положительных чисел: от 4,94065645841 247Е-324 до 1, 7976931 3486232Е308. Требуемая память: 8 байтов. Символ определения типа по умолчанию: # |
Integer | Короткие целые числовые значения. Диапазон возможных значений: от -32 768 до 32 767. Требуемая память: 2 байта. Символ определения типа по умолчанию: % |
Long | Длинные целые числовые значения. Диапазон возможных значений: от -2 147 483 648 до 2 147 483 647. Требуемая память: 4 байта. Символ определения типа по умолчанию: & |
Object | Используется только для хранения ссылок на объекты. Требуемая память: 4 байта |
Single | Числовые значения с плавающей точкой обычной точности. Диапазон возможных значений для отрицательных чисел: от -3.402823Е38 до -1 ,401 298Е-45. Диапазон возможных значений для положительных чисел: от 1 ,401 298Е-45 до 3.402823Е38. Требуемая память: 4 байта. Символ определения типа по умолчанию: ! |
String | Используется для хранения строковых значений. Длина строки: от 0 до 64 Кбайтов. Требуемая память: 1 байт на символ. Символ определения типа по умолчанию: $ |
Variant | Может использоваться для хранения различных типов данных: даты/времени, чисел с плавающей точкой, целых чисел, строк, объектов. Требуемая память: 16 байтов, плюс 1 байт на каждый символ строковых значений. Символ определения типа по умолчанию: отсутствует |
Определяемый пользователем тип | Определяемые пользователем типы данных, назначение и размер выделяемой памяти зависят от определения. Используется для описания структур данных. Позволяет хранить в переменной такого типа множество различных значений разного типа |
Таблица 13.1. Типы данных VBA
При описании переменной указание типа данных может быть опущено. Тип переменной в таком случае определяется последним символом имени переменной: @, #, %, &, ! или $ (Currency, Double, Integer, Long, Single или String соответственно). Например, поскольку символ "$" является символом определения типа для строковых данных, то переменная под именем text$ автоматически становится переменной типа "строка символов". В дальнейшем этот специальный символ указания типа данных может быть опущен, однако постоянное присутствие в имени переменной символа определения типа будет напоминать о том, к какому типу данных относится эта переменная, что поможет избежать ошибок использования несовместных типов данных.
Если же последний символ не является ни одним из вышеперечисленных и явное указание типа тоже не используется, в этом случае переменной будет назначен по умолчанию тип данных Variant, который позволяет хранить в ней данные любого типа.
Учтите также, что нельзя использовать в одной и той же процедуре имена переменных, отличающиеся друг от друга только специальным символом определения типа в конце переменной. Например, не допускается одновременное использование переменных var$ и var%. He допускается и явное объявление переменной, уже содержащей символ определения типа в конце имени, с помощью описателя As <типПеременной> (даже если такое определение не противоречит обычному применению символа определения типа). Так, например, вы получите сообщение об ошибке, попытавшись ввести любое из следующих определений:
Dim var1% As String Dim var2% As Integer
Для определения типа данных аргументов процедуры или функции используется описание типа данных непосредственно в заглавной строке процедуры или функции. Например, следующая заглавная строка процедуры описывает ее параметры как переменные строкового типа:
Sub SplitStr(str1 As String, str2 As String, str3 As String)
Определение типа данных возвращаемого функцией значения завершает заглавную строку функции, например:
Function FindSplitSpace (strl As String) As Integer
описывает возвращаемое функцией значение как переменную короткого целого типа.
Чтобы программа работала быстрее и занимала меньше памяти, рекомендуется использовать, когда это возможно, конкретные типы переменных, а не универсальный тип Variant. На обработку переменных типа Variant требуется не только дополнительная память (сравните размеры, приведенные в табл. 13.1), но и дополнительное время: требуется выяснить, к какому конкретному типу данных принадлежит такая переменная в момент обработки, а также при необходимости выполнить преобразование данных к нужному типу. Может показаться, что в таком случае лучше вообще не использовать подобные переменные. Это не так. Часто подобные переменные просто необходимы: например, в том случае, когда вы точно не уверены, какие именно данные будут присвоены переменной.
Приведем здесь лишь один пример. Если вы хотите, чтобы пользователь программы ввел некоторое целое значение, необходимое для дальнейшей работы программы, и описали для этого переменную целого типа, то рекомендуется использовать для ввода данных промежуточную переменную, описанную как Variant, а затем выполнить присваивание введенного значения нужной переменной (или же описать переменную, в которую вы хотите поместить это значение как Variant, несмотря на то, что ввести предполагается именно целое число). Дело в том, что пользователь может ошибиться и ввести, например, вещественное число или вообще нечаянно нажать не на ту клавишу и ввести строковое значение. В таком случае при присваивании введенного значения переменной целого типа произойдет ошибка во время выполнения программы. Если же переменная для ввода будет объявлена как Variant, ничего страшного не случится: введенное значение будет благополучно присвоено этой переменной, а вы получите возможность проанализировать введенное значение и попросить пользователя повторить ввод, если введенное им значение не отвечает нужным условиям.
И в завершение этого раздела обсудим использование именованных констант. Для их описания применяется оператор Const, схожий с оператором описания переменных Dim. Вот синтаксис этого оператора:
Const <имяКонстанты> [As <типДанных>] = <выражение>
где <выражение> — эго любое значение или формула, возвращающая значение, которое должно использоваться в качестве константы. Например, следующий оператор определяет целую константу maxLen:
Const maxLen% = 30
Как и переменные, константы могут содержать значения различных типов данных, но при этом они не меняют своих значений во время выполнения программы.
Совет
Если вы собираетесь использовать в вашей программе какие-либо константы, то рекомендуется дать этим константам осмысленные имена и описать их в самом начале модуля, а затем использовать всюду только именованные константы. Это не только делает программу понятнее, но и проще в сопровождении и отладке. Зачастую значение той или иной константы требуется изменить (хотя бы на время отладки), и тогда достаточно поменять лишь одно значение в описании именованной константы. Если же непосредственное значение использовалось прямо в тексте кода программы, то изменить все вхождения этого значения намного сложнее.
Кроме описываемых пользователем констант, существуют еще предопределенные встроенные константы, которые включаются в тексты программ без предварительного описания. Сведения о предопределенных встроенных константах, используемых для различных объектов приложений Microsoft Office и Visual Basic, можно найти в справке—в разделах описания свойств объектов (реже — в разделах описания методов). При именовании встроенных констант используется стандартное соглашение, позволяющее определить, к объектам какого приложения относится эта константа. Например, встроенные константы, относящиеся к объектам Access, начинаются с префикса ас, относящиеся к объектам Excel — с префикса xl, относящиеся к объектам Word — с префикса wd, а относящиеся к объектам VBA — с префикса vb. Например, в команде
DoCmd.OpenForm "Orders", acNormal, , stLinkCriteria
используется встроенная константа Access acNormal.