Как узнать тип переменной vba excel
Переменные — контейнеры для хранения изменяемых данных. Без них не обходится практически ни одна программа. Для простоты переменную можно сравнить с номерком в гардеробе — вы сдаете в "гардероб" какие-то данные, в ответ вам выдается номерок. Когда вам опять потребовались эти данные, вы "предъявляете номерок" и получаете их. Пример работы с переменными в VBA может выглядеть так:
Dim nMyAge As Integer
nMyAge = nMyAge + 10
Перед работой с переменной настоятельно рекомендуется ее объявить. Объявление переменной в нашем примере выглядит так:
Dim nMyAge As Integer
Как расшифровать эту строку:
Dim — это область видимости переменной. В VBA предусмотрено 4 ключевых слова для определения области видимости переменных:
- Dim — используется в большинстве случаев. Если переменная объявлена как Dim в области объявлений модуля, она будет доступна во всем модуле, если в процедуре — только на время работы этой процедуры;
- Private — при объявлении переменных в VBA значит то же, что и Dim;
- Public — такая переменная будет доступна всем процедурам во всех модулях данного проекта, если вы объявили ее в области объявлений модуля. Если вы объявили ее внутри процедуры, она будет вести себя как Dim/Private;
- Static — такие переменные можно использовать только внутри процедуры. Эти переменные видны только внутри процедуры, в которой они объявлены, зато они сохраняют свое значение между разными вызовами этой процедуры. Обычно используются для накопления каких-либо значений. Например:
Static nVar1 As Integer
nVar1 = nVar1 + 1
Если нет никаких особых требований, то есть смысл всегда выбирать область видимости Dim.
Второе слово в нашем объявление (nMyAge) — это идентификатор (проще говоря, имя) переменной. Правила выбора имен в VBA едины для многих элементов (переменные, константы, функции и процедуры и т.п.). Имя:
- должно начинаться с буквы;
- не должно содержать пробелов и символов пунктуации (исключение — символ подчеркивания);
- максимальная длина — 255 символов;
- должно быть уникальным в текущей области видимости (подробнее — далее);
- зарезервированные слова (те, которые подсвечиваются другим цветом в окне редактора кода) использовать нельзя.
При создании программ VBA настоятельно рекомендуется определиться с правилами, по которым будут присваиваться имена объектам — соглашение об именовании. Чаще всего используется так называемое венгерское соглашение (в честь одного из программистов Microsoft, Charles Simonyi, венгра по национальности):
- имя переменной должно начинаться с префикса, записанного строчными буквами. Префикс указывает, что именно будет храниться в этой переменной:
- str (или s) — String, символьное значение;
- fn (или f) — функция;
- c (или сделать все буквы заглавными) — константа;
- b — Boolean, логическое значение (true или false);
- d — дата;
- obj (или o) — ссылка на объект;
- n — числовое значение.
- в ранних версиях VB не было слова Const — все константы определялись как переменные, а для отличия их записывали заглавными буквами, между словами ставили подчеркивания:
Многие программисты используют такой подход для обозначения констант и сейчас (но использование ключевого слова Const теперь обязательно — об этом будет рассказано в следующем разделе).
Третья часть нашего объявления — As Integer — это указание на тип данных нашей переменной. Тип данных определяет, данные какого вида можно будет хранить в нашей переменной.
В VBA предусмотрены следующие типы данных:
- числовые (byte — целое число от 0 до 255, integer — целое число от -32768 до 32767, long — большое целое число, currency (большое десятичное число с 19 позициями, включая 4 позиции после запятой), decimal (еще большее десятичное число с 29 позициями), single и double — значение с плавающей запятой (double в два раза больше));
Внимание! Попытка объявить переменную с типом Decimal (например, Dim n As Decimal) приведет к синтаксической ошибке. Чтобы получить возможность работать с типом Decimal, переменную нужно изначально объявить как Variant или вообще объявить без типа (Dim n), поскольку тип данных Variant используется в VBA по умолчанию.
- строковые (string переменной длины (до примерно 2 млрд символов) и фиксированной длины (до примерно 65400 символов);
- дата и время (date — от 01.01.100 до 31.12.9999);
- логический (boolean — может хранить только значения True и False);
- объектный (object — хранит ссылку на любой объект в памяти);
- Variant — специальный тип данных, который может хранить любые другие типы данных.
Можно еще использовать пользовательские типы данных, но их вначале нужно определить при помощи выражения Type. Обычно пользовательские типы данных используются как дополнительное средство проверки вводимых пользователем значений (классический пример — почтовый индекс).
Некоторые моменты, связанные с выбором типов данных для переменных:
- общий принцип — выбирайте наименьший тип данных, который может вместить выбранные вами значения. Если есть какие-то сомнения — выбирайте больший тип данных во избежание возникновения ошибок;
- если есть возможность, лучше не использовать типы данных с плавающей запятой (single и double). Работа с такими типами данных производится медленнее, кроме того, могут быть проблемы при сравнениях за счет округлений;
- если есть возможность, лучше не пользоваться типом Variant. Этот тип все равно приводится VBA к одному из других типов, но памяти для него требуется больше. Кроме того, в ходе такого неявного образования могут возникнуть ошибки;
- при определении переменных можно использовать так называемые символы определения типа (% — integer, $ — String и т.п.). Например, в нашем примере нужно закомментировать строку Dim nVar 1 As Integer, а во второй строке написать:
Такой подход является устаревшим и к использованию не рекомендуется.
При объявлении переменных можно и не указывать ее тип. Например, наше объявление может выглядеть так:
В этом случае переменная будет автоматически объявлена с типом Variant.
В принципе, в VBA можно работать и без объявления переменных. Например, такой код
nVar1 = nVar1 + 1
будет вполне работоспособным. Если мы используем переменную в программе без ее объявления, то будет автоматически создана новая переменная типа Variant. Однако объявлять переменные нужно обязательно! И при этом желательно явно указывать нужный тип данных. Почему:
- сокращается количество ошибок: программа с самого начала откажется принимать в переменную значение неправильно типа (например, строковое вместо числового);
- при работе с объектами подсказка по свойствам и методам действует только тогда, когда мы изначально объявили объектную переменную с нужным типом. Например, в Excel два варианта кода будут работать одинаково:
Dim oWbk As Workbook
Set oWbk = Workbooks.Add()
Set oWbk = Workbooks.Add()
Но подсказка по свойствам и методам объекта oWbk будет работать только во втором случае.
Все опытные разработчики вообще запрещают использование переменных без явного их объявления. Для этого можно воспользоваться специальной командой компилятора (она помещается только в раздел объявлений модуля)
а можно вставлять эту команду во все модули при их создании автоматически — установив в окне редактора кода флажок Require Variable Declarations (меню Tools -> Options, вкладка Editor).
Проиллюстрировать, зачем они это делают, можно на простом примере:
Хорошее правило — объявлять переменные заблаговременно, а не когда они потребовались. Это позволяет сделать программу более читаемой и четко спланированной.
Можно объявить несколько переменных в одной строке, например, так:
Dim n1 As Integer, s1 As String
Присвоение значений переменным выглядит так:
Если нужно увеличить уже существующее значение переменной, то команда может выглядеть так:
nVar1 = nVar1 + 1
В обоих примерах знак равенства означает не "равно", а присвоить.
При присвоении значений переменным нужно помнить о следующем:
- строковые значения всегда заключаются в двойные кавычки:
- значение даты/времени заключаются в "решетки" — символы фунта:
Если нужно передать шестнадцатеричное значение, то перед ним ставятся символы &H:
Что содержится в переменных до присвоения им значений?
- В переменных всех числовых типов данных — 0.
- В строковых переменных переменной длины — "" (строка нулевой длины).
- В строковых переменных фиксированной длины — строка данной длины с символами ASCII 0 (эти символы на экран не выводятся).
- В Variant — пустое значение.
- В Object — ничто (нет ссылки ни на один из объектов).
Константы, объявление, ключевое слово Const, встроенные константы, vbCrLf
Константы — еще один контейнер для хранения данных, но, в отличие от переменных, они не изменяются в ходе выполнения VBA-программы. Для чего нужны константы:
- код становится лучше читаемым/убираются потенциальные ошибки;
- чтобы изменить какое-либо значение, которое много раз используется в программе (например, уровень налога) — это можно сделать один раз.
В VBA константы определяются при помощи ключевого слова Const:
Const COMP_NAME As String = “Microsoft”
Константы очень удобны при работе с группами именованных элементов (дни недели, месяцы, цвета, клавиши, типы окон и т.п.). Они позволяют использовать в коде программы легко читаемые обозначения вместо труднозапоминаемых числовых кодов. Например, строки
функционально одинаковы, но в чем смысл первой строки, догадаться гораздо легче.
В VBA встроено множество служебных констант: календарных, для работы с файлами, цветами, формами, типами дисков и т.п. Просмотреть их можно через справочную систему VBA: Microsoft Visual Basic Documentation -> Visual Basic Reference -> Constants. Про одну из констант (она находится в разделе Miscellaneous) следует сказать особо: константа vbCrLf позволяет произвести переход на новую строку. Например:
MsgBox ("Первая строка" + vbCrLf + "Вторая строка")
Множество наборов констант встроено в объектные модели, которые мы будем рассматривать в последних разделах.
В языке VBA есть универсальные типы данных, т.е. способные хранить как число, так и строку, дату и любой другой тип информации. Например, ячейка в таблице может содержать что угодно и изначально, программа не знает какой в ней тип данных хранится. Кроме того, в самой программе может использоваться тип данных Variant, который так же может содержать любое значение любого типа.
Чтобы определить какой тип данных в ячейке или в переменной типа Variant, можно воспользоваться несколькими способами.
Способ 1. Использовать функцию TypeName для определения типа данных
Эта функция возвращает строку с названием типа данных на английском. В качестве аргумента принимает переменную, значение ячейки.
Обратите внимание: Функция определяет только стандартные типы данных и не может определить пользовательский тип (определенный с помощью Type).Возможные возвращаемые функцией значения:
Byte Число типа Byte Integer Целое число Long Длинное целое число Single Число одиночной точности с плавающей запятой Double Число двойной точности с плавающей запятой Currency Валюта Decimal Число с плавающей запятой Date Дата String Строка Boolean Логическое Error Ошибка Empty Не проинициализировано (т.е. переменная не была объявлена) Null Неверные данные (в переменной нет корректных данных) Object Объект (класс) Unknown Тип данных не известен Nothing Объект, никуда не ссылающийся Приведу несколько примеров по использованию TypeName.
Пример 1. Определение типа переменной.
Обратите внимание: если вы используете результат TypeName в условии, т.е. проверяете, соответствует ли тип данных определенному, например, Integer, то регистр символов возвращаемого типа имеет значение. Т.е. нужно писать Integer с заглавной буквы, либо использовать приведение всех символов к одному регистру.
Пример 2. Использование TypeName в условии.
Пример 3. Определение типа данных в ячейке.
Если функции была передана переменная массив, она вернет тип данных в массиве с добавлением скобок.
Пример 4. Определение типа массива.
Способ 2. Проверка на возможность преобразования строки к нужному типу.
Бывает ситуация, когда значение, например, число или дата, содержится в строке. В этом случае TypeName вернет String, а не Integer или Date. Чтобы узнать, что содержится в строке, можно воспользоваться одной из функций IsNumeric, IsDate, IsObject, IsArray, IsNull, IsError.
IsNumeric Проверяет может ли выражение быть преобразовано в число IsDate Проверяет может ли выражение быть преобразовано в дату IsObject Проверяет, является ли переменная объектом IsArray Проверяет, является ли переменная массивом IsNull Проверка на пустое значение IsError Проверка выражения на ошибку Пример 4. Определение может ли переменная быть преобразована в число.
К сожалению, как видим из примера, нет возможности проверить, содержится ли в строке число с плавающей точкой.
Пример 5. Определение содержит ли переменная дату (может быть преобразована в дату).
Проверка, содержится ли число или дата в ячейке листа делается аналогично, как и с переменными.
Помимо этих способов можно конечно еще придумать и другие, например, проверку строки с данными регулярным выражением или пройти по каждому символу в цикле и проверить цифра это или нет и тому подобное. Но на мой взгляд, описанных мной способов вполне достаточно для решения повседневных задач.
Универсальные объектные переменные (т. е. переменные, объявляемые как Object ) могут содержать объекты из любого класса. Generic object variables (that is, variables you declare as Object ) can hold objects from any class. При использовании переменных типа Object может потребоваться выполнить различные действия в зависимости от класса объекта. Например, некоторые объекты могут не поддерживать определенное свойство или метод. When using variables of type Object , you may need to take different actions based on the class of the object; for example, some objects might not support a particular property or method. Visual Basic предоставляет два способа определения типа объекта, хранящегося в объектной переменной: функция TypeName и оператор TypeOf. Is . Visual Basic provides two means of determining which type of object is stored in an object variable: the TypeName function and the TypeOf. Is operator.
TypeName и TypeOf. Рекомендуется TypeName and TypeOf…Is
Функция TypeName возвращает строку и является лучшим выбором, если необходимо сохранить или отобразить имя класса объекта, как показано в следующем фрагменте кода: The TypeName function returns a string and is the best choice when you need to store or display the class name of an object, as shown in the following code fragment:
В этом случае следует соблюдать осторожность. A word of caution is due here. Оператор TypeOf. Is возвращает True , если объект относится к конкретному типу или является производным от определенного типа. The TypeOf. Is operator returns True if an object is of a specific type, or is derived from a specific type. Почти все, что выполняется с Visual Basic, включает объекты, которые включают в себя некоторые элементы, которые обычно не считаются объектами, например строками и целыми числами. Almost everything you do with Visual Basic involves objects, which include some elements not normally thought of as objects, such as strings and integers. Эти объекты являются производными от Objectи наследуют от них методы. These objects are derived from and inherit methods from Object. При передаче Integer и вычислении с Object оператор TypeOf. Is возвращает True . When passed an Integer and evaluated with Object , the TypeOf. Is operator returns True . В следующем примере сообщается, что параметр InParam является как Object , так и Integer : The following example reports that the parameter InParam is both an Object and an Integer :
В следующем примере используются как TypeOf. Is , так и TypeName для определения типа объекта, переданного в него в аргументе Ctrl . The following example uses both TypeOf. Is and TypeName to determine the type of object passed to it in the Ctrl argument. TestObject процедура вызывает ShowType с тремя различными видами элементов управления. The TestObject procedure calls ShowType with three different kinds of controls.
Запуск примера To run the example
Создайте новый проект приложения Windows и добавьте в форму элемент управления Button, CheckBox и элемент управления RadioButton. Create a new Windows Application project and add a Button control, a CheckBox control, and a RadioButton control to the form.
С помощью кнопки в форме вызовите процедуру TestObject . From the button on your form, call the TestObject procedure.
Добавьте в форму следующий код: Add the following code to your form:
Как и любой язык программирования, VBA содержит широкий круг типов переменных для написания программ.
Переменные разделяют на глобальные и локальные, их описывают выражением Dim имя as тип.
В языке выделяют следующие типы: Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String, Object, Variant.
Если переменная указана вне функции или модуля и объявлена в разделе Declarations, то она является глобальной или Public и доступ к ней возможен из других модулей.
Переменная типа Private доступна только в пределах одного модуля, но из любой функции данного модуля.
Переменная находящаяся внутри функции или модуля доступна локально и обращение к ней возможно только из функции или модуля.
Так же существует тип локальной переменной Static, она позволяет сохранять прежнее значение, объявленное при инициализации.
Информация о типе переменной
Есть такой термин RTTI - run-time type information. Информация о типе переменной, доступная во время выполнения программы. Иногда эта информация оказывается просто необходимой. В VBA есть тип данных Variant, который может принимать значения любого типа за исключением пользовательского. Вот например так:
Sub Test()
Dim v_string As String
Dim v_int As Integer
Dim v_variant As Variant
v_string = "Hello Variant"
v_int = 123
v_variant = v_string
v_variant = v_int
End SubVariant можно использовать в качестве аргумента процедуры. В этом случае может потребоваться информация о том, что же находится в переменной в данный момент. Для этого есть функция TypeName(), которая вернет строку с именем типа переменной. Вот пример её использования:
Sub TestVariant()
Dim v_string As String
Dim v_int As Integer
Dim v_variant As Variant
v_string = "Hello Variant"
v_int = 123
v_variant = v_string
MsgBox (TypeName(v_variant))
v_variant = v_int
MsgBox (TypeName(v_variant))
End SubКроме этого есть еще ряд функций для проверки типа переменных. IsArray позволяет проверить, является ли переменная массивом.
Sub TestArray()
Dim v_arr(10) As String
If IsArray(v_arr) Then MsgBox ("Массив")
End SubIsEmpty проверяет, была ли переменная инициализирована. Попробуйте запустить код, приведенный ниже, а потом раскомментируйте строку.
Sub TestEmpty()
' Dim v_arr As String
If IsEmpty(v_arr) Then MsgBox ("NO")
End SubSub TestDate()
Dim v_arr As String
v_arr = "01.01.2001"
If IsDate(v_arr) Then MsgBox ("YES")
v_arr = "41.01.2001"
If IsDate(v_arr) Then MsgBox ("YES")
End SubФункция IsNumeric проверяет, можно ли перевести строку в число:
Sub TestNumeric()
Dim v_arr As String
v_arr = "not numeric"
If IsNumeric(v_arr) Then MsgBox ("YES")
v_arr = "1998"
If IsNumeric(v_arr) Then MsgBox ("YES")
End SubВстроенные функции преобразования и проверки типов данных VBA, функции CBool(), CByte(), CCur(), CDate(), CDbl(), CDec(), CInt(), CLng(), CSng(), CStr(), CVar(), CVDate(), CVErr(), Str(), Val(), IsNumeric(), IsDate(), IsEmpty(), IsError(), IsMissing(), IsNull(), IsObject(), IsArray(), Hex(), Oct()
В программах на VBA очень часто приходится преобразовывать значения из одного типа данных в другой. Несколько типичных ситуаций, когда этим приходится заниматься:
- преобразование из строкового значение в числовое при приеме значения от пользователя через InputBox();
- преобразование значения даты/времени в строковое, когда нам нужно отобразить дату или время единообразно вне зависимости от региональных настроек на компьютерах пользователей;
- преобразование значения из строкового в дату/время для применения специальных функций даты/времени.
Чаще всего для конвертации типов данных используются функции, имя которых выглядит как C (от слова Convert) + имя типа данных. Вот перечень этих функций: CBool(), CByte(), CCur(), CDate(), CDbl(), CDec(), CInt(), CLng(), CSng(), CStr(), CVar(), CVDate(), CVErr(). Просмотреть, что в итоге получилось, можно при помощи функции TypeName(), например:
nVar1 = CInt(InputBox("Введите значение"))
Кроме того, еще несколько полезных для конвертации функций:
- Str() — позволяет перевести числовое значение в строковое. Делает почти то же самое, что и CStr(), но при этом вставляет пробел впереди для положительных чисел.
- Val() — "вытаскивает" из смеси цифр и букв только числовое значение. При этом эта функция читает данные слева направо и останавливается на первом нечисловом значении (допускается единственное нечисловое значение — точка, которая будет отделять целую часть от дробной). Очень удобно, когда у нас вперемежку с числовыми данными прописываются единицы измерения или валюта.
Чтобы не возникло ошибок при конвертации, можно вначале проверять значения на возможность конвертации при помощи функций IsNumeric() и IsDate(). Для проверки на соответствие специальным значениям можно использовать функции IsArray(), IsEmpty(), IsError(), IsMissing(), IsNull() и IsObject(). Все эти функции возвращают True или False в зависимости от результатов проверки переданного им значения.
Для того, чтобы преобразовать десятичные данные в строковое представление шестнадцатеричных и восьмеричных значений, используются функции Hex() и Oct(). Для обратного преобразования специальных функций не предусмотрено, но вы можете указать компилятору VBA, что эти числа записаны в шестнадцатеричном или восьмеричном формате, записав их, например, как &O12 и &HA.
Читайте также: