Division by zero ошибка vba

This repo is no longer accepting new issues. To request changes, you can create a branch, make changes, then submit a PR. For more resources, see README.MD - VBA-Docs/division-by-zero-error-11.md a...

Permalink

Cannot retrieve contributors at this time

title keywords f1_keywords ms.prod ms.assetid ms.date ms.localizationpriority

Division by zero (Error 11)

vblr6.chm1011128

vblr6.chm1011128

office

3c6783d9-24a4-ef25-fdab-9e26a08e35a9

06/08/2017

medium

Division by zero isn’t possible. This error has the following cause and solution:

  • The value of an expression being used as a divisor is zero.

    Check the spelling of variables in the expression. A misspelled variable name can implicitly create a numeric variable that is initialized to zero. Check previous operations on variables in the expression, especially those passed into the procedure as arguments from other procedures.

For additional information, select the item in question and press F1 (in Windows) or HELP (on the Macintosh).

[!includeSupport and feedback]

Permalink

Cannot retrieve contributors at this time

title keywords f1_keywords ms.prod ms.assetid ms.date ms.localizationpriority

Division by zero (Error 11)

vblr6.chm1011128

vblr6.chm1011128

office

3c6783d9-24a4-ef25-fdab-9e26a08e35a9

06/08/2017

medium

Division by zero isn’t possible. This error has the following cause and solution:

  • The value of an expression being used as a divisor is zero.

    Check the spelling of variables in the expression. A misspelled variable name can implicitly create a numeric variable that is initialized to zero. Check previous operations on variables in the expression, especially those passed into the procedure as arguments from other procedures.

For additional information, select the item in question and press F1 (in Windows) or HELP (on the Macintosh).

[!includeSupport and feedback]

Replace all of your code: —

private sub textbox1_change()
if textbox1.value = "" then exit sub 
if textbox2.value = "" then exit sub 
textbox3.value = cdbl(textbox1.value) / cdbl(textbox2.value)
end sub 
private sub textbox2_change()
if textbox1.value = "" then exit sub
if textbox2.value = "" then exit sub
textbox3.value = cdbl(textbox1.value) / cdbl(textbox2.value)
end sub 

With this code: —

Private Sub textbox1_change()
ShowResult
End Sub
Private Sub textbox2_change()
ShowResult
End Sub
Private Sub ShowResult()
Dim Str1        As String
Dim Str2        As String
Str1 = Trim(textbox1.Value)
Str2 = Trim(textbox2.Value)
If (Str1 = "") Or (Str2 = "") Then Exit Sub
If (IsDouble(Str1) = False) Or (IsDouble(Str2) = False) Then
    textbox3.Value = "NA"
Else
    If (CDbl(Str2) = 0) Or ((CDbl(Str2) + CDbl(Str1)) = 0) Then
        textbox3.Value = "NA"
    Else
        textbox3.Value = CDbl(Str1) / CDbl(Str2)
    End If
End If
End Sub
Private Function IsDouble(ByVal StrValue As String) As Boolean
Dim DblTest As Double
On Error GoTo ErrorHandle
DblTest = CDbl(StrValue)
IsDouble = True
Exit Function
ErrorHandle:
Err.Clear
End Function

This will check for values that can’t be Double data types (i.e. a string) and bad division (i.e. error code 6 and 11).

EDIT: —
The below is walkthrough of what is happening in the above code.

The procedures textbox1_change and textbox2_change are doing the same thing so to avoid repetition of code; they both call on the one instance of that code.

Private Sub textbox1_change()
ShowResult
End Sub

Private Sub textbox2_change()
ShowResult
End Sub

After that, there is the new procedure ShowResult that holds the single instance of the code that textbox1_change and textbox2_change call upon.

Private Sub ShowResult()
Dim Str1        As String
Dim Str2        As String
Str1 = Trim(textbox1.Value)
Str2 = Trim(textbox2.Value)
If (Str1 = "") Or (Str2 = "") Then Exit Sub
If (IsDouble(Str1) = False) Or (IsDouble(Str2) = False) Then
    textbox3.Value = "NA"
Else
    If (CDbl(Str2) = 0) Or ((CDbl(Str2) + CDbl(Str1)) = 0) Then
        textbox3.Value = "NA"
    Else
        textbox3.Value = CDbl(Str1) / CDbl(Str2)
    End If
End If
End Sub

The ShowResult code does a number of checks.

First it places textbox1 into Str1 and textbox2 into Str2 and using trim on them. Trim means that leading and trailing spaces are removed. For example if the textbox1 value was » » (maybe done by copy and paste by the user) then technically it’s not empty and could cause an error.

Dim Str1        As String
Dim Str2        As String
Str1 = Trim(textbox1.Value)
Str2 = Trim(textbox2.Value)

The next check is if either value is empty then exit the procedure, much like you did before but now on a single line.

If (Str1 = "") Or (Str2 = "") Then Exit Sub

The next check calls another procedure that does a check to ensure the value could be converted to a double. for Example CDbl("Hello World!") would fail because it’s not a number to begin with. So this check gets around that potential issue, if its not a number that can be divided then output ‘NA’.

If (IsDouble(Str1) = False) Or (IsDouble(Str2) = False) Then
    textbox3.Value = "NA"

The final check is that if the second value is zero or both are zero then «NA2 is output, else the division is done and output.

If (CDbl(Str2) = 0) Or ((CDbl(Str2) + CDbl(Str1)) = 0) Then
    textbox3.Value = "NA"
Else
    textbox3.Value = CDbl(Str1) / CDbl(Str2)
End If

This is the final procedure that was called by ShowResult to check the value could be converted to a Double data type. It tried to do the conversion, if an error occurs the error is cleared and false (by default) will be returned to the caller, if there is no error then true is output.

Private Function IsDouble(ByVal StrValue As String) As Boolean
Dim DblTest As Double
On Error GoTo ErrorHandle
DblTest = CDbl(StrValue)
IsDouble = True
Exit Function
ErrorHandle:
Err.Clear
End Function

Hope this helps.

Содержание

  1. Run time error 11 division by zero vba excel
  2. Answered by:
  3. Question
  4. Типы ошибок в VBA
  5. Ошибки компиляции
  6. Ошибки выполнения
  7. Перехват ошибок выполнения
  8. Логические ошибки
  9. Excel vba обработка ошибок
  10. Типы ошибок в VBA
  11. Ошибки компиляции
  12. Ошибки выполнения
  13. Перехват ошибок выполнения
  14. Логические ошибки
  15. Обработка ошибок
  16. Обработка ошибок с двумя разными метками (VBA)

Run time error 11 division by zero vba excel

This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.

Answered by:

Question

When I call a function from a DLL, written in C++ and compiled in Visual Studio 2015 «Release» mode, I get the runtime error message “Run-time error ’11’: Division by zero” at the function call. However, when I compile as «Debug», everything runs fine.

I found out that the «Release» compilation does some name mangling with the called function, while «Debug» doesn’t do that. I found the real exported name through applying «dumpbin» on the DLL. Therefore one needs to use this alias name in VBA’s Declare-statement in the “Release” case (see below), while for the «Debug» compilation this is not needed. Furthermore, all this is done in a 32-bit environment (Windows 7, Office 2010), if I do that in a 64-bit environment (Windows 10, Office 365), there is no problem.

Does anybody have an idea what is going on here?

Here are the details of the problem:

The DLL “Simulation.dll” is written in C++ and compiled in Visual Studio 2015. The C++ function definition is in the file “source.cpp” which doesn’t have any header file, and reads

Now I compile in Visual Studio 2015 “Debug” mode to produce the DLL “Simulation.dll”. I declare the DLL function in VBA through

Running the VBA macro like this, everything works fine and the correct result is reproduced.

However, when I compile in “Release” mode, this first gives the error “Can’t find DLL entry point”. I could resolve this error, by finding out the real exported function name through applying “dumpbin” on “Simulation.dll” . This showed that the function name was mangled to “?simulationCPP18@@YGNPAN00000000N00000000000NNN00N0N00NNNNNNN@Z”. Now I used this name as function Alias in the declare statement, written as

The VBA macro seems to find the entry point now, but throws the error message : “Run-time error ’11’: Division by zero” at the point of the function call within the VBA macro, where it reads

Note that there is no explicit division happening at any point close to this function call, nor within the parameters.

Do you know where this different behaviour between “Debug” and “Release” compilation is coming from? Obviously, the mangled function name itself is correctly used, otherwise the Error “Can’t find DLL entry point” would prevail, right?

Источник

Типы ошибок в VBA

При выполнении макросов Excel могут возникнуть ошибки, которые в VBA делят на три категории:

Далее мы поговорим о каждом из трёх типов ошибок VBA подробно.

Ошибки компиляции

Компилятор VBA рассматривает ошибки компиляции как недопустимые и выделяет их в коде ещё до того, как дело дойдёт до запуска макроса.

Если при написании кода допущена синтаксическая ошибка, то редактор VBA сигнализирует об этом немедленно: либо при помощи окна с сообщением, либо выделяя ошибку красным цветом, в зависимости от статуса режима Auto Syntax Check.

Примечание: При включённом режиме Auto Syntax Check каждый раз, при появлении в редакторе Visual Basic во введённом коде синтаксической ошибки, будет показано соответствующее сообщение. Если же этот режим выключен, то редактор VBA продолжит сообщать о синтаксических ошибках, просто выделяя их красным цветом. Опцию Auto Syntax Check можно включить/выключить в меню Tools > Options редактора Visual Basic.

В некоторых случаях ошибка компиляции может быть обнаружена при выполнении компиляции кода, непосредственно перед тем, как макрос будет выполнен. Обычно ошибку компиляции несложно обнаружить и исправить, потому что компилятор VBA даёт информацию о характере и причине ошибки.

Например, сообщение «Compile error: Variable not defined» при попытке запустить выполнение кода VBA говорит о том, что происходит попытка использовать или обратиться к переменной, которая не была объявлена для текущей области (такая ошибка может возникнуть только если используется Option Explicit).

Ошибки выполнения

Ошибки выполнения возникают в процессе выполнения кода и приводят к остановке выполнения программы. Этот тип ошибок VBA, как правило, также не сложно обнаружить и исправить, так как сообщается информация о характере ошибки и место в коде, где произошла остановка.

Примером такой ошибки может служить попытка выполнить деление на ноль. В результате будет показано сообщение «Run-time error ’11’: Division by zero«.

В зависимости от структуры проекта VBA, может быть предложено выполнить отладку кода (как показано на рисунке ниже). В этом случае при нажатии на кнопку Debug (в окне сообщения о необходимости отладки) будет выделена цветом строка кода, которая стала причиной ошибки VBA.

Получив такое сообщение и видя выделенную строку кода, как в приведённом выше примере, обнаружить причину ошибки будет совсем не сложно.

В случае если код сложнее, чем в нашем примере, то, чтобы получить больше информации о причине возникновения ошибки VBA, можно проверить значения используемых переменных. В редакторе VBA для этого достаточно навести указатель мыши на имя переменной, или можно открыть окно отслеживания локальных переменных (в меню редактора View > Locals Window).

Коды различных ошибок выполнения расшифрованы на сайте Microsoft Support (на английском). Наиболее часто встречающиеся ошибки VBA перечислены в этой таблице:

5 Недопустимый вызов процедуры (Invalid procedure call)
7 Недостаточно памяти (Out of memory)
9 Индекс вне заданного диапазона (Subscript out of range)

