Vba excel коды ошибок

Номер

Сообщение

Описание

3

Return
without GoSub

Оператор Return без GoSub

5

Invalid
procedure call

Неверный вызов процедуры

6

Overflow

Переполнение

7

Out of
memory

Недостаточно памяти

9

Subscript
out of range

Индекс вне заданного диапазона

10

This
array is fixed or temporarily locked

Этот массив имеет фиксированную длину или он временно
заблокирован

11

Division
by zero

Деление на ноль

13

Type mismatch

Несоответствие типа

14

Out of
string space

Не хватает памяти для строки

16

Expression
too complex

Выражение слишком сложное

17

Can’t
perform requested operation

Невозможно выполнить требуемую операцию

18

User
interrupt occurred

Произошло прерывание по команде пользователя

20

Resume
without error

Оператор Resume применен за пределами кода, отвечающего за
обработку ошибки

28

Out of
stack space

В стеке не хватает памяти

35

Sub,
Function or Property not defined

Процедура Sub, Function или Property не определена

47

Too many
DLL application clients

Слишком много приложений обращаются к DLL

48

Error in
loading DLL

Ошибка при загрузке DLL

49

Bad DLL
calling convention

Неверный вызов DLL

51

Internal
error

Внутренняя ошибка

52

Bad file
name or number

Неверное имя или номер файла

53

File not
found

Файл не найден

54

Bad file
mode

Неверный тип доступа

55

File
already open

Файл уже открыт

57

Device
I/O error

Ошибка устройства ввода/вывода

58

File
already exists

Файл уже существует

59

Bad
record length

Неверный размер записи

61

Disk full

Диск переполнен

62

Input
past end of file

Чтение файла невозможно, т.к. достигнут его конец

63

Bad
record number

Неверный номер записи

67

Too many
files

Слишком много файлов

68

Device unavailable

Устройство недоступно

70

Permission
denied

Доступ запрещен

71

Disk not
ready

Диск не готов

74

Can’t
rename with different drive

Нельзя переименовать файл со сменой носителя

75

Path/File
access error

Ошибка доступа к каталогу/файлу

76

Path not
found

Каталог не найден

91

Object
variable or With block variable not set

Переменная объекта или переменная блока With не задана

92

For loop
not initialized

Цикл For не инициализирован

93

Invalid
pattern string

Неверная маска

94

Invalid
use or Null

Неверное использование Null

97

Can’t
call Friend procedure on an object that is not an instance of the defining
class

Нельзя вызвать процедуру Friend, т.к. она не является
экземпляром класса

98

A
property or method call cannot include a reference to a private object,
either as an argument or as a return value

Обращение к свойству или методу не может включать ссылку
на локальный объект. Этот объект также не может быть аргументом или
возвращаемым значением

260

No timer
available

Ни один таймер не доступен

282

No
foreign application responded to a DDE initiate

Ни одно внешнее приложение не ответило на инициативу DDE

288

Destination
is busy

Адресат занят

290

Data is
wrong format

Неправильный формат данных

294

Invalid
DDE Link format

Неверный формат данных в DDE-диалоге

296

PasteLink
already performed on this control

PasteLink для этого элемента управления уже выполнен

297

Can’t set
LinkMode; invalid LinkTopic

Нельзя установить LinkMode; неправильный LinkTopic

298

System
DLL could not be loaded

Системная DLL
(библиотека) не может быть загружена

320

Can’t use
character device names in specified file names

Нельзя использовать имя устройства в определении имени
файла

321

Invalid
file format

Неверный формат файла

322

Can’t
create necessary temporary file

Не могу создать необходимый временный файл

325

Invalid
format in resource file

Неверный формат файла ресурсов

327

Data
value named not found

Значение не найдено

328

Illegal
parameter; can’t write arrays

Неверный параметр; не могу записать массив

335

Could not
access system registry

Доступ к системному реестру невозможен

336

ActiveX
component not correctly registered

Компонент ActiveX зарегистрирован неправильно

337

ActiveX
component not found

Компонент ActiveX не найден

338

ActiveX
component did not run correctly

Компонент ActiveX не может быть корректно выполнен

340

Control
array element ‘item’ doesn’t exist

Элемент управления ‘имя’ не найден

341

Invalid
control array index

Неверный индекс массива элементов управления

342

Not
enough room to allocate control array ‘item’

Недостаточно памяти для создания элемента управления ‘имя’

343

Object
not an array

Объект не является массивом

344

Must
specify index for object array

Необходимо указать индекс массива

345

Reached
limit: cannot create any more controls on this form

Достигнута верхняя граница: нельзя создать больше ни
одного элемента управления в этой форме

360

Object
already loaded

Объект уже загружен

361

Can’t
load or unload this object

Невозможно загрузить или выгрузить данный объект

363

ActiveX
control specified not found

Элемент управления ActiveX не найден

364

Object
was unload

Объект был выгружен

365

Unable to
unload within this context

Нет возможности в данном контексте произвести выгрузку

366

No MDI
form available to load

Форма, не определенная как MDI, не может быть загружена

368

The
specified file is out of date. This program requires a later version

Данный файл устарел. Эта программа требует более новой
версии

371

The
specified object can’t be used as an owner form for Show

Данный объект не может быть использован как родитель формы
для ее показа

380

Invalid
property value

Неверное значение свойства

381

Invalid
property-array index

Неверный индекс массива свойств

382

Property
Set can’t be executed at run time

Процедура установки свойства (Property Set) не может быть запущена
во время выполнения программы

383

Property
Set can’t be used with
а read-only property

Процедура установки свойства (Property Set) не может быть
использована для свойств, доступных только для чтения

385

Need
property-array index

Для массива свойств надо указать индекс

387

Property
Set not permitted

Процедура установки свойства (Property Set) не разрешена

389

Invalid key

Нажата неверная клавиша

393

Property
Get can’t be executed at run time

Процедура чтения свойства (Property Get) не поддерживается
во время выполнения программы

394

Property
Get can’t be executed on write-only property

Процедура чтения свойства (Property Get) не может быть
использована для свойств, доступных только для записи

396

‘Item’
property cannot be set within a page

Свойство ‘имя’ нельзя установить для страницы (объект
Printer)

400

Form
already displayed; can’t show modally

Форма уже отображена, ее нельзя отобразить как модальную

401

Can’t
show non-modal form when modal form is displayed

Немодальную форму нельзя отобразить одновременно с модальной

402

Must
close or hide topmost modal form first

Сначала необходимо закрыть верхнюю модальную форму

403

HDI forms
cannot be shown modally

MDI-формы не могут быть отображены как модальные

404

MDI child
forms cannot be shown modally

Дочерние MDI-формы не могут быть отображены модальными

419

Permission
to use object denied

Использование объекта запрещено

422

Property
not found

Свойство не найдено

423

Property
or method not found

Свойство или метод не найдены

424

Object required

Необходим объект

425

Invalid
object use

Неверное использование объекта

427

Invalid
object type; Menu control required

Неверный тип объекта; требуется элемент управления типа
Menu

429

ActiveX
component can’t create object or return reference to this object

Компонент ActiveX
не может создать объект или возвратить ссылку на этот объект

430

Class
doesn’t support Automation

Класс не поддерживает программирование объектов
(Automation)

432

File name
or class name not found during Automation operation

Имя файла или класса не найдено в процессе операции
программирования объектов (Automation)

438

Object
doesn’t support this property or method

Объект не поддерживает данное свойство или метод

440

Automation error

Ошибка программирования объектов (Automation)

442

Connection
to type library or object library for remote process has been lost

Связь с библиотекой типов или объектов для удаленного
процесса была утеряна

443

Automation
object doesn’t have a default value

Объект Automation
не имеет значения по умолчанию

444

Method not applicable in this context

Метод в этом контексте недоступен

445

Object doesn’t support this action

Объект не поддерживает эту команду

446

Object
doesn’t support named arguments

Объект не поддерживает указанные аргументы

447

Object doesn’t support current locale setting

Объект не поддерживает текущие национальные стандарты

448

Name argument not found

Именованный аргумент не найден

449

Argument
not optional or invalid property assignment

Аргумент обязателен или неверное
назначение свойства

450

Wrong
number of arguments

Неправильное количество аргументов

451

Object not a collection

Объект не является коллекцией

452

Invalid ordinal

Неверный порядковый номер

453

Specified DLL function not found

Указанная функция DLL не найдена

454

Code
resource not found

Код ресурса не найден

457

This key
is already associated with an element of this collection

Этот ключ уже ассоциирован с элементом этой коллекции

458

Variable
uses a type not supported in Visual Basic

Переменная использует тип, не поддерживаемый Visual Basic

459

This
component doesn’t support the set of events

