В языке 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. Определение типа переменной.
Dim v As Integer MsgBox TypeName(v) ' Выведет: Integer
Обратите внимание: если вы используете результат TypeName в условии, т.е. проверяете, соответствует ли тип данных определенному, например, Integer, то регистр символов возвращаемого типа имеет значение. Т.е. нужно писать Integer с заглавной буквы, либо использовать приведение всех символов к одному регистру.
Пример 2. Использование TypeName в условии.
Dim v As Integer If TypeName(v) = "Integer" Then MsgBox "Yes" Else MsgBox "No" ' Yes If TypeName(v) = "integer" Then MsgBox "Yes" Else MsgBox "No" ' No If LCase(TypeName(v)) = "integer" Then MsgBox "Yes" Else MsgBox "No" ' Yes
Пример 3. Определение типа данных в ячейке.
MsgBox TypeName(Cells(1, 1).Value) ' Выведет тип данных в ячейке A1
Если функции была передана переменная массив, она вернет тип данных в массиве с добавлением скобок.
Пример 4. Определение типа массива.
Dim Arr1(10) As Integer Dim Arr2(10) MsgBox TypeName(Arr1) ' Выведет: Integer() MsgBox TypeName(Arr2) ' Выведет: Variant()
Способ 2. Проверка на возможность преобразования строки к нужному типу.
Бывает ситуация, когда значение, например, число или дата, содержится в строке. В этом случае TypeName вернет String, а не Integer или Date. Чтобы узнать, что содержится в строке, можно воспользоваться одной из функций IsNumeric, IsDate, IsObject, IsArray, IsNull, IsError.
IsNumeric | Проверяет может ли выражение быть преобразовано в число |
IsDate | Проверяет может ли выражение быть преобразовано в дату |
IsObject | Проверяет, является ли переменная объектом |
IsArray | Проверяет, является ли переменная массивом |
IsNull | Проверка на пустое значение |
IsError | Проверка выражения на ошибку |
Пример 4. Определение может ли переменная быть преобразована в число.
Dim v As String If IsNumeric(v) Then MsgBox "yes" Else MsgBox "no" ' Выведет: no (т.к. в строке нет числа) v = "120" If IsNumeric(v) Then MsgBox "yes" Else MsgBox "no" ' Выведет: yes v = "120.45" If IsNumeric(v) Then MsgBox "yes" Else MsgBox "no" ' Выведет: no v = "test 120" If IsNumeric(v) Then MsgBox "yes" Else MsgBox "no" ' Выведет: no v = "120 test" If IsNumeric(v) Then MsgBox "yes" Else MsgBox "no" ' Выведет: no
К сожалению, как видим из примера, нет возможности проверить, содержится ли в строке число с плавающей точкой.
Пример 5. Определение содержит ли переменная дату (может быть преобразована в дату).
Dim firstDate, secondDate As Date Dim timeOnly, dateAndTime, noDate As String firstDate = CDate("12.05.2017") secondDate = #12/5/2017# timeOnly = "15:45" dateAndTime = "12.05.2017 15:45" noDate = "Test" If IsDate(firstDate) Then MsgBox "yes" Else MsgBox "no" ' Выведет: yes If IsDate(secondDate) Then MsgBox "yes" Else MsgBox "no" ' Выведет: yes If IsDate(timeOnly) Then MsgBox "yes" Else MsgBox "no" ' Выведет: yes If IsDate(dateAndTime) Then MsgBox "yes" Else MsgBox "no" ' Выведет: yes If IsDate(noDate) Then MsgBox "yes" Else MsgBox "no" ' Выведет: no
Проверка, содержится ли число или дата в ячейке листа делается аналогично, как и с переменными.
Помимо этих способов можно конечно еще придумать и другие, например, проверку строки с данными регулярным выражением или пройти по каждому символу в цикле и проверить цифра это или нет и тому подобное. Но на мой взгляд, описанных мной способов вполне достаточно для решения повседневных задач.
Проверка переменных и выражений с помощью встроенных функций VBA Excel: IsArray, IsDate, IsEmpty, IsError, IsMissing, IsNull, IsNumeric, IsObject.
Проверка переменных и выражений
Встроенные функции VBA Excel — IsArray, IsDate, IsEmpty, IsError, IsMissing, IsNull, IsNumeric, IsObject — проверяют значения переменных и выражений на соответствие определенному типу данных или специальному значению.
Синтаксис функций для проверки переменных и выражений:
Expression — выражение, переменная или необязательный аргумент для IsMissing.
Все функции VBA Excel для проверки переменных и выражений являются логическими и возвращают значение типа Boolean — True или False.
Функция IsArray
Описание функции
Функция IsArray возвращает значение типа Boolean, указывающее, является ли переменная массивом:
- True — переменная является массивом;
- False — переменная не является массивом.
Пример с IsArray
Sub Primer1() Dim arr1(), arr2(1 To 10), arr3 Debug.Print IsArray(arr1) ‘Результат: True Debug.Print IsArray(arr2) ‘Результат: True Debug.Print IsArray(arr3) ‘Результат: False arr3 = Array(1, 2, 3, 4, 5) Debug.Print IsArray(arr3) ‘Результат: True End Sub |
Как показывает пример, функция IsArray возвращает True и в том случае, если переменная только объявлена как массив, но еще не содержит значений.
Функция IsDate
Описание функции
Функция IsDate возвращает логическое значение, указывающее, содержит ли переменная значение, которое можно интерпретировать как дату:
- True — переменная содержит дату, выражение возвращает дату, переменная объявлена с типом As Date;
- False — в иных случаях.
Пример с IsDate
Sub Primer2() Dim d1 As String, d2 As Date Debug.Print IsDate(d1) ‘Результат: False Debug.Print IsDate(d2) ‘Результат: True d1 = «14.01.2023» Debug.Print IsDate(d1) ‘Результат: True Debug.Print IsDate(Now) ‘Результат: True End Sub |
Функция IsEmpty
Описание функции
Функция IsEmpty возвращает значение типа Boolean, указывающее, содержит ли переменная общего типа (As Variant) значение Empty:
- True — переменная содержит значение Empty;
- False — переменной присвоено значение, отличное от Empty.
Пример с IsEmpty
Sub Primer3() Dim s As String, v As Variant Debug.Print IsEmpty(s) ‘Результат: False Debug.Print IsEmpty(v) ‘Результат: True v = 125 Debug.Print IsEmpty(v) ‘Результат: False Range(«A1»).Clear Debug.Print IsEmpty(Range(«A1»)) ‘Результат: True Range(«A1») = 123 Debug.Print IsEmpty(Range(«A1»)) ‘Результат: False End Sub |
Как видно из примера, функцию IsEmpty можно использовать для проверки ячеек на содержание значения Empty (пустая ячейка общего формата).
Функция IsError
Описание функции
Функция IsError возвращает логическое значение, указывающее, является ли аргумент функции значением ошибки, определенной пользователем:
- True — аргумент функции является значением ошибки, определенной пользователем;
- False — в иных случаях.
Пользователь может определить одну или несколько ошибок для своей процедуры или функции с рекомендациями действий по ее (их) исправлению. Возвращается номер ошибки с помощью функции CVErr.
Пример с IsError
Допустим, пользователь определил, что ошибка №25 означает несоответствие аргумента функции Vkuba числовому формату:
Function Vkuba(x) If IsNumeric(x) Then Vkuba = x ^ 3 Else Vkuba = CVErr(25) End If End Function Sub Primer4() Debug.Print Vkuba(5) ‘Результат: 125 Debug.Print IsError(Vkuba(5)) ‘Результат: False Debug.Print Vkuba(«пять») ‘Результат: Error 25 Debug.Print IsError(Vkuba(«пять»)) ‘Результат: True End Sub |
Функция IsMissing
Описание функции
Функция IsMissing возвращает значение типа Boolean, указывающее, был ли необязательный аргумент типа данных Variant передан процедуре:
- True — если в процедуру не было передано значение для необязательного аргумента;
- False — значение для необязательного аргумента было передано в процедуру.
Пример с IsMissing
Function Scepka(x, Optional y) If Not IsMissing(y) Then Scepka = x & y Else Scepka = x & » (а необязательный аргумент не подставлен)» End If End Function Sub Primer5() Debug.Print Scepka(«Тропинка», » в лесу») ‘Результат: Тропинка в лесу Debug.Print Scepka(«Тропинка») ‘Результат: Тропинка (а необязательный аргумент не подставлен) End Sub |
Функция IsNull
Описание функции
Функция IsNull возвращает логическое значение, указывающее, является ли Null значением переменной или выражения:
- True — значением переменной или выражения является Null;
- False — в иных случаях.
Пример с IsNull
Функция IsNull особенно необходима из-за того, что любое условие с выражением, в которое входит ключевое слово Null, возвращает значение False:
Sub Primer6() Dim Var Var = Null If Var = Null Then Debug.Print Var ‘Результат: «» If Var <> Null Then Debug.Print Var ‘Результат: «» If IsNull(Var) Then Debug.Print Var ‘Результат: Null End Sub |
Функция IsNumeric
Описание функции
Функция IsNumeric возвращает значение типа Boolean, указывающее, можно ли значение выражения или переменной рассматривать как число:
- True — если аргумент функции может рассматриваться как число;
- False — в иных случаях.
Пример с IsNumeric
Sub Primer7() Debug.Print IsNumeric(«3,14») ‘Результат: True Debug.Print IsNumeric(«четыре») ‘Результат: False End Sub |
Функция IsObject
Описание функции
Функция IsObject возвращает логическое значение, указывающее, является ли переменная объектной:
- True — переменная содержит ссылку на объект или значение Nothing;
- False — в иных случаях.
Функция IsObject актуальна для переменных типа Variant, которые могут содержать как ссылки на объекты, так и значения других типов данных.
Пример с IsObject
Sub Primer8() Dim myObj As Object, myVar As Variant Debug.Print IsObject(myObj) ‘Результат: True Debug.Print IsObject(myVar) ‘Результат: False Set myVar = ActiveSheet Debug.Print IsObject(myVar) ‘Результат: True End Sub |
Здравствуйте! |
|
LightZ Пользователь Сообщений: 1748 |
Может я что-то не правильно понял? Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете? |
Понял ошибку. Я пробовал Is Numeric. |
|
LightZ Пользователь Сообщений: 1748 |
Не за что Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете? |
Юрий М Модератор Сообщений: 60575 Контакты см. в профиле |
{quote}{login=LightZ}{date=09.07.2012 07:29}{thema=}{post}Debug.Print IIf(Application.IsText(Cells(1, 1).Value), «Text», «Numeric»){/post}{/quote}С этим нужно осторожнее: при пустом значении и дате, получим неверные ответы |
Ну мне для решения конкретной задачи больше всего походит первый вариант в виде: |
|
ZVI Пользователь Сообщений: 4328 |
Добрый вечер, Михаил! |
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
Здравствуйте все. В дополнение, и это тоже: Я сам — дурнее всякого примера! … |
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
Забыл еще: Я сам — дурнее всякого примера! … |
LightZ Пользователь Сообщений: 1748 |
Так я думаю вряд ли кто-то будет использовать Const x As Long = «111»: Const z As String = «abc» False True Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете? |
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
Богдан, вот это — неправильно: Я сам — дурнее всякого примера! … |
LightZ Пользователь Сообщений: 1748 |
Серёж, а в чём разница то? Const x As Long = «111» Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете? |
Юрий М Модератор Сообщений: 60575 Контакты см. в профиле |
«111» — строка |
{quote}{login=ZVI}{date=09.07.2012 09:56}{thema=}{post}Добрый вечер, Михаил! |
|
LightZ Пользователь Сообщений: 1748 |
{quote}{login=Юрий М}{date=09.07.2012 11:37}{thema=}{post}»111″ — строка Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете? |
Юрий М Модератор Сообщений: 60575 Контакты см. в профиле |
Богдан, а тогда зачем объявлять заведомо неверно? Об этом Серж и говорит… Если «111», ту нужно и писать: As String. Если хотим числовую переменную — кавычки не нужны. Вот о чём разговор. |
> А почему к «d» и «e» такое «избранное» отношение? Михаил, это экспоненциальная запись числа. 1d3=1000, 1e2=100. ?isnumeric(«ff»),isnumeric(«&hff»),isnumeric(«&o75»),isnumeric(«&o79») |
|
Я попробовал так: хоть 234е765б + 1 хоть 123d765 + 1 =11 (+25 = 35) |
|
k61 Пользователь Сообщений: 2441 |
IsNumeric(«ЧислоИлиЦифра» & Chr(160) & «ЧислоИлиЦифра»)=True |
Если данные будут считываться только из ячеек рабочего_листа: Function ValueIsNumber(X) As Boolean Если даты или логические не считать числами — удалить vbDate или vbBoolean |
|
LightZ Пользователь Сообщений: 1748 |
{quote}{login=Юрий М}{date=10.07.2012 10:40}{thema=}{post}Богдан, а тогда зачем объявлять заведомо неверно? Об этом Серж и говорит… Если «111», ту нужно и писать: As String. Если хотим числовую переменную — кавычки не нужны. Вот о чём разговор.{/post}{/quote}Юрий, я понял. Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете? |
Юрий М Модератор Сообщений: 60575 Контакты см. в профиле |
Если других данных не будет, то всё нормально. Весь сыр-бор разгорелся из-за того, что с проверкой типа есть подводные камни, и их желательно учитывать. |
LightZ Пользователь Сообщений: 1748 |
Загвоздочка может произойти только с пробелом или пустой ячейкой, т.к. vba считает, что пустая ячейка это число, а вот с датой проблем нет (false) Dim x As Range Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете? |
ran Пользователь Сообщений: 7091 |
Что-то я не улавливаю. |
Юрий М Модератор Сообщений: 60575 Контакты см. в профиле |
{quote}{login=LightZ}{date=10.07.2012 10:01}{thema=}{post}Загвоздочка может произойти только с пробелом или пустой ячейкой, т.к. vba считает, что пустая ячейка это число, а вот с датой проблем нет {/post}{/quote}Ну как же нет? |
ZVI Пользователь Сообщений: 4328 |
E — это экспоненциальная форма записи числа В окне Immediate: Если вписать в VBA-модуле, например, такую строку: |
Павел Гость |
#27 10.07.2012 22:23:57 2 Михаил С
Точка и знаки «d» и «e» могут быть частью записи числа, не поэтому ли? |
||
LightZ Пользователь Сообщений: 1748 |
RAN, воспроизведите макрос: .Value = Empty Т.е. с помощью Application.Trim(x.Value) убиваю сразу двух зайцев: пустоту и пробел Юрий, я описал про IsNumeric, а с текстом придется учитывать и дату With Cells(1, 1) Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете? |
Юрий М Модератор Сообщений: 60575 Контакты см. в профиле |
{quote}{login=LightZ}{date=10.07.2012 10:29}{thema=}{post}Юрий, я описал про IsNumeric, а с текстом придется учитывать и дату{/post}{/quote}Я реагировал на это: |
Михаил С. Пользователь Сообщений: 10514 |
#30 10.07.2012 23:15:44 Такой, казалось бы, простой вопрос, а столько подводных камней! |
I want to check Data in all excel sheet column to ensure that data is as per its specified data type.
Like in a numeric column there should not be char value.
Thanks in Advance.
Luuklag
3,90711 gold badges39 silver badges57 bronze badges
asked Apr 4, 2014 at 14:26
Yes, use the same functions as you would in Visual Basic. isdate, isnumeric, etc. Make sure you test your data some. Some of the data type checker functions are not fool-proof, especially isnumeric. Here is one related thread to that Wrong result from IsNumeric() in VB.NET
There are many more out there if you search.
answered Apr 4, 2014 at 15:12
Alan WaageAlan Waage
6034 silver badges12 bronze badges
As mentioned in the other post, Excel has some built in functions which allow you to test data in a field. This works great for the front end. It should also be noted that the datatypes available in the front end Excel are not the same datatypes available in the backend VBA (they are similar but different).
Datatypes in VBA in the backend can be trickier than other languages for two reasons: 1) The Variant datatype (which is a nondescript datatype) and 2) VBA doesn’t by default require you to specify the datatype of a variable (it will try and guess what you meant unless you use the Option Explicit command).
Check out the following articles on available VBA datatypes and converting between them:
- Data Type Summary
- Type Conversions in VB
- Variant Data Type
answered Apr 4, 2014 at 15:21
1 / 1 / 0 Регистрация: 02.04.2012 Сообщений: 24 |
|
1 |
|
Как определить тип данных в ячейке03.04.2012, 18:31. Показов 17896. Ответов 3
Есть объект Range (фактически столбец листа Excel), как определить тип данных в каждой из ячеек?
0 |
mc-black 2784 / 716 / 106 Регистрация: 04.02.2011 Сообщений: 1,443 |
||||
03.04.2012, 18:51 |
2 |
|||
2 |
1 / 1 / 0 Регистрация: 02.04.2012 Сообщений: 24 |
|
03.04.2012, 18:55 [ТС] |
3 |
Спасибо. TypeName как раз то что нужно.
0 |
chirs 0 / 0 / 0 Регистрация: 06.03.2017 Сообщений: 5 |
||||
12.09.2017, 06:38 |
4 |
|||
Вот здесь еще неплохая статья подробно с примерами об определении типа данных.
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
12.09.2017, 06:38 |
4 |