Лабораторная работа № 3. Синтаксис и программные конструкции VBA
3.1. Основы синтаксиса
Мы подошли к теме, которая многим покажется самой скучной, – синтаксис языка VBA. Относиться к этой теме, следует так же, как к изучению азбуки или таблицы умножения: в самой азбуке или таблице умножения ничего интересного нет, но без их знания не удастся читать интересные книги или производить важные вычисления. Кроме того, VBA изначально проектировался и создавался как язык программирования, максимально дружелюбный по отношению к пользователю, который не является профессиональным программистом.
Для тех, кто хорошо знаком с обычным Visual Basic, в этой лабораторной не будет почти ничего нового. Те, кто обладают опытом работы с любым другим современным языком программирования (C++, Java, Delphi, VBScript и JavaScript, Perl и т. п.) также освоят изложенный далее материал почти мгновенно. А тем, кто никогда не сталкивался ни с одним языком программирования, стоит просто выучить то, что изложено в этой главе, и постараться в течение какого-то времени активно применять полученные знания на практике, чтобы они не успели забыться. Потраченные усилия окупятся многократно, тем более что материала на самом деле не так и много – язык VBA очень прост.
Теперь рассмотрим некоторые общие моменты, связанные с синтаксисом языка VBA.
Синтаксис VBA, как понятно из самого названия этого языка (которое расшифровывается как Visual Basic for Applications), почти полностью совпадает с синтаксисом Visual Basic.
Основные синтаксические принципы этого языка следующие:
· VBA нечувствителен к регистру;
· чтобы закомментировать код до конца строки, используется одинарная кавычка (') или команда REM;
· символьные значения должны заключаться в двойные кавычки (");
· максимальная длина любого имени в VBA (переменные, константы, процедуры) – 255 символов;
· начало нового оператора – перевод на новую строку (точка с запятой, как в C, Java, JavaScript, для этого не используется);
· ограничений на максимальную длину строки нет (хотя в редакторе в строке помещается только 308 символов). Несколько операторов в одной строке разделяются двоеточиями:
MsgBox "Проверка 1" : MsgBox "Проверка 2"
· для удобства чтения можно объединить несколько физических строк в одну логическую при помощи пробела и знака подчеркивания после него:
MsgBox "Сообщение пользователю" _
& vUserName
3.2. Операторы
Оператор – это наименьшая способная выполняться единица кода VBA. Оператор может объявлять или определять переменную, устанавливать параметр компилятора VBA или выполнять какое-либо действие в программе.
Арифметических операторов в VBA всего 7. Четыре стандартных: сложение (+), вычитание (), умножение (*), деление (/), и еще три:
· возведение в степень (^). Например, 2^3 = 8;
· целочисленное деление (\). Делит первое число на второе, отбрасывая (не округляя) дробную часть. Например, 5\2 = 2;
· деление по модулю (Mod). Делит первое число на второе, возвращая только остаток от деления. Например, 5 Mod 2 = 1.
Оператор присваивания в VBA – это знак равенства. Можно записывать так:
Let nVar = 10
а можно еще проще:
nVar = 10
Здесь не путайте знак равенства с оператором равенства. Последнее выражение означает "присвоить переменной nVar значение 10", а если строка выглядит так:
If (nVar = 10)
то это значит "если значение переменной nVar равно 10".
Если переменной нужно назначить объект, то делается это другими способами.
Операторов сравнения в VBA всего 8:
· равенство (=). Например, If (nVar = 10);
· больше, чем (>) и меньше, чем (<). Например, If (nVar > 10);
· больше или равно (>=) и меньше или равно (<=). Например, If (nVar >= 10);
· не равно (<>). Например, If (nVar<>10);
· сравнение объектов (Is). Определяет, ссылаются объектные переменные на один и тот же объект или на разные. Например, If (obj1 is obj2);
· подобие (Like). Сравнивает строковый объект с шаблоном и определяет, подходит ли шаблон.
Операторы сравнения всегда возвращают True (если утверждение истинно) или False (если утверждение ложно).
Приведем некоторые особенности сравнения строковых значений:
· при сравнении строковых значений учитывается регистр;
· пробелы в строковых значениях также учитываются;
· при сравнении текстовых строк на больше/меньше по умолчанию сравниваются просто двоичные коды символов – какие больше или меньше. Если нужно использовать тот порядок, который идет в алфавите, то нужно воспользоваться командой
Option Compare Text
Общий синтаксис оператора Like выглядит так:
Выражение1 Like Выражение2
При этом Выражение1 – это любое текстовое выражение VBA, а Выражение2 – шаблон, который передается оператору Like. В этом шаблоне можно использовать специальные подстановочные символы (табл. 3.1).
Таблица 3.1. Подстановочные символы для оператора Like
Подстановочный символ | Значение |
# | Любая одна цифра от 0 до 9 |
* | Любое количество любых символов (включая нулевое) |
? | Любой один символ |
[a,b,c] | Любой один символ из приведенного в квадратных скобках списка |
[!a,b,c] | Любой один символ, кроме приведенных в списке |
Очень часто при проверке нескольких условий используются логические операторы:
· And – логическое И. Должны быть истинными оба условия;
· Or – логическое ИЛИ. Должно быть истинным хотя бы одно из условий;
· Not – логическое отрицание. Возвращает True, если условие ложно;
· Xor – логическое исключение. В выражении E1 Xor E2 возвращает True, если только E1 = True или только E2 = True, иначе – False;
· Eqv – эквивалентность двух выражений, возвращает True, если они имеют одинаковое значение;
· Imp – импликация, E1 Imp E2 возвращает False, если E1 = True и E2 = False, иначе – True.
Помнить нужно про And, Or, Not, остальные логические операторы используются редко.
Почти в любой программе VBA используются операторы конкатенации, т. е. слияния строковых значений. В VBA их два – (+) или (&). Рекомендуется всегда использовать оператор (&), потому что:
· при использовании (&) производится автоматическое преобразование чи-словых значений в строковые – нет опасности допустить ошибку;
· при использовании оператора (+) сложение строкового значения со значением типа Null дает Null.
Пример использования оператора (&):
MsgBox "Сообщение пользователю " & vUserName
Порядок применения операторов выглядит так: вначале в выражении вычисляются арифметические операторы, затем операторы конкатенации, следующими идут операторы сравнения и уже в самом конце логические. Если в выражении есть несколько операторов одного типа, то они применяются в обычном порядке – слева направо. При необходимости можно изменять порядок применения операторов при помощи круглых скобок.
3.3. Переменные и типы данных
Переменные – это контейнеры для хранения изменяемых данных. Без них не обходится практически ни одна программа. Для простоты переменную можно сравнить с номерком в гардеробе – вы сдаете в гардероб какие-то данные, в ответ вам выдается номерок. Когда вам опять потребовались эти данные, вы "предъявляете номерок" и получаете их. Пример работы с переменными в VBA может выглядеть так:
Dim nMyAge As Integer
nMyAge = nMyAge + 10
MsgBox nMyAge
Перед работой с переменной настоятельно рекомендуется ее объявить. Объ-явление переменной в нашем примере выглядит так:
Dim nMyAge As Integer
Расшифруем эту строку.
Dim – это область видимости переменной. В VBA предусмотрено 4 ключевых слова для определения области видимости переменных.
· Dim – используется в большинстве случаев. Если переменная объявлена как Dim в области объявлений модуля, то она будет доступна во всем модуле, если в процедуре – только на время работы этой процедуры.
· Private – при объявлении переменных в стандартных модулях VBA значит то же, что и Dim. Отличия проявляются только при создании своих классов (эта тема в данной книге не рассматривается).
· Public – такая переменная будет доступна всем процедурам во всех модулях данного проекта, если вы объявили ее в области объявлений модуля. Если вы объявили ее внутри процедуры, она будет вести себя как Dim.
· Static – такие переменные можно использовать только внутри процедуры. Эти переменные видны только внутри процедуры, в которой они объявлены, зато они сохраняют свое значение между разными вызовами этой процедуры. Обычно используются для накопления каких-либо значений. Например:
Static nVar1 As Integer
nVar1 = nVar1 + 1
MsgBox nVar1
Если нет никаких особых требований, то имеет смысл всегда выбирать область видимости Dim.
Второе слово в нашем объявление (nMyAge) – это идентификатор (проще говоря, имя) переменной. Правила выбора имен в VBA едины для многих элементов (переменные, константы, функции, процедуры и т. п.):
· имя должно начинаться с буквы;
· не должно содержать пробелов и символов пунктуации (исключение – символ подчеркивания);
· максимальная длина – 255 символов;
· должно быть уникальным в текущей области видимости;
· зарезервированные слова (те, которые подсвечиваются синим цветом в окне редактора кода) использовать нельзя.
При создании программ VBA настоятельно рекомендуется определиться с правилами, по которым будут присваиваться имена объектам – соглашение об именовании. Чаще всего используется так называемое венгерское соглашение (в честь одного из программистов Microsoft, Charles Simonyi, венгра по национальности):
· имя переменной должно начинаться с префикса, записанного строчными буквами. Префикс указывает, что именно будет храниться в этой переменной:
– str (или s) – String, символьное значение;
– fn (или f) – функция;
– sub – процедура;
– c (или все буквы имени заглавные) – константа;
– b – Boolean, логическое значение (True или False);
– d – дата;
– obj (или o) – ссылка на объект;
– n – числовое значение;
· имена функций, методов и каждое слово в составном слове должно начинаться с заглавной буквы:
MsgBox objMyDocument.Name
Sub CheckDateSub()
· в ранних версиях VB не было слова Const, все константы определялись как переменные, а для отличия их записывали заглавными буквами, между словами ставили символ подчеркивания, например COMPANY_NAME.
Многие программисты используют такой подход для обозначения констант и сейчас (но использование ключевого слова Const теперь обязательно.
Третья часть нашего объявления (As Integer) – это указание на тип данных нашей переменной. Тип данных определяет, данные какого вида можно будет хранить в этой переменной.
В VBA предусмотрены следующие типы данных:
· числовые:
– Byte – целое число от 0 до 255;
– Integer – целое число от 32 768 до 32 767;
– Long – большое целое число от 2 147 483 648 до 2 147 483 647;
– Currency – большое десятичное число с 19 позициями, включая 4 позиции после запятой;
– Decimal – еще большее десятичное число с 29 позициями (после запятой можно использовать от 0 до 28 позиций);
– Single и Double – значения с плавающей запятой (Double в 2 раза больше));
Внимание! Попытка объявить переменную с типом Decimal (например, Dim n As Decimal) приведет к синтаксической ошибке. Чтобы получить возможность работать с типом Decimal, переменную нужно изначально объявить как Variant или вообще объявить без типа (Dim n), поскольку тип данных Variant используется в VBA по умолчанию. Если мы присвоим переменной с типом Variant числовое значение, для которого подходит только Decimal, VBA автоматически назначит ей этот тип данных. Кроме того, можно явно указать подтип Decimal для пере-менной типа Variant при помощи функции CDec().
· строковые (String переменной длины (примерно до 2 млрд символов) и фиксированной длины (примерно до 65 400 символов));
· дата и время (Date – от 01.01.100 до 31.12.9999);
· логический (Boolean – может хранить только значения True и False);
· объектный (Object – хранит ссылку на любой объект в памяти);
· Variant – специальный тип данных, который может хранить любые другие типы данных.
Можно также использовать пользовательские типы данных, но их вначале нужно определить при помощи выражения Type. Обычно пользовательские типы данных используются как дополнительное средство проверки вводимых пользователем значений (классический пример – почтовый индекс).
Приведем некоторые моменты, связанные с выбором типов данных для переменных:
· общий принцип – выбирайте наименьший тип данных, который может вместить выбранные вами значения. Если есть какие-то сомнения – выбирайте больший тип во избежание возникновения ошибок;
· если есть возможность, лучше не использовать типы данных с плавающей запятой (Single и Double). Работа с ними производится медленнее, кроме того, могут быть проблемы при сравнениях за счет округлений;
· при определении переменных можно использовать так называемые символы определения типа ((%) – Integer, ($) – String и т. п.). Например, в нашем примере можно закомментировать строку:
' Dim nVar1 As Integer
а во второй строке написать:
nVar1% = nVar1% + 1
Такой подход является устаревшим и к использованию не рекомендуется.
При объявлении переменной можно не указывать ее тип. Например, наше объявление может выглядеть так:
Dim nVar1
В этом случае переменная будет автоматически объявлена с типом Variant.
В принципе, в VBA можно работать и без объявления переменных. Например, такой код
nVar1 = nVar1 + 1
MsgBox nVar1
будет вполне работоспособным. Если мы используем переменную в программе без ее объявления, то будет автоматически создана новая переменная типа Variant. Однако объявлять переменные нужно обязательно! И при этом желательно явно указывать нужный тип данных. Потому что:
· сокращается количество ошибок: программа с самого начала откажется принимать в переменную значение неправильного типа (например, строковое вместо числового);
· при работе с объектами подсказка по свойствам и методам действует только тогда, когда мы изначально объявили объектную переменную с нужным типом. Например, в Excel два варианта кода будут работать одинаково:
– первый вариант:
Dim oWbk As Workbook
Set oWbk = Workbooks.Add
– второй вариант:
Set oWbk = Workbooks.Add
Но подсказка по свойствам и методам объекта oWbk будет работать только в первом случае.
Все опытные разработчики вообще запрещают использовать переменные без явного их объявления. Для этого можно воспользоваться специальной командой компилятора (она помещается только в раздел объявлений модуля):
Option Explicit
а можно вставлять эту команду во все модули при их создании автоматически, установив в окне Optionsфлажок Require Variable Declarations(меню Tools | Options, вкладка Editor).
Проиллюстрировать, зачем они это делают, можно на простом примере:
Dim n
n = n + 1
MsgBox п
С виду код не должен вызывать никаких проблем и просто выводить в окне сообщения единицу. На самом деле он выведет пустое окно сообщения. При-чина спрятана очень коварно: в третьей строке n — это вовсе не английская буква N, а русская П. На вид в окне редактора кода отличить их очень сложно. В то же время компилятор VBA, встретив такой код, просто создаст новую переменную с типом данных Variant, у которой будет пустое значение. На выявление такой ошибки может потребоваться определенное время. В то же время при установленном Option Explicit проблема определяется мгновенно.
Можно объявить несколько переменных в одной строке, например, так:
Dim nVar1 As Integer, s1 As String
Присвоение значений переменным выглядит так:
nVar1 = 30
Если нужно увеличить уже существующее значение переменной, то команда может выглядеть так:
nVar1 = nVar1 + 1
В обоих примерах знак равенства означает не "равно", а "присвоить".
При присвоении значений переменным нужно помнить о следующем:
· строковые значения всегда заключаются в двойные кавычки:
sVar1 = "Hello"
· начение дата/время заключается в символы "решетка" (#):
dVar1 = #05/06/2004#
Обратите внимание, что при присвоении значения даты/времени таким "явным" способом нам приходится использовать принятые в США стандарты: 05 в данном случае – это месяц, 06 — день. А отображение этого значения (например, в окне сообщения) будет зависеть от региональных настроек на компьютере пользователя;
· если нужно передать шестнадцатеричное значение, то перед ним ставятся символы (&H):
nVar1 = &HFF00
Для передачи восьмеричного значения (что случается намного реже) нужно использовать набор символов (&O).
В переменных до присвоения им значений пользователем содержится:
· в переменных всех числовых типов данных – 0;
· в строковых переменных переменной длины – "" (строка нулевой длины);
· в строковых переменных фиксированной длины – строка заданной длины с символами ASCII 0 (эти символы на экран не выводятся);
· в Variant – специальное пустое значение Empty. Произвести проверку на это значение (т. е. было ли присвоено значение переменной или нет) можно при помощи функции IsEmpty();
· в Object – ничего (нет ссылки ни на один из объектов).
Задание для самостоятельной работы 3.1.
Работа с переменными и операторами
Подготовка:
1. Создайте новую книгу Excel и сохраните ее как C:\LabVariablesOperators.xls. Введите в ячейки A1, A2 и A3 этой книги любые значения.
2. Откройте редактор Visual Basic в Excel и создайте в этой книге новый стандартный модуль.
3. При помощи меню Tools | Referencesдобавьте в ваш проект ссылку на библиотеку Microsoft Word 11.0 Object Library.
4. Введите в созданном вами стандартном модуле следующий код:
Public Sub FromExcelToWord()
MsgBox Range("A1").Text
MsgBox Range("A2").Text
MsgBox Range("A3").Text
Dim oWord As Word.Application
Dim oDoc As Word.Document
Set oWord = CreateObject("Word.Application")
oWord.Visible = True
Set oDoc = oWord.Documents.Add()
oDoc.Activate
oWord.Selection.TypeText "Вставляемый текст"
End Sub
Этот код должен выводить в окна сообщений значения ячеек A1, A2 и A3, а затем открыть Word и впечатать в начало нового документа строку "Вставляемый текст".
5. Убедитесь, что код работает без ошибок.
ЗАДАНИЕ:
Измените код этой процедуры таким образом, чтобы вместо строки "Вставляемый текст" выводились значения ячеек A1, A2 и A3 вместе.
Ответ к заданию 3.1
Итоговый код может выглядеть так:
Public Sub FromExcelToWordAnswer()
Dim sA1, sA2, sA3, sText As String
sA1 = Range("A1").Text
sA2 = Range("A2").Text
sA3 = Range("A3").Text
sText = sA1 + " " + sA2 + " " + sA3
Set oWord = CreateObject("Word.Application")
oWord.Visible = True
Set oDoc = oWord.Documents.Add()
oDoc.Activate
oWord.Selection.TypeText sText
End Sub