Содержание
- Error messages in Visual Basic
- Run-time errors
- Compile-time errors
- Office 2013 Visual Basic for Applications (VBA) errors
- Symptoms
- Microsoft Access
- Microsoft Word
- Microsoft Excel
- Cause
- Resolution
- Сообщения об ошибках в Visual Basic
- Ошибки во время выполнения
- Ошибки времени компиляции
- Office 2013 Visual Basic для приложений (VBA) ошибки
- Симптомы
- Microsoft Access
- Microsoft Word
- Microsoft Excel
- Причина
- Решение
- Обработка ошибок
- Типы ошибок
- Инструкция On Error
- Инструкция Resume
- Получение информации об ошибке и генерация ошибки
- Способы поиска ошибок в программе
- Отладка программы в VBA
- Подача звукового сигнала
Error messages in Visual Basic
When you compile or run a Visual Basic application, the following types of errors can occur:
Compile-time errors, which occur when you compile an application.
Run-time errors, which occur when an application is running.
For information about how to troubleshoot a specific error, see Additional Resources for Visual Basic Programmers.
Run-time errors
If a Visual Basic application tries to perform an action that the system can’t execute, a run-time error occurs, and Visual Basic throws an Exception object. Visual Basic can generate custom errors of any data type, including Exception objects, by using the Throw statement. An application can identify the error by displaying the error number and message of a caught exception. If an error isn’t caught, the application ends.
The code can trap and examine run-time errors. If you enclose the code that produces the error in a Try block, you can catch any thrown error within a matching Catch block. For information about how to trap errors at run time and respond to them in your code, see Try. Catch. Finally Statement.
Compile-time errors
If the Visual Basic compiler encounters a problem in the code, a compile-time error occurs. In the Visual Studio code editor, you can easily identify which line of code caused the error because a wavy line appears under that line of code. The error message appears if you either point to the wavy underline or open the Error List, which also shows other messages.
If an identifier has a wavy underline and a short underline appears under the rightmost character, you can generate a stub for the class, constructor, method, property, field, or enum. For more information, see Generate From Usage (Visual Studio).
By resolving warnings from the Visual Basic compiler, you might be able to write code that runs faster and has fewer bugs. These warnings identify code that may cause errors when the application is run. For example, the compiler warns you if you try to invoke a member of an unassigned object variable, return from a function without setting the return value, or execute a Try block with errors in the logic to catch exceptions. For more information about warnings, including how to turn them on and off, see Configuring Warnings in Visual Basic.
Источник
Office 2013 Visual Basic for Applications (VBA) errors
Symptoms
When you open a file or try to use macros in Microsoft Office 2013 Click 2 Run (C2R), you may experience one of the following symptoms.
Microsoft Access
Windows Installer window continuously flashes.
When you use Access wizards you get the following error:
«This feature isn’t installed, or has been disabled»
When you open the Visual Basic Editor (VBE) you get the following error:
«Microsoft Access is unable to load the Visual Basic for Applications dynamic-link library (dll) Vbe7»
Microsoft Word
After you click Macros, you get the following error:
«The function you are attempting to run contains macros or content that requires macro language support»
Microsoft Excel
When you open existing workbooks, you get the following error:
«The Visual Basic for Applications (VBA) macros in this workbook are corrupted and have been deleted.» opening existing workbooks
The Visual Basic, Macros, and Record Macro options are disabled under the Developer and View ribbon.
The Visual Basic and Macros options are disabled on the ribbon.
When you open presentations with VBA code you get the following error:
«The document contains macros. Macro language support for this application is disabled. Features requiring VBA are not available. Would you like to open this document read-only?»
Cause
Non-Microsoft registry cleaners and system maintenance applications deleted multiple registry key values that are used for VBA functionality in Microsoft Office 2013 applications.
Resolution
Run an Online Repair of Office. Here’s how:
Click Start> Control Panel> Programs and Features.
Click your Microsoft Office program, and then click Change.

Select Online Repair, and then click Repair.
After Online Repair is complete, you should be able to use your Office 2013 applications.
From the Start screen, type Control Panel in the Search box, and then tap or click Apps.
Tap or click Control Panel > Programs > Programs and Features.
Select your Microsoft Office program, and then click Change.

Select Online Repair, and then click Repair.
After Online Repair is complete, you should be able to use your Office 2013 applications.
To prevent recurrences, contact the provider of the registry cleaner or system-maintenance application.
Источник
Сообщения об ошибках в Visual Basic
При компиляции или запуске приложения Visual Basic могут возникать следующие типы ошибок:
Ошибки во время компиляции, возникающие при компиляции приложения.
Ошибки во время выполнения, возникающие при запуске приложения.
Сведения о способах устранения некоторых ошибок можно найти в статье Additional Resources for Visual Basic Programmers (Дополнительные ресурсы для программирования на Visual Basic).
Ошибки во время выполнения
Если приложение Visual Basic пытается выполнить действие, которое система не может выполнить, возникает Exception ошибка во время выполнения и Visual Basic создает объект. Visual Basic может создавать пользовательские ошибки любого типа данных, включая Exception объекты, с помощью инструкции Throw . Приложение может идентифицировать ошибки, отображая номер ошибки и сообщение перехваченного исключения. Если ошибка не будет перехвачена, приложение завершается.
Код может перехватывать и проверять ошибки времени выполнения. Если вы заключите код, создающий ошибку, в блок Try , вы сможете перехватить любую созданную ошибку в соответствующем блоке Catch . Сведения о том, как в коде отлавливать ошибки во время выполнения и реагировать на них, можно найти в статье Try. Catch. Finally Statement (Оператор Try. Catch. Finally).
Ошибки времени компиляции
Если компилятор Visual Basic обнаруживает проблему в коде, возникает ошибка времени компиляции. В редакторе кода Visual Studio можно легко определить, какая строка кода вызвала ошибку, так как волнистая строка отображается под этой строкой кода. Если навести курсор на подчеркнутый фрагмент, появляется сообщение об ошибке. Также его можно увидеть вместе с другими сообщениями в списке ошибок.
Если идентификатор имеет волнистый подчеркивание и короткое подчеркивание отображается под самым правым символом, можно создать заглушку для класса, конструктора, метода, свойства, поля или перечисления. Дополнительные сведения см. в разделе «Создание из использования» (Visual Studio).
Если вы будете правильно учитывать предупреждения компилятора Visual Basic, ваш код будет работать быстрее и с меньшим количеством ошибок. Эти предупреждения сообщают о том, что в коде могут возникнуть ошибки при запуске приложения. Например, компилятор предупреждает о вызове члена неопределенной объектной переменной, о возврате из функции без задания возвращаемого значения, а также о выполнении блока Try с ошибками в логике перехвата исключений. Дополнительные сведения о предупреждениях, в том числе о возможности включать и отключать их, см. в статье Configuring Warnings in Visual Basic (Настройка предупреждений в Visual Basic).
Источник
Office 2013 Visual Basic для приложений (VBA) ошибки
Симптомы
При открытии файла или попробуйте использовать макросы в Microsoft Office 2013 2 нажмите кнопку Run (C2R) возможно возникновение следующих проблем.
Microsoft Access
Постоянно мигает, окно установщика Windows.
При использовании мастера Access появляется следующее сообщение об ошибке:
«Это средство не установлено или была отключена»
При открытии редактора Visual Basic (VBE) появляется следующее сообщение об ошибке:
«Microsoft Access не удалось загрузить Visual Basic для приложений библиотеки динамической компоновки (dll) Vbe7»
Microsoft Word
После нажатия кнопки макросы, , вы получаете следующее сообщение об ошибке:
«Функция, которую вы пытаетесь запустить, содержит макросы или содержимое требует поддержки языка создания макросов»
Microsoft Excel
При открытии существующих книг, можно получить следующее сообщение об ошибке:
«Visual Basic для приложений (VBA) макросов в данной книге повреждены и были удалены.» Открытие существующей книги
Параметры Visual Basic, макросыи Записи макросов отключены в группе разработчиков и просмотр ленты.
Параметры Visual Basic и макросы отключаются на ленте.
При открытии презентаций с VBA-кодом возникает следующая ошибка:
«Документ содержит макросы. Для этого приложения поддержка макроязыка отключена. Компоненты, которым требуется VBA не доступны. Вы хотите открыть этот документ только для чтения?»
Причина
Очистители реестра сторонних разработчиков и обслуживание приложений системы удалены несколько разделов реестра, используемых для выполнения функций VBA в приложениях Microsoft Office 2013.
Решение
Запустите интерактивный ремонт пакета Office. Вот как:
Нажмите кнопку Пуск> Панель управления> программы и компоненты.
Выберите приложение Microsoft Office и нажмите кнопку Изменить.

Выберите Восстановление по сети и затем нажмите кнопку Восстановить.
После завершения восстановления сети следует использовать приложения Office 2013.
На начальном экране введите в поле поиска Панели управления и затем коснитесь или щелкните приложения.
Нажмите кнопку или выберите Панель управления > программы > программы и компоненты.
Выберите программу Microsoft Office и нажмите кнопку Изменить.

Выберите Восстановление по сети и затем нажмите кнопку Восстановить.
После завершения восстановления сети следует использовать приложения Office 2013.
Во избежание повторения обратитесь к поставщик очистки реестра или обслуживания системы приложений.
Источник
Обработка ошибок
Если вы когда-нибудь учились водить автомобиль, то наверняка вспомните, что при первой посадке на водительское сиденье все внимание было приковано к трем деталям: рулю, педалям и рычагу переключения передач. Происходящее вне автомобиля уходило на второй план, так как вначале нужно было стронуться с места. По мере практики навыки вождения улучшались и эти три детали постепенно уходили на задний план. Как ни странно, но руль и рычаг переключения передач всегда оказывались там, куда вы не смотря протягивали руки, а ноги сами находили педали. Теперь все внимание стало занимать происходящее на дороге. Иными словами, вы стали опытным водителем.
В программировании все абсолютно также. Начинающие программисты больше обращают внимание на первые попавшиеся на глаза операторы, функции и другие элементы языка, а сам алгоритм уходит на задний план. Если программа скомпилировалась без ошибок, то это уже большое счастье, хотя это еще не означает, что программа работает правильно. По мере практики мышление программиста меняется, он начинает обращать внимание на мелочи, на форматирование программы, использует более эффективные алгоритмы и в результате всего этого допускает меньше ошибок. Подводя итоги, можно сказать, что начинающий программист просто пишет программу, а опытный программист пытается найти оптимальный алгоритм и предусмотреть поведение программы в различных ситациях. Однако, от ошибок никто не застрахован, поэтому очень важно знать как быстро найти ошибку.
Типы ошибок
Существуют три типа ошибок в программе:
- синтаксические — это ошибки в имени оператора или подпрограммы, отсутствие закрывающей или открывающей кавычек и т. д., то есть ошибки в синтаксисе языка. Как правило, компилятор предупредит о наличии ошибки, а программа не будет выполняться совсем;
- логические — это ошибки в логике работы программы, которые можно выявить только по результатам работы программы. Как правило, компилятор не предупреждает о наличии ошибки, а программа будет выполняться, так как не содержит синтаксических ошибок. Такие ошибки достаточно трудно выявить;
- ошибки времени выполнения — это ошибки, которые возникают во время работы программы. В одних случаях ошибки времени выполнения являются следствием логических ошибок, а в других случаях причиной являются внешние события, например, нехватка оперативной памяти, отсутствие прав для записи в файл и др.
Инструкция On Error
Ошибки времени выполнения можно перехватывать внутри подпрограммы. Для этого используется инструкция On Error , которая имеет три формата:
- On Error GoTo — при возникновении ошибки управление передается инструкции, помеченной меткой . Метка должна быть допустимым идентификатором, к которому предъявляются такие же требования как и к переменным. Внутри подпрограммы метка указывается в самом начале помечаемой строки и после метки ставится двоеточие. В качестве примера создадим функцию для деления двух целых чисел. Внутри функции предусмотрим обработку ошибки деления на 0 :
Если при вызове функции во втором параметре передать значение 0 , то управление будет передано в строку, помеченную с помощью метки ПриОшибке . Обратите внимание на то, что метка расположена после инструкции Exit Function . В этом случае код после инструкции Exit Function будет выполнен только в том случае, если возникнет ошибка;
- On Error Resume Next — при возникновении ошибки управление передается следующей инструкции;
- On Error GoTo 0 — отключает перехват ошибок.
Если внутри подпрограммы не предусмотрен перехват ошибки, то при возникновении ошибки работа программы прерывается и выводится стандартное окно с описанием и несколькими кнопками: Continue (продолжить), End (завершить выполнение программы), Debug (перейти в режим отладки) и Help (вывод справки).
Инструкция Resume
Инструкция Resume позволяет указать куда следует переходить после обработки ошибки. Инструкция имеет несколько форматов:
- Resume [0] — управление передается инструкции, вызвавшей ошибку;
- Resume Next — управление передается инструкции, следующей за инструкцией, вызвавшей ошибку;
- Resume — управление передается инструкции, помеченной меткой .
Если инструкция Resume не указана, то выполняется только код внутри обработчика ошибки и производится выход из подпрограммы.
Получение информации об ошибке и генерация ошибки
Вся информация о последней ошибке доступна через объект Err . Объект содержит следующие свойства:
- Number — код ошибки, например, код 11 для ошибки деления на 0 . Если ошибки не произошло, то свойство содержит значение 0 ;
- Description — описание ошибки, например, строка «Division by zero» для ошибки деления на 0 . Пример вывода кода и описания ошибки:
- Source — название текущего проекта;
- HelpFile — путь к файлу справки;
- HelpContext — идентификатор раздела в справочном файле;
- LastDLLError — системный код ошибки при работе с DLL.
Объект Err содержит следующие методы:
- Clear() — очищает всю информацию о последней ошибке. Этот метод следует вызвать после успешной обработки ошибки. Информация об ошибке автоматически очищается при выходе из подпрограммы и ряде других случаев;
- Raise() — позволяет сгенерировать ошибку в программе. Формат метода:
В параметре Number указывается код генерируемой ошибки (целое число от 0 до 65 535 ). Коды от 0 до 512 зарезервированы под системные ошибки, а остальные коды можно использовать под пользовательские ошибки. Чтобы сгенерировать ошибку с пользовательским кодом необходимо сложить код с константой vbObjectError . Остальные параметры являются необязательными и полностью аналогичны одноименным свойствам объекта Err . Пример генерации и обработки пользовательской ошибки:
Способы поиска ошибок в программе
В предыдущих разделах мы научились обрабатывать ошибки времени выполнения. Однако, наибольшее количество времени программист затрачивает на другой тип ошибок — логические ошибки. В этом случае программа компилируется без ошибок, но результат выполнения программы не соответствует ожидаемому результату. Ситуация еще более осложняется, когда неверный результат проявляется лишь периодически, а не постоянно. Инсценировать такую же ситуацию, чтобы получить этот же неверный результат, бывает крайне сложно и занимает очень много времени. В этом разделе мы рассмотрим лишь «дедовские» (но по прежнему актуальные) способы поиска ошибок, а современные способы отладки приложений, доступные в VBA, изучим в следующем разделе.
Первое, на что следует обратить внимание, — на объявления переменных. Например, рассмотрим простой пример:
Как вы думаете, какое значение отобразится в окне Immediate после выполнения этого кода? Думаете, что число 10? Не факт! Вот тут-то и кроется проблема не видная на первый взгляд. В первой инструкции присваивается значение переменной x , имя которой набрано на английской раскладке клавиатуры, а вот во второй инструкции выводится значение переменной x , имя которой набрано на русской раскладке клавиатуры. В результате значение присваивается одной переменной, а выводится значение другой переменной. Такие ситуации очень часто встречаются в программах на языке VBA, так как объявлять переменную не обязательно. Чтобы избежать такой ситуации следует обязательно объявлять переменные явным образом. Контроль за соблюдением этого правила можно возложить на компилятор, добавив в начале модуля следующую инструкцию:
При наличии инструкции компилятор производит проверку объявления всех переменных. Если переменная не была объявлена явным образом, то компилятор выведет сообщение об ошибке и выполнение программы будет остановлено. Таким образом, код должен выглядеть следующим образом:
Далее следует обратить внимание на форматирование кода. Начинающие программисты обычно не обращают на это никакого внимания, считая этот процесс лишним. А на самом деле зря! Компилятору абсолютно все равно, разместите вы все инструкции на одной строке или выполните форматирование кода. Однако, при поиске ошибок форматирование кода позволит найти ошибку гораздо быстрее.
Перед всеми инструкциями внутри блока должно быть расположено одинаковое количество пробелов. Обычно используют три или четыре пробела. От применения символов табуляции лучше отказаться. Если все же используете, то не следует в одном файле совмещать и пробелы и табуляцию. Для вложенных блоков количество пробелов умножают на уровень вложенности. Если для блока первого уровня вложенности использовалось три пробела, то для блока второго уровня вложенности должно использоваться шесть пробелов, для третьего уровня — девять пробелов и т. д. Пример форматирования вложенных блоков приведен в листинге 11.1.
Листинг 11.1. Пример форматирования вложенных блоков
Длина одной строки не должна содержать более 80 символов. Если количество символов больше, то следует выполнить переход на новую строку. При этом продолжение смещается относительно основной инструкции на величину отступа или выравнивается по какому-либо элементу. Иначе приходится пользоваться горизонтальной полосой прокрутки, а это очень неудобно при поиске ошибок.
Если программа слишком большая, то следует задуматься о разделении программы на отдельные подпрограммы или классы, которые выполняют логически законченные действия. Помните, что отлаживать отдельную подпрограмму гораздо легче, чем «спагетти»-код. Причем прежде чем вставить подпрограмму (или класс) в основную программу ее следует протестировать в отдельном проекте, передавая подпрограмме различные значения и проверяя результат ее выполнения.
Обратите внимание на то, что форматирование кода должно выполняться при написании кода, а не во время поиска ошибок. Этим вы сократите время поиска ошибки и скорее всего заметите ошибку еще на этапе написания. Если все же ошибка возникла, то вначале следует инсценировать ситуацию, при которой ошибка проявляется. После этого можно начать поиск ошибки.
Причиной периодических ошибок чаще всего являются внешние данные. Например, если числа получаются от пользователя, а затем производится деление чисел, то вполне возможна ситуация, при которой пользователь введет число 0 . Деление на ноль приведет к ошибке. Следовательно, все данные, которые поступают от пользователей, должны проверяться на соответствие допустимым значениям. Если данные не соответствуют, то нужно вывести сообщение об ошибке, а затем повторно запросить новое число или прервать выполнение всей программы. Кроме того, нужно обработать возможность того, что пользователь может ввести вовсе не число, а строку.
Метод Print() объекта Debug удобно использовать для вывода промежуточных значений. В этом случае значения переменных вначале выводятся в самом начале программы и производится проверка соответствия значений. Если значения соответствуют, то инструкция с методом Print() перемещается на следующую строку программы и опять производится проверка и т. д. Если значения не совпали, то ошибка возникает в инструкции, расположенной перед инструкцией с методом Print() . Если это пользовательская подпрограмма, то проверку значений производят внутри подпрограммы, каждый раз перемещая инструкцию с выводом значений. На одном из этих многочисленных этапов ошибка обычно обнаруживается. В больших программах можно логически догадаться о примерном расположении инструкции с ошибкой и начать поиск ошибки оттуда, а не с самого начала программы.
Инструкции для вывода промежуточных значений можно расставить уже при написании программы, не дожидаясь возникновения ошибки. В этом случае в начале программы объявляется константа с помощью инструкции #Const , а внутри программы производится проверка значения константы:
Проверить значение константы позволяет следующая конструкция:
Таким образом, меняя значение константы MY_DEBUG с 1 на 0 , можно отлючать вывод всех промежуточных значений.
Отладка программы в VBA
Сделать поиск ошибок более эффективным позволяет отладчик, встроенный в редактор VBA. С его помощью можно выполнять программу по шагам, при этом контролируя значения переменных на каждом шагу. Отладчик позволяет также проверить, соответствует ли порядок выполнения инструкций разработанному ранее алгоритму.
Прежде чем начать отладку необходимо пометить строки внутри программы с помощью точек останова. Для добавления точки останова делаем строку активной, а затем из меню Debug выбираем пункт Toggle Breakpoint. Слева от строки появится кружок, обозначающий точку останова. Добавить точку останова можно еще быстрее. Для этого достаточно щелкнуть слева от строки левой кнопкой мыши. Повторный щелчок позволяет удалить точку останова. Кроме того, для добавления или удаления точки отстанова можно воспользоваться клавишей . Чтобы удалить все точки останова следует из меню View выбрать пункт Clear All Breakpoints.
Когда точки останова расставлены можно начать отладку. Для этого запускаем программу на выполнение обычным способом. При достижении точки останова выполнение программы прерывается и отладчик ожидает дальнейших действий программиста. Инструкция, которая будет выполняться на следующем шаге, помечается желтой стрелкой слева от строки.
В режиме прерывания можно посмотреть значения различных переменных в окне Locals. Если окно не отображается, то отобразить его можно выбрав в меню View пункт Locals Window. Посмотреть значение переменной можно также если навести указатель мыши на переменную. Значение переменной отобразится во всплывающей подсказке.
При отладке можно контролировать значения отдельных переменных, а не всех сразу. Для этого следует выделить название переменной и из меню Debug выбрать пункт Add Watch. Можно также выделить название переменной и из контектного меню выбрать пункт Add Watch. В открывшемся окне устанавливаем флажок Watch Expression и нажимаем кнопку OK. Значение переменной будет отображаться в окне Watches. Чтобы отобразить окно Watches из меню View выбираем пункт Watch Window. Чтобы отменить отслеживание нужно выделить строку в окне Watches и нажать клавишу .
Для пошагового выполнения программы предназначены следующие пункты в меню Debug или соответствующие кнопки на панели инструментов Debug ( View | Toolbars | Debug):
- Step Into (клавиша ) — выполняет переход к следующей инструкции;
- Step Over — выполняет одну инструкцию. Если в этой инструкции производится вызов подпрограммы, то подпрограмма выполняется за один шаг и отладчик переходит в режим ожидания после выхода из подпрограммы;
- Step Out — при заходе в подпрограмму этот пункт позволяет выполнить подпрограмму за один шаг и выйти из нее. Отладчик переходит в режим прерывания после выхода из подпрограммы;
- Run To Cursor — выполняет переход к инструкции, в которой расположен курсор.
Если необходимо посмотреть последовательность вызова подпрограмм, то следует открыть окно Call Stack, выбрав в меню View пункт Call Stack.
Подача звукового сигнала
При возникновении ошибки или при неправильном вводе данных имеет смысл привлечь внимание пользователя звуковым сигналом. Сгенерировать звуковой сигнал позволяет инструкция Beep . Пример:
Статьи по Visual Basic for Applications (VBA)
Помощь сайту
ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов
Источник
На чтение 25 мин. Просмотров 13.7k.
Эта статья содержит полное руководство по обработке ошибок VBA. Если вы ищете краткое резюме, посмотрите таблицу быстрого руководства в первом разделе.
Если вы ищете конкретную тему по обработке ошибок VBA, ознакомьтесь с приведенным ниже содержанием.
Если вы новичок в VBA, то вы можете прочитать пост от начала до конца, так как он выложен в логическом порядке.
Содержание
- Краткое руководство по обработке ошибок
- Введение
- Ошибки VBA
- Заявление об ошибке
- Err объект
- Логирование
- Другие элементы, связанные с ошибками
- Простая стратегия обработки ошибок
- Полная стратегия обработки ошибок
- Обработка ошибок в двух словах
Краткое руководство по обработке ошибок
| Пункт | Описание |
| 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
В VBA есть три типа ошибок
- Синтаксис
- Компиляция
- Время выполнения
Мы используем обработку ошибок для устранения ошибок во
время выполнения. Давайте посмотрим на каждый из этих типов ошибок, чтобы было
ясно, что такое ошибка во время выполнения.
Синтаксические ошибки
Если вы использовали VBA в течение какого-то времени, вы
увидите синтаксическую ошибку. Когда вы набираете строку и нажимаете return,
VBA оценивает синтаксис и, если он неверен, выдает сообщение об ошибке.
Например, если вы введете If и забудете ключевое слово Then,
VBA отобразит следующее сообщение об ошибке.