Этот компонент не поддерживает установку событий

460

Invalid Clipboard format

Неверный формат Буфера обмена

461

Specified
format doesn’t match format of data

Данный формат не совпадает с форматом данных

462

The
remote server machine does not exist or is unavailable

Удаленная машина сервера не существует или недоступна

463

Class not
registered on local machine

Класс не зарегистрирован на локальной машине

480

Can’t create AutoRedraw image

Нельзя создать автоматически восстанавливаемое изображение

481

Invalid picture

Неверный рисунок

482

Printer error

Ошибка принтера

483

Printer driver does not support specified property

Драйвер принтера не поддерживает указанное свойство

484

Problem
getting printer information from the system. Make sure the printer is set up
correctly

Проблема при чтении информации принтером из системы.
Убедитесь, что принтер установлен правильно

485

Invalid
picture type

Неверный тип рисунка

486

Can’t
print form image to this type of printer

Нельзя распечатать изображение формы на принтере такого
типа

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
object <name>. Make sure the object exists and that you spell its name
and the path name correctly

Объект <name> не найден ядром базы данных Microsoft
Jet. Проверьте существование объекта и правильность имени и пути

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
<name>

Записи не могут быть добавлены; отсутствует разрешение на
вставку данных для объекта <name>

3108

Record(s) can’t be edited; no update permission or
<name>

Записи не могут быть изменены; отсутствует разрешение на
обновление данных для объекта <name>

3109

Record(s) can’t be deleted; no delete permission or
<name>

Записи не могут быть удалены; отсутствует разрешение на
удаление данных для объекта <name>

3111

Couldn’t create; no modify design permission for table or
query <name>

Создание невозможно; отсутствует разрешение на изменение
макета для таблицы или запроса <name>

3117

Can’t sort on Memo or OLE Object <clause>

Невозможна сортировка по полю Memo или объекта ActiveX в
<clause>

3116

Can’t join on Memo or OLE Object <name>

Невозможно объединение с полем Memo или объекта ActiveX
<name>

3146

ODBC – call failed

ODBC – ошибка вызова

3154

ODBC – couldn’t find DLL <name>

ODBC – не удается найти DLL <name>

3197

The Microsoft Jet database engine stopped the process
because you and another user are attempting to change the same data at the
same time

Процесс остановлен ядром базы данных 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
headings

Перекрестный запрос содержит один или несколько неверных
заголовков столбцов

3342

Invalid Memo or OLE Object in sub-query<name>

Ошибочное поле Memo или поле объекта ActiveX в подчиненном
запросе <name>

3360

Query is too complex

Слишком сложный запрос

3409

Invalid field name<name> in definition of index or
relationship

Неверное имя поля <name> при определении индекса или
связи

3411

Invalid entry. Can’t perform cascading operation in
table<name> because the value entered is too large for field
<name>

Ошибочное значение. Невозможно выполнить каскадную
операцию в таблице <name>; значение велико для поля <name>

3423

You cannot use ODBC to import from, export to, or link an
external Microsoft Jet or ISAM database table to your database

Не допускается использование ODBC для импорта, экспорта
или присоединения таблицы из внешней базы данных Microsoft Jet или базы
данных ISAM

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
the table is already in use

Невозможно открыть системную таблицу репликации
<name>, так как она уже используется

3584

Insufficient memory to complete operation

Не хватает памяти для завершения операции

3586

Syntax
error in partial filter expression

Ошибка синтаксиса в выражении фильтра для таблицы
<name> в частичной реплике

3613

Can’t
create a relationship on linked ODBC tables

Не допускается создание связи между присоединенными
таблицами ODBC

3614

GUID not allowed in Find method criteria expression

Не допускается использование типа GUID в выражениях для
условия поиска в методах Find

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
subquery

Нельзя использовать составной или нефиксированный столбец
в качестве вторичного запроса

На чтение 25 мин. Просмотров 17.7k.

VBA Error Handling

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

Если вы ищете конкретную тему по обработке ошибок VBA, ознакомьтесь с приведенным ниже содержанием.

Если вы новичок в VBA, то вы можете прочитать пост от начала до конца, так как он выложен в логическом порядке.

Содержание

  1. Краткое руководство по обработке ошибок
  2. Введение
  3. Ошибки VBA
  4. Заявление об ошибке
  5. Err объект
  6. Логирование
  7. Другие элементы, связанные с ошибками
  8. Простая стратегия обработки ошибок
  9. Полная стратегия обработки ошибок
  10. Обработка ошибок в двух словах

Краткое руководство по обработке ошибок

Пункт Описание
On Error Goto 0 При возникновении ошибки код останавливается и отображает
ошибку.
On Error Resume Next Игнорирует ошибку и
продолжает.
On Error Goto [Label] Переход к определенной метке при возникновении ошибки.
Это позволяет нам справиться
с ошибкой.
Err Object При возникновении ошибки
информация об ошибке
сохраняется здесь.
Err.Number Номер ошибки.
(Полезно, только если вам
нужно проверить, произошла ли конкретная ошибка.)
Err.Description Содержит текст ошибки.
Err.Source Вы можете заполнить это, когда используете Err.Raise.
Err.Raise Функция, которая позволяет
генерировать вашу собственную ошибку.
Error Function Возвращает текст ошибки из
номера ошибки.
Вышло из употребления.
Error Statement Имитирует ошибку. Вместо этого используйте Err.Raise.

Введение

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

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

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

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

VBA Error Handling

Ошибки VBA

В VBA есть три типа ошибок

  1. Синтаксис
  2. Компиляция
  3. Время выполнения

Мы используем обработку ошибок для устранения ошибок во
время выполнения. Давайте посмотрим на каждый из этих типов ошибок, чтобы было
ясно, что такое ошибка во время выполнения.

Синтаксические ошибки

Если вы использовали VBA в течение какого-то времени, вы
увидите синтаксическую ошибку. Когда вы набираете строку и нажимаете return,
VBA оценивает синтаксис и, если он неверен, выдает сообщение об ошибке.

Например, если вы введете If и забудете ключевое слово Then,
VBA отобразит следующее сообщение об ошибке.

VBA Error Handling

Некоторые примеры синтаксических ошибок

' then отсутствует
If a > b

' не хватает = после i
For i 2 To 7