Эта ошибка возникает при попытке обратиться к элементу массива за пределами заданного размера массива – например, если объявлен массив с индексами от 1 до 10, а мы пытаемся обратиться к элементу этого же массива с индексом 11.

11 Деление на ноль (Division by zero)
13 Несоответствие типа (Type mismatch)

Эта ошибка возникает при попытке присвоить переменной значение не соответствующего типа – например, объявлена переменная i типа Integer, и происходит попытка присвоить ей значение строкового типа.

53 Файл не найден (File not found)

Иногда возникает при попытке открыть не существующий файл.

Перехват ошибок выполнения

Не все ошибки выполнения бывают вызваны недочётами в коде. Например, ошибки VBA не удастся избежать, если для работы макроса необходимо открыть файл с данными, а этого файла не существует. В таких случаях признаком профессионализма будет перехват ошибок и написание кода VBA, который будет выполняться при их возникновении. Таким образом, вместо неприятных сбоев будет происходить изящное завершение работы макроса.

Для того, чтобы помочь справиться с возникающими ошибками, VBA предоставляет разработчику операторы On Error и Resume. Эти операторы отслеживают ошибки и направляют выполнение макроса в специальный раздел кода VBA, в котором происходит обработка ошибки. После выполнения кода обработки ошибки, работа программы может быть продолжена с того места, где возникла ошибка, или макрос может быть остановлен полностью. Далее это показано на примере.

В этом коде производится попытка открыть файл Excel с именем Data. Если файл не найден, то пользователю будет предложено поместить этот файл в нужную папку. После того, как пользователь сделает это и нажмёт ОК, выполнение кода продолжится, и попытка открыть этот файл повторится. При желании вместо попытки открыть нужный файл, выполнение процедуры Sub может быть прервано в этом месте при помощи команды Exit Sub.

Логические ошибки

Логические ошибки (или баги) возникают в процессе выполнения кода VBA, но позволяют ему выполняться до самого завершения. Правда в результате могут выполняться не те действия, которые ожидалось, и может быть получен неверный результат. Такие ошибки обнаружить и исправить труднее всего, так как компилятор VBA их не распознаёт и не может указать на них так, как это происходит с ошибками компиляции и выполнения.

Например, при создании макроса в процедуре случайно были просуммированы не те переменные, которые требовалось просуммировать. Результат будет ошибочным, но макрос будет продолжать выполняться до завершения.

Редактор Excel VBA предоставляет набор инструментов отладки, которые помогут найти и исправить логические ошибки в коде VBA. В данной статье мы не будем рассматривать подробно эти инструменты. Любознательный пользователь может найти обзор инструментов отладки VBA на сайте Microsoft Help & Support (на английском).

Источник

Excel vba обработка ошибок

Типы ошибок в VBA

​Смотрите также​ вероятностью 1/5 If​ момент возникновения ошибки​ / 0 j​ On Error Resume​

  • ​. Спасибо.​
  • ​ = wdSeekCurrentPageHeader Do​
  • ​On Error GoTo​

​ будет ошибочным, но​ этот файл повторится.​ = Workbooks.Open(«C:Documents and​ справиться с возникающими​

Ошибки компиляции

​ попытке присвоить переменной​ расшифрованы на сайте​ случае при нажатии​ использовать или обратиться​ Visual Basic во​При выполнении макросов Excel​ Cells(i, 1).Value >​

​ в цикле For​ = «test» If​ Next For i​Грузить файлы запрещено​ Selection.WholeStory Selection.Copy ActiveWindow.ActivePane.View.NextHeaderFooter​ err1 ‘включаем первую​ макрос будет продолжать​ При желании вместо​ SettingsData») ‘Присваиваем переменным​ ошибками, VBA предоставляет​​ значение не соответствующего​​ Microsoft Support (на​

​ на кнопку​​ к переменной, которая​​ введённом коде синтаксической​​ могут возникнуть ошибки,​ 3 Then On​ у меня останавливалось​ Err Then Cells(i,​ = 1 To​ в организации, поэтому​ Loop footercopy: ActiveWindow.ActivePane.View.SeekView​ обработку ‘создаём исключение​ выполняться до завершения.​ попытки открыть нужный​ Val1 и Val2​ разработчику операторы​​ типа – например,​​ английском). Наиболее часто​Debug​​ не была объявлена​​ ошибки, будет показано​​ которые в VBA​​ Error GoTo errH2​

​ выполнение кода и​ 2).Value = Err.Description:​ 10 If Cells(i,​ опишу пример.​ = wdSeekMainDocument Application.Run​ On Error GoTo​Редактор Excel VBA предоставляет​ файл, выполнение процедуры​ данные из рабочей​On Error​ объявлена переменная​ встречающиеся ошибки VBA​

​(в окне сообщения​​ для текущей области​ соответствующее сообщение. Если​​ делят на три​ x = 1​ переходило на Next?​ Err.Clear: End If​ 1).Value > 3​Есть книга со​ «footercopy» End Sub​ 0 ‘отключаем её​ набор инструментов отладки,​Sub​ книги DataWorkbook Val1​​и​​i​

Ошибки выполнения

​ перечислены в этой​ о необходимости отладки)​ (такая ошибка может​ же этот режим​ категории:​ / 0 End​Казанский​ Next End SubErr.Description​ Then If Err​ значениями на Листе1​ Sub footercopy() On​ On Error GoTo​ которые помогут найти​

​может быть прервано​ = Sheets(«Лист1»).Cells(1, 1)​Resume​типа​ таблице:​​ будет выделена цветом​ возникнуть только если​​ выключен, то редактор​

​Ошибки компиляции​ If nxt: Next​: Да уж наверно,​ будет выдавать последнюю​ Then Cells(i, 2).Value​ [A1:A5]= <1;2;3;4;5>и макрос:​ Error GoTo ExitSub​ err2 ‘включаем вторую​​ и исправить логические​​ в этом месте​ Val2 = Sheets(«Лист1»).Cells(1,​. Эти операторы отслеживают​Integer​5​ строка кода, которая​

​ используется​ VBA продолжит сообщать​Ошибки выполнения​ Exit Sub ‘Если​ раз не работает​ ошибку, а не​ = «Ошибка 1»:​

​ Sub test() Dim​ ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageFooter​ обработку ‘создаём исключение​ ошибки в коде​ при помощи команды​ 2) DataWorkbook.Close Exit​ ошибки и направляют​, и происходит попытка​Недопустимый вызов процедуры (Invalid​ стала причиной ошибки​Option Explicit​ о синтаксических ошибках,​Логические ошибки (баги)​ ошибка в условии​Resume​​ первую.​​ Err.Clear: Exit Sub​​ i%, x# [B:B].ClearContents​​ Do Selection.WholeStory Selection.Copy​

​ Exit Sub ‘выход​ VBA. В данной​Exit Sub​ Sub ErrorHandling: ‘Если​ выполнение макроса в​ присвоить ей значение​ procedure call)​

​ VBA.​ ​).​ просто выделяя их​
​Далее мы поговорим о​ ​ цикла, значит Netx​нужен для того,​
​А почему в​ ​ x = 1​ For i =​ ActiveWindow.ActivePane.View.NextHeaderFooter Loop ExitSub:​

​ из процедуры err1:​ статье мы не​.​ файл не найден,​ специальный раздел кода​ строкового типа.​7​​Получив такое сообщение и​​Ошибки выполнения возникают в​ красным цветом. Опцию​ каждом из трёх​ errH2: ‘If Err.Number​​ чтобы выйти из​​ моём варианте возникает​

​ / 0 If​ ​ 1 To 10​ ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument​
​ MsgBox Err.Description ‘обрабатываем​ ​ будем рассматривать подробно​

​Логические ошибки (или баги)​ предлагаем пользователю разместить​ VBA, в котором​53​Недостаточно памяти (Out of​​ видя выделенную строку​​ процессе выполнения кода​​Auto Syntax Check​​ типов ошибок VBA​ > 0 Then​ состояния обработки ошибки​

​ ошибка?​ ​ Err Then Cells(i,​ On Error GoTo​

​ End SubЯ здесь​ первое исключение Exit​ эти инструменты. Любознательный​

Перехват ошибок выполнения

​ возникают в процессе​ его в ‘нужном​ происходит обработка ошибки.​Файл не найден (File​ memory)​ кода, как в​ и приводят к​можно включить/выключить в​ подробно.​ ‘проверка не нужна,​ и перейти в​Вроде всё верно​ 2).Value = «Ошибка​ errH1 If Cells(i,​ сделал вызов другого​ Sub ‘выход из​ пользователь может найти​ выполнения кода VBA,​ месте и продолжить​

​ После выполнения кода​ not found)​9​ приведённом выше примере,​​ остановке выполнения программы.​​ меню​​Компилятор VBA рассматривает ошибки​​ т.к. без ошибки​ состояние нормальной работы.​ написано, но обработка​ 2″: Err.Clear: End​ 1).Value > 3​ макроса, т.к. не​ процедуры err2: MsgBox​ обзор инструментов отладки​ но позволяют ему​ работу MsgBox «Рабочая​ обработки ошибки, работа​Иногда возникает при попытке​Индекс вне заданного диапазона​ обнаружить причину ошибки​ Этот тип ошибок​

​Tools​ компиляции как недопустимые​ мы бы сюда​Если при работе​ не срабатывает. ​ If Next End​ Then On Error​ знал, как применить​ Err.Description ‘обрабатываем второе​ VBA на сайте​ выполняться до самого​ книга не найдена!​ программы может быть​ открыть не существующий​ (Subscript out of​ будет совсем не​ VBA, как правило,​>​ и выделяет их​ не попали Cells(i,​ обработчика ошибок происходит​Казанский​ Sub​ GoTo errH2 x​ обработку 2 ошибок,​ исключениеНо зачем?​ Microsoft Help &​ завершения. Правда в​ » & _​ продолжена с того​ файл.​ range)​ сложно.​ также не сложно​Options​ в коде ещё​

​ 2).Value = «Ошибка​ ошибка, происходит останов​: 1. Нет выхода​​Евгений​​ = 1 /​ которые должны по-любому​Можно и в​ Support (на английском).​ результате могут выполняться​ «Пожалуйста добавьте книгу​ места, где возникла​Не все ошибки выполнения​​Эта ошибка возникает при​​В случае если код​ обнаружить и исправить,​редактора Visual Basic.​ до того, как​ 2″ ‘ Err.Clear​ (есть правда возможность​​ из обработчика ошибки​​: Т.е. выполняется условие,​ 0 End If​ произойти (это является​​ одной метке обработать​​Урок подготовлен для Вас​

Логические ошибки

​ не те действия,​ Data.xlsx в каталог​ ошибка, или макрос​ бывают вызваны недочётами​ попытке обратиться к​ сложнее, чем в​ так как сообщается​В некоторых случаях ошибка​ дело дойдёт до​ ‘End If Resume​ обойти его:​ — оператор Resume​ а только потом​ ‘Если ошибка в​ функциональностью макроса).​ несколько ошибок​ командой сайта office-guru.ru​ которые ожидалось, и​ C:Documents and Settings​ может быть остановлен​ в коде. Например,​

​ элементу массива за​ нашем примере, то,​ информация о характере​ компиляции может быть​ запуска макроса.​ nxt ‘Если ошибка​On Error Goto -1​2. Нет обхода​

​ проверяется наличие ошибок,​ условии цикла, значит​Евгений​On Error GoTo​Источник: http://www.excelfunctions.net/VBA-Error.html​ может быть получен​ и нажмите OK.»​ полностью. Далее это​ ошибки VBA не​ пределами заданного размера​ чтобы получить больше​ ошибки и место​ обнаружена при выполнении​Если при написании кода​

​ перед условием цикла,​, но это​
​ обработчиков ошибок при​
​ а не в​

Обработка ошибок

​: Добрый день!​​ errLabel Open «C:имя_файла»​Перевел: Антон Андронов​ неверный результат. Такие​
​ Resume End Sub​ показано на примере.​ удастся избежать, если​ массива – например,​
​ информации о причине​ в коде, где​ компиляции кода, непосредственно​

​ допущена синтаксическая ошибка,​​ значит End errH1:​
​ крайний случай), а​
​ нормальном выполнении программы.​ момент её возникновения?​ Err.Number > 0​Необходимо построить обработку​ For Input As​Автор: Антон Андронов​ ошибки обнаружить и​В этом коде производится​’Процедура Sub присваивает​ для работы макроса​ если объявлен массив​ возникновения ошибки VBA,​ произошла остановка.​ перед тем, как​ то редактор VBA​ ‘If Err.Number >​
​ если ошибка происходит​Евгений​Так работает, спасибо!​
​ Then Cells(i, 2).Value​ ошибок с двумя​ 0 Exit Sub​Busine2009​ исправить труднее всего,​ попытка открыть файл​ переменным Val1 и​ необходимо открыть файл​ с индексами​ можно проверить значения​Примером такой ошибки может​ макрос будет выполнен.​ сигнализирует об этом​