Некоторые примеры синтаксических ошибок
' 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.

Использование 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 отобразит ошибку, когда ваш
код попытается открыть его.
Другие примеры ошибок времени выполнения
- база данных недоступна
- пользователь вводит неверные данные
- ячейка, содержащая текст вместо числа
Как мы уже видели, целью обработки ошибок является обработка
ошибок времени выполнения, когда они возникают.
Ожидаемые и неожиданные ошибки
Когда мы думаем, что может произойти ошибка во время
выполнения, мы помещаем код на место для ее обработки. Например, мы обычно
помещаем код на место, чтобы иметь дело с файлом, который не найден.
Следующий код проверяет, существует ли файл, прежде чем он
пытается его открыть. Если файл не существует, отображается сообщение, удобное
для пользователя, и код выходит из подпрограммы.
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.
Заявление об ошибке
Как мы видели, есть два способа обработки ошибок во время
выполнения
- Ожидаемые ошибки — напишите конкретный код для
их обработки. - Неожиданные ошибки — используйте операторы
обработки ошибок VBA для их обработки.
Оператор VBA On Error используется для обработки ошибок.
Этот оператор выполняет некоторые действия при возникновении ошибки во время
выполнения.
Есть четыре различных способа использовать это утверждение
- On Error Goto 0 — код останавливается на строке с ошибкой и отображает сообщение.
- On Error Resume Next — код перемещается на следующую строку. Сообщение об ошибке не отображается.
- On Error Goto [label] — код перемещается на определенную строку или метку. Сообщение об ошибке не отображается. Это тот, который мы используем для обработки ошибок.
- 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
Вторая строка присваивания приводит к ошибке деления на ноль. Когда мы запустим этот код, мы получим сообщение об ошибке, показанное на скриншоте ниже.

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

Это нормально, когда вы пишете код 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 переходит на метку 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:templogging.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. В этом разделе я покажу вам, как
реализовать простую стратегию обработки ошибок, которую вы можете использовать
во всех своих приложениях.
Основная реализация
Это простой обзор нашей стратегии
- Поместите строку On Error Goto Label в начале нашего верхнего Sub.
- Поместите Label у обработки ошибок в конце нашего верхнего
Sub. - Если происходит ожидаемая ошибка, обработайте ее и продолжайте.
- Если приложение не может продолжить работу, используйте Err.Raise для перехода к метке обработки ошибок.
- В случае непредвиденной ошибки код автоматически перейдет к метке обработки ошибок.
На следующем рисунке показан обзор того, как это выглядит

Следующий код показывает простую реализацию этой стратегии
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 чем-либо полезным, поэтому мы
должны сделать это сами.
В этом разделе я собираюсь представить более полную
стратегию ошибок. Я написал два сабвуфера, которые выполняют всю тяжелую
работу, поэтому все, что вам нужно сделать, это добавить их в свой проект.
Целью этой стратегии является предоставление вам стека * и
номера строки в случае возникновения ошибки.
* Стек — это список вспомогательных функций, которые
использовались в данный момент при возникновении ошибки.
Это наша стратегия
- Разместите обработку ошибок во всех
подпрограммах. - Когда происходит ошибка, обработчик ошибок
добавляет подробности к ошибке и вызывает ее снова. - Когда ошибка достигает самой верхней
подпрограммы, она отображается.
Мы просто «всплываем» из-за ошибки. Следующая диаграмма
показывает простое визуальное представление о том, что происходит, когда в Sub3
возникает ошибка

Единственная грязная часть этого — правильное форматирование
строк. Я написал две подводные лодки, которые справляются с этим, поэтому он
позаботится о вас.
Это две вспомогательные подводные лодки
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
Результат выглядит так

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

Примечание: вы можете получить следующую ошибку при использовании этого кода:
“Programmatic Access to Visual Basic Project is not trusted”
Чтобы решить эту проблему, выполните следующие действия.
- Перейдите в раздел «Разработчик» на ленте и
нажмите «Macro Security», которая находится под кодом. - Нажмите «Настройка макроса» в левом списке.
- Поставьте флажок в поле «Доверительный доступ к
объектной модели проекта VBA». - Нажмите Ok.
Обработка ошибок в двух словах
- Обработка ошибок используется для обработки ошибок, возникающих во время работы приложения.
- Вы пишете определенный код для обработки ожидаемых ошибок. Вы используете оператор обработки ошибок VBA
On Error Goto [label] для отправки VBA на метку при возникновении непредвиденной ошибки. - Вы можете получить подробную информацию об ошибке из Err.Description.
- Вы можете создать свою собственную ошибку, используя Err.Raise.
- Использование одного оператора On Error в самой верхней подпрограмме перехватит все ошибки в подпрограммах, которые вызываются отсюда.
- Если вы хотите записать имя Sub с ошибкой, вы можете обновить ошибку и сбросить ее.
- Вы можете использовать журнал для записи информации о приложении, когда оно запущено.
При выполнении макросов Excel могут возникнуть ошибки, которые в VBA делят на три категории:
- Ошибки компиляции
- Ошибки выполнения
- Логические ошибки (баги)
Далее мы поговорим о каждом из трёх типов ошибок VBA подробно.
Содержание
- Ошибки компиляции
- Ошибки выполнения
- Перехват ошибок выполнения
- Логические ошибки
Ошибки компиляции
Компилятор VBA рассматривает ошибки компиляции как недопустимые и выделяет их в коде ещё до того, как дело дойдёт до запуска макроса.
Если при написании кода допущена синтаксическая ошибка, то редактор VBA сигнализирует об этом немедленно: либо при помощи окна с сообщением, либо выделяя ошибку красным цветом, в зависимости от статуса режима Auto Syntax Check.
Примечание: При включённом режиме Auto Syntax Check каждый раз, при появлении в редакторе Visual Basic во введённом коде синтаксической ошибки, будет показано соответствующее сообщение. Если же этот режим выключен, то редактор VBA продолжит сообщать о синтаксических ошибках, просто выделяя их красным цветом. Опцию Auto Syntax Check можно включить/выключить в меню Tools > Options редактора Visual Basic.
В некоторых случаях ошибка компиляции может быть обнаружена при выполнении компиляции кода, непосредственно перед тем, как макрос будет выполнен. Обычно ошибку компиляции несложно обнаружить и исправить, потому что компилятор VBA даёт информацию о характере и причине ошибки.

Например, сообщение «Compile error: Variable not defined» при попытке запустить выполнение кода VBA говорит о том, что происходит попытка использовать или обратиться к переменной, которая не была объявлена для текущей области (такая ошибка может возникнуть только если используется Option Explicit).
Ошибки выполнения
Ошибки выполнения возникают в процессе выполнения кода и приводят к остановке выполнения программы. Этот тип ошибок VBA, как правило, также не сложно обнаружить и исправить, так как сообщается информация о характере ошибки и место в коде, где произошла остановка.
Примером такой ошибки может служить попытка выполнить деление на ноль. В результате будет показано сообщение «Run-time error ’11’: Division by zero«.

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