' отсутствует правая скобка
b = left("АБВГ",1

Синтаксические ошибки относятся только к одной строке. Они
возникают, когда синтаксис одной строки неверен.

Примечание. Диалоговое окно «Ошибка синтаксиса» можно отключить, выбрав «Сервис» -> «Параметры» и отметив «Автосинтаксическая проверка». Строка по-прежнему будет отображаться красным цветом в случае ошибки, но диалоговое окно не появится.

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

Ошибки компиляции происходят более чем в одной строке.
Синтаксис в одной строке правильный, но неверный, если учесть весь код проекта.

Примеры ошибок компиляции:

  • Оператор If без соответствующего оператора End If
  • For без Next
  •  Select без End Select
  • Вызов Sub или Function, которые не существуют
  • Вызов Sub или Function с неверными параметрами
  • Присвоение Sub или Function того же имени, что и для модуля
  • Переменные не объявлены (Option Explicit должен присутствовать в верхней части модуля)

На следующем снимке экрана показана ошибка компиляции,
которая возникает, когда цикл For не имеет соответствующего оператора Next.

VBA Error Handling

Использование Debug-> Compile

Чтобы найти ошибки компиляции, мы используем Debug->
Compile VBA Project из меню Visual Basic.

Когда вы выбираете Debug-> Compile, VBA отображает первую
обнаруженную ошибку.

Когда эта ошибка исправлена, вы можете снова запустить
Compile, и VBA найдет следующую ошибку.

Debug-> Compile также будет включать синтаксические
ошибки в поиск, что очень полезно.

Если ошибок не осталось и вы запускаете Debug-> Compile,
может показаться, что ничего не произошло. Однако «Компиляция» будет недоступна
в меню «Отладка». Это означает, что ваше приложение не имеет ошибок компиляции
в текущий момент.

Debug->Compile Error Summary

Debug-> Compile находит ошибки компиляции (проекта).

Он также найдет синтаксические ошибки.

Он находит одну ошибку каждый раз, когда вы ее используете.

Если нет ошибок компиляции, оставленная опция Компиляция
будет отображаться серым цветом в меню.

Debug-> Compile Usage

Вы должны всегда использовать Debug-> Compile, прежде чем
запускать свой код. Это гарантирует, что ваш код не будет иметь ошибок
компиляции при запуске.

Если вы не запускаете Debug-> Compile, то VBA может
обнаружить ошибки компиляции при запуске. Их не следует путать с ошибками
времени выполнения.

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

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

VBA Error Handling

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

Другие примеры ошибок времени выполнения

  • база данных недоступна
  • пользователь вводит неверные данные
  • ячейка, содержащая текст вместо числа

Как мы уже видели, целью обработки ошибок является обработка
ошибок времени выполнения, когда они возникают.

Ожидаемые и неожиданные ошибки

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

Следующий код проверяет, существует ли файл, прежде чем он
пытается его открыть. Если файл не существует, отображается сообщение, удобное
для пользователя, и код выходит из подпрограммы.

Sub OtkritFail()
    
    Dim sFile As String
    sFile = "C:\Документы\Отчет.xlsx"
    
    ' Используйте Dir, чтобы проверить, существует ли файл
    If Dir(sFile) = "" Then
        ' если файл не существует, отобразить сообщение
        MsgBox "Файл не найден" & sFile
        Exit Sub
    End If
    
    ' Код достигнет только если файл существует
    Workbooks.Open sFile
    
End Sub

Когда мы думаем, что в какой-то момент может произойти
ошибка, рекомендуется добавить код для обработки ситуации. Мы обычно называем
эти ошибки ожидаемыми.

Если у нас нет специального кода для обработки ошибки, это
считается неожиданной ошибкой. Мы используем операторы обработки ошибок VBA для
обработки непредвиденных ошибок.

Ошибки времени выполнения, которые не являются ошибками VBA

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

Позвольте мне объяснить это на примере. Представьте, что у
вас есть приложение, которое требует, чтобы вы добавили значения в переменные a
и b

Допустим, вы по ошибке используете звездочку вместо знака
плюс

Это не ошибка VBA. Ваш синтаксис кода является совершенно
законным. Однако, с вашей точки зрения, это ошибка.

Эти ошибки не могут быть обработаны с помощью обработки ошибок, поскольку они, очевидно, не будут генерировать никаких ошибок. Вы можете справиться с этими ошибками, используя Unit Testing and Assertions.

Заявление об ошибке

Как мы видели, есть два способа обработки ошибок во время
выполнения

  1. Ожидаемые ошибки — напишите конкретный код для
    их обработки.
  2. Неожиданные ошибки — используйте операторы
    обработки ошибок VBA для их обработки.

Оператор VBA On Error используется для обработки ошибок.
Этот оператор выполняет некоторые действия при возникновении ошибки во время
выполнения.

Есть четыре различных способа использовать это утверждение

  1. On Error Goto 0 — код останавливается на строке с ошибкой и отображает сообщение.
  2. On Error Resume Next — код перемещается на следующую строку. Сообщение об ошибке не отображается.
  3. On Error Goto [label] — код перемещается на определенную строку или метку. Сообщение об ошибке не отображается. Это тот, который мы используем для обработки ошибок.
  4. On Error Goto -1 — очищает текущую ошибку.

Давайте посмотрим на каждое из этих утверждений по очереди.

On Error Goto 0

Это поведение по умолчанию VBA. Другими словами, если вы не
используете On Error, это поведение вы увидите.

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

Давайте посмотрим на пример. В следующем коде мы не
использовали строку On Error, поэтому VBA будет использовать поведение On Error
Goto 0 по умолчанию.

Sub IspDefault()

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

End Sub

Вторая строка присваивания приводит к ошибке деления на ноль. Когда мы запустим этот код, мы получим сообщение об ошибке, показанное на скриншоте ниже.

VBA Error Handling

Когда появляется ошибка, вы можете выбрать End или Debug

Если вы выберете Конец, то приложение просто остановится.

Если вы выберете Отладить, приложение остановится на строке
ошибки, как показано на скриншоте ниже.

VBA Error Handling

Это нормально, когда вы пишете код VBA, поскольку он
показывает вам точную строку с ошибкой.

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

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

Используя On Error Goto [label], мы можем дать пользователю
более контролируемое сообщение об ошибке. Это также предотвращает остановку
приложения. Мы можем заставить приложение работать предопределенным образом.

On Error Resume Next

Использование On Error Resume Next указывает VBA
игнорировать ошибку и продолжать работу.

Есть конкретные случаи, когда это полезно. Большую часть
времени вы должны избегать его использования.

Если мы добавим Resume Next к нашему примеру Sub, то VBA
проигнорирует ошибку деления на ноль

Sub UsingResumeNext()

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

End Sub

Это не очень хорошая идея, чтобы сделать это. Если вы
игнорируете ошибку, то поведение может быть непредсказуемым. Ошибка может
повлиять на приложение несколькими способами. Вы можете получить неверные
данные. Проблема в том, что вы не знаете, что что-то пошло не так, потому что
вы подавили ошибку.

Приведенный ниже код является примером использования Resume
Next.

Sub OtprSoobsch()

   On Error Resume Next
   
    ' Требуется ссылка:
    ' Библиотека объектов Microsoft Outlook 15.0
    Dim Outlook As Outlook.Application
    Set Outlook = New Outlook.Application

    If Outlook Is Nothing Then
        MsgBox " Не удается создать сеанс Microsoft Outlook." _
                   & " Письмо не будет отправлено."
        Exit Sub
    End If
    
End Sub

В этом коде мы проверяем, доступен ли Microsoft Outlook на компьютере. Все,
что мы хотим знать — это доступно или нет. Нас не интересует конкретная ошибка.

В приведенном выше коде мы продолжаем, если есть ошибка.
Затем в следующей строке мы проверяем значение переменной Outlook. Если произошла ошибка, тогда
значение этой переменной будет установлено равным Nothing.

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

On Error Goto [label]

Вот как мы используем обработку ошибок в VBA. Это эквивалент функциональности Try and Catch, которую вы видите на
таких языках, как C # и
Java.

При возникновении ошибки вы отправляете ошибку на
определенный ярлык. Обычно это внизу саба.

Давайте применим это к подводной лодке, которую мы
использовали

Sub IspGotoLine()

    On Error Goto eh
    
    Dim x As Long, y As Long
    
    x = 6
    y = 6 / 0
    x = 7
    
Done:
    Exit Sub
eh:
    MsgBox "Произошла следующая ошибка: " & Err.Description
End Sub

Снимок экрана ниже показывает, что происходит при возникновении ошибки.

VBA Error Handling

VBA переходит на метку eh, потому что мы указали это в
строке «Перейти к ошибке».

Примечание 1: Метка, которую мы используем в операторе On… Goto, должна быть в текущей Sub / Function. Если нет, вы получите ошибку компиляции.

Примечание 2: Когда возникает ошибка при использовании On Error Goto [label], обработка ошибок возвращается к поведению по умолчанию, т.е. код остановится на строке с ошибкой и отобразит сообщение об ошибке. См. Следующий раздел для получения дополнительной информации об этом.

On Error Goto -1

Это утверждение отличается от других трех. Он используется
для очистки текущей ошибки, а не для настройки конкретного поведения.

При возникновении ошибки с помощью функции On Error Goto [label] поведение обработки ошибки возвращается к поведению по умолчанию, т.е. On Error Goto 0 . Это означает, что если произойдет другая ошибка, код остановится на текущей строке.

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

Посмотрите на код ниже. Первая ошибка приведет к переходу
кода на метку eh. Вторая ошибка остановится на строке с ошибкой 1034.

Sub DveOshibki()

    On Error Goto eh
        
    ' генерировать ошибку «Несоответствие типов»
    Error (13)

Done:
    Exit Sub
eh:
    ' генерировать «определенную приложением» ошибку
    Error (1034)
End Sub

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

В коде ниже мы добавили строку

после того как мы поймаем первую ошибку.

Это не имеет никакого эффекта, так как ошибка не была
очищена. Другими словами, код остановится на строке с ошибкой и отобразит
сообщение.

Sub DveOshibki()

    On Error Goto eh
        
    ' генерировать ошибку «Несоответствие типов»
    Error (13)

Done:
    Exit Sub
eh:
    On Error Goto eh_other
    ' генерировать «определенную приложением» ошибку
    Error (1034)
Exit Sub
eh_other:
    Debug.Print "ehother " & Err.Description
End Sub

Для устранения ошибки мы используем On Error Goto -1.
Думайте об этом как об установке ловушки для мыши. Когда ловушка сработает, вам
нужно установить ее снова.

В приведенном ниже коде мы добавляем эту строку, и вторая
ошибка теперь приведет к переходу кода на метку eh_other.

Sub DveOshibki()

    On Error Goto eh
        
    ' генерировать ошибку «Несоответствие типов»
    Error (13)

Done:
    Exit Sub
eh:
    ' явная ошибка
    On Error Goto -1
    
    On Error Goto eh_other
    ' генерировать «определенную приложением» ошибку
    Error (1034)
Exit Sub
eh_other:
    Debug.Print "ehother " & Err.Description
End Sub

Примечание 1. Вероятно, в редких случаях полезно использовать On Error Goto -1. Мне лично никогда не приходилось пользоваться этой линией. Помните, что как только вы выйдете из Sub, ошибка все равно будет очищена.

Примечание 2. у объекта Err есть член Clear. Использование Clear очищает текст и цифры в объекте Err, но НЕ сбрасывает ошибку.

Использование On Error

Как мы уже видели, VBA будет делать одну из трех вещей при возникновении ошибки:

  • Остановитесь и отобразите ошибку.
  • Игнорируйте ошибку и продолжайте.
  • Перейти к определенной строке.

VBA всегда будет настроен на одно из этих действий. Когда вы
используете On Error, VBA изменит ваше поведение и забудет о любом предыдущем.

В следующем подпункте VBA изменяет поведение ошибки каждый
раз, когда мы используем оператор On Error

Sub ErrorSostoyaniya()

    Dim x As Long
    
    ' Перейти на этикетке, если ошибка
    On Error Goto eh
    
    ' это проигнорирует ошибку в следующей строке
    On Error Resume Next
    x = 1 / 0
    
    ' это отобразит сообщение об ошибке в следующей строке
    On Error Goto 0
    x = 1 / 0
  
Done:  
   Exit Sub
eh:
    Debug.Print Err.Description
End Sub

Err объект

При возникновении ошибки вы можете просмотреть детали
ошибки, используя объект Err.

При возникновении ошибки времени выполнения VBA
автоматически заполняет объект Err деталями.

Приведенный ниже код выведет «Error Number: 13 Type
Mismatch», которое возникает, когда мы пытаемся поместить строковое значение в
длинное целое число.

Sub IspErr()

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

Done:
    Exit Sub
eh:
    Debug.Print "Номер ошибки: " & Err.Number _
            & " " & Err.Description
End Sub

Err.Description предоставляет подробную информацию об ошибке, которая происходит. Это текст, который вы обычно видите, когда возникает ошибка, например, «Несоответствие типов»

Err.Number — это идентификационный номер ошибки, например, номер ошибки для «Несоответствие типов» — 13. Единственное время, когда вам действительно нужно это, если вы проверяете, что произошла конкретная ошибка, и это необходимо только в редких случаях.

Свойство Err.Source кажется отличной идеей, но оно не работает при ошибке VBA. Источник вернет имя проекта, которое вряд ли сузит место возникновения ошибки. Однако, если вы создаете ошибку с помощью Err.Raise, вы можете установить источник самостоятельно, и это может быть очень полезно.

Получение номера строки

Функция Erl используется для возврата номера строки, где
произошла ошибка.

Это часто вызывает путаницу. В следующем коде Erl вернет ноль.

Sub IspErr()

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

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

Это потому, что нет номеров строк. Большинство людей не
понимают этого, но VBA позволяет вам иметь номера строк.

Если мы изменим подпрограмму, указав номер строки, она теперь выведет 20.

Sub IspErr()

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

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

Добавление номеров строк в код вручную затруднительно.
Однако есть инструменты, которые позволят вам легко добавлять и удалять номера
строк в подпрограмме.

Когда вы закончите работу над проектом и передадите его
пользователю, в этот момент может быть полезно добавить номера строк. Если вы
используете стратегию обработки ошибок в последнем разделе этого поста, то VBA
сообщит строку, где произошла ошибка.

Использование Err.Raise

Err.Raise позволяет нам создавать ошибки. Мы можем
использовать его для создания пользовательских ошибок для нашего приложения,
что очень полезно. Это эквивалент оператора Throw в Java \ C #.

Формат следующий

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

Давайте посмотрим на простой пример. Представьте, что мы
хотим убедиться, что в ячейке есть запись длиной 5 символов. Мы могли бы иметь конкретное сообщение для
этого

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" _
            , "Значение в ячейке A1 должно иметь ровно 5 символов."
    End If
    
    ' продолжить, если ячейка имеет действительные данные
    Dim id As String
    id = Sheet1.Range("A1")
    

Done:
    Exit Sub
eh:
    ' Err.Raise отправит код сюда
    MsgBox " Обнаружена ошибка: " & Err.Description
End Sub

Когда мы создаем ошибку, используя Err.Raise, нам нужно присвоить ей номер. Мы можем использовать любое
число от 513 до 65535 для нашей ошибки. Мы должны использовать vbObjectError с номером,
например

Err.Raise vbObjectError + 513

Использование Err.Clear

Err.Clear используется для очистки текста и чисел из объекта
Err.Object. Другими словами, он очищает описание и номер.

Редко вам понадобится его использовать, но давайте
рассмотрим пример, где вы могли бы.

В приведенном ниже коде мы подсчитываем количество ошибок,
которые могут возникнуть. Для простоты мы генерируем ошибку для каждого
нечетного числа.

Мы проверяем номер ошибки каждый раз, когда проходим цикл.
Если число не равно нулю, то произошла ошибка. Как только мы посчитаем ошибку,
нам нужно установить номер ошибки на ноль, чтобы он был готов проверить
следующую ошибку.

Sub IspErrClear()

    Dim count As Long, i As Long

    ' Продолжите, если ошибка, так как мы проверим номер ошибки
    On Error Resume Next
    
    For i = 0 To 9
        ' генерировать ошибку для каждого второго
        If i Mod 2 = 0 Then Error (13)
        
        ' Проверьте на ошибку
        If Err.Number <> 0 Then
            count = count + 1
            Err.Clear    ' Очистить Err, как только он считается
        End If
    Next

    Debug.Print " Количество ошибок было: " & count
End Sub

Примечание: Err.Clear сбрасывает текст и цифры в объекте ошибки, но не очищает ошибку — см. On Error Goto -1 для получения дополнительной информации об очистке фактической ошибки.

Логирование

Ведение журнала означает запись информации из вашего
приложения, когда оно запущено. При возникновении ошибки вы можете записать
детали в текстовый файл, чтобы у вас была запись об ошибке.

Код ниже показывает очень простую процедуру регистрации

Sub Logger(sType As String, sSource As String, sDetails As String)
    
    Dim sFilename As String
    sFilename = "C:\temp\logging.txt"
    
    ' Архивный файл определенного размера
    If FileLen(sFilename) > 20000 Then
        FileCopy sFilename _
            , Replace(sFilename, ".txt", Format(Now, "ddmmyyyy hhmmss.txt"))
        Kill sFilename
    End If
    
    ' Откройте файл для записи
    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

Вы можете использовать это так:

' Создать уникальный номер ошибки
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", "Данные отсутствуют в ячейке A1"
    End If

    ' другой код здесь
Done:
    Exit Sub
eh:
    Logger "Error", Err.Source, Err.Description
End Sub

Журнал не только для записи ошибок. Вы можете записывать
другую информацию во время работы приложения. При возникновении ошибки вы
можете проверить последовательность событий до того, как произошла ошибка.

Ниже приведен пример регистрации. То, как вы реализуете
журналирование, зависит от характера приложения и его полезности.

Sub ReadingData()
    
    Logger "Information", "ReadingData()", "Starting to read data."
       
    Dim coll As New Collection
    ' Read data
    Set coll = ReadData
    
    If coll.Count < 10 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

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

Другие элементы, связанные с ошибками

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

Функция ошибки

Функция Error используется для печати описания ошибки с
заданным номером ошибки. Он включен в VBA для обеспечения обратной
совместимости и не нужен, поскольку вместо него можно использовать описание
Err.Description.

Ниже приведены некоторые примеры

' Распечатать текст «Деление на ноль»
Debug.Print Error(11)
' Распечатать текст "Несоответствие типов"
Debug.Print Error(13)
' Распечатать текст "Файл не найден"
Debug.Print Error(53)

Заявление об ошибке

Заявление об ошибке позволяет имитировать ошибку. Он включен
в VBA для обратной совместимости. Вместо этого вы должны использовать
Err.Raise.

В следующем коде мы моделируем ошибку «Разделить на ноль».

Sub ZayavlObOshibke()

    On Error Goto eh
        
    ' Это создаст деление на ноль ошибок
    Error 11
    
    Exit Sub
eh:
    Debug.Print Err.Number, Err.Description
End Sub

Это утверждение включено в VBA для обратной совместимости.
Вместо этого вы должны использовать Err.Raise.

Простая стратегия обработки ошибок

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

Основная реализация

Это простой обзор нашей стратегии

  1. Поместите строку On Error Goto Label  в начале нашего верхнего Sub.
  2. Поместите Label у обработки ошибок в конце нашего верхнего
    Sub.
  3. Если происходит ожидаемая ошибка, обработайте ее и продолжайте.
  4. Если приложение не может продолжить работу, используйте Err.Raise для перехода к метке обработки ошибок.
  5. В случае непредвиденной ошибки код автоматически перейдет к метке обработки ошибок.

На следующем рисунке показан обзор того, как это выглядит

error-handling

Следующий код показывает простую реализацию этой стратегии

Public Const ERROR_NO_ACCOUNTS As Long = vbObjectError + 514

Sub BuildReport()

    On Error Goto eh
    
    ' Если ошибка в ReadAccounts, то перейти к ошибке
    ReadAccounts
    
    ' Сделай что-нибудь с кодом
    
Done:
    Exit Sub
eh:
    ' Все ошибки будут прыгать сюда
    MsgBox Err.Source & ": Произошла следующая ошибка  " & Err.Description
End Sub

Sub ReadAccounts()
    
    ' ОЖИДАЕМАЯ ОШИБКА - Может обрабатываться кодом
    ' Приложение может обрабатывать A1 равным нулю
    If Sheet1.Range("A1") = 0 Then
        Sheet1.Range("A1") = 1
    End If
    
    ' ОЖИДАЕМАЯ ОШИБКА - не может быть обработана кодом
    ' Приложение не может быть продолжено, если нет учетной записи
    If Dir("C:\Документы\Отчет.xlsx") = "" Then
        Err.Raise ERROR_NO_ACCOUNTS, "UsingErr" _
                , "There are no accounts present for this month."
    End If

    ' НЕОЖИДАННАЯ ОШИБКА - не может быть обработана кодом
    ' Если ячейка B3 содержит текст, мы получим ошибку несоответствия типов
    Dim total As Long
    total = Sheet1.Range("B3")
    
    
    ' продолжить и читать счета
    
End Sub

Это хороший способ реализации обработки ошибок, потому что

  • Нам не нужно добавлять код обработки ошибок в
    каждую подпрограмму.
  • Если возникает ошибка, то VBA корректно
    завершает работу приложения.

Полная стратегия обработки ошибок

Стратегия выше имеет один недостаток. Он не сообщает вам,
где произошла ошибка. VBA не наполняет Err.Source чем-либо полезным, поэтому мы
должны сделать это сами.

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

Целью этой стратегии является предоставление вам стека * и
номера строки в случае возникновения ошибки.

* Стек — это список вспомогательных функций, которые
использовались в данный момент при возникновении ошибки.

Это наша стратегия

  1. Разместите обработку ошибок во всех
    подпрограммах.
  2. Когда происходит ошибка, обработчик ошибок
    добавляет подробности к ошибке и вызывает ее снова.
  3. Когда ошибка достигает самой верхней
    подпрограммы, она отображается.

Мы просто «всплываем» из-за ошибки. Следующая диаграмма
показывает простое визуальное представление о том, что происходит, когда в Sub3
возникает ошибка

Error Handling – bubbling

Единственная грязная часть этого — правильное форматирование
строк. Я написал две подводные лодки, которые справляются с этим, поэтому он
позаботится о вас.

Это две вспомогательные подводные лодки

Option Explicit

Public Const MARKER As String = "NOT_TOPMOST"

' Вызывает ошибку и добавляет номер строки и имя текущей процедуры
Sub RaiseError(ByVal errorno As Long, ByVal src As String _
                , ByVal proc As String, ByVal desc As String, ByVal lineno As Long)
    
    Dim sLineNo As Long, sSource As String
    
    ' Если маркера нет, тогда RaiseError вызывается впервые.
    If Left(src, Len(MARKER)) <> MARKER Then

        ' Добавить номер строки ошибки, если она есть
        If lineno <> 0 Then
            sSource = vbCrLf & "Line no: " & lineno & " "
        End If
   
        ' Добавить маркер и процедуру к источнику
        sSource = MARKER & sSource & vbCrLf & proc
        
    Else
        ' Если ошибка уже возникла, просто добавьте имя процедуры
        sSource = src & vbCrLf & proc
    End If
    
    ' Если код останавливается здесь, убедитесь, что DisplayError находится в верхней части Sub
    Err.Raise errorno, sSource, desc
    
End Sub

' Отображает ошибку, когда она достигает самого верхнего sub
' Примечание: вы можете добавить вызов для входа из этого подпункта
Sub DisplayError(ByVal src As String, ByVal desc As String _
                    , ByVal sProcname As String)

    ' Удалить маркер
    src = Replace(src, MARKER, "")
    
    Dim sMsg As String
    sMsg = " Произошла следующая ошибка: " & vbCrLf & Err.Description _
                    & vbCrLf & vbCrLf & " Расположение ошибки: "
    
    sMsg = sMsg + src & vbCrLf & sProcname
    
    ' Показать сообщение
    MsgBox sMsg, Title:="Ошибка "
    
End Sub

Пример использования этой стратегии

Вот простое кодирование, которое использует эти Sub. В этой стратегии мы не размещаем какой-либо код в верхнем подпрограмме. Мы только вызываем подводные лодки.

Sub Topmost()

    On Error Goto EH
    
    Level1

Done:
    Exit Sub
EH:
    DisplayError Err.source, Err.Description, "Module1.Topmost"
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
    
    ' Ошибка здесь
    Dim a As Long
    a = "7 / 0"

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

Результат выглядит так

error handling output

Если в вашем проекте есть номера строк, результат будет содержать номер строки ошибки.

error handling output line

Примечание: вы можете получить следующую ошибку при использовании этого кода:

“Programmatic Access to Visual Basic Project is not trusted”

Чтобы решить эту проблему, выполните следующие действия.

  1. Перейдите в раздел «Разработчик» на ленте и
    нажмите «Macro Security», которая находится под кодом.
  2. Нажмите «Настройка макроса» в левом списке.
  3. Поставьте флажок в поле «Доверительный доступ к
    объектной модели проекта VBA».
  4. Нажмите Ok.

Обработка ошибок в двух словах

  • Обработка ошибок используется для обработки ошибок, возникающих во время работы приложения.
  • Вы пишете определенный код для обработки ожидаемых ошибок. Вы используете оператор обработки ошибок VBA
    On Error Goto [label] для отправки VBA на метку при возникновении непредвиденной ошибки.
  • Вы можете получить подробную информацию об ошибке из Err.Description.
  • Вы можете создать свою собственную ошибку, используя Err.Raise.
  • Использование одного оператора On Error в самой верхней подпрограмме перехватит все ошибки в подпрограммах, которые вызываются отсюда.
  • Если вы хотите записать имя Sub с ошибкой, вы можете обновить ошибку и сбросить ее.
  • Вы можете использовать журнал для записи информации о приложении, когда оно запущено.

“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:\docs\data.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 Java\C#.

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:\temp\logging.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:\Docs\Account.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.)

