Проверка переменных и выражений с помощью встроенных функций 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 |
Hi all,
I´m trying to build in an error check for a simple macro that will clear all filters. For this I created a Userform, added some bottons, assigned the relevant Makros to them and Bob´s your Unlcle.
Works great bu then I noticed if I don´t have any filters set and click the «Clear Filter» button, it throws me an error.
So I´m trying to catch and test for the error and in the event that it happens, it should just jump to the end of the makro.
Makro used to be this
Code:
Sub RemFilter()
ActiveSheet.ShowAllData
End Sub
Now I´m trying to cathc the error and thought this should work, but it doesnt
Code:
Sub RemFilter()
If Not IsError(ActiveSheet.ShowAllData) Then
ActiveSheet.ShowAllData
Else
End If
End Sub
Any suggestions ? The error code is 1004
N1K0 Пользователь Сообщений: 70 |
Имеется ячейка с формулой, которая может выдавать значения ошибок (#Н/Д и т.п) или if Ячейка является числом Then выполнить код помогите! |
ytk5kyky Пользователь Сообщений: 2410 |
If IsNumeric(ячейка.Value) Then Если известен вид ошибки, то можно проверить значение, например, для #Н/Д: Или так: |
ZVI Пользователь Сообщений: 4328 |
Или так: If Not IsError(ActiveCell) Then MsgBox «Нет ошибки» |
N1K0 Пользователь Сообщений: 70 |
Перепробовал все способы, работает. |
Здравствуйте. Решил не создавать новую тему а эту освежить, таким вопросом. Как в коде VBA проверить, что в ячейке находится дата ну например 01.01.2011. Знаю что ексель хранит дату и время в числовом формате, но может есть какой то способ? Спасибо! |
|
{quote}{login=}{date=06.04.2011 06:40}{thema=Как проверить что в ячейке формат даты}{post}Как в коде VBA проверить, что в ячейке находится дата ну например 01.01.2011. {/post}{/quote} If IsDate(ActiveCell) Then MsgBox «В активной ячейке находится дата!» Вот только IsDate почему-то распознаёт дату даже в ячейке, где содержится текст 1,2,2011 |
|
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
Игорь, я так понял из вопроса, надо на конкретную дату проверить, что-то вроде: Я сам — дурнее всякого примера! … |
Guest Гость |
#8 06.04.2011 07:29:07 Да Игорь все правильно вы поняли, надо именно на формат проверить, а не на конкретную дату, я думаю если к вашему методу добавить такую проверку: If (IsDate(ActiveCell) And ActiveCell.Value Like «*.*.*» Then MsgBox «В активной ячейке находится дата!» |
Just to modify scott’s answer to make it a function:
Function FindFirstInRange(FindString As String, RngIn As Range, Optional UseCase As Boolean = True, Optional UseWhole As Boolean = True) As Variant
Dim LookAtWhat As Integer
If UseWhole Then LookAtWhat = xlWhole Else LookAtWhat = xlPart
With RngIn
Set FindFirstInRange = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=LookAtWhat, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=UseCase)
If FindFirstInRange Is Nothing Then FindFirstInRange = False
End With
End Function
This returns FALSE if the value isn’t found, and if it’s found, it returns the range.
You can optionally tell it to be case-sensitive, and/or to allow partial-word matches.
I took out the TRIM because you can add that beforehand if you want to.
An example:
MsgBox FindFirstInRange(StringToFind, Range("2:2"), TRUE, FALSE).Address
That does a case-sensitive, partial-word search on the 2nd row and displays a box with the address. The following is the same search, but a whole-word search that is not case-sensitive:
MsgBox FindFirstInRange(StringToFind, Range("2:2")).Address
You can easily tweak this function to your liking or change it from a Variant to to a boolean, or whatever, to speed it up a little.
Do note that VBA’s Find is sometimes slower than other methods like brute-force looping or Match, so don’t assume that it’s the fastest just because it’s native to VBA. It’s more complicated and flexible, which also can make it not always as efficient. And it has some funny quirks to look out for, like the «Object variable or with block variable not set» error.
Excel VBA ISERROR Function
VBA IsError, the function name itself, sums up the functionality. This function will identify whether or not the value we have supplied is an error value. If the supplied or range reference value is an error value, we will get the result as “TRUE.” If the value is not an error, we will get the result as “FALSE.”
Table of contents
- Excel VBA ISERROR Function
- Examples
- Example #1
- Example #2
- Things to Remember
- Recommended Articles
- Examples
Syntax
The expression is nothing but the value we are testing or the cell reference value or formula expression. And as you can see, the result will be “Boolean.”
Examples
You can download this VBA ISERROR Excel Template here – VBA ISERROR Excel Template
Example #1
We will see a simple example to find whether the value is an error. For example, we have the below value in cell A1.
We will test whether this value is an error value or not.
- Start the macro code.
Code:
Sub IsError_Example1() End Sub
- Declare a variable to store the cell A1 value.
Code:
Sub IsError_Example1() Dim ExpValue As Variant End Sub
- Now, assign the value of cell A1 to this variable in VBA.
Code:
Sub IsError_Example1() Dim ExpValue As Variant ExpValue = Range("A1").Value End Sub
- Now, test whether this variable value is an error or not.
Code:
Sub IsError_Example1() Dim ExpValue As Variant ExpValue = Range("A1").Value IsError (ExpValue) End Sub
- Enclose this result in a message box in VBA.
Code:
Sub IsError_Example1() Dim ExpValue As Variant ExpValue = Range("A1").Value MsgBox IsError(ExpValue) End Sub
Let us run the code and see the result of the ISERROR function.
The result is TRUE because the value in cell A1 is #DIV/0! which is the division error.
Now, we will change the value of cell A1 to “Hello.”
Now run the code and see the result.
So, the result is FALSE now because the value in cell A1 is not the error value.
So, first, we need to understand the error types and why they occur in the Excel worksheet. Below are the detailed error values and explanations.
- #DIV/0: This error occurs when we try to divide the number by zero. This error is called “Division by Zero.”
- #N/A: When you try to fetch the data from different tables, and if it finds no value, then we will get this error, which is called “Not Available.”
- #NAME?: If Excel cannot recognize the formula or name, we will get this error.
- #NULL!: When you specify space between the cell referencesCell reference in excel is referring the other cells to a cell to use its values or properties. For instance, if we have data in cell A2 and want to use that in cell A1, use =A2 in cell A1, and this will copy the A2 value in A1.read more instead of a comma.
- #NUM!: The numerical value supplied to the data isn’t a valid one.
- #VALUE!: When you reference the cell values for mathematical calculations, and if the number format is not correct, we will get this error.
- #REF!: If the cell is a formula, it has cell references. If that referenced cell deletes, then we will get this reference error.
Example #2
Now, look at the below data set.
We need to identify the error values from this list and store the result, either TRUE or FALSE, in the next column.
Since we need to test more than one cell, we need to include this in loops. The below code will identify the error values.
Code:
Sub IsError_Example2() Dim k As Integer For k = 2 To 12 Cells(k, 4).Value = IsError(Cells(k, 3).Value) Next k End Sub
When you run this code, we will get the below result in column 4.
Wherever TRUE is, that value is an error value.
Things to Remember
- The ISERROR function returns the Boolean type result, i.e., TRUE or FALSE.
- It is available as a worksheet function as well as a VBA functionVBA functions serve the primary purpose to carry out specific calculations and to return a value. Therefore, in VBA, we use syntax to specify the parameters and data type while defining the function. Such functions are called user-defined functions.read more.
- It is useful as part of large VBA projects.
- It recognizes only pre-determined error values (Read error type).
Recommended Articles
This article has been a guide to VBA ISERROR. Here, we discuss how the Excel VBA ISERROR function identifies whether the value we have supplied is an error value or not with examples. You can learn more about VBA functions from the following articles: –
- VBA IsDate Function
- IFERROR in VBA
- VBA On Error GoTo
- VBA 1004 Error Example
- VBA Double
Using Excel worksheet functions taps into the native calculation engine: using Excel’s very own MATCH
function instead of writing a lookup loop or otherwise reinventing that wheel every time makes a lot of sense if your project is hosted in Excel in the first place, or if you’re otherwise referencing the Excel type library.
You may have seen it look like this:
Dim result As Variant result = Application.WorksheetFunction.Match(...)
Or like this:
Dim result As Variant result = Application.Match(...)
You’ve tested both, confirmed they both work, and might be using them interchangeably in code, and all is well… until it isn’t anymore and you’re facing a cryptic run-time error:
What could this nonsense possibly mean? First, we need to understand that we’re looking at a templated error message where “property” has to have been mistakenly made part of the templated string – because we’re really looking at a function member here, but even reading the message with the correct kind of member makes no sense… until we read it as simply “the worksheet function returned a worksheet error value“: if we typed that exact same invocation in an actual worksheet cell formula, Excel’s own error-handling would do the same, and the cell would contain an #N/A
error:
MATCH
or VLOOKUP
fails in a cell, that cell’s error value propagates to any caller/cell that references it. When you invoke these functions from VBA code, it’s into your VBA code that these errors propagate now.
Given bad arguments or a failed lookup, Application.WorksheetFunction.Match
and Application.Match
will behave very differently. Let us understand why and how. Note I’m going to be using a VLookup
function here, but Index
or Match
wouldn’t be any different, and everything here holds true for any other worksheet function, from the simplest Sum
to the most obscure financial function nobody ever used.
The two forms are not interchangeable, and it’s important to understand the difference!
Early Bound: Errors are Raised
When you invoke WorksheetFunction
members, errors are raised as VBA run-time errors. This means a failed lookup can be caught with an On Error
statement, as would any other run-time error.
On Error GoTo LookupFailed Debug.Print Application.WorksheetFunction.VLookup(...) Exit Sub LookupFailed: Debug.Print "..." Resume Next
When you type these member calls, you know you’re typing early-bound code because IntelliSense (its ancestor, anyway) is listing that member in an inline dropdown:
VLookup
is a member of the object returned by the WorksheetFunction
property of the Application
object.
The implication is that the function is assumed to “just work”: if using that same function with these same parameter values in an actual worksheet formula results in a #REF!
, #VALUE!
, #N/A
, #NAME?
, or any other Variant/Error
value… then the early-bound WorksheetFunction
equivalent raises run-time error 1004.
This VBA-like behavior is very useful when any failure of the worksheet function needs to be treated as a run-time error, for example when we are expecting the function to succeed every time and it failing would be a bug: throwing an error puts us on an early path to recovery.
Sometimes though, we don’t know what to expect, and a worksheet function returning an error is just one of the possible outcomes – using error handling in such cases would amount to using error handling for control flow, and that is a design smell: we should be using runtime errors for exceptional things that we’re not expecting. When a worksheet function can fail as part of normal execution, we have other options.
Late Bound: Errors are Values
When you invoke worksheet functions using late-bound member calls against an Excel.Application
object, when a function fails, it returns an error code.
Dim result As Variant result = Application.VLookup(...)
It’s important to understand that the Variant
type means nothing in particular until it gets a subtype at runtime; result
is a Variant/Empty
until the assignment succeeds – when it does result
might be a Variant/Double
if the value is numeric; if the lookup failed, instead of raising a run-time error result
will now be a Variant/Error
value.
Operations Involving Variant/Error: Removing Assumptions
Because a failed late-bound WorksheetFunction
returns an error value, it’s easy to forget the data type of the result might not be convertible to the declared type, so the first opportunity for things to go wrong materializes if we simply assume a non-error result by declaring a non-Variant
data type for the variable that is being assigned with the function’s result:
Dim result As Long 'assumes a successful lookup... result = Application.VLookup(...) 'runtime error 13 when lookup fails!
So we soon start systematically assigning these results to a Variant
:
Dim result As Variant result = Application.VLookup(...)
…only to find that all we did was moving the type mismatch error further down, here:
If result > 0 Then 'runtime error 13 when result is Variant/Error!
The first thing we should do with a Variant
, is to remove any assumptions about its content. The VBA.Information.IsError
function returns True
given a Variant/Error
, and we must use it to correctly remove assumptions about what’s in this result
variable:
Dim result As Variant result = Application.VLookup(...) If IsError(result) Then 'lookup failed Else 'lookup succeeded End If
Inside the lookup failed
conditional block, result
is a Variant/Error
value that can only be compared against another Variant/Error
value – involving result
in an operation with any other runtime type will throw a type mismatch error.
Using the VBA.Conversion.CVErr
function, we can convert a Long
integer into a Variant/Error
value; the Excel object model library includes named constants for each type of worksheet error, so we can use them with the CVErr
function to refine our knowledge of what’s in result
, if we need anything more detailed than “something went wrong”:
Dim result As Variant result = Application.VLookup(...) If IsError(result) Then 'lookup failed Select Case result Case CVErr(xlErrNA) 'result is a #N/A error: value wasn't found in the lookup range Case CVErr(xlErrRef) 'result is a #REF! error: is the lookup range badly defined? Case Else 'result is another type of error value End Select Else 'lookup succeeded End If
By systematically treating the result of a late-bound Application.{WorksheetFunction}
call as a potential Variant/Error
value, we avoid assuming success and handle a bad result without exposing our “happy path” to type mismatch errors; we then use If...Else...Then
standard control flow statements to branch execution differently depending on the outcome, using standard On Error
statements / error handling for the exceptional situations that could arise beyond these worksheet errors we’re already accounting for.
Other Variant/Error Pitfalls
The IsError
function isn’t just useful to determine whether a late-bound WorksheetFunction
call returned a usable value or not. The function returns True
given any Variant/Error
value, which makes it the perfect tool to identify worksheet cells that contain values that aren’t usable either.
Dim cell As Range Set cell = Sheet1.Range("A1") If cell.Value > 42 Then 'assumes cell.Value can be compared to 42! '... End If
VBA code often assumes cells contain valid values, and whenever that assumption is broken, a type mismatch error occurs. Unless the cell value was written by the same VBA code, it’s never really safe to assume a worksheet cell contains what the code expects it to contain. Using the IsError
function we remove such assumptions and make the code more resilient:
Dim cell As Range Set cell = Sheet1.Range("A1") If Not IsError(cell.Value) Then If cell.Value > 42 Then '... End If Else MsgBox cell.Address(External:=True) & " contains an unexpected value." End If
A Variant/Error
value can spell trouble in many other ways. Sometimes it’s an implicit conversion to String
that causes the type mismatch:
Dim cell As Range Set cell = Sheet1.Range("A1") MsgBox cell.Value 'assumes cell.Value can be converted to a String!
Implicit conversions can be hard to spot, but if your code is blowing up with a type mismatch error involving the value of a worksheet cell, or a value returned by a worksheet function, then that’s where you need to look.