Получив такое сообщение и видя выделенную строку кода, как в приведённом выше примере, обнаружить причину ошибки будет совсем не сложно.
В случае если код сложнее, чем в нашем примере, то, чтобы получить больше информации о причине возникновения ошибки VBA, можно проверить значения используемых переменных. В редакторе VBA для этого достаточно навести указатель мыши на имя переменной, или можно открыть окно отслеживания локальных переменных (в меню редактора View > Locals Window).
Коды различных ошибок выполнения расшифрованы на сайте Microsoft Support (на английском). Наиболее часто встречающиеся ошибки VBA перечислены в этой таблице:
| 5 | Недопустимый вызов процедуры (Invalid procedure call) |
| 7 | Недостаточно памяти (Out of memory) |
| 9 | Индекс вне заданного диапазона (Subscript out of range)
Эта ошибка возникает при попытке обратиться к элементу массива за пределами заданного размера массива – например, если объявлен массив с индексами от 1 до 10, а мы пытаемся обратиться к элементу этого же массива с индексом 11. |
| 11 | Деление на ноль (Division by zero) |
| 13 | Несоответствие типа (Type mismatch)
Эта ошибка возникает при попытке присвоить переменной значение не соответствующего типа – например, объявлена переменная i типа Integer, и происходит попытка присвоить ей значение строкового типа. |
| 53 | Файл не найден (File not found)
Иногда возникает при попытке открыть не существующий файл. |
Перехват ошибок выполнения
Не все ошибки выполнения бывают вызваны недочётами в коде. Например, ошибки VBA не удастся избежать, если для работы макроса необходимо открыть файл с данными, а этого файла не существует. В таких случаях признаком профессионализма будет перехват ошибок и написание кода VBA, который будет выполняться при их возникновении. Таким образом, вместо неприятных сбоев будет происходить изящное завершение работы макроса.
Для того, чтобы помочь справиться с возникающими ошибками, VBA предоставляет разработчику операторы On Error и Resume. Эти операторы отслеживают ошибки и направляют выполнение макроса в специальный раздел кода VBA, в котором происходит обработка ошибки. После выполнения кода обработки ошибки, работа программы может быть продолжена с того места, где возникла ошибка, или макрос может быть остановлен полностью. Далее это показано на примере.
'Процедура Sub присваивает переменным Val1 и Val2 значения,
'хранящиеся в ячейках A1 и B1 рабочей книги Data.xlsx расположенной в каталоге C:Documents and Settings
Sub Set_Values(Val1 As Double, Val2 As Double)
Dim DataWorkbook As Workbook
On Error GoTo ErrorHandling
'Открываем рабочую книгу с данными
Set DataWorkbook = Workbooks.Open("C:Documents and SettingsData")
'Присваиваем переменным Val1 и Val2 данные из рабочей книги DataWorkbook
Val1 = Sheets("Лист1").Cells(1, 1)
Val2 = Sheets("Лист1").Cells(1, 2)
DataWorkbook.Close
Exit Sub
ErrorHandling:
'Если файл не найден, предлагаем пользователю разместить его в
'нужном месте и продолжить работу
MsgBox "Рабочая книга не найдена! " & _
"Пожалуйста добавьте книгу Data.xlsx в каталог C:Documents and Settings и нажмите OK."
Resume
End Sub
В этом коде производится попытка открыть файл Excel с именем Data. Если файл не найден, то пользователю будет предложено поместить этот файл в нужную папку. После того, как пользователь сделает это и нажмёт ОК, выполнение кода продолжится, и попытка открыть этот файл повторится. При желании вместо попытки открыть нужный файл, выполнение процедуры Sub может быть прервано в этом месте при помощи команды Exit Sub.
Логические ошибки
Логические ошибки (или баги) возникают в процессе выполнения кода VBA, но позволяют ему выполняться до самого завершения. Правда в результате могут выполняться не те действия, которые ожидалось, и может быть получен неверный результат. Такие ошибки обнаружить и исправить труднее всего, так как компилятор VBA их не распознаёт и не может указать на них так, как это происходит с ошибками компиляции и выполнения.
Например, при создании макроса в процедуре случайно были просуммированы не те переменные, которые требовалось просуммировать. Результат будет ошибочным, но макрос будет продолжать выполняться до завершения.
Редактор Excel VBA предоставляет набор инструментов отладки, которые помогут найти и исправить логические ошибки в коде VBA. В данной статье мы не будем рассматривать подробно эти инструменты. Любознательный пользователь может найти обзор инструментов отладки VBA на сайте Microsoft Help & Support (на английском).
Оцените качество статьи. Нам важно ваше мнение:
Не так давно очередной раз столкнулся с ошибками приложения Excel при попытке включения макросов после открытия файлов .xlsm. Вспомнил, что подобные проблемы преследуют пользователей довольно давно, но чаще всего они наблюдались с Excel 2013 и Excel 2016. Характерные особенности этой группы ошибок следующие:
- Приложение Excel закрывается при открытии файла с макросами (при включенном режиме безопасности Включить все макросы);
- Ошибка приложения Excel возникает при попытке включить содержимое (нажатии соответствующей кнопки);
- Ошибка приложения Excel возникает при сохранении файла с макросами;
Ну и по горячим следам очередного инцидента, дабы не откладывать на потом, решил для себя собрать небольшой хаб по ошибкам приложения Excel с последующей модификацией, дабы опять не терять время на поиск информации в Сети и на составление облака причин.
Суть в том, что в процессе открытия файла xlsm, и при отключенных макросах, в верхней части основного окна (над таблицей), высвечивается строка уведомления: ПРЕДУПРЕЖДЕНИЕ СИСТЕМЫ БЕЗОПАСНОСТИ Запуск макросов отключен, с кнопкой включения содержимого (макросов). Как только пользователь её нажимает, Excel попросту аварийно завершается (падает) с ошибкой Программа Microsoft Excel не работает и характерным окном уведомления:

При этом было замечено, что непосредственно перед возникновением ошибки приложения Excel никаких системных обновлений и обновлений пакета Office не устанавливалось. Возможно, каким-то образом задействованы последние обновления на Office, но прямой связи я не заметил, а подробного исследования проблемы не проводил. При этом зависимости от версии операционной системы (мною лично сбои наблюдались на Windows 10 LTSC и Windows 7 Professional) так же выявлено не было. При анализе аварийного дампа приложения (*.hdmp) обычно можно увидеть подобную информацию исключения (вывод урезан):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
. . . EXCEPTION_RECORD: (.exr —1) ExceptionAddress: 00007ff86a1e05ac (VBE7+0x00000000001405ac) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 0000000000000001 Parameter[1]: 0000000000000010 Attempt to write to address 0000000000000010 DEFAULT_BUCKET_ID: NULL_CLASS_PTR_WRITE PROCESS_NAME: EXCEL.EXE ERROR_CODE: (NTSTATUS) 0xc0000005 — <Unable to get error code text> EXCEPTION_CODE: (NTSTATUS) 0xc0000005 — <Unable to get error code text> EXCEPTION_CODE_STR: c0000005 EXCEPTION_PARAMETER1: 0000000000000001 EXCEPTION_PARAMETER2: 0000000000000010 WRITE_ADDRESS: 0000000000000010 . . . |
обычно это NTSTATUS с кодом c0000005 — Access violation, доступ запрещен. И чаще всего в дампе можно увидеть такой вот стек потока (вывод оптимизирован для улучшения представления):
|
. . . STACK_TEXT: 000000b9`1acfdd00 000001d3`2fb24e90 : 000001d3`5a0e0ef0 00000000`00000000 : VBE7+0x1405ac 000000b9`1acfdd08 000001d3`24c1fe20 : 00000000`00000000 000001d3`2fda9640 : 0x000001d3`2fb24e90 000000b9`1acfdd10 000001d3`6cf35760 : 000001d3`2fda9640 000001d3`045c9b30 : 0x000001d3`24c1fe20 000000b9`1acfdd18 000001d3`5a0e0ef0 : 000001d3`045c9b30 000001d3`2fcbb2b0 : 0x000001d3`6cf35760 000000b9`1acfdd20 00000000`00000000 : 000001d3`2fcbb2b0 000001d3`2fcbb318 : 0x000001d3`5a0e0ef0 . . . |
из которого единственное что понятно, так это то, что падение Excel происходит в недрах функций библиотеки vbe7.dll (среда исполнения VBA), подгруженной в адресное пространство процесса. Это указывает на проблемы с обработчиком VBA-скриптов, в контексте Excel чаще именуемых макросами.
НЕРЕШЕННОЕ: при отладке приложений из комплекта MS Office, вы не увидите имен функций в стеке вызовов, поскольку отсутствуют отладочные символы как к основным исполняемым файлам (Excel/Word/Outlook), так и к многочисленным библиотекам. Интересно, есть ли какое-либо решение?
VBA
Так что же такое VBA и для чего он предназначается?
VBA (Visual Basic for Application) — язык макропрограммирования, основанный на языке Visual Basic.
В приложениях, входящих в комплект MS Office, таких как Excel, Word, PowerPoint и Access, VBA используется для автоматизации множества рутинных задач (напр.: повторяющихся однотипных действий), позволяет создавать формы для общения с пользователем и предлагает множество иного богатого функционала. При помощи VBA доступно управление электронной таблицей посредством объектно-ориентированной модели кода/данных, при помощи VBA-кода входные данные таблиц могут быть обработаны и представлены в итоговых (результирующих) таблицах и диаграммах (графиках). Таблица становится интерфейсом кода, позволяя легко работать, изменять его и управлять расчётами. На выходе VBA проект, используемый в структурах описанных выше приложений (электронные таблицы Excel, презентации PowerPoint, базы Access), компилируется в специальный бинарный исполняемый файл, который размещается внутри файла основного формата. Применительно к Excel это файл vbaProject.bin, который располагается внутри *.xslm-файла в директории /xl, представляющий собой бинарный исполняемый файл проекта, содержащий макрос в откомпилированном (готовом к исполнению) виде.
Наиболее вероятной причиной сбоя является повреждение блока кода VBA, содержащегося в книге Excel. Об истоках этого остается только догадываться, возможно что в структуре .xlsm-файла, в процессе работы с документом, происходят какие-то [непредвиденные разработчиками] изменения, способные приводить блок кода в неработоспособное состояние.
Решение 1: вставка нового листа
Выполните приведенную последовательность действий:
- Открываем [проблемный] .xlsm-файл (файл с макросами).
- Не нажимаем кнопку Включить содержимое.
- Добавляем в книгу Excel новый лист: правая кнопка мыши на ярлыках Лист1/Лист2/Лист3 → Вставить → Лист.
- Сохраняем электронную таблицу. Закрываем Excel.
- Открываем проблемный файл заново и включаем макросы.
Решение 2: перекомпиляция проекта
Выполните последовательность действий:
- Запускаем и открываем новую книгу Excel (не ваш проблемный файл).
- Открываем меню Файл — выбираем Параметры — далее открываем Центр управления безопасностью и заходим в Параметры центра управления безопасностью.
- В разделе Параметры макросов — выставляем чекбокс Отключить все макросы с уведомлением.
- В разделе Надежные расположения — выставляем чекбокс Отключить все надежные расположения.
- В разделе Надежные документы — выставляем чекбокс Отключить надежные документы.
- Жмем везде OK. Закрываем Excel.
- Открываем [проблемный] .xlsm-файл (файл с макросами).
- Не нажимаем кнопку Включить содержимое.
- Открывает редактор Visual Basic при помощи комбинации клавиш Alt+F11. Либо можно использовать обходной маневр: в настройках включаем меню Разработчик, после этого в появившемся сверху в ленте меню Разработчик выбираем пункт Visual Basic.
- В открывшемся окне редактора Visual Basic (VBA редактор) пересохраняем проект: для этого жмем на панели инструментов кнопку Сохранить (изображение дискетки или комбинация Ctrl+S).
- Выбираем из меню Debug — выбираем пункт меню Compile VBA Project:

- Еще раз сохраняем проект кнопкой Сохранить.
- Закрываем редактор Visual Basic.
- Сохраняем файл Excel через меню Файл — опцию Сохранить (или нажатием на значок дискетки в левом верхнем углу, либо комбинация клавиш Ctrl+S).
- Возвращаем все установки безопасности, сделанные на предыдущих шагах (пункты 2-5).
- Закрываем xlsm-файл.
- Заново открываем [проблемный] файл, в верхней части, в строке статуса — включаем макросы посредством кнопки Включить содержимое.
Решение 3: добавление модуля
Дополнительное решение состоит в том, что бы внести изменения в макрос без перекомпиляции.
- Открываем [проблемный] .xlsm-файл (файл с макросами).
- Не нажимаем кнопку Включить содержимое.
- Открывает редактор Visual Basic (при помощи комбинации клавиш Alt+F11).
- Открываем меню Tools → пункт Options. В открывшемся окне переходим на вкладку General и деактивируем чекбокс Compile on Demand:

Закрываем окно Опции нажатием клавиши OK.
- В левом фрейме окна проекта (Project) спускаемся вниз, находим раздел Modules, жмем на нём правую кнопку → пункт Insert → Module:

- Далее просто закрываем окно редактора Visual Basic, сохраняем основной xslm-документ и закрываем Excel.
- Заново открываем [проблемный] файл, в верхней части, в строке статуса — включаем макросы посредством кнопки Включить содержимое.
“Abort, Retry, Fail?” – MS-DOS error message circa 1986
This post provides a complete guide to VBA Error Handing. If you are looking for a quick summary then check out the quick guide table in the first section.
If you are looking for a particular topic on VBA Error Handing then check out the table of contents below(if it’s not visible click on the post header).
If you are new to VBA Error Handling, then you can read the post from start to finish as it is laid out in logical order.
Contents
- 1 A Quick Guide to Error Handing
- 2 The Webinar
- 3 Download the Error Handling Library
- 4 Introduction
- 5 VBA Errors
- 5.1 Syntax Errors
- 5.2 Compilation Errors
- 5.2.1 Using Debug->Compile
- 5.2.2 Debug->Compile Error Summary
- 5.2.3 Debug->Compile Usage
- 5.3 Runtime Errors
- 5.3.1 Expected Versus Unexpected Errors
- 5.4 Runtime Errors that are not VBA Errors
- 6 The On Error Statement
- 6.1 On Error GoTo 0
- 6.2 On Error Resume Next
- 6.3 On Error GoTo [label]
- 6.4 On Error GoTo -1
- 6.5 Using On Error
- 7 Resume Next
- 8 The Err Object
- 8.1 Getting the Line Number
- 8.2 Using Err.Raise
- 8.3 Using Err.Clear
- 9 Logging
- 10 Other Error Related Items
- 10.1 Error Function
- 10.2 Error Statement
- 11 A Simple Error Handling Strategy
- 11.1 The Basic Implementation
- 12 A Complete Error Handling Strategy
- 12.1 An Example of using this strategy
- 13 Error Handling in a Nutshell
- 14 What’s Next?
A Quick Guide to Error Handing
| Item | Description |
|---|---|
| On Error Goto 0 | When error occurs, the code stops and displays the error. |
| On Error Goto -1 | Clears the current error setting and reverts to the default. |
| On Error Resume Next | Ignores the error and continues on. |
| On Error Goto [Label] | Goes to a specific label when an error occurs. This allows us to handle the error. |
| Err Object | When an error occurs the error information is stored here. |
| Err.Number | The number of the error. (Only useful if you need to check a specific error occurred.) |
| Err.Description | Contains the error text. |
| Err.Source | You can populate this when you use Err.Raise. |
| Err.Raise | A function that allows you to generate your own error. |
| Error Function | Returns the error text from an error number. Obsolete. |
| Error Statement | Simulates an error. Use Err.Raise instead. |
The Webinar
Members of the Webinar Archives can access the webinar for this article by clicking on the image below.
(Note: Archive members have access to the webinar archive.)

Download the Error Handling Library
Introduction
Error Handling refers to code that is written to handle errors which occur when your application is running. These errors are normally caused by something outside your control like a missing file, database being unavailable, data being invalid etc.
If we think an error is likely to occur at some point, it is good practice to write specific code to handle the error if it occurs and deal with it.
For all other errors, we use generic code to deal with them. This is where the VBA error handling statement comes into play. They allow our application to deal gracefully with any errors we weren’t expecting.
To understand error handling we must first understand the different types of errors in VBA.

VBA Errors
There are three types of errors in VBA:
- Syntax
- Compilation
- Runtime
We use error handling to deal with runtime errors. Let’s have a look at each of these error types so that it is clear what a runtime error is.
Syntax Errors
If you have used VBA for any length of time you will have seen a syntax error. When you type a line and press return, VBA will evaluate the syntax and if it is not correct it will display an error message.
For example if you type If and forget the Then keyword, VBA will display the following error message

Some examples of syntax errors are
' then is missing If a > b ' equals is missing after i For i 2 To 7 ' missing right parenthesis b = left("ABCD",1
Syntax errors relate to one line only. They occur when the syntax of one line is incorrect.
Note: You can turn off the Syntax error dialog by going to Tools->Options and checking off “Auto Syntax Check”. The line will still appear red if there is an error but the dialog will not appear.
Compilation Errors
Compilation errors occur over more than one line. The syntax is correct on a single line but is incorrect when all the project code is taken into account.
Examples of compilation errors are:
- If statement without corresponding End If statement
- For without Next
- Select without End Select
- Calling a Sub or Function that does not exist
- Calling a Sub or Function with the wrong parameters
- Giving a Sub or Function the same name as a module
- Variables not declared(Option Explicit must be present at the top of the module)
The following screenshot shows a compilation error that occurs when a For loop has no matching Next statement.

Using Debug->Compile
To find compilation errors, we use Debug->Compile VBA Project from the Visual Basic menu.
When you select Debug->Compile, VBA displays the first error it comes across.
When this error is fixed, you can run Compile again and VBA will then find the next error.
Debug->Compile will also include syntax errors in it’s search which is very useful.
If there are no errors left and you run Debug->Compile , it may appear that nothing happened. However, “Compile” will be grayed out in the Debug menu. This means your application has no compilation errors at the current time.
Debug->Compile Error Summary
- Debug->Compile finds compilation(project wide) errors.
- It will also find syntax errors.
- It finds one error each time you use it.
- When there are no compilation errors left the Compile option will appear grayed out in the menu.
Debug->Compile Usage
You should always use Debug->Compile before you run your code. This ensures that your code has no compilation errors when you run it.
If you do not run Debug->Compile then VBA may find compile errors when it runs. These should not be confused with Runtime errors.
Runtime Errors
Runtime errors occur when your application is running. They are normally outside of your control but can be caused by errors in your code.

For example, imagine your application reads from an external workbook. If this file gets deleted then VBA will display an error when your code tries to open it.
Other examples of runtime errors are
- a database not being available
- the user entering invalid data
- a cell containing text instead of a number
As we have seen, the purpose of error handling is to deal with runtime errors when they occur.
Expected Versus Unexpected Errors
When we think a runtime error could occur we put code in place to handle it. For example, we would normally put code in place to deal with a file not being found.
The following code checks if the file exists before it tries to open it. If the file does not exist then a user friendly message is displayed and the code exits the sub.
' https://excelmacromastery.com/ Sub OpenFile() Dim sFile As String sFile = "C:docsdata.xlsx" ' Use Dir to check if file exists If Dir(sFile) = "" Then ' if file does not exist display message MsgBox "Could not find the file " & sFile Exit Sub End If ' Code will only reach here if file exists Workbooks.Open sFile End Sub
When we think an error is likely to occur at some point, it is good practice to add code to handle the situation. We normally refer to these errors as expected errors.
If we don’t have specific code to handle an error it is considered an unexpected error. We use the VBA error handling statements to handle the unexpected errors.
Runtime Errors that are not VBA Errors
Before we look at the VBA Handling there is one type of error we must mention. Some runtime errors are not considered errors by VBA but only by the user.
Let me explain this with an example. Imagine you have an application that requires you to add the values in the variables a and b
result = a + b
Let’s say you mistakenly use an asterisk instead of the plus sign
result = a * b
This is not a VBA error. Your code syntax is perfectly legal. However, from your requirements point of view it is an error.
These errors cannot be dealt with using error handling as they obviously won’t generate any error. You can deal with these errors using Unit Testing and Assertions. I have an in-depth post about using VBA assertions – see How to Make Your Code BulletProof.
The On Error Statement
As we have seen there are two ways to treat runtime errors
- Expected errors – write specific code to handle them.
- Unexpected errors – use VBA error handling statements to handle them.
The VBA On Error statement is used for error handling. This statement performs some action when an error occurs during runtime.
There are four different ways to use this statement
- On Error GoTo 0 – the code stops at the line with the error and displays a message.
- On Error Resume Next – the code moves to next line. No error message is displayed.
- On Error GoTo [label] – the code moves to a specific line or label. No error message is displayed. This is the one we use for error handling.
- On Error GoTo -1 – clears the current error.
Let’s look at each of these statements in turn.
On Error GoTo 0
This is the default behavior of VBA. In other words, if you don’t use On Error then this is the behavior you will see.
When an error occurs, VBA stops on the line with the error and displays the error message. The application requires user intervention with the code before it can continue. This could be fixing the error or restarting the application. In this scenario no error handling takes place.
Let’s look at an example. In the following code, we have not used any On Error line so VBA will use the On Error GoTo 0 behavior by default.
' https://excelmacromastery.com/ Sub UsingDefault() Dim x As Long, y As Long x = 6 y = 6 / 0 x = 7 End Sub
The second assignment line results in a divide by zero error. When we run this code we will get the error message shown in the screenshot below