Error handling refers to the way runtime errors are handled. Error handling in VBA is done using the On Error statement and the Err object. Runtime errors can be generated by attempting to execute error-causing code or they can be raised explicitly using the Err.Raise method. There are a number of built-in types of runtime errors, and custom errors can be defined as well. Each type of runtime error has a unique number which can be used to determine at runtime which type of error has occurred and respond accordingly.

On Error

The On Error statement is used to control what happens when a runtime error occurs. The On Error statement sets or removes the current error handling scope. When a runtime error occurs in VBA the error trap is triggered and if an On Error statement has been set, VBA will respond according to which type of On Error statement was used.

Statement Description
On Error Resume Next Skips lines of code that cause errors. Use with caution.
On Error GoTo Line When an error occurs execution will jump to a specified label or line number.
On Error GoTo 0 Clears the current error and disables error handling.
On Error GoTo -1 Clears the current error and resets the error trap.
Resume When used after the On Error GoTo statement, Resume will continue execution from the line of code that caused the error.
Resume Next When used after the On Error GoTo statement, Resume Next will continue execution from the line of code directly after the line that caused the error.
Resume Line When used after the On Error GoTo statement, Resume Line will jump to a specified label or line number and continue execution.

On Error Resume Next

Public Sub Example()

    On Error Resume Next

    Err.Raise 1004

    Debug.Print "Error was skipped"

