Добавить в корзинуПозвонить
Найти в Дзене
Макрос решает

Ловить ошибки в VBA — On Error, обработка ошибок, примеры

Подробно разбираем обработку ошибок в VBA: почему нет Catch, как использовать On Error, шаблоны и реальные примеры. Вы написали макрос, всё выглядит правильно, нажимаете запуск — и Excel вываливает ошибку. Первая реакция: «Сейчас просто добавлю Catch, как в других языках, и всё будет нормально». Но VBA на это смотрит спокойно и говорит: «Нет». И вот здесь начинается путаница, из-за которой многие либо игнорируют ошибки, либо пишут нестабильный код. Разберёмся, как это работает на самом деле. В языках вроде C#, Java или Python есть привычная конструкция: try → catch → finally Она позволяет:
— обернуть код
— перехватить ошибку
— обработать её В VBA этого механизма нет. Если написать: Catch: это просто метка, но без правильной логики перехода она ничего не делает. Всё управление ошибками в VBA построено вокруг одной конструкции: On Error Есть три варианта: — On Error GoTo
— On Error Resume Next
— On Error GoTo 0 И именно они определяют поведение макроса. Вот шаблон, который нужно запомнит
Оглавление

Подробно разбираем обработку ошибок в VBA: почему нет Catch, как использовать On Error, шаблоны и реальные примеры.

Вы написали макрос, всё выглядит правильно, нажимаете запуск — и Excel вываливает ошибку. Первая реакция: «Сейчас просто добавлю Catch, как в других языках, и всё будет нормально». Но VBA на это смотрит спокойно и говорит: «Нет». И вот здесь начинается путаница, из-за которой многие либо игнорируют ошибки, либо пишут нестабильный код. Разберёмся, как это работает на самом деле.

Почему Catch в VBA не работает

В языках вроде C#, Java или Python есть привычная конструкция:

try → catch → finally

Она позволяет:
— обернуть код
— перехватить ошибку
— обработать её

В VBA этого механизма нет. Если написать:

Catch:

это просто метка, но без правильной логики перехода она ничего не делает.

Единственный механизм в VBA — On Error

Всё управление ошибками в VBA построено вокруг одной конструкции:

On Error

Есть три варианта:

— On Error GoTo
— On Error Resume Next
— On Error GoTo 0

И именно они определяют поведение макроса.

Правильная базовая схема (золотой стандарт)

Вот шаблон, который нужно запомнить:

Sub Example()
On Error GoTo ErrHandler
' основной код
Dim x As Integer
x = 1 / 0
Exit Sub
ErrHandler:
MsgBox "Ошибка #" & Err.Number & vbCrLf & Err.Description
Err.Clear
End Sub

Почему здесь важна строка Exit Sub

Это момент, который часто пропускают. Если её убрать, макрос выполнит:
— основной код
— затем
всё равно зайдёт в ErrHandler

Даже если ошибки не было.

👉 Поэтому Exit Sub — обязательная часть.

Разбор вашей ошибки (на практике)

Вы писали что-то вроде:

Catch:
MsgBox ("Description = " + Err.Description + ...)

Здесь сразу несколько проблем:

1. В VBA нет Catch

Нужно:

On Error GoTo Catch

И только тогда метка начинает работать.

2. Нельзя использовать “+” для строк

В VBA строки соединяются так:

Err.Description & " текст"

А не через +

3. Лишние скобки в MsgBox

Это не критично, но выглядит как перенос из других языков.

Исправленный вариант

Sub Test()
On Error GoTo Catch
' код с ошибкой
Dim x As Integer
x = 1 / 0
Exit Sub
Catch:
MsgBox "Description = " & Err.Description & " Number = " & CStr(Err.Number)
End Sub

Когда использовать On Error Resume Next

Это опасный инструмент.

Он говорит VBA:

👉 «если ошибка — просто игнорируй»

Пример:

On Error Resume Next
Set ws = Worksheets("НетЛиста")
On Error GoTo 0

Если листа нет:
— ошибки не будет
— но переменная будет пустой

Где это реально нужно

— проверка существования объектов
— попытки безопасного доступа
— работа с внешними ресурсами

Где это ломает код

Если использовать его «на весь макрос»:

— ошибки пропадают
— код продолжает выполняться
— результат становится непредсказуемым

Это одна из самых частых причин «магических багов».

Профессиональный шаблон обработки ошибок

Вот вариант, который используют в нормальных проектах:

Sub SafeRun()
On Error GoTo ErrHandler
' основной код
Exit Sub
ErrHandler:
MsgBox "Ошибка #" & Err.Number & vbCrLf & Err.Description, vbCritical, "Ошибка VBA"
Err.Clear
End Sub

Что можно получить из Err

Объект Err даёт много информации:

— Number — код ошибки
— Description — описание
— Source — источник
— HelpFile — файл справки
— HelpContext — контекст

Но в 90% случаев хватает первых двух.

Главная ошибка новичков

Они пытаются:

— сделать универсальную обработку
— перехватить всё
— не думать о логике

Но правильный подход другой:

👉 обрабатывать только там, где это нужно

Когда ошибка — это нормально

Иногда лучше:

— не ловить ошибку
— а исправить причину

Пример: если деление на 0 — значит логика сломана, а не код.

Итог

В VBA нет try/catch.

Есть:

— On Error GoTo — правильный способ
— On Error Resume Next — аккуратно
— Exit Sub — обязательно

И если использовать их грамотно, макросы перестают «падать» неожиданно.

Если вы хотите писать стабильные макросы, а не «надеяться, что пронесёт» — начните с нормальной обработки ошибок. Это один из тех навыков, который отличает новичка от разработчика.

📌 В Telegram разбираю реальные ошибки из макросов и показываю, как их исправлять.

Напишите в комментариях, какую ошибку VBA вы ловили чаще всего — разберём и покажу решение.