​ 0 Then ‘проверка​​ после Resume, то​
​: 1. Может я​ Только что делать,​ = «Ошибка 2″​ разными метками выхода​ errLabel: Select Case​: Можно в одной​ так как компилятор​ Excel с именем​ Val2 значения, ‘хранящиеся​ с данными, а​от 1 до 10​ используемых переменных. В​ служить попытка выполнить​ Обычно ошибку компиляции​ немедленно: либо при​ не нужна, т.к.​ вызывается обработчик ошибок,​ неправильно представлял работу​ если будет так:​ Err.Clear End If​ (всё в цикле):​ Err.Number . Case​

Обработка ошибок с двумя разными метками (VBA)

​ процедуре использовать 2​​ VBA их не​
​Data​ в ячейках A1​ этого файла не​, а мы пытаемся​
​ редакторе VBA для​ деление на ноль.​ несложно обнаружить и​ помощи окна с​ без ошибки мы​
​ который назначен в​ обработчика, но зачем​ Sub test() Dim​ Next ‘Если ошибка​
​1. Если возникает​ 52 MsgBox «Неправильный​ раза​​ распознаёт и не​
​. Если файл не​ и B1 рабочей​ существует. В таких​
​ обратиться к элементу​ этого достаточно навести​ В результате будет​ исправить, потому что​ сообщением, либо выделяя​ бы сюда не​ данный момент.​ делать Resume, если​ i%, x#, j%​ перед условием цикла,​ ошибка до условия​ дискриптор файла» Case​On Error GoToсоответственно​ может указать на​ найден, то пользователю​ книги Data.xlsx расположенной​ случаях признаком профессионализма​ этого же массива​ указатель мыши на​ показано сообщение «​ компилятор VBA даёт​ ошибку красным цветом,​ попали Cells(i, 2).Value​Ваш код может​ есть GoTo?​ [B:B].ClearContents On Error​ значит End errH1:​ If, то просто​ 53 MsgBox «Файл​

​ для одной части​​ них так, как​
​ будет предложено поместить​ в каталоге C:Documents​ будет перехват ошибок​ с индексом​ имя переменной, или​Run-time error ’11’: Division​ информацию о характере​ в зависимости от​ = «Ошибка 1″​ выглядеть так: Sub​2. Я для​ Resume Next For​ If Err.Number >​ переходим на End​ не найден» . ​ кода и для​ это происходит с​ этот файл в​