When the error appears you can choose End or Debug
If you select End then the application simply stops.
If you select Debug the application stops on the error line as the screenshot below shows

This behaviour is fine when you are writing VBA code as it shows you the exact line with the error.
This behavior is unsuitable for an application that you are given to a user. These errors look unprofessional and they make the application look unstable.
An error like this is essentially the application crashing. The user cannot continue on without restarting the application. They may not use it at all until you fix the error for them.
By using On Error GoTo [label] we can give the user a more controlled error message. It also prevents the application stopping. We can get the application to perform in a predefined manner.
On Error Resume Next
Using On Error Resume Next tells VBA to ignore the error and continue on.
There are specific occasions when this is useful. Most of the time you should avoid using it.
If we add Resume Next to our example Sub then VBA will ignore the divide by zero error
' https://excelmacromastery.com/ Sub UsingResumeNext() On Error Resume Next Dim x As Long, y As Long x = 6 y = 6 / 0 x = 7 End Sub
It is not a good idea to do this. If you ignore the error, then the behavior can be unpredictable. The error can affect the application in multiple ways.You could end up with invalid data. The problem is that you aren’t aware that something went wrong because you have suppressed the error.
The code below is an example of where using Resume Next is valid
' https://excelmacromastery.com/ Sub SendMail() On Error Resume Next ' Requires Reference: ' Microsoft Outlook 15.0 Object Library Dim Outlook As Outlook.Application Set Outlook = New Outlook.Application If Outlook Is Nothing Then MsgBox "Cannot create Microsoft Outlook session." _ & " The email will not be sent." Exit Sub End If End Sub
In this code we are checking to see if Microsoft Outlook is available on a computer. All we want to know is if it is available or not. We are not interested in the specific error.
In the code above, we continue on if there is an error. Then in the next line we check the value of the Outlook variable. If there has been an error then the value of this variable will be set to Nothing.
This is an example of when Resume could be useful. The point is that even though we use Resume we are still checking for the error. The vast majority of the time you will not need to use Resume.
On Error GoTo [label]
This is how we use Error Handling in VBA. It is the equivalent of the Try and Catch functionality you see in languages such as C# and Java.
When an error occurs you send the error to a specific label. It is normally at the bottom of the sub.
Let’s apply this to the sub we have been using
' https://excelmacromastery.com/ Sub UsingGotoLine() On Error GoTo eh Dim x As Long, y As Long x = 6 y = 6 / 0 x = 7 Done: Exit Sub eh: MsgBox "The following error occurred: " & Err.Description End Sub
The screenshot below shows what happens when an error occurs

VBA jumps to the eh label because we specified this in the On Error Goto line.
Note 1: The label we use in the On…GoTo statement, must be in the current Sub/Function. If not you will get a compilation error.
Note 2: When an error occurs when using On Error GoTo [label], the error handling returns to the default behaviour i.e. The code will stop on the line with the error and display the error message. See the next section for more information about this.
On Error GoTo -1
This statement is different than the other three. It is used to clear the current error rather than setting a particular behaviour.
When an error occurs using On Error GoTo [label], the error handling behaviour returns to the default behaviour i.e. “On Error GoTo 0”. That means that if another error occurs the code will stop on the current line.
This behaviour only applies to the current sub. Once we exit the sub, the error will be cleared automatically.
Take a look at the code below. The first error will cause the code to jump to the eh label. The second error will stop on the line with the 1034 error.
' https://excelmacromastery.com/ Sub TwoErrors() On Error Goto eh ' generate "Type mismatch" error Error (13) Done: Exit Sub eh: ' generate "Application-defined" error Error (1034) End Sub
If we add further error handling it will not work as the error trap has not been cleared.
In the code below we have added the line
On Error Goto eh_other
after we catch the first error.
This has no effect as the error has not been cleared. In other words the code will stop on the line with the error and display the message.
' https://excelmacromastery.com/ Sub TwoErrors() On Error Goto eh ' generate "Type mismatch" error Error (13) Done: Exit Sub eh: On Error Goto eh_other ' generate "Application-defined" error Error (1034) Exit Sub eh_other: Debug.Print "eh_other " & Err.Description End Sub
To clear the error we use On Error GoTo -1. Think of it like setting a mouse trap. When the trap goes off you need to set it again.
In the code below we add this line and the second error will now cause the code to jump to the eh_other label
' https://excelmacromastery.com/ Sub TwoErrors() On Error Goto eh ' generate "Type mismatch" error Error (13) Done: Exit Sub eh: ' clear error On Error Goto -1 On Error Goto eh_other ' generate "Application-defined" error Error (1034) Exit Sub eh_other: Debug.Print "eh_other " & Err.Description End Sub
Note 1: There are probably rare cases where using On Error GoTo -1 is useful. In most cases using Resume Next is better as it clears the error and resumes the code at the next line after the error occurs.
Note 2: The Err Object has a member Clear. Using Clear clears the text and numbers in the Err object, but it does NOT reset the error.
Using On Error
As we have seen, VBA will do one of three things when an error occurs
- Stop and display the error.
- Ignore the error and continue on.
- Jump to a specific line.
VBA will always be set to one of these behaviors. When you use On Error, VBA will change to the behaviour you specify and forget about any previous behavior.
In the following Sub, VBA changes the error behaviour each time we use the On Error statement
' https://excelmacromastery.com/ Sub ErrorStates() Dim x As Long ' Go to eh label if error On Error Goto eh ' this will ignore the error on the following line On Error Resume Next x = 1 / 0 ' this will display an error message on the following line On Error Goto 0 x = 1 / 0 Done: Exit Sub eh: Debug.Print Err.Description End Sub
Resume Next
The Resume Next statement is used to clear the error and then resume the code from the line after where the error occurred.
If your code can have multiple errors and you want to keep detecting them then this line is very useful.
For example, in the following code we want to resume the code after the error has been reported:
Private Sub Main() On Error Goto eh Dim i As Long For i = 1 To 3 ' Generate type mismatch error Error 13 Next i done: Exit Sub eh: Debug.Print i, Err.Description End Sub
We could use On Error Goto -1 to clear the code and then use a goto statement to go back to the code like this:
Private Sub Main() On Error Goto eh Dim i As Long For i = 1 To 3 ' Generate type mismatch error Error 13 continue: Next i done: Exit Sub eh: Debug.Print i, Err.Description On Error Goto -1 ' clear the error Goto continue ' return to the code End Sub
The Resume Next provides a nicer way of doing it and it always means the code is much clearer and easier to understand:
Private Sub Main() On Error Goto eh Dim i As Long For i = 1 To 3 ' Generate type mismatch error Error 13 continue: Next i done: Exit Sub eh: Debug.Print i, Err.Description ' clear the error and return to the code Resume Next End Sub
The Err Object
When an error occurs you can view details of the error using the Err object.
When an runtime error occurs, VBA automatically fills the Err object with details.
The code below will print “Error Number: 13 Type Mismatch” which occurs when we try to place a string value in the long integer total
' https://excelmacromastery.com/ Sub UsingErr() On Error Goto eh Dim total As Long total = "aa" Done: Exit Sub eh: Debug.Print "Error number: " & Err.Number _ & " " & Err.Description End Sub
The Err.Description provides details of the error that occurs. This is the text you normally see when an error occurs e.g. “Type Mismatch”
The Err.Number is the ID number of the error e.g. the error number for “Type Mismatch” is 13. The only time you really need this is if you are checking that a specific error occurred and this is only necessary on rare occasions.
The Err.Source property seems like a great idea but it does not work for a VBA error. The source will return the project name, which hardly narrows down where the error occurred. However, if you create an error using Err.Raise you can set the source yourself and this can be very useful.
Getting the Line Number
The Erl function is used to return the line number where the error occurs.
It often causes confusion. In the following code, Erl will return zero
' https://excelmacromastery.com/ Sub UsingErr() On Error Goto eh Dim val As Long val = "aa" Done: Exit Sub eh: Debug.Print Erl End Sub
This is because there are no line numbers present. Most people don’t realise it but VBA allows you to have line numbers.
If we change the Sub above to have line number it will now print out 20
' https://excelmacromastery.com/ Sub UsingErr() 10 On Error Goto eh Dim val As Long 20 val = "aa" Done: 30 Exit Sub eh: 40 Debug.Print Erl End Sub
Adding line numbers to your code manually is cumbersome. However there are tools available that will allow you to easily add and remove line numbers to a sub.
When you are finished working on a project and hand it over to the user it can be useful to add line numbers at this point. If you use the error handling strategy in the last section of this post, then VBA will report the line where the error occurred.
Using Err.Raise
Err.Raise allows us to create errors. We can use it to create custom errors for our application which is very useful. It is the equivalent of the Throw statement in JavaC#.
The format is as follows
Err.Raise [error number], [error source], [error description]
Let’s look at a simple example. Imagine we want to ensure that a cell has an entry that has a length of 5 characters. We could have a specific message for this
' https://excelmacromastery.com/ Public Const ERROR_INVALID_DATA As Long = vbObjectError + 513 Sub ReadWorksheet() On Error Goto eh If Len(Sheet1.Range("A1")) <> 5 Then Err.Raise ERROR_INVALID_DATA, "ReadWorksheet" _ , "The value in the cell A1 must have exactly 5 characters." End If ' continue on if cell has valid data Dim id As String id = Sheet1.Range("A1") Done: Exit Sub eh: ' Err.Raise will send code to here MsgBox "Error found: " & Err.Description End Sub
When we create an error using Err.Raise we need to give it a number. We can use any number from 513 to 65535 for our error. We must use vbObjectError with the number e.g.
Err.Raise vbObjectError + 513
Using Err.Clear
Err.Clear is used to clear the text and numbers from the Err.Object. In other words, it clears the description and number.If you want the clear the actual error you can use either On Error GoTo -1 or Resume Next
It is rare that you will need to use Err.Clear but let’s have a look at an example where you might.
In the code below we are counting the number of errors that will occur. To keep it simple we are generating an error for each odd number.
We check the error number each time we go through the loop. If the number does not equal zero then an error has occurred. Once we count the error we need to set the error number back to zero so it is ready to check for the next error.
' https://excelmacromastery.com/ Sub UsingErrClear() Dim count As Long, i As Long ' Continue if error as we will check the error number On Error Resume Next For i = 0 To 9 ' generate error for every second one If i Mod 2 = 0 Then Error (13) ' Check for error If Err.Number <> 0 Then count = count + 1 Err.Clear ' Clear Err once it is counted End If Next Debug.Print "The number of errors was: " & count End Sub
Note 1: Err.Clear resets the text and numbers in the error object but it does not clear the error – see Resume Next Or On Error GoTo -1 for more information about clearing the actual error.
Logging
Logging means writing information from your application when it is running. When an error occurs you can write the details to a text file so you have a record of the error.
The code below shows a very simple logging procedure
' https://excelmacromastery.com/ Sub Logger(sType As String, sSource As String, sDetails As String) Dim sFilename As String sFilename = "C:templogging.txt" ' Archive file at certain size If FileLen(sFilename) > 20000 Then FileCopy sFilename _ , Replace(sFilename, ".txt", Format(Now, "ddmmyyyy hhmmss.txt")) Kill sFilename End If ' Open the file to write Dim filenumber As Variant filenumber = FreeFile Open sFilename For Append As #filenumber Print #filenumber, CStr(Now) & "," & sType & "," & sSource _ & "," & sDetails & "," & Application.UserName Close #filenumber End Sub
You can use it like this
' Create unique error number ' https://excelmacromastery.com/ Public Const ERROR_DATA_MISSING As Long = vbObjectError + 514 Sub CreateReport() On Error Goto eh If Sheet1.Range("A1") = "" Then Err.Raise ERROR_DATA_MISSING, "CreateReport", "Data is missing from Cell A1" End If ' other code here Done: Exit Sub eh: Logger "Error", Err.Source, Err.Description End Sub
The log is not only for recording errors. You can record other information as the application runs. When an error occurs you can then check the sequence of events before an error occurred.
Below is an example of logging. How you implement logging really depends on the nature of the application and how useful it will be:
' https://excelmacromastery.com/ Sub ReadingData() Logger "Information", "ReadingData()", "Starting to read data." Dim coll As New Collection ' add data to the collection coll.Add "Apple" coll.Add "Pear" If coll.Count < 3 Then Logger "Warning", "ReadingData()", "Number of data items is low." End If Logger "Information", "ReadingData()", "Number of data items is " & coll.Count Logger "Information", "ReadingData()", "Finished reading data." End Sub
Having a lot of information when dealing with an error can be very useful. Often the user may not give you accurate information about the error that occurred. By looking at the log you can get more accurate information about the information.
This section covers some of the other Error Handling tools that VBA has. These items are considered obsolete but I have included them as they may exist in legacy code.
Error Function
The Error Function is used to print the error description from a given error number. It is included in VBA for backward compatibility and is not needed because you can use the Err.Description instead.
Below are some examples:
' Print the text "Division by zero" Debug.Print Error(11) ' Print the text "Type mismatch" Debug.Print Error(13) ' Print the text "File not found" Debug.Print Error(53)
Error Statement
The Error statement allows you to simulate an error. It is included in VBA for backward compatibility. You should use Err.Raise instead.
In the following code we simulate a “Divide by zero” error.
' https://excelmacromastery.com/ Sub SimDivError() On Error Goto eh ' This will create a division by zero error Error 11 Exit Sub eh: Debug.Print Err.Number, Err.Description End Sub
This statement is included in VBA for backward compatibility. You should use Err.Raise instead.
A Simple Error Handling Strategy
With all the different options you may be confused about how to use error handling in VBA. In this section, I’m going to show you how to implement a simple error handling strategy that you can use in all your applications.
The Basic Implementation
This is a simple overview of our strategy
- Place the On Error GoTo Label line at the start of our topmost sub.
- Place the error handling Label at the end of our topmost sub.
- If an expected error occurs then handle it and continue.
- If the application cannot continue then use Err.Raise to jump to the error handling label.
- If an unexpected error occurs the code will automatically jump to the error handling label.
The following image shows an overview of how this looks