End Sub

On Error GoTo Line

Public Sub Example()

    On Error GoTo HandleError

    Err.Raise 1004

    Exit Sub

HandleError:
    Debug.Print "Error Handled"

End Sub

Note: It is not recommended to use line numbers.

Public Sub Example() 
10
20  On Error GoTo 80
30
40  Err.Raise 1004
50
60  Exit Sub
70
80  Debug.Print "Error Handled"
90
End Sub

On Error GoTo…Resume

Public Sub Example()

    Dim N As Long
    N = 0

    On Error GoTo HandleError

    'Divide by zero error will be fixed by error handler
    Debug.Print 1 / N

    Debug.Print "Error Handled."

    Exit Sub

HandleError:
    If Err.Number = 11 Then
        Debug.Print "Handling 'Division by zero' Error..."
        N = 1
        Resume
    Else
        Err.Raise Err.Number
    End If

End Sub

On Error GoTo…Resume Next

Public Sub Example()

    On Error GoTo HandleError

    Err.Raise 1004

    Debug.Print "Error Handled. Resuming Next..."

    Exit Sub

HandleError:
    Debug.Print "Handling Error..."
    Resume Next

End Sub

On Error GoTo…Resume Line

Public Sub Example()

    On Error GoTo HandleError

    Err.Raise 1004