​ and Settings Sub​​ и написание кода​11​ можно открыть окно​ by zero​ и причине ошибки.​
​ статуса режима​ ‘End If End​ test() Dim i%,​ этого вставил условие​ i = 1​ 0 Then Cells(i,​ Sub.​ Case Else MsgBox​ другой части кода?​ ошибками компиляции и​ нужную папку. После​ Set_Values(Val1 As Double,​ VBA, который будет​.​ отслеживания локальных переменных​«.​Например, сообщение «​Auto Syntax Check​ Sub​ x# [B:B].ClearContents For​ If Err.Number >​ To 10 If​ 2).Value = «Ошибка​2. Если возникает​
​ «Другая ошибка» End​Если можно, то​ выполнения.​
​ того, как пользователь​ Val2 As Double)​ выполняться при их​

​11​​ (в меню редактора​В зависимости от структуры​Compile error: Variable not​
​.​Евгений​ i = 1​

​ 0 Then . ​​ Cells(i, 1).Value >​ 1″ End If​ ошибка в условии​ Select​ напишите как. Буду​
​Например, при создании макроса​ сделает это и​ Dim DataWorkbook As​ возникновении. Таким образом,​Деление на ноль (Division​

​View​​ проекта VBA, может​ defined​Примечание:​: Спасибо за подробное​ To 10 On​ End If​ 3 Then If​ End Sub​

​ If, то переходим​​Busine2009​ очень признательным.​
​ в процедуре случайно​​ нажмёт​ Workbook On Error​ вместо неприятных сбоев​ by zero)​>​
​ быть предложено выполнить​» при попытке запустить​При включённом режиме​ объяснение, всё работает​ Error GoTo errH1​​Евгений​​ Err Then Cells(i,​KuklP​ на Netx.​: Вот конкретный пример:​Abu​ были просуммированы не​ОК​
​ GoTo ErrorHandling ‘Открываем​ будет происходить изящное​13​Locals Window​ отладку кода (как​ выполнение кода VBA​Auto Syntax Check​А то у​ x = 1​: Задам немного другой​ 2).Value = Err.Description:​: Так не проще?:​Прошу помочь разобраться​Sub HeaderCopy() On​: Можно!​ те переменные, которые​, выполнение кода продолжится,​ рабочую книгу с​ завершение работы макроса.​Несоответствие типа (Type mismatch)​).​ показано на рисунке​ говорит о том,​каждый раз, при​ Уокенбаха такого не​ / Int(Rnd *​ вопрос: как сделать​ Err.Clear: Exit Sub​Sub test() Dim​ почему на срабатывает​ Error GoTo footercopy​Можно так​ требовалось просуммировать. Результат​ и попытка открыть​ данными Set DataWorkbook​Для того, чтобы помочь​Эта ошибка возникает при​Коды различных ошибок выполнения​ ниже). В этом​ что происходит попытка​ появлении в редакторе​

​ написано​​ 5) ‘ошибка с​ так, что в​
​ x = 1​ i%, x# [B:B].ClearContents​ макрос​

Источник

Adblock
detector

При выполнении макросов Excel могут возникнуть ошибки, которые в VBA делят на три категории:

  • Ошибки компиляции
  • Ошибки выполнения
  • Логические ошибки (баги)

Далее мы поговорим о каждом из трёх типов ошибок VBA подробно.

Содержание

  1. Ошибки компиляции
  2. Ошибки выполнения
  3. Перехват ошибок выполнения
  4. Логические ошибки

Ошибки компиляции

Компилятор VBA рассматривает ошибки компиляции как недопустимые и выделяет их в коде ещё до того, как дело дойдёт до запуска макроса.

Если при написании кода допущена синтаксическая ошибка, то редактор VBA сигнализирует об этом немедленно: либо при помощи окна с сообщением, либо выделяя ошибку красным цветом, в зависимости от статуса режима Auto Syntax Check.

Примечание: При включённом режиме Auto Syntax Check каждый раз, при появлении в редакторе Visual Basic во введённом коде синтаксической ошибки, будет показано соответствующее сообщение. Если же этот режим выключен, то редактор VBA продолжит сообщать о синтаксических ошибках, просто выделяя их красным цветом. Опцию Auto Syntax Check можно включить/выключить в меню Tools > Options редактора Visual Basic.

В некоторых случаях ошибка компиляции может быть обнаружена при выполнении компиляции кода, непосредственно перед тем, как макрос будет выполнен. Обычно ошибку компиляции несложно обнаружить и исправить, потому что компилятор VBA даёт информацию о характере и причине ошибки.

Ошибки в Excel VBA

Например, сообщение «Compile error: Variable not defined» при попытке запустить выполнение кода VBA говорит о том, что происходит попытка использовать или обратиться к переменной, которая не была объявлена для текущей области (такая ошибка может возникнуть только если используется Option Explicit).

Ошибки выполнения

Ошибки выполнения возникают в процессе выполнения кода и приводят к остановке выполнения программы. Этот тип ошибок VBA, как правило, также не сложно обнаружить и исправить, так как сообщается информация о характере ошибки и место в коде, где произошла остановка.

Примером такой ошибки может служить попытка выполнить деление на ноль. В результате будет показано сообщение «Run-time error ’11’: Division by zero«.

Ошибки в Excel VBA

В зависимости от структуры проекта VBA, может быть предложено выполнить отладку кода (как показано на рисунке ниже). В этом случае при нажатии на кнопку Debug (в окне сообщения о необходимости отладки) будет выделена цветом строка кода, которая стала причиной ошибки VBA.

Ошибки в Excel VBA

Получив такое сообщение и видя выделенную строку кода, как в приведённом выше примере, обнаружить причину ошибки будет совсем не сложно.

В случае если код сложнее, чем в нашем примере, то, чтобы получить больше информации о причине возникновения ошибки VBA, можно проверить значения используемых переменных. В редакторе VBA для этого достаточно навести указатель мыши на имя переменной, или можно открыть окно отслеживания локальных переменных (в меню редактора View > Locals Window).

Коды различных ошибок выполнения расшифрованы на сайте Microsoft Support (на английском). Наиболее часто встречающиеся ошибки VBA перечислены в этой таблице:

5 Недопустимый вызов процедуры (Invalid procedure call)
7 Недостаточно памяти (Out of memory)
9 Индекс вне заданного диапазона (Subscript out of range)

Эта ошибка возникает при попытке обратиться к элементу массива за пределами заданного размера массива – например, если объявлен массив с индексами от 1 до 10, а мы пытаемся обратиться к элементу этого же массива с индексом 11.

11 Деление на ноль (Division by zero)
13 Несоответствие типа (Type mismatch)

Эта ошибка возникает при попытке присвоить переменной значение не соответствующего типа – например, объявлена переменная i типа Integer, и происходит попытка присвоить ей значение строкового типа.

53 Файл не найден (File not found)

Иногда возникает при попытке открыть не существующий файл.

Перехват ошибок выполнения

Не все ошибки выполнения бывают вызваны недочётами в коде. Например, ошибки VBA не удастся избежать, если для работы макроса необходимо открыть файл с данными, а этого файла не существует. В таких случаях признаком профессионализма будет перехват ошибок и написание кода VBA, который будет выполняться при их возникновении. Таким образом, вместо неприятных сбоев будет происходить изящное завершение работы макроса.

Для того, чтобы помочь справиться с возникающими ошибками, VBA предоставляет разработчику операторы On Error и Resume. Эти операторы отслеживают ошибки и направляют выполнение макроса в специальный раздел кода VBA, в котором происходит обработка ошибки. После выполнения кода обработки ошибки, работа программы может быть продолжена с того места, где возникла ошибка, или макрос может быть остановлен полностью. Далее это показано на примере.

'Процедура Sub присваивает переменным Val1 и Val2 значения,
'хранящиеся в ячейках A1 и B1 рабочей книги Data.xlsx расположенной в каталоге C:Documents and Settings

Sub Set_Values(Val1 As Double, Val2 As Double)

   Dim DataWorkbook As Workbook

   On Error GoTo ErrorHandling

      'Открываем рабочую книгу с данными

      Set DataWorkbook = Workbooks.Open("C:Documents and SettingsData")

      'Присваиваем переменным Val1 и Val2 данные из рабочей книги DataWorkbook

      Val1 = Sheets("Лист1").Cells(1, 1)
      Val2 = Sheets("Лист1").Cells(1, 2)

      DataWorkbook.Close

   Exit Sub

ErrorHandling:

   'Если файл не найден, предлагаем пользователю разместить его в
   'нужном месте и продолжить работу

   MsgBox "Рабочая книга не найдена! " & _
      "Пожалуйста добавьте книгу Data.xlsx в каталог C:Documents and Settings и нажмите OK."

   Resume

End Sub

В этом коде производится попытка открыть файл Excel с именем Data. Если файл не найден, то пользователю будет предложено поместить этот файл в нужную папку. После того, как пользователь сделает это и нажмёт ОК, выполнение кода продолжится, и попытка открыть этот файл повторится. При желании вместо попытки открыть нужный файл, выполнение процедуры Sub может быть прервано в этом месте при помощи команды Exit Sub.

Логические ошибки

Логические ошибки (или баги) возникают в процессе выполнения кода VBA, но позволяют ему выполняться до самого завершения. Правда в результате могут выполняться не те действия, которые ожидалось, и может быть получен неверный результат. Такие ошибки обнаружить и исправить труднее всего, так как компилятор VBA их не распознаёт и не может указать на них так, как это происходит с ошибками компиляции и выполнения.

Например, при создании макроса в процедуре случайно были просуммированы не те переменные, которые требовалось просуммировать. Результат будет ошибочным, но макрос будет продолжать выполняться до завершения.

Редактор Excel VBA предоставляет набор инструментов отладки, которые помогут найти и исправить логические ошибки в коде VBA. В данной статье мы не будем рассматривать подробно эти инструменты. Любознательный пользователь может найти обзор инструментов отладки VBA на сайте Microsoft Help & Support (на английском).

Оцените качество статьи. Нам важно ваше мнение:

title keywords f1_keywords ms.prod ms.assetid ms.date ms.localizationpriority

Elements of run-time error handling

vbaac10.chm5186924

vbaac10.chm5186924

access

a0e06a1e-2709-aa51-92d0-340788a31a8a

09/21/2018

medium

Errors and error handling

When you are programming an application, you need to consider what happens when an error occurs. An error can occur in your application for one of two of reasons. First, some condition at the time the application is running makes otherwise valid code fail. For example, if your code attempts to open a table that the user has deleted, an error occurs. Second, your code may contain improper logic that prevents it from doing what you intended. For example, an error occurs if your code attempts to divide a value by zero.

If you’ve implemented no error handling, then Visual Basic halts execution and displays an error message when an error occurs in your code. The user of your application is likely to be confused and frustrated when this happens. You can forestall many problems by including thorough error-handling routines in your code to handle any error that may occur.

When adding error handling to a procedure, you should consider how the procedure will route execution when an error occurs. The first step in routing execution to an error handler is to enable an error handler by including some form of the On Error statement within the procedure. The On Error statement directs execution in event of an error. If there’s no On Error statement, Visual Basic simply halts execution and displays an error message when an error occurs.

When an error occurs in a procedure with an enabled error handler, Visual Basic doesn’t display the normal error message. Instead it routes execution to an error handler, if one exists. When execution passes to an enabled error handler, that error handler becomes active. Within the active error handler, you can determine the type of error that occurred and address it in the manner that you choose. Access provides three objects that contain information about errors that have occurred, the ADO Error object, the Visual Basic Err object, and the DAO Error object.

Routing execution when an error occurs

An error handler specifies what happens within a procedure when an error occurs. For example, you may want the procedure to end if a certain error occurs, or you may want to correct the condition that caused the error and resume execution. The On Error and Resume statements determine how execution proceeds in the event of an error.

On Error statement

The On Error statement enables or disables an error-handling routine. If an error-handling routine is enabled, execution passes to the error-handling routine when an error occurs.

There are three forms of the On Error statement: On Error GoTo label, On Error GoTo 0, and On Error Resume Next. The On Error GoTo label statement enables an error-handling routine, beginning with the line on which the statement is found. You should enable the error-handling routine before the first line at which an error could occur. When the error handler is active and an error occurs, execution passes to the line specified by the label argument.

The line specified by the label argument should be the beginning of the error-handling routine. For example, the following procedure specifies that if an error occurs, execution passes to the line labeled:

Function MayCauseAnError() 
    ' Enable error handler. 
    On Error GoTo Error_MayCauseAnError 
    .            ' Include code here that may generate error. 
    . 
    . 
 
Error_MayCauseAnError: 
    .            ' Include code here to handle error. 
    . 
    . 
End Function

The On Error GoTo 0 statement disables error handling within a procedure. It doesn’t specify line 0 as the start of the error-handling code, even if the procedure contains a line numbered 0. If there’s no On Error GoTo 0 statement in your code, the error handler is automatically disabled when the procedure has run completely. The On Error GoTo 0 statement resets the properties of the Err object, having the same effect as the Clear method of the Err object.

The On Error Resume Next statement ignores the line that causes an error and routes execution to the line following the line that caused the error. Execution isn’t interrupted. Use the On Error Resume Next statement if you want to check the properties of the Err object immediately after a line at which you anticipate an error will occur, and handle the error within the procedure rather than in an error handler.

Resume statement

The Resume statement directs execution back to the body of the procedure from within an error-handling routine. You can include a Resume statement within an error-handling routine if you want execution to continue at a particular point in a procedure. However, a Resume statement isn’t necessary; you can also end the procedure after the error-handling routine.

There are three forms of the Resume statement. The Resume or Resume 0 statement returns execution to the line at which the error occurred. The Resume Next statement returns execution to the line immediately following the line at which the error occurred. The Resume label statement returns execution to the line specified by the label argument. The label argument must indicate either a line label or a line number.

You typically use the Resume or Resume 0 statement when the user must make a correction. For example, if you prompt the user for the name of a table to open, and the user enters the name of a table that doesn’t exist, you can prompt the user again and resume execution with the statement that caused the error.

You use the Resume Next statement when your code corrects for the error within an error handler, and you want to continue execution without rerunning the line that caused the error. You use the Resume label statement when you want to continue execution at another point in the procedure, specified by the label argument. For example, you might want to resume execution at an exit routine, as described in the following section.

Exiting a procedure

When you include an error-handling routine in a procedure, you should also include an exit routine, so that the error-handling routine will run only if an error occurs. You can specify an exit routine with a line label in the same way that you specify an error-handling routine.

For example, you can add an exit routine to the example in the previous section. If an error doesn’t occur, the exit routine runs after the body of the procedure. If an error occurs, then execution passes to the exit routine after the code in the error-handling routine has run. The exit routine contains an Exit statement.

Function MayCauseAnError() 
    ' Enable error handler. 
    On Error GoTo Error_MayCauseAnError 
    .            ' Include code here that may generate error. 
    . 
    . 
 
Exit_MayCauseAnError: 
    Exit Function 
 
Error_MayCauseAnError: 
    .            ' Include code to handle error. 
    . 
    . 
    ' Resume execution with exit routine to exit function. 
    Resume Exit_MayCauseAnError 
End Function

Handling errors in nested procedures

When an error occurs in a nested procedure that doesn’t have an enabled error handler, Visual Basic searches backward through the calls list for an enabled error handler in another procedure, rather than simply halting execution. This provides your code with an opportunity to correct the error within another procedure. For example, suppose Procedure A calls Procedure B, and Procedure B calls Procedure C. If an error occurs in Procedure C and there’s no enabled error handler, Visual Basic checks Procedure B, then Procedure A, for an enabled error handler. If one exists, execution passes to that error handler. If not, execution halts and an error message is displayed.

Visual Basic also searches backward through the calls list for an enabled error handler when an error occurs within an active error handler. You can force Visual Basic to search backward through the calls list by raising an error within an active error handler with the Raise method of the Err object. This is useful for handling errors that you don’t anticipate within an error handler. If an unanticipated error occurs, and you regenerate that error within the error handler, then execution passes back up the calls list to find another error handler, which may be set up to handle the error.

For example, suppose Procedure C has an enabled error handler, but the error handler doesn’t correct for the error that has occurred. Once the error handler has checked for all the errors that you’ve anticipated, it can regenerate the original error. Execution then passes back up the calls list to the error handler in Procedure B, if one exists, providing an opportunity for this error handler to correct the error. If no error handler exists in Procedure B, or if it fails to correct for the error and regenerates it again, then execution passes to the error handler in Procedure A, assuming one exists.

To illustrate this concept in another way, suppose that you have a nested procedure that includes error handling for a type mismatch error, an error which you’ve anticipated. At some point, a division-by-zero error, which you haven’t anticipated, occurs within Procedure C. If you’ve included a statement to regenerate the original error, then execution passes back up the calls list to another enabled error handler, if one exists. If you’ve corrected for a division-by-zero error in another procedure in the calls list, then the error will be corrected. If your code doesn’t regenerate the error, then the procedure continues to run without correcting the division-by-zero error. This in turn may cause other errors within the set of nested procedures.

In summary, Visual Basic searches back up the calls list for an enabled error handler if:

  • An error occurs in a procedure that doesn’t include an enabled error handler.

  • An error occurs within an active error handler. If you use the Raise method of the Err object to raise an error, you can force Visual Basic to search backward through the calls list for an enabled error handler.

Getting information about an error

After execution has passed to the error-handling routine, your code must determine which error has occurred and address it. Visual Basic and Access provide several language elements that you can use to get information about a specific error. Each is suited to different types of errors. Since errors can occur in different parts of your application, you need to determine which to use in your code based on what errors you expect.

The language elements available for error handling include:

  • Err object

  • ADO Error object and Errors collection

  • DAO Error object and Errors collection

  • AccessError method

  • Error event

Err object

The Err object is provided by Visual Basic. When a Visual Basic error occurs, information about that error is stored in the Err object. The Err object maintains information about only one error at a time. When a new error occurs, the Err object is updated to include information about that error instead.

To get information about a particular error, you can use the properties and methods of the Err object:

  • The Number property is the default property of the Err object; it returns the identifying number of the error that occurred.
  • The Err object’s Description property returns the descriptive string associated with a Visual Basic error.
  • The Clear method clears the current error information from the Err object.
  • The Raise method generates a specific error and populates the properties of the Err object with information about that error.

The following example shows how to use the Err object in a procedure that may cause a type mismatch error:

Function MayCauseAnError() 
    ' Declare constant to represent likely error. 
    Const conTypeMismatch As Integer = 13 
 
    On Error GoTo Error_MayCauseAnError 
        .            ' Include code here that may generate error. 
        . 
        . 
 
Exit_MayCauseAnError: 
    Exit Function 
 
Error_MayCauseAnError: 
    ' Check Err object properties. 
    If Err = conTypeMismatch Then 
        .            ' Include code to handle error. 
        . 
        . 
    Else 
        ' Regenerate original error. 
        Dim intErrNum As Integer 
        intErrNum = Err 
        Err.Clear 
        Err.Raise intErrNum 
    End If 
    ' Resume execution with exit routine to exit function. 
    Resume Exit_MayCauseAnError 
End Function

Note that in the preceding example, the Raise method is used to regenerate the original error. If an error other than a type mismatch error occurs, execution will be passed back up the calls list to another enabled error handler, if one exists.

The Err object provides you with all the information you need about Visual Basic errors. However, it doesn’t give you complete information about Access errors or Access database engine errors. Access and Data Access Objects (DAO)) provide additional language elements to assist you with those errors.