The following code shows a simple implementation of this strategy:
' https://excelmacromastery.com/ Public Const ERROR_NO_ACCOUNTS As Long = vbObjectError + 514 Sub BuildReport() On Error Goto eh ' If error in ReadAccounts then jump to error ReadAccounts ' Do something with the code Done: Exit Sub eh: ' All errors will jump to here MsgBox Err.Source & ": The following error occured " & Err.Description End Sub Sub ReadAccounts() ' EXPECTED ERROR - Can be handled by the code ' Application can handle A1 being zero If Sheet1.Range("A1") = 0 Then Sheet1.Range("A1") = 1 End If ' EXPECTED ERROR - cannot be handled by the code ' Application cannot continue if no accounts workbook If Dir("C:DocsAccount.xlsx") = "" Then Err.Raise ERROR_NO_ACCOUNTS, "UsingErr" _ , "There are no accounts present for this month." End If ' UNEXPECTED ERROR - cannot be handled by the code ' If cell B3 contains text we will get a type mismatch error Dim total As Long total = Sheet1.Range("B3") ' continue on and read accounts End Sub
This is a nice way of implementing error handling because
- We don’t need to add error handling code to every sub.
- If an error occurs then VBA exits the application gracefully.
A Complete Error Handling Strategy
The above strategy has one major drawback. It doesn’t provide any information about the error. It is better than having no strategy as it prevents the application crashing. But that is the only real benefit.
VBA doesn’t fill Err.Source with anything useful so we have to do this ourselves.
In this section, I am going to introduce a more complete error strategy. I have written two subs that perform all the heavy lifting so all you have to do is add them to your project.
The purpose of this strategy is to provide you with the Stack* and line number when an error exists.
*The Stack is the list of sub/functions that were currently in use when the error occurred.
This is our strategy
- Place error handling in all the subs.
- When an error occurs, the error handler adds details to the error and raises it again.
- When the error reaches the topmost sub it is displayed.
We are simply “bubbling” the error to the top. The following diagram shows a simple visual of what happens when an error occurs in Sub3

The only messy part to this is formatting the strings correctly. I have written two subs that handle this, so it is taken care of for you.
There are the two helper subs, RaiseError and DisplayError. You can download the library below:
An Example of using this strategy
Here is a simple coding example that uses these subs. In this strategy, we don’t place any code in the topmost sub. We only call subs from it.
' https://excelmacromastery.com/ Sub Topmost() On Error Goto EH Level1 Done: Exit Sub EH: DisplayError Err.source, Err.Description, "Module1.Topmost", Erl End Sub Sub Level1() On Error Goto EH Level2 Done: Exit Sub EH: RaiseError Err.Number, Err.source, "Module1.Level1", Err.Description, Erl End Sub Sub Level2() On Error Goto EH ' Error here Dim a As Long a = "7 / 0" Done: Exit Sub EH: RaiseError Err.Number, Err.source, "Module1.Level2", Err.Description, Erl End Sub
The result looks like this:

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

Error Handling in a Nutshell
- Error Handling is used to handle errors that occur when your application is running.
- You write specific code to handle expected errors. You use the VBA error handling statement On Error GoTo [label] to send VBA to a label when an unexpected error occurs.
- You can get details of the error from Err.Description.
- You can create your own error using Err.Raise.
- Using one On Error statement in the top most sub will catch all errors in subs that are called from here.
- If you want to record the name of the Sub with the error, you can update the error and rethrow it.
- You can use a log to record information about the application as it is running.
What’s Next?
Free VBA Tutorial If you are new to VBA or you want to sharpen your existing VBA skills then why not try out the The Ultimate VBA Tutorial.
Related Training: Get full access to the Excel VBA training webinars and all the tutorials.
(NOTE: Planning to build or manage a VBA Application? Learn how to build 10 Excel VBA applications from scratch.)
Just like any other programming language, VBA has no luck when it comes to errors and you have to deal with them, no matter what. They may come from different sources, like bad coding, impossible operations (like zero division), or unexpected errors.
The best way to deal with it is to have a proper understanding of all the possible outcomes of the result that you could get with code. Look at the below example where we have a VBA code that calculates the square root of the number using the value which you have in the selected cell.
Sub Square_Root()
ActiveCell.Value = ActiveCell.Value ^ (1 / 2)
End Sub
But if the active cell has a value other than a number, you’ll get a run-time error, just like below.

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

- Break on All Errors: If you have this option activated, VBA will stop the code for all types of errors even if you have used all kinds of error handling techniques.
- Break-in Class Module: With this option, VBA will stop all your codes that are not handled by any technique. And if you’re using objects such as Userforms, it will also break within those objects and highlight the exact line where the error is.
- Break on Unhandled Errors: This is the default setting that helps you to know about all the errors where you are not using any error handling technique and stop the code for all the unhandled errors. (But, if you’re using objects such as Userforms, this will not highlight the line causing the error in the object but will only highlight the line that’s referring to that object).
Types of VBA Errors
To understand VBA errors, you can split them into four categories, and below is the explanation of these types of errors.
1. Syntax Errors
While writing VBA code you need to follow a particular Syntax and when you skip it or don’t write it in the way it should be you can face SYNTAX error (also called Language error). It’s like typos that you do while writing your codes.
Well, VBA helps you by pointing out these errors by showing an error message. You just need to make sure you have “Auto Syntax Check” activated in your VB editor.
Go to the Tool ➤ Options and make sure to tick the “Auto Syntax Check”. With this, whenever you make a SYNTAX error, VBA will show an error message.

But if “Auto Syntax Check” is disabled VBA still highlights the line of code with the error but won’t show the error message.
2. Compile Errors
It comes when you write code to perform an activity, but that activity is not valid or can’t be performed by VBA. The best example is where you have a code using the IF statement but missed to add END IF at the end of the statement and now when you run this VBA will show you a compilation error message.

Apart from this, there are some other examples of compile errors:
- Using For without Next (For Next).
- Select without End Select (Select Case).
- Not Declaring a Variable when you have “Option Explicit” enabled.
- Calling a Sub/Function that does not exist.
3. Runtime Errors
A runtime error occurs at the time of executing the code. Remember the example, I shared with you above when the code calculated the square root of a number.

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

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