Continue:
    Debug.Print "Resuming..."

    Exit Sub

HandleError:
    Debug.Print "Error Handled"
    Resume Continue

End Sub

Note: It is not recommended to use line numbers.

Public Sub Example()
10
20    On Error GoTo 100
30
40    Err.Raise 1004
50
60    Debug.Print "Resuming..."
70
80    Exit Sub
90
100   Debug.Print "Error Handled"
110   Resume 60
120
End Sub

On Error GoTo 0

Public Sub Example()

    On Error Resume Next

    Err.Raise 1004 'Error will be skipped

    On Error GoTo 0

    Err.Raise 1004 'Error will be raised

End Sub

On Error GoTo -1

Public Sub Example()

    On Error GoTo HandleError1

    Err.Raise 1004

    Exit Sub

HandleError1:
    Debug.Print "HandleError1"
    On Error GoTo -1
    On Error GoTo HandleError2
    Err.Raise 1004
    Exit Sub

HandleError2:
    Debug.Print "HandleError2"
    Exit Sub

End Sub

The Err Object

The Err Object is used to access information about a runtime error that has occurred. When a runtime error occurs, the Err object’s properties are filled with information about the error. The Err object can also be used to raise errors explicitly.

Member Description
Clear Clears properties of the Err object. Does NOT reset error trap or clear error handling scope.
Description A text description of the error.
HelpContext The context ID for a topic in a help file.
HelpFile The path to help file.
LastDllError Returns a system error code produced by a call to a dynamic-link library (DLL). Read-only. Always returns zero on Mac.
Number The error number, 0 through 65535.
Raise Raises a specified runtime error.
Source The name of the object or application that originated the error.

The Err Object is a Singleton

The Err object has a single default global instance and cannot be instantiated. The Err object can be accessed anywhere in VBA just by typing Err.

Public Sub Example()

    Err.Raise 1004 'No need to instantiate Err object

End Sub

Public Sub Example()

    Dim E As ErrObject
    Set E = New ErrObject 'Causes error

End Sub

Properties

The Err object’s properties are filled with data when a runtime error occurs. The Number property is especially important because it can be used to dynamically respond to different types of errors. If no runtime error has occurred, the Number property will be 0. Therefore, to determine if an error has occurred in a particular line, the Number property can be checked to see if it is 0 or not.

Public Sub Example()

    On Error Resume Next

    Err.Raise 1004

    If Err.Number <> 0 Then

        With Err
            Debug.Print "Number: " & .Number
            Debug.Print "Description: " & .Description
            Debug.Print "Source: " & .Source
            Debug.Print "HelpFile: " & .HelpFile
            Debug.Print "HelpContext: " & .HelpContext
            Debug.Print "LastDllError: " & .LastDllError
        End With

        Err.Raise Err.Number

    Else

        Debug.Print "No Error"

    End If

End Sub

Clearing The Err Object

The Err object can be reset in a few different ways. The Err object is reset when Err.Clear is called, a Resume or Resume Next statement is executed for the error, or another On Error statement is executed. Exiting an error-causing procedure does not reset the Err object.

Note: Exiting an error-causing procedure does not reset the Err object.

Public Sub Example()

    Call ErrorCausingProcedure1
    Debug.Print Err.Number 'Prints 1004

    Call ErrorCausingProcedure2
    Debug.Print Err.Number 'Prints 0

    Call ErrorCausingProcedure3
    Debug.Print Err.Number 'Prints 0

    Call ErrorCausingProcedure4
    Debug.Print Err.Number 'Prints 0

End Sub

Public Sub ErrorCausingProcedure1()
    'Exiting procedure doe NOT reset the Err object
    On Error Resume Next
    Err.Raise 1004
End Sub

Public Sub ErrorCausingProcedure2()
    'Calling Err.Clear resets the Err object
    On Error Resume Next
    Err.Raise 1004
    Err.Clear
End Sub

Public Sub ErrorCausingProcedure3()
    'Resume Next resets the Err object
    On Error GoTo HandleError
    Err.Raise 1004
    Exit Sub
HandleError:
    Resume Next
End Sub

Public Sub ErrorCausingProcedure4()
    'On Error statement resets the Err object
    On Error Resume Next
    Err.Raise 1004
    On Error GoTo 0
End Sub

Calling Err.Clear only clears the Err object. Err.Clear does not reset the error handling trap or end the error handling scope. On Error GoTo -1 will clear the Err object and reset error trapping, allowing another error to be raised. On Error GoTo 0 will clear the Err object and clear the error handling scope.

Public Sub Example()

    On Error Resume Next

    'Error is skipped
    Err.Raise 1004

    'Prints 1004
    Debug.Print Err.Number

    'Err object is reset
    Err.Clear

    'Prints 0
    Debug.Print Err.Number

    'Error is skipped because error handling scope was not reset
    Err.Raise 1004

    'Prints 1004
    Debug.Print Err.Number

    'Clears Err object and error handling scope
    On Error GoTo 0

    'Prints 0
    Debug.Print Err.Number

    'Raises a runtime error
    Err.Raise 1004

End Sub

Error Trapping Options

Error Trapping options can be selected which can override error handling code in VBA. To change error trapping options navigate to Tools → Options → General in the Visual Basic Editor.

Error Trapping Options

Option Description
Break on All Errors Will enter break mode when any error is encountered regardless of error handling code.
Break in Class Module Will enter break mode and show errors inside class modules.
Break on Unhandled Errors This is the default setting. Will enter break mode when an error is encountered and it is not handled by code.

CVErr Function

The CVErr function can be used to return an error from a function. CVErr returns a value of type Variant with subtype Error. Only variables of type Variant can be assigned a value using the CVErr function. CVErr can take any error number as an argument. CVErr can be used to return a cell error from a user-defined function that is intended for use in spreadsheets.

Option Explicit

Public Function ReturnValueError() As Variant

    'Shows #VALUE Error in cell
    ReturnValueError = CVErr(xlErrValue)

End Function

xlErr Cell Errors

xlErr Constant Cell Error
xlErrBlocked #BLOCKED!
xlErrCalc #CALC!
xlErrConnect #CONNECT!
xlErrDiv0 #DIV/0!
xlErrField #FIELD!
xlErrGettingData #GETTING_DATA
xlErrNA #N/A
xlErrName #NAME?
xlErrNull #NULL!
xlErrNum #NUM!
xlErrRef #REF!
xlErrSpill #SPILL!
xlErrUnknown #UNKNOWN!
xlErrValue #VALUE!

IsError Function

The IsError function returns True if the argument expression evaluates to an error. IsError can be used to test if a cell value contains an error or a user-defined function returns an error. To return an error from a function use the CVErr function.

Option Explicit

Public Sub Example()

    If IsError(Range("A1").Value) Then
        Debug.Print "Range A1 contains an error."
    End If

    Dim E As Variant
    E = ReturnError()

    If IsError(E) Then
        Debug.Print "E is Error: " & CStr(E)
    End If

End Sub

Public Function ReturnError() As Variant

    ReturnError = CVErr(xlErrValue)

End Function

Error Function

The Error/Error$ function is used to return the description text of an error. The Error function can be used to return a specific error description based on an error number or it can return the description text of the last error to occur.

Specific Error Description

Pass the optional ErrorNumber argument to the Error function to return a specific error description. Although the Error function can take a number between -2147483648 and 65535, it should be intended for use with the range 0 through 65535. If the error number is outside the valid range an Overflow runtime error will occur. If the error number is within the valid range but is not defined, the message «Application-defined or object-defined error» will be returned.

Public Sub Example()

    Debug.Print Error(5) 'Prints: Invalid procedure call or argument

End Sub

Most Recent Error Description

Call the Error function with no ErrorNumber argument to return the description text for the last error to occur. If no error has occurred, a zero-length string will be returned. The Err.Description property can be used to get the text description of the most recent runtime error instead of using the Error function.

Public Sub Example()

    On Error Resume Next

    Err.Raise 5

    Debug.Print Error() 'Prints: Invalid procedure call or argument

End Sub

Raising Errors