Error object and Errors collection

The Error object and Errors collection are provided by ADO and DAO. The Error object represents an ADO or DAO error. A single ADO or DAO operation may cause several errors, especially if you are performing DAO ODBC operations. Each error that occurs during a particular data access operation has an associated Error object. All the Error objects associated with a particular ADO or DAO operation are stored in the Errors collection, the lowest-level error being the first object in the collection and the highest-level error being the last object in the collection.

When a ADO or DAO error occurs, the Visual Basic Err object contains the error number for the first object in the Errors collection. To determine whether additional ADO or DAO errors have occurred, check the Errors collection. The values of the ADO Number or DAO Number properties and the ADO Description or DAO Description properties of the first Error object in the Errors collection should match the values of the Number and Description properties of the Visual Basic Err object.

AccessError method

Use the Raise method of the Err object to generate a Visual Basic error that hasn’t actually occurred and determine the descriptive string associated with that error. However, you can’t use the Raise method to generate a Access error, an ADO error, or a DAO error. To determine the descriptive string associated with an Access error, an ADO error, or a DAO error that hasn’t actually occurred, use the AccessError method.

Error event

Use the Error event to trap errors that occur on an Access form or report. For example, if a user tries to enter text in a field whose data type is Date/Time, the Error event occurs. If you add an Error event procedure to an Employees form, then try to enter a text value in the HireDate field, the Error event procedure runs.

The Error event procedure takes an integer argument, DataErr. When an Error event procedure runs, the DataErr argument contains the number of the Access error that occurred. Checking the value of the DataErr argument within the event procedure is the only way to determine the number of the error that occurred. The Err object isn’t populated with error information after the Error event occurs. Use the value of the DataErr argument together with the AccessError method to determine the number of the error and its descriptive string.

[!NOTE]
The Error statement and Error function are provided for backward compatibility only. When writing new code, use the Err and Error objects, the AccessError function, and the Error event for getting information about an error.

About the contributors

Link provided by Community Member Icon the UtterAccess community.

  • Handling Access Errors with VBA

UtterAccess is the premier Microsoft Access wiki and help forum.

See also

  • Access for developers forum
  • Access help on support.office.com
  • Access forums on UtterAccess
  • Access developer and VBA programming help center (FMS)
  • Access posts on StackOverflow

[!includeSupport and feedback]

Just like any other programming language, VBA has no luck when it comes to errors and you have to deal with them, no matter what. They may come from different sources, like bad coding, impossible operations (like zero division), or unexpected errors.

The best way to deal with it is to have a proper understanding of all the possible outcomes of the result that you could get with code. Look at the below example where we have a VBA code that calculates the square root of the number using the value which you have in the selected cell.

Sub Square_Root()
ActiveCell.Value = ActiveCell.Value ^ (1 / 2)
End Sub

But if the active cell has a value other than a number, you’ll get a run-time error, just like below.

Error Settings in VBA (Error Trapping)

In the VBA option, you can configure the setting to deal with errors before you start writing codes. To open the VBA settings, go to Tools ➤ Options ➤ Generals ➤ Error Trapping. Here you have three options which you can use.

  • Break on All Errors: If you have this option activated, VBA will stop the code for all types of errors even if you have used all kinds of error handling techniques.
  • Break-in Class Module: With this option, VBA will stop all your codes that are not handled by any technique. And if you’re using objects such as Userforms, it will also break within those objects and highlight the exact line where the error is.
  • Break on Unhandled Errors: This is the default setting that helps you to know about all the errors where you are not using any error handling technique and stop the code for all the unhandled errors. (But, if you’re using objects such as Userforms, this will not highlight the line causing the error in the object but will only highlight the line that’s referring to that object).

Types of VBA Errors

To understand VBA errors, you can split them into four categories, and below is the explanation of these types of errors.

1. Syntax Errors

While writing VBA code you need to follow a particular Syntax and when you skip it or don’t write it in the way it should be you can face SYNTAX error (also called Language error). It’s like typos that you do while writing your codes.

Well, VBA helps you by pointing out these errors by showing an error message. You just need to make sure you have “Auto Syntax Check” activated in your VB editor.

Go to the Tool ➤ Options and make sure to tick the “Auto Syntax Check”. With this, whenever you make a SYNTAX error, VBA will show an error message.

But if “Auto Syntax Check” is disabled VBA still highlights the line of code with the error but won’t show the error message.

2. Compile Errors

It comes when you write code to perform an activity, but that activity is not valid or can’t be performed by VBA. The best example is where you have a code using the IF statement but missed to add END IF at the end of the statement and now when you run this VBA will show you a compilation error message.

Apart from this, there are some other examples of compile errors:

  • Using For without Next (For Next).
  • Select without End Select (Select Case).
  • Not Declaring a Variable when you have “Option Explicit” enabled.
  • Calling a Sub/Function that does not exist.

3. Runtime Errors

A runtime error occurs at the time of executing the code. Remember the example, I shared with you above when the code calculated the square root of a number.

When a runtime error occurs while running code, it stops the code and shows you the error dialog box and that error box talks about the nature of the error you have. Let’s say you have written a code that opens a workbook from the location which you have specified but now that workbook is relocated or deleted by someone.

So, when you run the code, VBA will show you a runtime error as it can’t find that file on that location. The message you get in a run time error describes the reason which helps you to understand the reason for the error.

And when a runtime error occurs it stops the execution of the code. If you click on the “Debug” button it shows you the line of code that has that error by highlighting it yellow. Or you can click on the “End” button to stop the code to execute and close the error message.

4. Logical Error

It’s not an error but a mistake while writing code. These types of errors sometimes can give you nuts while finding them and correcting them.

Let’s say you write code and while declaring a variable you used the wrong data type, or you have used the wrong calculation steps. In this case, your code will work fine, and you won’t find this error easily. The best way to deal with this kind of problem is to run each line of code one by one.

Using Debug Tools in VBA

VBA provides you a set of tools to debug your code and remove bugs from your codes.

1. Compile VBA Project

In Visual Basic Editor, there’s an option that you can use instantly after completing your code. These compile options scan each line of your code and show a message box if there is an error in your code.

Note: Compile VBA option only traces Syntax and Compile errors, not runtime errors as these errors only rise when a code is running. To use Compile VBA Project, go to ➤ Debug ➤ Compile VBA Project.

Once you run “Compile VBA Project” and you have no error in your code, the options will be greyed out.

2. Run Each Line of Code One by One

This is how I do it. When I complete a code, I simply run it line by line to check if there’s an error occurring. It may take time, but it helps you to get to about all the errors (Syntax, Compile, and Run-Time).

On the “Debug Toolbar”, there’s a button “Step In” which you can use to execute a code line by line or you can simply press F8 to execute a single line and then press it again to execute the next line in the code.

Using “On ERROR” Statement to Handle VBA Errors

It’s important to check your codes and find possible errors in all the debugging ways you have. But, the best and most effective way is to create error-handling statements that can deal with an error and make your code flawless while executing. Let’s learn about these statements. When an error occurs in a VBA code the best possible ways to handle that error can be:

  • Let the VBA ignore the error and execute the code
  • Let a special set of statements to run when an error occurs.

In both solutions, you can use “On Error” statements. Below four “On Error” statements that you can use. And now, let’s look at each statement one by one.

1. On Error Resume Next

This simple line of code lets VBA continue executing the code despite the occurrence of an error. The IDEA is simple: Move to the next line of the code if there’s an error found somewhere while executing.

In the below code, you have two lines of code:

  • The first line says the value  of cell A1 is 25 divided by 0
  • And the second line says the value cell A2 is 10 divided by 5

Now there’s a problem with the code which you have inline one. As you know if you divide anything with 0 the result will be an error.  So, when you run this code VBA will show an error message “Run-time error ‘11’ Division by Zero” and stop the execution.

But when you add the “On Error Resume Next” at the very beginning of the code and run the code, VBA simply skips that line of code where the error occurs and continues with the second line and add that value in cell A2.

Sub myDivide()
On Error Resume Next
    Range("A1").Value = 25 / 0
    Range("A2").Value = 10 / 5
End Sub

So, whenever you want your code to get executed despite an error occurring anywhere simply use the “On Error Resume Next” statement in your code.

But here’s one more thing you need to note down: It will only skip errors that occur after it.

Let’s say if an error occurs at line 5 and you have added “On Error Resume Next” on line 8 then it would not skip that error.  So, the best way is to add it as the first line of the code in the procedure.

2. On Error GoTo 0

It’s the default behavior of VBA that when an error occurred it stops the execution of the code.

Well, using “On Error GoTo 0” make no difference in your code. VBA will simply stop the code and show a message with a description of the error. Then why would I bother to use it? Smart Question. Let’s use the example you have used above in “On Error Resume Next”.

In this code whenever an error will occur VBA will resume to the next line of code and run it and you won’t see any error message. But let’s say you have more lines in your code and you don’t want to surpass those lines if there’s an error in the code.

So, if you enter “On Error GoTo 0” after the second line of code it will restore the VBA’s default error handler which shows error messages each time an error occurs.

3. On Error GoTo [Label]

Think about a place in a building where you can head up in an emergency. In the same way, using “On Error GoTo [Label]”, you can simply create a separate block of code in your main code to deal with an error.

Actually, “On Error GoTo [Label]” is a far better and more convenient way to deal with errors. In the below code, you have “On Error GoTo Oh!Error” now in this line statement the word “Oh!Error” is the label.

If you look at the end of the code where you have a specific starting with the label name and then a code for a message box with a message about the code.

Now, what happens if an error occurs the VBA will jump to the label “Oh!Error” and run the block of code which you have after that label.

But there’s one thing you need to take care of: If an error doesn’t occur even then the label you have in your code will get executed. There are two things you need to do:

  • First, make sure to add your Error label at the end of the code.
  • Second, add an “Exit Sub” before the error label.

With this, you’ll benefit in both situations. Let’s say if an error occurs and VBA jumps to the label you specified there would only be code from the label itself to code. And if an error doesn’t occur “Exit Sub” statement which you have before the label will exit the procedure without executing the error label.

4. On Error GoTo -1

Before we get into this, let me share something with you.  When an error occurs in a code VBA stores that error log in its memory and only clears it when the routine ends.

O VBA! Live in Present

To deal with the second error in a VBA code you need to clear the first error from VBA’s memory. In the below code, you have two “On Error GoTo [Label]” statements that deal with errors from two different blocks of code.

But if you run this code, when the second error VBA won’t jump to the label which you have defined and instead show the error message “Type Mismatch”.

Sub Square_Root()
On Error GoTo myError1
Range("A1").Value = Range("A1").Value ^ (1 / 2)
myError1:
MsgBox "There's some problem with the value you have in the cell A1."
On Error GoTo myError2
Range("A2").Value = Range("A2").Value ^ (1 / 2)
myError2:
MsgBox "There's some problem with the value you have in the cell A2."
End Sub

