Номер |
Сообщение |
Описание |
3 |
Return |
Оператор Return без GoSub |
5 |
Invalid |
Неверный вызов процедуры |
6 |
Overflow |
Переполнение |
7 |
Out of |
Недостаточно памяти |
9 |
Subscript |
Индекс вне заданного диапазона |
10 |
This |
Этот массив имеет фиксированную длину или он временно |
11 |
Division |
Деление на ноль |
13 |
Type mismatch |
Несоответствие типа |
14 |
Out of |
Не хватает памяти для строки |
16 |
Expression |
Выражение слишком сложное |
17 |
Can’t |
Невозможно выполнить требуемую операцию |
18 |
User |
Произошло прерывание по команде пользователя |
20 |
Resume |
Оператор Resume применен за пределами кода, отвечающего за |
28 |
Out of |
В стеке не хватает памяти |
35 |
Sub, |
Процедура Sub, Function или Property не определена |
47 |
Too many |
Слишком много приложений обращаются к DLL |
48 |
Error in |
Ошибка при загрузке DLL |
49 |
Bad DLL |
Неверный вызов DLL |
51 |
Internal |
Внутренняя ошибка |
52 |
Bad file |
Неверное имя или номер файла |
53 |
File not |
Файл не найден |
54 |
Bad file |
Неверный тип доступа |
55 |
File |
Файл уже открыт |
57 |
Device |
Ошибка устройства ввода/вывода |
58 |
File |
Файл уже существует |
59 |
Bad |
Неверный размер записи |
61 |
Disk full |
Диск переполнен |
62 |
Input |
Чтение файла невозможно, т.к. достигнут его конец |
63 |
Bad |
Неверный номер записи |
67 |
Too many |
Слишком много файлов |
68 |
Device unavailable |
Устройство недоступно |
70 |
Permission |
Доступ запрещен |
71 |
Disk not |
Диск не готов |
74 |
Can’t |
Нельзя переименовать файл со сменой носителя |
75 |
Path/File |
Ошибка доступа к каталогу/файлу |
76 |
Path not |
Каталог не найден |
91 |
Object |
Переменная объекта или переменная блока With не задана |
92 |
For loop |
Цикл For не инициализирован |
93 |
Invalid |
Неверная маска |
94 |
Invalid |
Неверное использование Null |
97 |
Can’t |
Нельзя вызвать процедуру Friend, т.к. она не является |
98 |
A |
Обращение к свойству или методу не может включать ссылку |
260 |
No timer |
Ни один таймер не доступен |
282 |
No |
Ни одно внешнее приложение не ответило на инициативу DDE |
288 |
Destination |
Адресат занят |
290 |
Data is |
Неправильный формат данных |
294 |
Invalid |
Неверный формат данных в DDE-диалоге |
296 |
PasteLink |
PasteLink для этого элемента управления уже выполнен |
297 |
Can’t set |
Нельзя установить LinkMode; неправильный LinkTopic |
298 |
System |
Системная DLL |
320 |
Can’t use |
Нельзя использовать имя устройства в определении имени |
321 |
Invalid |
Неверный формат файла |
322 |
Can’t |
Не могу создать необходимый временный файл |
325 |
Invalid |
Неверный формат файла ресурсов |
327 |
Data |
Значение не найдено |
328 |
Illegal |
Неверный параметр; не могу записать массив |
335 |
Could not |
Доступ к системному реестру невозможен |
336 |
ActiveX |
Компонент ActiveX зарегистрирован неправильно |
337 |
ActiveX |
Компонент ActiveX не найден |
338 |
ActiveX |
Компонент ActiveX не может быть корректно выполнен |
340 |
Control |
Элемент управления ‘имя’ не найден |
341 |
Invalid |
Неверный индекс массива элементов управления |
342 |
Not |
Недостаточно памяти для создания элемента управления ‘имя’ |
343 |
Object |
Объект не является массивом |
344 |
Must |
Необходимо указать индекс массива |
345 |
Reached |
Достигнута верхняя граница: нельзя создать больше ни |
360 |
Object |
Объект уже загружен |
361 |
Can’t |
Невозможно загрузить или выгрузить данный объект |
363 |
ActiveX |
Элемент управления ActiveX не найден |
364 |
Object |
Объект был выгружен |
365 |
Unable to |
Нет возможности в данном контексте произвести выгрузку |
366 |
No MDI |
Форма, не определенная как MDI, не может быть загружена |
368 |
The |
Данный файл устарел. Эта программа требует более новой |
371 |
The |
Данный объект не может быть использован как родитель формы |
380 |
Invalid |
Неверное значение свойства |
381 |
Invalid |
Неверный индекс массива свойств |
382 |
Property |
Процедура установки свойства (Property Set) не может быть запущена |
383 |
Property |
Процедура установки свойства (Property Set) не может быть |
385 |
Need |
Для массива свойств надо указать индекс |
387 |
Property |
Процедура установки свойства (Property Set) не разрешена |
389 |
Invalid key |
Нажата неверная клавиша |
393 |
Property |
Процедура чтения свойства (Property Get) не поддерживается |
394 |
Property |
Процедура чтения свойства (Property Get) не может быть |
396 |
‘Item’ |
Свойство ‘имя’ нельзя установить для страницы (объект |
400 |
Form |
Форма уже отображена, ее нельзя отобразить как модальную |
401 |
Can’t |
Немодальную форму нельзя отобразить одновременно с модальной |
402 |
Must |
Сначала необходимо закрыть верхнюю модальную форму |
403 |
HDI forms |
MDI-формы не могут быть отображены как модальные |
404 |
MDI child |
Дочерние MDI-формы не могут быть отображены модальными |
419 |
Permission |
Использование объекта запрещено |
422 |
Property |
Свойство не найдено |
423 |
Property |
Свойство или метод не найдены |
424 |
Object required |
Необходим объект |
425 |
Invalid |
Неверное использование объекта |
427 |
Invalid |
Неверный тип объекта; требуется элемент управления типа |
429 |
ActiveX |
Компонент ActiveX |
430 |
Class |
Класс не поддерживает программирование объектов |
432 |
File name |
Имя файла или класса не найдено в процессе операции |
438 |
Object |
Объект не поддерживает данное свойство или метод |
440 |
Automation error |
Ошибка программирования объектов (Automation) |
442 |
Connection |
Связь с библиотекой типов или объектов для удаленного |
443 |
Automation |
Объект Automation |
444 |
Method not applicable in this context |
Метод в этом контексте недоступен |
445 |
Object doesn’t support this action |
Объект не поддерживает эту команду |
446 |
Object |
Объект не поддерживает указанные аргументы |
447 |
Object doesn’t support current locale setting |
Объект не поддерживает текущие национальные стандарты |
448 |
Name argument not found |
Именованный аргумент не найден |
449 |
Argument |
Аргумент обязателен или неверное |
450 |
Wrong |
Неправильное количество аргументов |
451 |
Object not a collection |
Объект не является коллекцией |
452 |
Invalid ordinal |
Неверный порядковый номер |
453 |
Specified DLL function not found |
Указанная функция DLL не найдена |
454 |
Code |
Код ресурса не найден |
457 |
This key |
Этот ключ уже ассоциирован с элементом этой коллекции |
458 |
Variable |
Переменная использует тип, не поддерживаемый Visual Basic |
459 |
This |
Этот компонент не поддерживает установку событий |
460 |
Invalid Clipboard format |
Неверный формат Буфера обмена |
461 |
Specified |
Данный формат не совпадает с форматом данных |
462 |
The |
Удаленная машина сервера не существует или недоступна |
463 |
Class not |
Класс не зарегистрирован на локальной машине |
480 |
Can’t create AutoRedraw image |
Нельзя создать автоматически восстанавливаемое изображение |
481 |
Invalid picture |
Неверный рисунок |
482 |
Printer error |
Ошибка принтера |
483 |
Printer driver does not support specified property |
Драйвер принтера не поддерживает указанное свойство |
484 |
Problem |
Проблема при чтении информации принтером из системы. |
485 |
Invalid |
Неверный тип рисунка |
486 |
Can’t |
Нельзя распечатать изображение формы на принтере такого |
520 |
Can’t empty Clipboard |
Нельзя очистить буфер обмена |
521 |
Can’t open Clipboard |
Нельзя открыть буфер обмена |
735 |
Can’t save file to TEMP directory |
Нельзя сохранить файл в каталоге TEMP |
744 |
Search text not found |
Исходный текст не найден |
746 |
Replacements too long |
Слишком длинная замена |
Номер |
Сообщение |
Описание |
2420 |
Syntax error in number |
Число содержит синтаксическую ошибку |
2421 |
Syntax error in date |
Дата содержит синтаксическую ошибку |
2422 |
Syntax error in string |
Строка содержит синтаксическую ошибку |
2423 |
Invalid use of ‘.’, ‘!’ or ‘( )’ |
Неверное использование ‘.’, ‘!’ или ‘( )’ |
2424 |
Unknown name |
Неизвестное имя |
2425 |
Unknown function name |
Неизвестное имя функции |
2427 |
Object has no value |
Объект не имеет значения |
2428 |
Invalid arguments used with domain function |
Неверные аргументы статистической функции по подмножеству |
2431 |
Syntax error(missing operator) |
Синтаксическая ошибка (отсутствует оператор) |
2433 |
Syntax error |
Синтаксическая ошибка |
2439 |
Wrong number of arguments used with function |
Неверное число аргументов функции |
2442 |
Invalid use of parentheses |
Неверное использование скобок |
2443 |
Invalid use of Is operator |
Неверное использование оператора Is |
2445 |
Expression too complex |
Слишком сложное выражение |
2446 |
Out of memory during calculation |
Недостаточно памяти при вычислениях |
2448 |
Can’t set value |
Не удается задать значение |
3001 |
Invalid argument |
Ошибочный аргумент |
3005 |
<Database name> isn’t a valid database name |
Имя базы данных не является допустимым именем базы данных |
3006 |
Database <name> is exclusively locked |
Для базы данных <name> установлен монопольный доступ |
3007 |
Can’t open library database <name> |
Не удается открыть библиотечную базу данных <name> |
3011 |
The Microsoft Jet database engine could not find the |
Объект <name> не найден ядром базы данных Microsoft |
3012 |
Object <name> already exists |
Объект <name> уже существует |
3017 |
The size of a field is too long |
Слишком большая длина поля |
3021 |
No current record |
Текущая запись отсутствует |
3024 |
Couldn’t find file <name> |
Не удается найти файл <name> |
3025 |
Can’t open any moor |
Открытие дополнительных файлов невозможно |
3027 |
Can’t update. Database or object is read-only |
Обновление невозможно. База данных или объект доступны |
3036 |
Database has reached maximum size |
Достигнут максимальный размер базы данных |
3037 |
Can’t open any more tables or queries |
Открытие дополнительных таблиц или запросов невозможно |
3042 |
Out of MS-DOS file handles |
Не хватает дескрипторов файлов MS-DOS |
3043 |
Disk or network error |
Дисковая или сетевая ошибка |
3046 |
Couldn’t save; currently locked by another user |
Сохранение невозможно; блокировка другим пользователем |
3056 |
Couldn’t repair this database |
Не удается восстановить эту базу данных |
3107 |
Record(s) can’t be added; no insert permission or |
Записи не могут быть добавлены; отсутствует разрешение на |
3108 |
Record(s) can’t be edited; no update permission or |
Записи не могут быть изменены; отсутствует разрешение на |
3109 |
Record(s) can’t be deleted; no delete permission or |
Записи не могут быть удалены; отсутствует разрешение на |
3111 |
Couldn’t create; no modify design permission for table or |
Создание невозможно; отсутствует разрешение на изменение |
3117 |
Can’t sort on Memo or OLE Object <clause> |
Невозможна сортировка по полю Memo или объекта ActiveX в |
3116 |
Can’t join on Memo or OLE Object <name> |
Невозможно объединение с полем Memo или объекта ActiveX |
3146 |
ODBC – call failed |
ODBC – ошибка вызова |
3154 |
ODBC – couldn’t find DLL <name> |
ODBC – не удается найти DLL <name> |
3197 |
The Microsoft Jet database engine stopped the process |
Процесс остановлен ядром базы данных Microsoft Jet, так |
3230 |
Out-of-date Paradox lock file |
Устаревший файл блокировок Paradox |
3231 |
ODBC – field would be too long; data truncated |
ODBC – слишком большое поле; произошло усечение данных |
3232 |
ODBC – couldn’t create table |
ODBC – создание таблицы невозможно |
3235 |
ODBC – data type not supported on server |
ODBC – тип данных не поддерживается сервером |
3238 |
ODBC – data out of range |
ODBC – данные выходят за пределы допустимого диапазона |
3276 |
Invalid database object reference |
Неверная ссылка на объект Database |
3322 |
Crosstab query contains one or more invalid fixed column |
Перекрестный запрос содержит один или несколько неверных |
3342 |
Invalid Memo or OLE Object in sub-query<name> |
Ошибочное поле Memo или поле объекта ActiveX в подчиненном |
3360 |
Query is too complex |
Слишком сложный запрос |
3409 |
Invalid field name<name> in definition of index or |
Неверное имя поля <name> при определении индекса или |
3411 |
Invalid entry. Can’t perform cascading operation in |
Ошибочное значение. Невозможно выполнить каскадную |
3423 |
You cannot use ODBC to import from, export to, or link an |
Не допускается использование ODBC для импорта, экспорта |
3424 |
Can’t create database because the locale is invalid |
Создание базы данных невозможно; неверная национальная |
3436 |
Failure creating file |
Ошибка при создании, файла |
3462 |
Failure to load DLL |
Сбой при загрузке библиотеки |
3506 |
The Synchronizer is unable to open the Synchronizer log |
Синхронизатору не удается открыть журнал |
3507 |
Failure writing to the Synchronizer log |
Сбой при записи в журнал синхронизатора |
3517 |
Synchronizer could not find any messages to process |
Синхронизатор не может найти сообщение для обработки |
3519 |
Failed to send a message |
Сбой при отправке сообщения |
3558 |
Disk I/O error at destination dropbox folder |
Ошибка ввода/вывода на диске для результирующего банка |
3581 |
Can’t open replication system table <name> because |
Невозможно открыть системную таблицу репликации |
3584 |
Insufficient memory to complete operation |
Не хватает памяти для завершения операции |
3586 |
Syntax |
Ошибка синтаксиса в выражении фильтра для таблицы |
3613 |
Can’t |
Не допускается создание связи между присоединенными |
3614 |
GUID not allowed in Find method criteria expression |
Не допускается использование типа GUID в выражениях для |
3621 |
Can’t change password on a shared open database |
Невозможно изменение пароля базы данных, открытой для |
3624 |
Couldn’t read the record; currently locked by another user |
Чтение невозможно. Блокировка другим сеансом на данной |
3637 |
Cannot use the crosstab of as a non-fixed column a |
Нельзя использовать составной или нефиксированный столбец |
Contains a searchable list of common (core) VBA error codes used by the intrinsic Err object, as well as a separate list of all other errors.
When an error is generated in your application—whether it’s handled or not—the properties of the Err object are assigned values with information about the error that just occurred. You can access this information, or generate your own errors explicitly using the Err.Raise method.
Err.Raise Number, [Source], [Description], [HelpFile], [HelpContext]
This, of course, requires knowledge of the error codes understood by the Err object. These are listed in searchable tables below (with hyperlinks to associated MSDN pages where available) . Error codes and descriptions were obtained from the following sources:
- Core Visual Basic Language Errors
- Miscellaneous Visual Basic Errors
- ActiveX Control Errors
You can also define your own errors to unify the error-handling process. For example, see the article: Organizing Unstructured Errors in VBA.
Add the vbObjectError
constant to custom error codes to guaranteed that the resulting number is not already in use.
Common VBA Error Codes
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 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]
“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.)
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 Errors
There are three types of errors in VBA:
- Syntax
- Compilation
- 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
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.
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.
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
- Expected errors – write specific code to handle them.
- 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
- On Error GoTo 0 – the code stops at the line with the error and displays a message.
- On Error Resume Next – the code moves to next line. No error message is displayed.
- 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.
- 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
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
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 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
- Place the On Error GoTo Label line at the start of our topmost sub.
- Place the error handling Label at the end of our topmost sub.
- If an expected error occurs then handle it and continue.
- If the application cannot continue then use Err.Raise to jump to the error handling label.
- 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
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
- Place error handling in all the subs.
- When an error occurs, the error handler adds details to the error and raises it again.
- 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
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:
If your project has line numbers the result will include the line number of the error:
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.)