Use the Err.Raise method to raise a runtime error. Errors should be raised when an unacceptable state has been reached in a program. Existing VBA error numbers can be used to raise errors or custom error numbers can be created.

Raising Existing Errors

An appropriate VBA error number can be selected which describes the error.

Public Function RandomLong(MinValue As Long, MaxValue As Long) As Long

    If MinValue > MaxValue Then
        Err.Raise 5
    End If

    Randomize
    RandomLong = Int((MaxValue - MinValue + 1) * Rnd + MinValue)

End Function

User-Defined Errors

To raise a user-defined error, create an error number by using the vbObjectError constant and adding a number between 513 and 65535. The range 0 through 512 is reserved for system errors. The vbObjectError constant has the value -2147221504 so user-defined errors will be negative. To derive the positive portion of a user-defined error simply subtract the vbObjectError constant from the error number.

Public Sub Example()

    On Error GoTo HandleError

    Err.Raise Number:=vbObjectError + 513, Description:="Custom Error"

    Exit Sub

HandleError:
    Debug.Print Err.Number - vbObjectError, Err.Description 'Prints: 513 Custom Error
    Resume Next

End Sub

Error Statement

The Error statement raises a runtime error for a given error number. The Error statement is included for backward compatibility with older versions of VBA and Err.Raise should be used instead for new code.

Public Sub Example()

    'Backward compatible
    Error 5

    'Use this for new code
    Err.Raise 5

End Sub

Error Numbers

Runtime errors each have a number used to identify what type of error it is. Error numbers can be used with the Err.Raise method, the Error statement, and the Error function. When a runtime error occurs, the Err.Number property will be set to the number associated with the type of error. Any positive error number not listed in the table below returns «Application-defined or object-defined error».

Error Number Error Text
3 Return without GoSub
5 Invalid procedure call or argument
6 Overflow
7 Out of memory
9 Subscript out of range
10 This array is fixed or temporarily locked
11 Division by zero
13 Type mismatch
14 Out of string space
16 Expression too complex
17 Can’t perform requested operation
18 User interrupt occurred
20 Resume without error
28 Out of stack space
35 Sub or Function not defined
47 Too many DLL application clients
48 Error in loading DLL
49 Bad DLL calling convention
51 Internal error
52 Bad file name or number
53 File not found
54 Bad file mode
55 File already open
57 Device I/O error
58 File already exists
59 Bad record length
61 Disk full
62 Input past end of file
63 Bad record number
67 Too many files
68 Device unavailable
70 Permission denied
71 Disk not ready
74 Can’t rename with different drive
75 Path/File access error
76 Path not found
91 Object variable or With block variable not set
92 For loop not initialized
93 Invalid pattern string
94 Invalid use of Null
96 Unable to sink events of object because the object is already firing events to the maximum number of event receivers that it supports
97 Can not call friend function on object which is not an instance of defining class
98 A property or method call cannot include a reference to a private object, either as an argument or as a return value
321 (1 — 2) Invalid file format
322 Can’t create necessary temporary file
325 Invalid format in resource file
380 (1 — 2) Invalid property value
381 Invalid property array index
382 Set not supported at runtime
383 Set not supported (read-only property)
385 Need property array index
387 Set not permitted
393 Get not supported at runtime
394 Get not supported (write-only property)
422 Property not found
423 Property or method not found
424 Object required
429 ActiveX component can’t create object
430 Class does not support Automation or does not support expected interface
432 File name or class name not found during Automation operation
438 Object doesn’t support this property or method
440 Automation error
442 Connection to type library or object library for remote process has been lost. Press OK for dialog to remove reference.
443 Automation object does not have a default value
445 Object doesn’t support this action
446 Object doesn’t support named arguments
447 Object doesn’t support current locale setting
448 Named argument not found
449 Argument not optional
450 Wrong number of arguments or invalid property assignment
451 Property let procedure not defined and property get procedure did not return an object
452 Invalid ordinal
453 Specified DLL function not found
454 Code resource not found
455 Code resource lock error
457 This key is already associated with an element of this collection
458 Variable uses an Automation type not supported in Visual Basic
459 Object or class does not support the set of events
460 (1 — 2) Invalid clipboard format
461 Method or data member not found
462 The remote server machine does not exist or is unavailable
463 Class not registered on local machine
481 (1 — 2) Invalid picture
482 (1 — 2) Printer error
735 Can’t save file to TEMP
744 Search text not found
746 Replacements too long
1004 Application-defined or object-defined error
31001 Application-defined or object-defined error. *Out of memory
31004 Application-defined or object-defined error. *No object
31018 Application-defined or object-defined error. *Class is not set
31027 Application-defined or object-defined error. *Unable to activate object
31032 Application-defined or object-defined error. *Unable to create embedded object
31036 Application-defined or object-defined error. *Error saving to file
31037 Application-defined or object-defined error. *Error loading from file

In this Article

  • VBA Errors Cheat Sheet
    • Errors
  • VBA Error Handling
  • VBA On Error Statement
    • On Error GoTo 0
    • On Error Resume Next
    • Err.Number, Err.Clear, and Catching Errors
    • On Error GoTo Line
  • VBA IsError
  • If Error VBA
  • VBA Error Types
    • Runtime Errors
    • Syntax Errors
    • Compile Errors
    • Debug > Compile
    • OverFlow Error
  • Other VBA Error Terms
    • VBA Catch Error
    • VBA Ignore Error
    • VBA Throw Error / Err.Raise
    • VBA Error Trapping
    • VBA Error Message
    • VBA Error Handling in a Loop
  • VBA Error Handling in Access

VBA Errors Cheat Sheet

Errors

On Error – Stop code and display error

On Error Goto 0

On Error – Skip error and continue running

On Error Resume Next

On Error – Go to a line of code [Label]

On Error Goto [Label]

Clears (Resets) Error

On Error GoTo1

Show Error number

MsgBox Err.Number

Show Description of error

MsgBox Err.Description

Function to generate own error

Err.Raise

See more VBA “Cheat Sheets” and free PDF Downloads

VBA Error Handling

VBA Error Handling refers to the process of anticipating, detecting, and resolving VBA Runtime Errors. The VBA Error Handling process occurs when writing code, before any errors actually occur.

VBA Runtime Errors are errors that occur during code execution. Examples of runtime errors include:

  • Referencing a non-existent workbook, worksheet, or other object (Run-time Error 1004)
  • Invalid data ex. referencing an Excel cell containing an error (Type Mismatch – Run-time Error 13)
  • Attempting to divide by zero

VBA On Error Statement

Most VBA error handling is done with the On Error Statement. The On Error statement tells VBA what to do if it encounters an error. There are three On Error Statements:

  • On Error GoTo 0
  • On Error Resume Next
  • On Error GoTo Line

On Error GoTo 0

On Error GoTo 0 is VBA’s default setting. You can restore this default setting by adding the following line of code:

On Error GoTo 0

When an error occurs with On Error GoTo 0, VBA will stop executing code and display its standard error message box.

vba runtime error 13

Often you will add an On Error GoTo 0 after adding On Error Resume Next error handling (next section):

Sub ErrorGoTo0()

On Error Resume Next
    ActiveSheet.Shapes("Start_Button").Delete
On Error GoTo 0

'Run More Code

End Sub

On Error Resume Next

On Error Resume Next tells VBA to skip any lines of code containing errors and proceed to the next line.

On Error Resume Next

Note: On Error Resume Next does not fix an error, or otherwise resolve it. It simply tells VBA to proceed as if the line of code containing the error did not exist. Improper use of On Error Resume Next can result in unintended consequences.

A great time to use On Error Resume Next is when working with objects that may or may not exist. For example, you want to write some code that will delete a shape, but if you run the code when the shape is already deleted, VBA will throw an error. Instead you can use On Error Resume Next to tell VBA to delete the shape if it exists.

On Error Resume Next
    ActiveSheet.Shapes("Start_Button").Delete
On Error GoTo 0

Notice we added On Error GoTo 0 after the line of code containing the potential error. This resets the error handling.

In the next section we’ll show you how to test if an error occurred using Err.Number, giving you more advanced error handling options.

VBA Coding Made Easy

Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!

automacro

Learn More

Err.Number, Err.Clear, and Catching Errors

Instead of simply skipping over a line containing an error, we can catch the error by using On Error Resume Next and Err.Number.

Err.Number returns an error number corresponding with the type of error detected. If there is no error, Err.Number = 0.

For example, this procedure will return “11” because the error that occurs is Run-time error ’11’.

Sub ErrorNumber_ex()

On Error Resume Next
ActiveCell.Value = 2 / 0
MsgBox Err.Number

End Sub

vba run-time error 11 err.number

Error Handling with Err.Number