To fix this problem you can use “On Error GoTo -1” which makes VBA remove the current error from its storage memory.

Sub Square_Root()
 On Error GoTo myError1
 Range("A1").Value = Range("A1").Value ^ (1 / 2)
 myError1:
 MsgBox "There's some problem with the value you have in the cell A1."
 On Error GoTo -1
 On Error GoTo myError2
 Range("A2").Value = Range("A2").Value ^ (1 / 2)
 myError2:
 MsgBox "There's some problem with the value you have in the cell A2."
 End Sub

Now when you run this code, “On Error GoTo -1” removes the error from the memory and VBA deals with the error in the second statement as you want.

What Else Do I Need to Know to Handle Errors in VBA?

Apart from using error handling techniques, there are a few other things that you can use to deal with errors in a better way.

Err Object

When an error occurred while executing of code, you can use the Err object to get details about that error. There are a few properties and methods which you can use with Err object. Let’s learn them one by one.

Properties

Below are the properties which you can use with the Err object:

  • Err.Number: With an error occurred there’s a number stored in the Err Object. In the below code, when occurred the message box will show the error number.  
  • Err.Description: This property shows the description of the error which can help you to understand the reason for the error.
  • Err.Source: This property shows you in which project the error has occurred.
  • Err.HelpContext: This property returns the help context id for the error in the help file.
  • Err.HelpContext: This is a string value for the location of the help file.

Normally when you are dealing with errors using error handling techniques you won’t be using the Err Object that much in your codes. But below is a simple example to use it.

Sub Square_Root()
On Error GoTo myError1
    Range("A1").Value = Sqr(Range("A1").Value)
Exit Sub
myError1:
    MsgBox "There's some problem with the value you have in the cell A1." & vbCrLf & _
                "Error Number: " & Err.Number  & vbCrLf & _
                "Error Description: " & Err.Description
End Sub

When you run the above code, and if an error occurred, it will show a message box with the error number and description of the error.

Methods

With Err Object there are two methods that you can also use.

  • Err.Clear: This method clears the error number and error description from VBA’s memory (It’s different from “On Error GoTo -1” as it doesn’t completely reset the error).
  • Err.Raise: With this method, you can generate a run time error in your code intentionally, and below is the syntax which needs to follow:

Err.Raise [number], [source], [description], [helpfile], [helpcontext]

Quick Tips on Error Handling

Here are a few quick tips which you can use to deal with VBA errors in a better way.

  • Use “On Error Resume Next” only when you know for sure about an error to occur and it’s OK to skip the line of code with an error and it’s safe to skip to the next line.
  • The best way to deal with run-time errors is by using “Error Handler” with “On Error GoTo [Label]”. This ensures that whenever the error occurs you will know about it, but it won’t show that nasty error message.
  • Whenever you use the error handler make sure to use “Exit Sub” before it.

There’s More

Below are some of the links which could be useful for you to learn more about error handling in VBA, make sure to check out all of these:

Type Mismatch (Error 13) | Runtime (Error 1004) | Object Required (Error 424) | Out of Memory (Error 7) | Object Doesn’t Support this Property or Method (Error 438) | Invalid Procedure Call or Argument (Error 5) | Overflow (Error 6) | Automation error (Error 440) | VBA Error 400 | VBA Subscript Out of Range Runtime Error 9

Hello all,

When I call a function from a DLL, written in C++ and compiled in Visual Studio 2015 «Release» mode, I get the runtime error message “Run-time error ’11’: Division by zero” at the function call. However, when I compile as «Debug»,
everything runs fine.

I found out that the «Release» compilation does some name mangling with the called function, while «Debug» doesn’t do that. I found the real exported name through applying «dumpbin» on the DLL. Therefore one needs to use this alias
name in VBA’s Declare-statement in the “Release” case (see below), while for the «Debug» compilation this is not needed. Furthermore, all this is done in a 32-bit environment (Windows 7, Office 2010), if I do that in a 64-bit environment (Windows
10, Office 365), there is no problem.

Does anybody have an idea what is going on here?

Here are the details of the problem:

The DLL “Simulation.dll” is written in C++ and compiled in Visual Studio 2015. The C++ function definition is in the file “source.cpp” which doesn’t have any header file, and reads

double __declspec(dllexport) simulationCPP18(<list of 50 parameters, all either double or double*>)

Now I compile in Visual Studio 2015 “Debug” mode to produce the DLL “Simulation.dll”. I declare the DLL function in VBA through

Declare Function simulationCPP18 _
Lib "Simulation.dll" _
(<list of 50 parameters, all double, some ByVal and some ByRef>) As Double

Running the VBA macro like this, everything works fine and the correct result is reproduced.

However, when I compile in “Release” mode, this first gives the error “Can’t find DLL entry point”. I could resolve this error, by finding out the real exported function name through applying “dumpbin” on “Simulation.dll” . This showed that the function
name was mangled to “?simulationCPP18@@YGNPAN00000000N00000000000NNN00N0N00NNNNNNN@Z”. Now I used this name as function Alias in the declare statement, written as

Declare Function simulationCPP18 _
Lib "Simulation.dll" Alias “?simulationCPP18@@YGNPAN00000000N00000000000NNN00N0N00NNNNNNN@Z" _
(<list of 50 parameters, all double, some ByVal and some ByRef>) As Double

The VBA macro seems to find the entry point now, but throws the error message : “Run-time error ’11’: Division by zero” at the  point of the function call within the VBA macro, where it reads

i = simulationCPP18(<list of 50 parameters>)

Note that there is no explicit division happening at any point close to this function call, nor within the parameters.

Do you know where this different behaviour between “Debug” and “Release” compilation is coming from? Obviously, the mangled function name itself is correctly used, otherwise the Error “Can’t find DLL entry point” would prevail, right?

Thanks for any help on that.

  • Moved by

    Tuesday, June 14, 2016 5:31 PM
    c++ problem/ maybe VBA

“Abort, Retry, Fail?” – MS-DOS error message circa 1986

This post provides a complete guide to VBA Error Handing. If you are looking for a quick summary then check out the quick guide table in the first section.

If you are looking for a particular topic on VBA Error Handing then check out the table of contents below(if it’s not visible click on the post header).

If you are new to VBA Error Handling, then you can read the post from start to finish as it is laid out in logical order.

Contents

  • 1 A Quick Guide to Error Handing
  • 2 The Webinar
  • 3 Download the Error Handling Library
  • 4 Introduction
  • 5 VBA Errors
    • 5.1 Syntax Errors
    • 5.2 Compilation Errors
      • 5.2.1 Using Debug->Compile
      • 5.2.2 Debug->Compile Error Summary
      • 5.2.3 Debug->Compile Usage
    • 5.3 Runtime Errors
      • 5.3.1 Expected Versus Unexpected Errors
    • 5.4 Runtime Errors that are not VBA Errors
  • 6 The On Error Statement
    • 6.1 On Error GoTo 0
    • 6.2 On Error Resume Next
    • 6.3 On Error GoTo [label]
    • 6.4 On Error GoTo -1
    • 6.5 Using On Error
  • 7 Resume Next
  • 8 The Err Object
    • 8.1 Getting the Line Number
    • 8.2 Using Err.Raise
    • 8.3 Using Err.Clear
  • 9 Logging
  • 10 Other Error Related Items
    • 10.1 Error Function
    • 10.2 Error Statement
  • 11 A Simple Error Handling Strategy
    • 11.1 The Basic Implementation
  • 12 A Complete Error Handling Strategy
    • 12.1 An Example of using this strategy
  • 13 Error Handling in a Nutshell
  • 14 What’s Next?

A Quick Guide to Error Handing

Item Description
On Error Goto 0 When error occurs, the code stops and displays the error.
On Error Goto -1 Clears the current error setting and reverts to the default.
On Error Resume Next Ignores the error and continues on.
On Error Goto [Label] Goes to a specific label when an error occurs.
This allows us to handle the error.
Err Object When an error occurs the error information is stored here.
Err.Number The number of the error.
(Only useful if you need to check a specific error occurred.)
Err.Description Contains the error text.
Err.Source You can populate this when you use Err.Raise.
Err.Raise A function that allows you to generate your own error.
Error Function Returns the error text from an error number.
Obsolete.
Error Statement Simulates an error. Use Err.Raise instead.

The Webinar

Members of the Webinar Archives can access the webinar for this article by clicking on the image below.

(Note: Archive members have access to the webinar archive.)

vba error handling video

Download the Error Handling Library

Introduction

Error Handling refers to code that is written to handle errors which occur when your application is running. These errors are normally caused by something outside your control like a missing file, database being unavailable, data being invalid etc.

If we think an error is likely to occur at some point, it is good practice to write specific code to handle the error if it occurs and deal with it.

For all other errors, we use generic code to deal with them. This is where the VBA error handling statement comes into play. They allow our application to deal gracefully with any errors we weren’t expecting.

To understand error handling we must first understand the different types of errors in VBA.

VBA Error Handling

VBA Errors

There are three types of errors in VBA:

  1. Syntax
  2. Compilation
  3. Runtime

We use error handling to deal with runtime errors. Let’s have a look at each of these error types so that it is clear what a runtime error is.

Syntax Errors

If you have used VBA for any length of time you will have seen a syntax error. When you type a line and press return, VBA will evaluate the syntax and if it is not correct it will display an error message.

For example if you type If and forget the Then keyword, VBA will display the following error message

VBA Error Handling

Some examples of syntax errors are

' then is missing
If a > b

' equals is missing after i
For i 2 To 7