And when a runtime error occurs it stops the execution of the code. If you click on the “Debug” button it shows you the line of code that has that error by highlighting it yellow. Or you can click on the “End” button to stop the code to execute and close the error message.
4. Logical Error
It’s not an error but a mistake while writing code. These types of errors sometimes can give you nuts while finding them and correcting them.
Let’s say you write code and while declaring a variable you used the wrong data type, or you have used the wrong calculation steps. In this case, your code will work fine, and you won’t find this error easily. The best way to deal with this kind of problem is to run each line of code one by one.
Using Debug Tools in VBA
VBA provides you a set of tools to debug your code and remove bugs from your codes.
1. Compile VBA Project
In Visual Basic Editor, there’s an option that you can use instantly after completing your code. These compile options scan each line of your code and show a message box if there is an error in your code.
Note: Compile VBA option only traces Syntax and Compile errors, not runtime errors as these errors only rise when a code is running. To use Compile VBA Project, go to ➤ Debug ➤ Compile VBA Project.

Once you run “Compile VBA Project” and you have no error in your code, the options will be greyed out.
2. Run Each Line of Code One by One
This is how I do it. When I complete a code, I simply run it line by line to check if there’s an error occurring. It may take time, but it helps you to get to about all the errors (Syntax, Compile, and Run-Time).
On the “Debug Toolbar”, there’s a button “Step In” which you can use to execute a code line by line or you can simply press F8 to execute a single line and then press it again to execute the next line in the code.

Using “On ERROR” Statement to Handle VBA Errors
It’s important to check your codes and find possible errors in all the debugging ways you have. But, the best and most effective way is to create error-handling statements that can deal with an error and make your code flawless while executing. Let’s learn about these statements. When an error occurs in a VBA code the best possible ways to handle that error can be:
- Let the VBA ignore the error and execute the code
- Let a special set of statements to run when an error occurs.
In both solutions, you can use “On Error” statements. Below four “On Error” statements that you can use. And now, let’s look at each statement one by one.
1. On Error Resume Next
This simple line of code lets VBA continue executing the code despite the occurrence of an error. The IDEA is simple: Move to the next line of the code if there’s an error found somewhere while executing.
In the below code, you have two lines of code:
- The first line says the value of cell A1 is 25 divided by 0
- And the second line says the value cell A2 is 10 divided by 5
Now there’s a problem with the code which you have inline one. As you know if you divide anything with 0 the result will be an error. So, when you run this code VBA will show an error message “Run-time error ‘11’ Division by Zero” and stop the execution.
But when you add the “On Error Resume Next” at the very beginning of the code and run the code, VBA simply skips that line of code where the error occurs and continues with the second line and add that value in cell A2.
Sub myDivide()
On Error Resume Next
Range("A1").Value = 25 / 0
Range("A2").Value = 10 / 5
End Sub
So, whenever you want your code to get executed despite an error occurring anywhere simply use the “On Error Resume Next” statement in your code.
But here’s one more thing you need to note down: It will only skip errors that occur after it.
Let’s say if an error occurs at line 5 and you have added “On Error Resume Next” on line 8 then it would not skip that error. So, the best way is to add it as the first line of the code in the procedure.
2. On Error GoTo 0
It’s the default behavior of VBA that when an error occurred it stops the execution of the code.
Well, using “On Error GoTo 0” make no difference in your code. VBA will simply stop the code and show a message with a description of the error. Then why would I bother to use it? Smart Question. Let’s use the example you have used above in “On Error Resume Next”.
In this code whenever an error will occur VBA will resume to the next line of code and run it and you won’t see any error message. But let’s say you have more lines in your code and you don’t want to surpass those lines if there’s an error in the code.
So, if you enter “On Error GoTo 0” after the second line of code it will restore the VBA’s default error handler which shows error messages each time an error occurs.
3. On Error GoTo [Label]
Think about a place in a building where you can head up in an emergency. In the same way, using “On Error GoTo [Label]”, you can simply create a separate block of code in your main code to deal with an error.
Actually, “On Error GoTo [Label]” is a far better and more convenient way to deal with errors. In the below code, you have “On Error GoTo Oh!Error” now in this line statement the word “Oh!Error” is the label.
If you look at the end of the code where you have a specific starting with the label name and then a code for a message box with a message about the code.
Now, what happens if an error occurs the VBA will jump to the label “Oh!Error” and run the block of code which you have after that label.
But there’s one thing you need to take care of: If an error doesn’t occur even then the label you have in your code will get executed. There are two things you need to do:
- First, make sure to add your Error label at the end of the code.
- Second, add an “Exit Sub” before the error label.
With this, you’ll benefit in both situations. Let’s say if an error occurs and VBA jumps to the label you specified there would only be code from the label itself to code. And if an error doesn’t occur “Exit Sub” statement which you have before the label will exit the procedure without executing the error label.
4. On Error GoTo -1
Before we get into this, let me share something with you. When an error occurs in a code VBA stores that error log in its memory and only clears it when the routine ends.
O VBA! Live in Present
To deal with the second error in a VBA code you need to clear the first error from VBA’s memory. In the below code, you have two “On Error GoTo [Label]” statements that deal with errors from two different blocks of code.
But if you run this code, when the second error VBA won’t jump to the label which you have defined and instead show the error message “Type Mismatch”.
Sub Square_Root()
On Error GoTo myError1
Range("A1").Value = Range("A1").Value ^ (1 / 2)
myError1:
MsgBox "There's some problem with the value you have in the cell A1."
On Error GoTo myError2
Range("A2").Value = Range("A2").Value ^ (1 / 2)
myError2:
MsgBox "There's some problem with the value you have in the cell A2."
End Sub
To fix this problem you can use “On Error GoTo -1” which makes VBA remove the current error from its storage memory.
Sub Square_Root()
On Error GoTo myError1
Range("A1").Value = Range("A1").Value ^ (1 / 2)
myError1:
MsgBox "There's some problem with the value you have in the cell A1."
On Error GoTo -1
On Error GoTo myError2
Range("A2").Value = Range("A2").Value ^ (1 / 2)
myError2:
MsgBox "There's some problem with the value you have in the cell A2."
End Sub
Now when you run this code, “On Error GoTo -1” removes the error from the memory and VBA deals with the error in the second statement as you want.
What Else Do I Need to Know to Handle Errors in VBA?
Apart from using error handling techniques, there are a few other things that you can use to deal with errors in a better way.
Err Object
When an error occurred while executing of code, you can use the Err object to get details about that error. There are a few properties and methods which you can use with Err object. Let’s learn them one by one.
Properties
Below are the properties which you can use with the Err object:
- Err.Number: With an error occurred there’s a number stored in the Err Object. In the below code, when occurred the message box will show the error number.
- Err.Description: This property shows the description of the error which can help you to understand the reason for the error.
- Err.Source: This property shows you in which project the error has occurred.
- Err.HelpContext: This property returns the help context id for the error in the help file.
- Err.HelpContext: This is a string value for the location of the help file.
Normally when you are dealing with errors using error handling techniques you won’t be using the Err Object that much in your codes. But below is a simple example to use it.
Sub Square_Root()
On Error GoTo myError1
Range("A1").Value = Sqr(Range("A1").Value)
Exit Sub
myError1:
MsgBox "There's some problem with the value you have in the cell A1." & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Description: " & Err.Description
End Sub
When you run the above code, and if an error occurred, it will show a message box with the error number and description of the error.
Methods
With Err Object there are two methods that you can also use.
- Err.Clear: This method clears the error number and error description from VBA’s memory (It’s different from “On Error GoTo -1” as it doesn’t completely reset the error).
- Err.Raise: With this method, you can generate a run time error in your code intentionally, and below is the syntax which needs to follow:
Err.Raise [number], [source], [description], [helpfile], [helpcontext]
Quick Tips on Error Handling
Here are a few quick tips which you can use to deal with VBA errors in a better way.
- Use “On Error Resume Next” only when you know for sure about an error to occur and it’s OK to skip the line of code with an error and it’s safe to skip to the next line.
- The best way to deal with run-time errors is by using “Error Handler” with “On Error GoTo [Label]”. This ensures that whenever the error occurs you will know about it, but it won’t show that nasty error message.
- Whenever you use the error handler make sure to use “Exit Sub” before it.
There’s More
Below are some of the links which could be useful for you to learn more about error handling in VBA, make sure to check out all of these:
Type Mismatch (Error 13) | Runtime (Error 1004) | Object Required (Error 424) | Out of Memory (Error 7) | Object Doesn’t Support this Property or Method (Error 438) | Invalid Procedure Call or Argument (Error 5) | Overflow (Error 6) | Automation error (Error 440) | VBA Error 400 | VBA Subscript Out of Range Runtime Error 9
Last week we received an update going from Windows7 Excel 2010 to Windows 10 with the MS package 2016.
We had a SHARED Excel workbook with some simple macro’s (nothing complicated). This worked fine for everybody.
After the update ones the workbook is opened by someone and changes are made and saved, i get Microsoft Visual Basic for Applications: «Automation error, Catastrophic failure». VBA opens to debug, but because i’m working in a shared workbook
there is nothing to see. This error keeps reappearing each time i open the workbook. Until someone opens the workbook who had nothing saved previously, removes all users and saves the workbook exclusive. At that point i can open the workbook, make it shared
again and as long nobody is making any changes in the workbook i’ll be able to open it in shared.
During exclusive mode, no error appears and everithing is working fine.
I tried a few things that i could find on the web but nothing worked so far (Add-in’s, Manual calculation, binary workbook,…).
On the web i found someting about MSCOMCTL.OCX. So in VBA i tried to set the automation references for MSCOMCTL.OCX . I can find MSCOMCTL.OCX (C:WindowsSysWOW64MSCOMCTL.OCX),
select it and in the list of references
Microsoft Windows Common Controls 6.0 (SP 6) appears referenced. When i close the references and reopen the references,
Microsoft Windows Common Controls 6.0 (SP 6) is disappeared and i have to brows again for MSCOMCTL.OCX . Sometimes when referenced it appears 4th or 5th in
the list, most of the times at the end.
This workbook is used by many people over different services, some having issues, some don’t. This problem occures now also by 1 user who diden’t update yet and works with Excel 2010, Windows 7.
My point of view: this is realy a sharing issue. But how can i solve it ? Does excel stores a «working copy» on my workstation during editing wich can cause the problem by reopening ?
-
Edited by
Tuesday, March 27, 2018 9:24 AM