The true power of Err.Number lies in the ability to detect if an error occurred (Err.Number <> 0).  In the example below, we’ve created a function that will test if a sheet exists by using Err.Number.

Sub TestWS()
    MsgBox DoesWSExist("test")
End Sub

Function DoesWSExist(wsName As String) As Boolean
    Dim ws As Worksheet
    
    On Error Resume Next
    Set ws = Sheets(wsName)
    
    'If Error WS Does not exist
    If Err.Number <> 0 Then
        DoesWSExist = False
    Else
        DoesWSExist = True
    End If

    On Error GoTo -1
End Function

Note: We’ve added a On Error GoTo -1 to the end which resets Err.Number to 0 (see two sections down).

With On Error Resume Next and Err.Number, you can replicate the “Try” & “Catch” functionality of other programming languages.

On Error GoTo Line

On Error GoTo Line tells VBA to “go to” a labeled line of code when an error is encountered.  You declare the Go To statement like this (where errHandler is the line label to go to):

On Error GoTo errHandler

and create a line label like this:

errHandler:

Note: This is the same label that you’d use with a regular VBA GoTo Statement.

Below we will demonstrate using On Error GoTo Line to Exit a procedure.

On Error Exit Sub

You can use On Error GoTo Line to exit a sub when an error occurs.

You can do this by placing the error handler line label at the end of your procedure:

Sub ErrGoToEnd()

On Error GoTo endProc

'Some Code
    
endProc:
End Sub

or by using the Exit Sub command:

Sub ErrGoToEnd()

On Error GoTo endProc

'Some Code
GoTo skipExit
    
endProc:
Exit Sub

skipExit:

'Some More Code

End Sub

Err.Clear, On Error GoTo -1,  and Resetting Err.Number

After an error is handled, you should generally clear the error to prevent future issues with error handling.

After an error occurs, both Err.Clear and On Error GoTo -1 can be used to reset Err.Number to 0. But there is one very important difference: Err.Clear does not reset the actual error itself, it only resets the Err.Number.

What does that mean?  Using Err.Clear, you will not be able to change the error handling setting. To see the difference, test out this code and replace On Error GoTo -1 with Err.Clear:

Sub ErrExamples()

    On Error GoTo errHandler:
        
    '"Application-defined" error
    Error (13)
    
Exit Sub
errHandler:
    ' Clear Error
    On Error GoTo -1
    
    On Error GoTo errHandler2:
    
    '"Type mismatch" error
    Error (1034)
    
Exit Sub
errHandler2:
    Debug.Print Err.Description
End Sub

Typically, I recommend always using On Error GoTo -1, unless you have a good reason to use Err.Clear instead.

VBA On Error MsgBox

You might also want to display a Message Box on error.  This example will display different message boxes depending on where the error occurs:

Sub ErrorMessageEx()
 
Dim errMsg As String
On Error GoTo errHandler

    'Stage 1
    errMsg = "An error occured during the Copy & Paste stage."
    'Err.Raise (11)
    
    'Stage 2
    errMsg = "An error occured during the Data Validation stage."
    'Err.Raise (11)
     
    'Stage 3
    errMsg = "An error occured during the P&L-Building and Copy-Over stage."
    Err.Raise (11)
     
    'Stage 4
    errMsg = "An error occured while attempting to log the Import on the Setup Page"
    'Err.Raise (11)

    GoTo endProc
    
errHandler:
    MsgBox errMsg
   
endProc:
End Sub

Here you would replace Err.Raise(11) with your actual code.

VBA IsError

Another way to handle errors is to test for them with the VBA ISERROR Function. The ISERROR Function tests an expression for errors, returning TRUE or FALSE if an error occurs.

Sub IsErrorEx()
    MsgBox IsError(Range("a7").Value)
End Sub

VBA Programming | Code Generator does work for you!

If Error VBA

You can also handle errors in VBA with the Excel IFERROR Function.  The IFERROR Function must be accessed by using the WorksheetFunction Class:

Sub IfErrorEx()

Dim n As Long
n = WorksheetFunction.IfError(Range("a10").Value, 0)

MsgBox n
End Sub

This will output the value of Range A10, if the value is an error, it will output 0 instead.

VBA Error Types

Runtime Errors

As stated above:

VBA Runtime Errors are errors that occur during code execution. Examples of runtime errors include:

  • Referencing a non-existent workbook, worksheet, or other object
  • Invalid data ex. referencing an Excel cell containing an error
  • Attempting to divide by zero

vba runtime error 13

You can “error handle” runtime errors using the methods discussed above.

Syntax Errors

VBA Syntax Errors are errors with code writing. Examples of syntax errors include:

  • Mispelling
  • Missing or incorrect punctuation

The VBA Editor identifies many syntax errors with red highlighting:

vba syntax error example

The VBA Editor also has an option to “Auto Syntax Check”:

vba syntax error option

When this is checked, the VBA Editor will generate a message box alerting you syntax errors after you enter a line of code:

vba syntax compile error

I personally find this extremely annoying and disable the feature.

Compile Errors

Before attempting to run a procedure, VBA will “compile” the procedure. Compiling transforms the program from source code (that you can see) into executable form (you can’t see).

VBA Compile Errors are errors that prevent the code from compiling.

A good example of a compile error is a missing variable declaration:

vba compile error variable

Other examples include:

  • For without Next
  • Select without End Select
  • If without End If
  • Calling a procedure that does not exist

Syntax Errors (previous section) are a subset of Compile Errors.

AutoMacro | Ultimate VBA Add-in | Click for Free Trial!

Debug > Compile

Compile errors will appear when you attempt to run a Procedure. But ideally, you would identify compile errors prior to attempting to run the procedure.

You can do this by compiling the project ahead of time. To do so, go to Debug > Compile VBA Project.

vba debug compile

The compiler will “go to” the first error. Once you fix that error, compile the project again. Repeat until all errors are fixed.

You can tell that all errors are fixed because Compile VBA Project will be grayed out:

vba compile vbaproject

OverFlow Error

The VBA OverFlow Error occurs when you attempt to put a value into a variable that is too large. For example, Integer Variables can only contain values between -32,768 to 32,768. If you enter a larger value, you’ll receive an Overflow error:

vba overflow error

Instead, you should use the Long Variable to store the larger number.

Other VBA Error Terms

VBA Catch Error

Unlike other programming languages, In VBA there is no Catch Statement. However, you can replicate a Catch Statement by using On Error Resume Next and If Err.Number <> 0 Then. This is covered above in Error Handling with Err.Number.

AutoMacro | Ultimate VBA Add-in | Click for Free Trial!

VBA Ignore Error

To ignore errors in VBA, simply use the On Error Resume Next statement:

On Error Resume Next

However, as mentioned above, you should be careful using this statement as it doesn’t fix an error, it just simply ignores the line of code containing the error.

VBA Throw Error / Err.Raise

To through an error in VBA, you use the Err.Raise method.

This line of code will raise Run-time error ’13’: Type mismatch:

Err.Raise (13)

vba runtime error 13

VBA Error Trapping

VBA Error Trapping is just another term for VBA Error Handling.

VBA Error Message

A VBA Error Message looks like this:

vba runtime error 13

When you click ‘Debug’, you’ll see the line of code that is throwing the error:

vba raise error

AutoMacro | Ultimate VBA Add-in | Click for Free Trial!

VBA Error Handling in a Loop

The best way to error handle within a Loop is by using On Error Resume Next along with Err.Number to detect if an error has occurred (Remember to use Err.Clear to clear the error after each occurrence).

The example below will divide two numbers (Column A by Column B) and output the result into Column C. If there’s an error, the result will be 0.

Sub test()
Dim cell As Range

On Error Resume Next
For Each cell In Range("a1:a10")

    'Set Cell Value
    cell.Offset(0, 2).Value = cell.Value / cell.Offset(0, 1).Value
    
    'If Cell.Value is Error then Default to 0
    If Err.Number <> 0 Then
         cell.Offset(0, 2).Value = 0
         Err.Clear
    End If
 Next
End Sub

VBA Error Handling in Access

All of the above examples work exactly the same in Access VBA as in Excel VBA.

Function DelRecord(frm As Form)
'this function is used to delete a record in a table from a form
   On Error GoTo ending
   With frm
      If .NewRecord Then
         .Undo
         Exit Function
      End If
   End With
   With frm.RecordsetClone
      .Bookmark = frm.Bookmark
      .Delete
      frm.Requery
   End With
   Exit Function
   ending:
   End
End Function

Понравилась статья? Поделить с друзьями:
  • Vba excel игнорировать ошибки
  • Vba end while ошибка
  • Vba else if without if ошибка
  • Vba constant expression required ошибка
  • Vba automation error ошибка