' missing right parenthesis
b = left("ABCD",1

Syntax errors relate to one line only. They occur when the syntax of one line is incorrect.

Note: You can turn off the Syntax error dialog by going to Tools->Options and checking off “Auto Syntax Check”. The line will still appear red if there is an error but the dialog will not appear.

Compilation Errors

Compilation errors occur over more than one line. The syntax is correct on a single line but is incorrect when all the project code is taken into account.

Examples of compilation errors are:

  • If statement without corresponding End If statement
  • For without Next
  • Select without End Select
  • Calling a Sub or Function that does not exist
  • Calling a Sub or Function with the wrong parameters
  • Giving a Sub or Function the same name as a module
  • Variables not declared(Option Explicit must be present at the top of the module)

The following screenshot shows a compilation error that occurs when a For loop has no matching Next statement.

VBA Error Handling

Using Debug->Compile

To find compilation errors, we use Debug->Compile VBA Project from the Visual Basic menu.

When you select Debug->Compile, VBA displays the first error it comes across.

When this error is fixed, you can run Compile again and VBA will then find the next error.

Debug->Compile will also include syntax errors in it’s search which is very useful.

If there are no errors left and you run Debug->Compile , it may appear that nothing happened. However, “Compile” will be grayed out in the Debug menu. This means your application has no compilation errors at the current time.

Debug->Compile Error Summary

  • Debug->Compile finds compilation(project wide) errors.
  • It will also find syntax errors.
  • It finds one error each time you use it.
  • When there are no compilation errors left the Compile option will appear grayed out in the menu.

Debug->Compile Usage

You should always use Debug->Compile before you run your code. This ensures that your code has no compilation errors when you run it.

If you do not run Debug->Compile then VBA may find compile errors when it runs. These should not be confused with Runtime errors.

Runtime Errors

Runtime errors occur when your application is running. They are normally outside of your control but can be caused by errors in your code.

VBA Error Handling

For example, imagine your application reads from an external workbook. If this file gets deleted then VBA will display an error when your code tries to open it.

Other examples of runtime errors are

  • a database not being available
  • the user entering invalid data
  • a cell containing text instead of a number

As we have seen, the purpose of error handling is to deal with runtime errors when they occur.

Expected Versus Unexpected Errors

When we think a runtime error could occur we put code in place to handle it. For example, we would normally put code in place to deal with a file not being found.

The following code checks if the file exists before it tries to open it. If the file does not exist then a user friendly message is displayed and the code exits the sub.

' https://excelmacromastery.com/
Sub OpenFile()
    
    Dim sFile As String
    sFile = "C:docsdata.xlsx"
    
    ' Use Dir to check if file exists
    If Dir(sFile) = "" Then
        ' if file does not exist display message
        MsgBox "Could not find the file " & sFile
        Exit Sub
    End If
    
    ' Code will only reach here if file exists
    Workbooks.Open sFile
    
End Sub

When we think an error is likely to occur at some point, it is good practice to add code to handle the situation. We normally refer to these errors as expected errors.

If we don’t have specific code to handle an error it is considered an unexpected error. We use the VBA error handling statements to handle the unexpected errors.

Runtime Errors that are not VBA Errors

Before we look at the VBA Handling there is one type of error we must mention. Some runtime errors are not considered errors by VBA but only by the user.

Let me explain this with an example. Imagine you have an application that requires you to add the values in the variables a and b

result = a + b

Let’s say you mistakenly use an asterisk instead of the plus sign

result = a * b

This is not a VBA error. Your code syntax is perfectly legal. However, from your requirements point of view it is an error.

These errors cannot be dealt with using error handling as they obviously won’t generate any error. You can deal with these errors using Unit Testing and Assertions. I have an in-depth post about using VBA assertions – see How to Make Your Code BulletProof.

The On Error Statement

As we have seen there are two ways to treat runtime errors

  1. Expected errors – write specific code to handle them.
  2. Unexpected errors – use VBA error handling statements to handle them.

The VBA On Error statement is used for error handling. This statement performs some action when an error occurs during runtime.

There are four different ways to use this statement

  1. On Error GoTo 0 – the code stops at the line with the error and displays a message.
  2. On Error Resume Next – the code moves to next line. No error message is displayed.
  3. On Error GoTo [label] – the code moves to a specific line or label. No error message is displayed. This is the one we use for error handling.
  4. On Error GoTo -1 – clears the current error.

Let’s look at each of these statements in turn.

On Error GoTo 0

This is the default behavior of VBA. In other words, if you don’t use On Error then this is the behavior you will see.

When an error occurs, VBA stops on the line with the error and displays the error message. The application requires user intervention with the code before it can continue. This could be fixing the error or restarting the application. In this scenario no error handling takes place.

Let’s look at an example. In the following code, we have not used any On Error line so VBA will use the On Error GoTo 0 behavior by default.

' https://excelmacromastery.com/
Sub UsingDefault()

    Dim x As Long, y As Long
    
    x = 6
    y = 6 / 0
    x = 7

End Sub

The second assignment line results in a divide by zero error. When we run this code we will get the error message shown in the screenshot below

VBA Error Handling

When the error appears you can choose End or Debug

If you select End then the application simply stops.
If you select Debug the application stops on the error line as the screenshot below shows

VBA Error Handling

This behaviour is fine when you are writing VBA code as it shows you the exact line with the error.

This behavior is unsuitable for an application that you are given to a user. These errors look unprofessional and they make the application look unstable.

An error like this is essentially the application crashing. The user cannot continue on without restarting the application. They may not use it at all until you fix the error for them.

By using On Error GoTo [label] we can give the user a more controlled error message. It also prevents the application stopping. We can get the application to perform in a predefined manner.

On Error Resume Next

Using On Error Resume Next tells VBA to ignore the error and continue on.

There are specific occasions when this is useful. Most of the time you should avoid using it.

If we add Resume Next to our example Sub then VBA will ignore the divide by zero error

' https://excelmacromastery.com/
Sub UsingResumeNext()

    On Error Resume Next
    
    Dim x As Long, y As Long
    
    x = 6
    y = 6 / 0
    x = 7

End Sub

It is not a good idea to do this. If you ignore the error, then the behavior can be unpredictable. The error can affect the application in multiple ways.You could end up with invalid data. The problem is that you aren’t aware that something went wrong because you have suppressed the error.

The code below is an example of where using Resume Next is valid

' https://excelmacromastery.com/
Sub SendMail()

   On Error Resume Next
   
    ' Requires Reference:
    ' Microsoft Outlook 15.0 Object Library
    Dim Outlook As Outlook.Application
    Set Outlook = New Outlook.Application

    If Outlook Is Nothing Then
        MsgBox "Cannot create Microsoft Outlook session." _
                   & " The email will not be sent."
        Exit Sub
    End If
    
End Sub

In this code we are checking to see if Microsoft Outlook is available on a computer. All we want to know is if it is available or not. We are not interested in the specific error.

In the code above, we continue on if there is an error. Then in the next line we check the value of the Outlook variable. If there has been an error then the value of this variable will be set to Nothing.

This is an example of when Resume could be useful. The point is that even though we use Resume we are still checking for the error. The vast majority of the time you will not need to use Resume.

On Error GoTo [label]

This is how we use Error Handling in VBA. It is the equivalent of the Try and Catch functionality you see in languages such as C# and Java.

When an error occurs you send the error to a specific label. It is normally at the bottom of the sub.

Let’s apply this to the sub we have been using

' https://excelmacromastery.com/
Sub UsingGotoLine()

    On Error GoTo eh
    
    Dim x As Long, y As Long
    
    x = 6
    y = 6 / 0
    x = 7
    
Done:
    Exit Sub
eh:
    MsgBox "The following error occurred: " & Err.Description
End Sub

The screenshot below shows what happens when an error occurs

VBA Error Handling

VBA jumps to the eh label because we specified this in the On Error Goto line.

Note 1: The label we use in the On…GoTo statement, must be in the current Sub/Function. If not you will get a compilation error.

Note 2: When an error occurs when using On Error GoTo [label], the error handling returns to the default behaviour i.e. The code will stop on the line with the error and display the error message. See the next section for more information about this.

On Error GoTo -1

This statement is different than the other three. It is used to clear the current error rather than setting a particular behaviour.

When an error occurs using On Error GoTo [label], the error handling behaviour returns to the default behaviour i.e. “On Error GoTo 0”. That means that if another error occurs the code will stop on the current line.

This behaviour only applies to the current sub. Once we exit the sub, the error will be cleared automatically.

Take a look at the code below. The first error will cause the code to jump to the eh label. The second error will stop on the line with the 1034 error.

' https://excelmacromastery.com/
Sub TwoErrors()

    On Error Goto eh
        
    ' generate "Type mismatch" error
    Error (13)

Done:
    Exit Sub
eh:
    ' generate "Application-defined" error
    Error (1034)
End Sub

If we add further error handling it will not work as the error trap has not been cleared.

In the code below we have added the line

On Error Goto eh_other

after we catch the first error.

This has no effect as the error has not been cleared. In other words the code will stop on the line with the error and display the message.

' https://excelmacromastery.com/
Sub TwoErrors()

    On Error Goto eh
        
    ' generate "Type mismatch" error
    Error (13)

Done:
    Exit Sub
eh:
    On Error Goto eh_other
    ' generate "Application-defined" error
    Error (1034)
Exit Sub
eh_other:
    Debug.Print "eh_other " & Err.Description
End Sub

To clear the error we use On Error GoTo -1. Think of it like setting a mouse trap. When the trap goes off you need to set it again.

In the code below we add this line and the second error will now cause the code to jump to the eh_other label

' https://excelmacromastery.com/
Sub TwoErrors()

    On Error Goto eh
        
    ' generate "Type mismatch" error
    Error (13)

Done:
    Exit Sub
eh:
    ' clear error
    On Error Goto -1
    
    On Error Goto eh_other
    ' generate "Application-defined" error
    Error (1034)
Exit Sub
eh_other:
    Debug.Print "eh_other " & Err.Description
End Sub

Note 1: There are probably rare cases where using On Error GoTo -1 is useful. In most cases using Resume Next is better as it clears the error and resumes the code at the next line after the error occurs.

Note 2: The Err Object has a member Clear. Using Clear clears the text and numbers in the Err object, but it does NOT reset the error.

Using On Error

As we have seen, VBA will do one of three things when an error occurs

  • Stop and display the error.
  • Ignore the error and continue on.
  • Jump to a specific line.

VBA will always be set to one of these behaviors. When you use On Error, VBA will change to the behaviour you specify and forget about any previous behavior.

In the following Sub, VBA changes the error behaviour each time we use the On Error statement

' https://excelmacromastery.com/
Sub ErrorStates()

    Dim x As Long
    
    ' Go to eh label if error
    On Error Goto eh
    
    ' this will ignore the error on the following line
    On Error Resume Next
    x = 1 / 0
    
    ' this will display an error message on the following line
    On Error Goto 0
    x = 1 / 0
  
Done:  
   Exit Sub
eh:
    Debug.Print Err.Description
End Sub

Resume Next

The Resume Next statement is used to clear the error and then resume the code from the line after where the error occurred.

If your code can have multiple errors and you want to keep detecting them then this line is very useful.

For example, in the following code we want to resume the code after the error has been reported:

Private Sub Main()

    On Error Goto eh
    
    Dim i As Long
    For i = 1 To 3
        ' Generate type mismatch error
         Error 13
    Next i

done:
    Exit Sub
eh:
    Debug.Print i, Err.Description
End Sub

 
We could use On Error Goto -1 to clear the code and then use a goto statement to go back to the code like this:

Private Sub Main()

    On Error Goto eh
    
    Dim i As Long
    For i = 1 To 3
        ' Generate type mismatch error
         Error 13
continue:
    Next i

done:
    Exit Sub
eh:
    Debug.Print i, Err.Description
    On Error Goto -1 ' clear the error
    Goto continue ' return to the code
End Sub

 
The Resume Next provides a nicer way of doing it and it always means the code is much clearer and easier to understand:

Private Sub Main()

    On Error Goto eh
    
    Dim i As Long
    For i = 1 To 3
        ' Generate type mismatch error
         Error 13
continue:
    Next i

done:
    Exit Sub
eh:
    Debug.Print i, Err.Description
    ' clear the error and return to the code
    Resume Next  
End Sub

The Err Object

When an error occurs you can view details of the error using the Err object.

When an runtime error occurs, VBA automatically fills the Err object with details.

The code below will print “Error Number: 13 Type Mismatch” which occurs when we try to place a string value in the long integer total

' https://excelmacromastery.com/
Sub UsingErr()

    On Error Goto eh
    
    Dim total As Long
    total = "aa"

Done:
    Exit Sub
eh:
    Debug.Print "Error number: " & Err.Number _
            & " " & Err.Description
End Sub

The Err.Description provides details of the error that occurs. This is the text you normally see when an error occurs e.g. “Type Mismatch”

The Err.Number is the ID number of the error e.g. the error number for “Type Mismatch” is 13. The only time you really need this is if you are checking that a specific error occurred and this is only necessary on rare occasions.

The Err.Source property seems like a great idea but it does not work for a VBA error. The source will return the project name, which hardly narrows down where the error occurred. However, if you create an error using Err.Raise you can set the source yourself and this can be very useful.

Getting the Line Number

The Erl function is used to return the line number where the error occurs.

It often causes confusion. In the following code, Erl will return zero

' https://excelmacromastery.com/
Sub UsingErr()

    On Error Goto eh
    
    Dim val As Long
    val = "aa"

Done:
    Exit Sub
eh:
    Debug.Print Erl
End Sub

This is because there are no line numbers present. Most people don’t realise it but VBA allows you to have line numbers.

If we change the Sub above to have line number it will now print out 20

' https://excelmacromastery.com/
Sub UsingErr()

10        On Error Goto eh
          
          Dim val As Long
20        val = "aa"

Done:
30        Exit Sub
eh:
40        Debug.Print Erl
End Sub

Adding line numbers to your code manually is cumbersome. However there are tools available that will allow you to easily add and remove line numbers to a sub.

When you are finished working on a project and hand it over to the user it can be useful to add line numbers at this point. If you use the error handling strategy in the last section of this post, then VBA will report the line where the error occurred.

Using Err.Raise

Err.Raise allows us to create errors. We can use it to create custom errors for our application which is very useful. It is the equivalent of the Throw statement in JavaC#.

The format is as follows

Err.Raise [error number], [error source], [error description]

Let’s look at a simple example. Imagine we want to ensure that a cell has an entry that has a length of 5 characters. We could have a specific message for this

' https://excelmacromastery.com/
Public Const ERROR_INVALID_DATA As Long = vbObjectError + 513

Sub ReadWorksheet()

    On Error Goto eh
    
    If Len(Sheet1.Range("A1")) <> 5 Then
        Err.Raise ERROR_INVALID_DATA, "ReadWorksheet" _
            , "The value in the cell A1 must have exactly 5 characters."
    End If
    
    ' continue on if cell has valid data
    Dim id As String
    id = Sheet1.Range("A1")
    

Done:
    Exit Sub
eh:
    ' Err.Raise will send code to here
    MsgBox "Error found: " & Err.Description
End Sub

When we create an error using Err.Raise we need to give it a number. We can use any number from 513 to 65535 for our error. We must use vbObjectError with the number e.g.

Err.Raise vbObjectError + 513

Using Err.Clear

Err.Clear is used to clear the text and numbers from the Err.Object. In other words, it clears the description and number.If you want the clear the actual error you can use either On Error GoTo -1 or Resume Next

It is rare that you will need to use Err.Clear but let’s have a look at an example where you might.

In the code below we are counting the number of errors that will occur. To keep it simple we are generating an error for each odd number.

We check the error number each time we go through the loop. If the number does not equal zero then an error has occurred. Once we count the error we need to set the error number back to zero so it is ready to check for the next error.

' https://excelmacromastery.com/
Sub UsingErrClear()

    Dim count As Long, i As Long

    ' Continue if error as we will check the error number
    On Error Resume Next
    
    For i = 0 To 9
        ' generate error for every second one
        If i Mod 2 = 0 Then Error (13)
        
        ' Check for error
        If Err.Number <> 0 Then
            count = count + 1
            Err.Clear    ' Clear Err once it is counted
        End If
    Next

    Debug.Print "The number of errors was: " & count
End Sub

Note 1: Err.Clear resets the text and numbers in the error object but it does not clear the error – see Resume Next Or On Error GoTo -1 for more information about clearing the actual error.

Logging

Logging means writing information from your application when it is running. When an error occurs you can write the details to a text file so you have a record of the error.

The code below shows a very simple logging procedure

' https://excelmacromastery.com/
Sub Logger(sType As String, sSource As String, sDetails As String)
    
    Dim sFilename As String
    sFilename = "C:templogging.txt"
    
    ' Archive file at certain size
    If FileLen(sFilename) > 20000 Then
        FileCopy sFilename _
            , Replace(sFilename, ".txt", Format(Now, "ddmmyyyy hhmmss.txt"))
        Kill sFilename
    End If
    
    ' Open the file to write
    Dim filenumber As Variant
    filenumber = FreeFile 
    Open sFilename For Append As #filenumber
    
    Print #filenumber, CStr(Now) & "," & sType & "," & sSource _
                                & "," & sDetails & "," & Application.UserName
    
    Close #filenumber
    
End Sub

You can use it like this

' Create unique error number
' https://excelmacromastery.com/
Public Const ERROR_DATA_MISSING As Long = vbObjectError + 514

Sub CreateReport()

    On Error Goto eh
    
    If Sheet1.Range("A1") = "" Then
       Err.Raise ERROR_DATA_MISSING, "CreateReport", "Data is missing from Cell A1"
    End If

    ' other code here
Done:
    Exit Sub
eh:
    Logger "Error", Err.Source, Err.Description
End Sub

The log is not only for recording errors. You can record other information as the application runs. When an error occurs you can then check the sequence of events before an error occurred.

Below is an example of logging. How you implement logging really depends on the nature of the application and how useful it will be:

' https://excelmacromastery.com/
Sub ReadingData()
    
    Logger "Information", "ReadingData()", "Starting to read data."
       
    Dim coll As New Collection
    ' add data to the collection
    coll.Add "Apple"
    coll.Add "Pear"
    
    If coll.Count < 3 Then
        Logger "Warning", "ReadingData()", "Number of data items is low."
    End If
    Logger "Information", "ReadingData()", "Number of data items is " & coll.Count
    
    Logger "Information", "ReadingData()", "Finished reading data."

End Sub

Having a lot of information when dealing with an error can be very useful. Often the user may not give you accurate information about the error that occurred. By looking at the log you can get more accurate information about the information.

This section covers some of the other Error Handling tools that VBA has. These items are considered obsolete but I have included them as they may exist in legacy code.

Error Function

The Error Function is used to print the error description from a given error number. It is included in VBA for backward compatibility and is not needed because you can use the Err.Description instead.

Below are some examples:

' Print the text "Division by zero"
Debug.Print Error(11)
' Print the text "Type mismatch"
Debug.Print Error(13)
' Print the text "File not found"
Debug.Print Error(53)

Error Statement

The Error statement allows you to simulate an error. It is included in VBA for backward compatibility. You should use Err.Raise instead.

In the following code we simulate a “Divide by zero” error.

' https://excelmacromastery.com/
Sub SimDivError()

    On Error Goto eh
        
    ' This will create a division by zero error
    Error 11
    
    Exit Sub
eh:
    Debug.Print Err.Number, Err.Description
End Sub

This statement is included in VBA for backward compatibility. You should use Err.Raise instead.

A Simple Error Handling Strategy

With all the different options you may be confused about how to use error handling in VBA. In this section, I’m going to show you how to implement a simple error handling strategy that you can use in all your applications.

The Basic Implementation

This is a simple overview of our strategy

  1. Place the On Error GoTo Label line at the start of our topmost sub.
  2. Place the error handling Label at the end of our topmost sub.
  3. If an expected error occurs then handle it and continue.
  4. If the application cannot continue then use Err.Raise to jump to the error handling label.
  5. If an unexpected error occurs the code will automatically jump to the error handling label.

The following image shows an overview of how this looks

error-handling

The following code shows a simple implementation of this strategy:

' https://excelmacromastery.com/
Public Const ERROR_NO_ACCOUNTS As Long = vbObjectError + 514

Sub BuildReport()

    On Error Goto eh
    
    ' If error in ReadAccounts then jump to error
    ReadAccounts
    
    ' Do something with the code
    
Done:
    Exit Sub
eh:
    ' All errors will jump to here
    MsgBox Err.Source & ": The following error occured  " & Err.Description
End Sub

Sub ReadAccounts()
    
    ' EXPECTED ERROR - Can be handled by the code
    ' Application can handle A1 being zero
    If Sheet1.Range("A1") = 0 Then
        Sheet1.Range("A1") = 1
    End If
    
    ' EXPECTED  ERROR - cannot be handled by the code
    ' Application cannot continue if no accounts workbook
    If Dir("C:DocsAccount.xlsx") = "" Then
        Err.Raise ERROR_NO_ACCOUNTS, "UsingErr" _
                , "There are no accounts present for this month."
    End If

    ' UNEXPECTED ERROR - cannot be handled by the code
    ' If cell B3 contains text we will get a type mismatch error
    Dim total As Long
    total = Sheet1.Range("B3")
    
    
    ' continue on and read accounts
    
End Sub

This is a nice way of implementing error handling because

  • We don’t need to add error handling code to every sub.
  • If an error occurs then VBA exits the application gracefully.

A Complete Error Handling Strategy

The above strategy has one major drawback. It doesn’t provide any information about the error. It is better than having no strategy as it prevents the application crashing. But that is the only real benefit.

VBA doesn’t fill Err.Source with anything useful so we have to do this ourselves.

In this section, I am going to introduce a more complete error strategy. I have written two subs that perform all the heavy lifting so all you have to do is add them to your project.

The purpose of this strategy is to provide you with the Stack* and line number when an error exists.

*The Stack is the list of sub/functions that were currently in use when the error occurred.

This is our strategy

  1. Place error handling in all the subs.
  2. When an error occurs, the error handler adds details to the error and raises it again.
  3. When the error reaches the topmost sub it is displayed.

We are simply “bubbling” the error to the top. The following diagram shows a simple visual of what happens when an error occurs in Sub3

Error Handling - bubbling

The only messy part to this is formatting the strings correctly. I have written two subs that handle this, so it is taken care of for you.

There are the two helper subs, RaiseError and DisplayError. You can download the library below:

An Example of using this strategy

Here is a simple coding example that uses these subs. In this strategy, we don’t place any code in the topmost sub. We only call subs from it.

' https://excelmacromastery.com/
Sub Topmost()

    On Error Goto EH
    
    Level1

Done:
    Exit Sub
EH:
    DisplayError Err.source, Err.Description, "Module1.Topmost", Erl
End Sub

Sub Level1()

    On Error Goto EH
    
    Level2

Done:
    Exit Sub
EH:
   RaiseError Err.Number, Err.source, "Module1.Level1", Err.Description, Erl
End Sub

Sub Level2()

    On Error Goto EH
    
    ' Error here
    Dim a As Long
    a = "7 / 0"

Done:
    Exit Sub
EH:
    RaiseError Err.Number, Err.source, "Module1.Level2", Err.Description, Erl
End Sub

The result looks like this:

error handling output

If your project has line numbers the result will include the line number of the error:

error handling output line

Error Handling in a Nutshell

  • Error Handling is used to handle errors that occur when your application is running.
  • You write specific code to handle expected errors. You use the VBA error handling statement On Error GoTo [label] to send VBA to a label when an unexpected error occurs.
  • You can get details of the error from Err.Description.
  • You can create your own error using Err.Raise.
  • Using one On Error statement in the top most sub will catch all errors in subs that are called from here.
  • If you want to record the name of the Sub with the error, you can update the error and rethrow it.
  • You can use a log to record information about the application as it is running.

What’s Next?

Free VBA Tutorial If you are new to VBA or you want to sharpen your existing VBA skills then why not try out the The Ultimate VBA Tutorial.

Related Training: Get full access to the Excel VBA training webinars and all the tutorials.

(NOTE: Planning to build or manage a VBA Application? Learn how to build 10 Excel VBA applications from scratch.)

Понравилась статья? Поделить с друзьями:
  • Division by 0 error token is
  • Divinity original sin ошибка при запуске
  • Divinity original sin ошибка подключения
  • Divinity original sin код ошибки 504
  • Divinity original sin как изменить характеристики