maseur Пользователь Сообщений: 282 |
Доброй ночи, форумчане. Такая вот проблемма. Rows(«1:1»).Delete В том случае, если нет ни одной такой строки (пустой лист) появляется сообщение об ошибке (rine time errore 91). |
EducatedFool Пользователь Сообщений: 3655 |
#2 21.01.2013 03:30:45 Первой строкой в макросе:
PS: Эта директива — наиболее часто встречающаяся строка в моих программах. Изменено: EducatedFool — 21.01.2013 03:31:23 |
||
Johny Пользователь Сообщений: 2737 |
#3 21.01.2013 08:38:12 Если Вы знаете предполагаемое место, где может быть ошибка, то после этого места необходимо вставить вот эту строку:
Если не поставить эту строчку, то макрос будет работать в режиме «Ошибка», и если далее в коде опять возникнет ошибка, то VBA не будет на неё реагировать. Другими словами, «On Error GoTo 0» возвращает VBA в нормальный режим. There is no knowledge that is not power |
||
maseur Пользователь Сообщений: 282 |
Спасибо за советы. |
Johny Пользователь Сообщений: 2737 |
#5 23.01.2013 09:24:50
Код от EducatedFool — единственный в данной теме, поэтому непонятно, из чего Вы выбирали.
А это тут причём? Я лишь предупредил о подводных камнях. There is no knowledge that is not power |
||||
iba2004 Пользователь Сообщений: 1034 |
#6 23.01.2013 09:29:30 off: Кому проще??? Excel’ю??? :о)) |
Хитрости »
21 Март 2015 96354 просмотров
Очень часто начинающие работать в VBA сталкиваются с различными ошибками, которые выдает код в момент выполнения. Если не знать как поступить в данном случае – то очень сложно будет исправить код быстро, а то и вообще невозможно будет определить причину ошибки без помощи более «продвинутых» пользователей. Новички зачастую делают правки наугад, что может порождать иные ошибки, а это в свою очередь не только затрудняет поиск первоначальной ошибки, но и может привести к невозможности исправить код вообще. Поэтому в этой статье я решил описать как производить отладку кода и определять ошибки.
Чтобы описанное в статье можно было сразу опробовать в практике советую скачать файл пример:
Пример таблицы и кода (35,5 KiB, 2 877 скачиваний)
Что будет рассмотрено:
- Способы отладки кода в момент появления ошибки
- Использование окон Locals и Watches для отладки
- Пошаговая отладка кода — что это такое, как и когда применять
- Ошибок нет, но код все равно не выполняется
Помимо этого в конце статьи можно скачать файл с кодами ошибок VBA и их расшифровками.
Исходные данные
Допустим, имеется простая таблица
И код, который должен пройтись по каждой строке таблицы, перемножить цену (столбец Цена) на количество (столбец Продажи шт), просуммировать перемноженные данные и вывести результирующую сумму в ячейку В17:
Option Explicit Sub PrimitiveCode() Dim lr As Long, dblSumm As Double, dblIncr As Double 'цикл от первой строки таблицы до последней For lr = 1 To 14 'перемножение Цены на Количество (C*E) dblIncr = Cells(l, 3).Value * Cells(lr, 5).Value 'прибавление результата к переменной общей суммы dblSumm = dblSumm + dblIncr Next 'выводим результат в ячейку B17 Cells(17, 2).Value = dblSumm End Sub
Если посмотреть на код выше, то опытный программист VBA сразу поймет, что в таком виде код работать не будет – не выполнится и одна строка. Сразу появится ошибка:
Ошибка означает, что внутри кода есть переменная, которая ранее не была объявлена.
Сама переменная, которую VBA считает не объявленной будет выделена:
Подробнее об этой ошибке и её причинах можно почитать в статье: Variable not defined или что такое Option Explicit и зачем оно нужно?
Если строки Option Explicit нет, то ошибка появится в момент выполнения строки с этой переменной, т.к. значение этой переменной будет 0, что нельзя использовать в качестве номер строки на листе. Как определить причину ошибки в конкретной строке описано ниже.
Если кратко, то переменной l нет среди объявленных переменных(Dim l As) и мы не можем её использовать, если объявлена директива Option Explicit(настоятельно рекомендую Option Explicit использовать всегда во избежание опечаток). В данном случае это опечатка и там должна быть lr, а не l. Исправляем переменную и код будет выглядеть так:
Sub PrimitiveCode() Dim lr As Long, dblSumm As Double, dblIncr As Double 'цикл от первой строки таблицы до последней For lr = 1 To 14 'перемножение Цены на Количество (C*E) dblIncr = Cells(lr, 3).Value * Cells(lr, 5).Value 'прибавление результата к переменной общей суммы dblSumm = dblSumm + dblIncr Next 'выводим результат в ячейку B17 Cells(17, 2).Value = dblSumm End Sub
С виду код теперь выполнен правильно и ошибок вызывать не должен. Однако, если его попытаться выполнить опять получим ошибку – на этот раз ошибку типов данных — Type Mismatch:
В момент появления главное нажать Debug, а не End (если будет желание прочитать про тип ошибки подробнее – можно еще нажать Help, текст будет на английском). VBA подсветит желтым строку, вычисления или операции в которой вызывают ошибку:
Теперь самый важный этап – необходимо определить причину ошибки. С виду все хорошо – одна ячейка перемножается на другую. Без опыта сложно сходу понять, что это ошибка типов данных, хоть VBA прямо об этом говорит(Type Mismatch – в переводе «Несовпадение типов»). Поэтому самое надежное в этом случае – это определить значение каждой составляющей той строки, в которой возникла ошибка. В случае с кодом выше можно воспользоваться двумя методами:
- Навести курсор мыши на любую переменную(dblSum, lr) и посмотреть всплывающую подсказку, которая показывает имя переменной и её текущее значение:
Значение нашей переменной lr = 1. Запоминаем и переходим на лист с таблицей и смотрим, какое значение в ячейке первой строки третьего столбца(Cells(1,3)). Там значение Закуп цена, что явно не является числом. Следовательно перемножить его нельзя, т.к. это текст. Отсюда и ошибка типов – с текстом нельзя производить математические операции. Для вычислений предполагается в данном случае числовой тип данных(Integer,Long,Double). - Узнать сразу значение ячейки Cells(lr, 3).Value и ячейки Cells(lr, 5).Value. Наведение курсора мыши в данном случае не даст результата. Как правило наведение курсора мыши не имеет эффекта если это не объявленные как переменные объекты (как в этом случае — Cells). Такие объекты не всегда могут быть вычислены в памяти в момент отладки. Поэтому чтобы просмотреть значение ячейки сначала необходимо отобразить окно Immediate(отобразить можно сочетанием клавиш Ctrl+G или через меню View —Immediate Window). Выделить и скопировать полностью нужную переменную Cells(i, 3).Value и в окне Immediate написать:
?
и после вопр.знака вставить скопированное. Должно получиться:
?Cells(i, 3).Value
И нажать Enter. Строкой ниже в этом окне будет выведено значение для объекта или переменной (если оно может быть получено):
По сути результат будет как и в первом примере – мы увидим, что в ячейке текст. Чем второй метод лучше первого? Тем, что таким образом можно сразу получить значение, не переходя на лист и не выискивая нужный номер строки. Ведь это в примере он равен 1, в реальности же строка может быть и 24451.
Окна Locals и Watches
Так же для отслеживания значений переменных очень удобно использовать окно
Locals
и окно
Watches
.
Окно Locals
Окно Locals отображает все локальные переменные, задействованные в выполняемой в настоящий момент процедуре:
Как видно в этом окне отображается имя переменной, её тип и значение. Все хорошо, но в этом окне отображаются исключительно локальные переменные, объявленные на уровне модуля. Переменных других модулей, объявленные как Public и используемые в текущей процедуре там не отображаются. Подробнее про видимость переменных можно узнать в статье: Что такое переменная и как правильно её объявить?
Окно Watches
Окно Watches представляет большую ценность – в это окно можно просто «перетащить» нужную переменную или объект и в этом окне будут отражены все данные об имени переменной, её типе и текущем значении:
Теперь рассмотрим чуть подробнее как перетаскивать в это окно данные. На примере кода выше:
- Выделяем Cells(i, 3).Value
- Не снимая выделения наводим курсор мыши на это выделение
- Зажимаем левую кнопку мыши и не отпуская её переносим курсор в любое место окна Watches
Теперь данные по переменной загружены и доступны для просмотра. По сути все умеют это делать — процесс очень схож с обычным перемещением файлов и папок по рабочему столу. Выделили и с зажатой левой кнопкой мыши перенесли в нужное место.
В чем еще один плюс этого окна – в этом окне можно оставлять эти значения и просматривать в моменты пошаговой отладки только занесенные в это окно переменные(про пошаговую отладку будет рассказано ниже). Если вдруг какая-то переменная/объект стали не нужны для постоянного отслеживания их данных – можно удалить их из окна Watches, чтобы не мешалась. Для этого выделяем переменную-правая кнопка мыши – Delete Watch. Так же можно поиграть с иными пунктами, наибольший интерес из которых на мой взгляд, представляет пункт Edit Watch. После его нажатия появится окно
Самые основные пункты в этом окне, важные для отладки:
- Break Then value Changes. Если его установить, VBA будет отслеживать значение этой переменной и останавливать код при любом изменении значения переменной. Это может пригодится для отслеживания значений в циклах
- Break Then value Is True – пункт пригодится для переменных с типом Boolean или для логических выражений. Как только переменная или результат выражения примет значение True – код будет остановлен на этой строке.
Например, необходимо остановить код, если номер строки будет равен 10(т.е. переменная lr примет значение 10). Тогда выражение будет иметь вид:If lr = 10 Then 'код End if
Тогда надо будет выделить в строке If lr = 10 Then само условное выражение lr = 10, перенести её в окно Watches, выделить строку в окне Watches с этим выражением, нажать правую кнопку мыши и выбрать Edit Watch. Выбрать в окне Break Then value Is True. Теперь как только переменная lr достигнет значения 10(т.е. обрабатываться будет 10-я строка таблицы) – код остановится и строка с выражением будет выделена желтым. Можно будет проанализировать другие переменные или продолжить выполнение кода в пошаговом режиме(см.далее).
Пошаговая отладка кода
После знакомства с отладкой кода при возникновении ошибки работать с пошаговой отладкой будет проще.
Что такое вообще пошаговая отладка?
Это просмотр этапов выполнения кода строка за строкой.
Для чего это может быть нужно?
- Чтобы проанализировать чужой код и понять более точно, что он делает изнутри, а не только увидеть результат его выполнения
- Если вы начинающий программист и часто используете макрорекордер(записываете макросы) — то пошаговая отладка поможет понять какое действия выполняет каждая строка. Это поможет быстрее научиться понимать код и убирать из него лишнее, а так же совмещать различные коды
- Если внутри кода есть ошибка логики выполнения. Это, пожалуй, самая сложная ошибка, т.к. в этом случае VBA не останавливает работу и не говорит об ошибке. Код выполняется без ошибок, но результат не такой, как ожидалось. Это означает, что либо какой-то переменной назначается не то значение, либо какое-то условие неверно или выполняется не в тот момент, в который должно. В общем по сути это ошибка разработчика, не приводящая к ошибкам синтаксиса или типов, которые VBA может отследить.
Как делать пошаговую отладку? Все просто: устанавливаете курсор в любом месте внутри кода и нажимаете клавишу F8 (либо выбрать в меню Degub —Step Into). Теперь при каждом нажатии клавиши F8 код будет выполнять одну строку кода за другой в той очередности, в которой они расположены в процедуре. Если внутри процедуры будет вызов второй процедуры или функции – код пошагово выполнит и её и затем вернется в основную процедуру.
Так же хочу привести еще пару сочетаний клавиш, которые удобно применять при пошаговой отладке:
- Shift+F8(Degub —Step Over) — выполнение вложенной функции/процедуры без захода в неё. Если внутри основной процедуры или функции выполняется другая процедура или функция и Вы уверены, что она работает правильно — просматривать пошагово весь код вложенной процедуры/функции не имеет смысла. Чтобы вложенная процедура/функция выполнилась без пошагового просмотра надо просто нажать указанное сочетание клавиш тогда, когда строка вызова вложенной процедуры/функции будет подсвечена желтым
- Ctrl+Shift+F8(Degub —Step Out) — завершение вложенной функции/процедуры и выход в основную с остановкой. Если все же перестарались и перешли в пошаговый проход вложенной функции(или сделали это специально, но посмотрели все, что надо) — то нажимаете это сочетание и код быстро выполнить вложенную функцию, перейдет в основную и остановится для дальнейшей пошаговой отладки
- Ctrl+F8(Degub —Run to Cursor) — выполнение процедуры до строки, в которой на данный момент установлен курсор
Точки останова
Но куда чаще бывает нужно не просто весь код пройти пошагово, а начать пошаговое выполнение только начиная с какой-либо одной строки, чтобы не мотать строк 40 кода(да еще с циклами) ради достижения одной какой-то строки. Еще точки останова очень полезны при отладке событийных процедур(вроде Worksheet_Change, Worksheet_BeforeDoubleClick, событий элементов форм и т.п.), т.к. они в большинстве своем содержат аргументы и выполнить по F8 их просто невозможно и выполняются они только при наступлении самого события, которые они призваны обработать. Тоже самое справедливо для функций пользователя(UDF) именно для проверки их работы из листа, т.к. эти функции нельзя начать выполнять по F5 — они начинают выполняться только после их пересчета и зачастую ошибки можно выявить исключительно при вызове именно с листа.
Чтобы дать понять VBA на какой строке необходимо будет остановится необходимо установить курсор мыши в любое место нужной строки и нажать F9 или Debug —Toggle Breakpoint. Строка будет выделена темно-красным цветом.
Это еще называется установкой точки останова. Убрать точку останова можно так же, как она была установлена – F9 или Debug —Toggle Breakpoint. Так же точку основа можно установить с помощью мыши: для этого необходимо в области левее окна с кодом напротив нужной строки один раз щелкнуть левой кнопкой мыши:
Теперь можно запустить код любым удобным способом (в отладке это как правило делается клавишей F5 или с панели: Run —Run Sub/UserForm). Как только код дойдет до указанной точки останова он остановится и строка будет подсвечена желтым. Дальше можно либо продолжить выполнение в пошаговом режиме (нажимая F8), либо (проверив значения нужных переменных и объектов) нажать опять F5 и код продолжит выполняться автоматически, пока не выполнится или не достигнет другой точки останова. Самих же точек останова может быть сколько угодно и расположены они могут быть в любой процедуре или функции.
Следует помнить, что после закрытия файла с кодом точки останова не сохраняются и при следующем открытии книги их необходимо будет установить заново, если это необходимо.
Еще хочу добавить, что ошибки могут появляться не всегда, даже если они есть. Бывает и так, что код выполняется без ошибок, но однако либо выполняется не так, либо вообще ничего не делает. Как правило причин две:
- Логика кода построена неверно и ошибок VBA действительно не возникает. Но т.к. логика неверна — код выполняет не то, что от него ожидается. Решение одно — пошагово выполнить весь код и детально просмотреть всё, чтобы обнаружить в какой строке или строках нарушена логика
- Один из очень распространенных вариантов: в начале кода стоит обработчик ошибок On Error Resume Next и дальше обработчик не отменяется. Данный обработчик указывает VBA, что при возникновении ошибки её следует игнорировать и переходит к выполнению следующего оператора/строки. Таким образом ошибка хоть и возникает, но она пропускается и не показывается, а выполнение кода продолжается как ни в чем не бывало. Однако как правило одна ошибка влечет другую и третью и т.д. и может получиться так, что все строки после первой ошибочной станут так же ошибочными и как следствие не выполнятся. Данный оператор будет применяться либо до конца процедуры, либо до тех пор, пока в коде не будет поставлен иной обработчик ошибок:
On Error GoTo Метка — переход выполнения кода к указанной метке(Метка).
On Error GoTo 0 — по сути отменяет условный переход при возникновении ошибок. Метка 0 считается обнулением переходов
Один из примеров того, для чего может применяться обработчик ошибок можно найти в статье: Как из Excel обратиться к другому приложению. Там данный обработчик необходим, чтобы проверить открыто ли уже приложение Word. Если открыто — то ошибка не возникнет. Если же закрыто — то будет ошибка. И этот момент как правило и отслеживается. Я расставил подробные комментарии в коде, чтобы было более понятно что к чему:
Sub Check_OpenWord() Dim objWrdApp As Object On Error Resume Next 'необходимо, чтобы на первой же строке код не выдал ошибку при закрытом Word 'пытаемся подключится к объекту Word Set objWrdApp = GetObject(, "Word.Application") 'если Word закрыт - обязательно возникнет ошибка 429, 'указывающая на то, что невозможно подключиться к объекту Word 'при этом переменная objWrdApp будет равняться Nothing, т.к. значение не удалось присвоить If objWrdApp Is Nothing Then 'так же можно использовать и такую строку: 'If Err.Number = 429 Then 'если ошибка 429 - значит Word не запущен - надо создавать новый 'создаем новый экземпляр Set objWrdApp = CreateObject("Word.Application") 'делаем приложение видимым. По умолчанию открывается в скрытом режиме objWrdApp.Visible = True Else 'приложение открыто - выдаем сообщение MsgBox "Приложение Word уже открыто", vbInformation, "Check_OpenWord" End If End Sub
Для чего вообще это нужно? Ведь можно создавать новый экземпляр. А дело в том, что не всегда правильно создавать новый — куда правильнее зачастую подключиться к ранее открытому, чем плодить новые экземпляры и захламлять диспетчер задач.
Тему обработки ошибок я здесь пока не раскрываю полностью, т.к. это не на один абзац. В одной из следующий статей постараюсь более подробно рассказать как и где их лучше применять и как правильно, а когда лучше вообще воздержаться от их использования.
Конечно, статья не описывает способы устранения ошибок — это просто невозможно. Только известных типов ошибок в VBA более 3 тысяч. Все их упоминать бессмысленно. Целью статьи было помочь начинающим найти строку с ошибкой и рассказать как производить отладку кода при необходимости. А все остальное придет с опытом. Однако на всякий случай я решил выложить файл Excel с описанием большей части ошибок, которые могут возникнуть. В файле указан номер ошибки, описание на английском и описание на русском. Причин ошибки может быть множество, поэтому нет однозначных рекомендаций по устранению каждой из них. Все зависит от данных и от самого кода.
Ошибки VBA с описанием (152,0 KiB, 5 641 скачиваний)
Удачи в программировании!
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
In this Article
- VBA Errors Cheat Sheet
- Errors
- VBA Error Handling
- VBA On Error Statement
- On Error GoTo 0
- On Error Resume Next
- Err.Number, Err.Clear, and Catching Errors
- On Error GoTo Line
- VBA IsError
- If Error VBA
- VBA Error Types
- Runtime Errors
- Syntax Errors
- Compile Errors
- Debug > Compile
- OverFlow Error
- Other VBA Error Terms
- VBA Catch Error
- VBA Ignore Error
- VBA Throw Error / Err.Raise
- VBA Error Trapping
- VBA Error Message
- VBA Error Handling in a Loop
- VBA Error Handling in Access
VBA Errors Cheat Sheet
Errors
On Error – Stop code and display error
On Error Goto 0
On Error – Skip error and continue running
On Error Resume Next
On Error – Go to a line of code [Label]
On Error Goto [Label]
Clears (Resets) Error
On Error GoTo –1
Show Error number
MsgBox Err.Number
Show Description of error
MsgBox Err.Description
Function to generate own error
Err.Raise
See more VBA “Cheat Sheets” and free PDF Downloads
VBA Error Handling
VBA Error Handling refers to the process of anticipating, detecting, and resolving VBA Runtime Errors. The VBA Error Handling process occurs when writing code, before any errors actually occur.
VBA Runtime Errors are errors that occur during code execution. Examples of runtime errors include:
- Referencing a non-existent workbook, worksheet, or other object (Run-time Error 1004)
- Invalid data ex. referencing an Excel cell containing an error (Type Mismatch – Run-time Error 13)
- Attempting to divide by zero
VBA On Error Statement
Most VBA error handling is done with the On Error Statement. The On Error statement tells VBA what to do if it encounters an error. There are three On Error Statements:
- On Error GoTo 0
- On Error Resume Next
- On Error GoTo Line
On Error GoTo 0
On Error GoTo 0 is VBA’s default setting. You can restore this default setting by adding the following line of code:
On Error GoTo 0
When an error occurs with On Error GoTo 0, VBA will stop executing code and display its standard error message box.
Often you will add an On Error GoTo 0 after adding On Error Resume Next error handling (next section):
Sub ErrorGoTo0()
On Error Resume Next
ActiveSheet.Shapes("Start_Button").Delete
On Error GoTo 0
'Run More Code
End Sub
On Error Resume Next
On Error Resume Next tells VBA to skip any lines of code containing errors and proceed to the next line.
On Error Resume Next
Note: On Error Resume Next does not fix an error, or otherwise resolve it. It simply tells VBA to proceed as if the line of code containing the error did not exist. Improper use of On Error Resume Next can result in unintended consequences.
A great time to use On Error Resume Next is when working with objects that may or may not exist. For example, you want to write some code that will delete a shape, but if you run the code when the shape is already deleted, VBA will throw an error. Instead you can use On Error Resume Next to tell VBA to delete the shape if it exists.
On Error Resume Next
ActiveSheet.Shapes("Start_Button").Delete
On Error GoTo 0
Notice we added On Error GoTo 0 after the line of code containing the potential error. This resets the error handling.
In the next section we’ll show you how to test if an error occurred using Err.Number, giving you more advanced error handling options.
VBA Coding Made Easy
Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!
Learn More
Err.Number, Err.Clear, and Catching Errors
Instead of simply skipping over a line containing an error, we can catch the error by using On Error Resume Next and Err.Number.
Err.Number returns an error number corresponding with the type of error detected. If there is no error, Err.Number = 0.
For example, this procedure will return “11” because the error that occurs is Run-time error ’11’.
Sub ErrorNumber_ex()
On Error Resume Next
ActiveCell.Value = 2 / 0
MsgBox Err.Number
End Sub
Error Handling with Err.Number
The true power of Err.Number lies in the ability to detect if an error occurred (Err.Number <> 0). In the example below, we’ve created a function that will test if a sheet exists by using Err.Number.
Sub TestWS()
MsgBox DoesWSExist("test")
End Sub
Function DoesWSExist(wsName As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = Sheets(wsName)
'If Error WS Does not exist
If Err.Number <> 0 Then
DoesWSExist = False
Else
DoesWSExist = True
End If
On Error GoTo -1
End Function
Note: We’ve added a On Error GoTo -1 to the end which resets Err.Number to 0 (see two sections down).
With On Error Resume Next and Err.Number, you can replicate the “Try” & “Catch” functionality of other programming languages.
On Error GoTo Line
On Error GoTo Line tells VBA to “go to” a labeled line of code when an error is encountered. You declare the Go To statement like this (where errHandler is the line label to go to):
On Error GoTo errHandler
and create a line label like this:
errHandler:
Note: This is the same label that you’d use with a regular VBA GoTo Statement.
Below we will demonstrate using On Error GoTo Line to Exit a procedure.
On Error Exit Sub
You can use On Error GoTo Line to exit a sub when an error occurs.
You can do this by placing the error handler line label at the end of your procedure:
Sub ErrGoToEnd()
On Error GoTo endProc
'Some Code
endProc:
End Sub
or by using the Exit Sub command:
Sub ErrGoToEnd()
On Error GoTo endProc
'Some Code
GoTo skipExit
endProc:
Exit Sub
skipExit:
'Some More Code
End Sub
Err.Clear, On Error GoTo -1, and Resetting Err.Number
After an error is handled, you should generally clear the error to prevent future issues with error handling.
After an error occurs, both Err.Clear and On Error GoTo -1 can be used to reset Err.Number to 0. But there is one very important difference: Err.Clear does not reset the actual error itself, it only resets the Err.Number.
What does that mean? Using Err.Clear, you will not be able to change the error handling setting. To see the difference, test out this code and replace On Error GoTo -1 with Err.Clear:
Sub ErrExamples()
On Error GoTo errHandler:
'"Application-defined" error
Error (13)
Exit Sub
errHandler:
' Clear Error
On Error GoTo -1
On Error GoTo errHandler2:
'"Type mismatch" error
Error (1034)
Exit Sub
errHandler2:
Debug.Print Err.Description
End Sub
Typically, I recommend always using On Error GoTo -1, unless you have a good reason to use Err.Clear instead.
VBA On Error MsgBox
You might also want to display a Message Box on error. This example will display different message boxes depending on where the error occurs:
Sub ErrorMessageEx()
Dim errMsg As String
On Error GoTo errHandler
'Stage 1
errMsg = "An error occured during the Copy & Paste stage."
'Err.Raise (11)
'Stage 2
errMsg = "An error occured during the Data Validation stage."
'Err.Raise (11)
'Stage 3
errMsg = "An error occured during the P&L-Building and Copy-Over stage."
Err.Raise (11)
'Stage 4
errMsg = "An error occured while attempting to log the Import on the Setup Page"
'Err.Raise (11)
GoTo endProc
errHandler:
MsgBox errMsg
endProc:
End Sub
Here you would replace Err.Raise(11) with your actual code.
VBA IsError
Another way to handle errors is to test for them with the VBA ISERROR Function. The ISERROR Function tests an expression for errors, returning TRUE or FALSE if an error occurs.
Sub IsErrorEx()
MsgBox IsError(Range("a7").Value)
End Sub
VBA Programming | Code Generator does work for you!
If Error VBA
You can also handle errors in VBA with the Excel IFERROR Function. The IFERROR Function must be accessed by using the WorksheetFunction Class:
Sub IfErrorEx()
Dim n As Long
n = WorksheetFunction.IfError(Range("a10").Value, 0)
MsgBox n
End Sub
This will output the value of Range A10, if the value is an error, it will output 0 instead.
VBA Error Types
Runtime Errors
As stated above:
VBA Runtime Errors are errors that occur during code execution. Examples of runtime errors include:
- Referencing a non-existent workbook, worksheet, or other object
- Invalid data ex. referencing an Excel cell containing an error
- Attempting to divide by zero
You can “error handle” runtime errors using the methods discussed above.
Syntax Errors
VBA Syntax Errors are errors with code writing. Examples of syntax errors include:
- Mispelling
- Missing or incorrect punctuation
The VBA Editor identifies many syntax errors with red highlighting:
The VBA Editor also has an option to “Auto Syntax Check”:
When this is checked, the VBA Editor will generate a message box alerting you syntax errors after you enter a line of code:
I personally find this extremely annoying and disable the feature.
Compile Errors
Before attempting to run a procedure, VBA will “compile” the procedure. Compiling transforms the program from source code (that you can see) into executable form (you can’t see).
VBA Compile Errors are errors that prevent the code from compiling.
A good example of a compile error is a missing variable declaration:
Other examples include:
- For without Next
- Select without End Select
- If without End If
- Calling a procedure that does not exist
Syntax Errors (previous section) are a subset of Compile Errors.
AutoMacro | Ultimate VBA Add-in | Click for Free Trial!
Debug > Compile
Compile errors will appear when you attempt to run a Procedure. But ideally, you would identify compile errors prior to attempting to run the procedure.
You can do this by compiling the project ahead of time. To do so, go to Debug > Compile VBA Project.
The compiler will “go to” the first error. Once you fix that error, compile the project again. Repeat until all errors are fixed.
You can tell that all errors are fixed because Compile VBA Project will be grayed out:
OverFlow Error
The VBA OverFlow Error occurs when you attempt to put a value into a variable that is too large. For example, Integer Variables can only contain values between -32,768 to 32,768. If you enter a larger value, you’ll receive an Overflow error:
Instead, you should use the Long Variable to store the larger number.
Other VBA Error Terms
VBA Catch Error
Unlike other programming languages, In VBA there is no Catch Statement. However, you can replicate a Catch Statement by using On Error Resume Next and If Err.Number <> 0 Then. This is covered above in Error Handling with Err.Number.
AutoMacro | Ultimate VBA Add-in | Click for Free Trial!
VBA Ignore Error
To ignore errors in VBA, simply use the On Error Resume Next statement:
On Error Resume Next
However, as mentioned above, you should be careful using this statement as it doesn’t fix an error, it just simply ignores the line of code containing the error.
VBA Throw Error / Err.Raise
To through an error in VBA, you use the Err.Raise method.
This line of code will raise Run-time error ’13’: Type mismatch:
Err.Raise (13)
VBA Error Trapping
VBA Error Trapping is just another term for VBA Error Handling.
VBA Error Message
A VBA Error Message looks like this:
When you click ‘Debug’, you’ll see the line of code that is throwing the error:
AutoMacro | Ultimate VBA Add-in | Click for Free Trial!
VBA Error Handling in a Loop
The best way to error handle within a Loop is by using On Error Resume Next along with Err.Number to detect if an error has occurred (Remember to use Err.Clear to clear the error after each occurrence).
The example below will divide two numbers (Column A by Column B) and output the result into Column C. If there’s an error, the result will be 0.
Sub test()
Dim cell As Range
On Error Resume Next
For Each cell In Range("a1:a10")
'Set Cell Value
cell.Offset(0, 2).Value = cell.Value / cell.Offset(0, 1).Value
'If Cell.Value is Error then Default to 0
If Err.Number <> 0 Then
cell.Offset(0, 2).Value = 0
Err.Clear
End If
Next
End Sub
VBA Error Handling in Access
All of the above examples work exactly the same in Access VBA as in Excel VBA.
Function DelRecord(frm As Form)
'this function is used to delete a record in a table from a form
On Error GoTo ending
With frm
If .NewRecord Then
.Undo
Exit Function
End If
End With
With frm.RecordsetClone
.Bookmark = frm.Bookmark
.Delete
frm.Requery
End With
Exit Function
ending:
End
End Function
Обработка ошибок в VBA Excel с помощью оператора On Error. Синтаксис выражений с оператором On Error. Пример кода с простым обработчиком ошибок.
On Error – это оператор, который используется для отслеживания ошибок во время исполнения кода VBA. При возникновении ошибки On Error передает информацию о ней в объект Err и включает программу обработки ошибок, начинающуюся с указанной строки.
В первую очередь, обработчик ошибок нужен для пользователей файлов Excel с кодами VBA. Любая ошибка приводит к прекращению выполнения программы, открытию редактора VBA с непонятным для пользователя сообщением или даже к полному зависанию приложения.
Обработчик ошибок позволяет завершить выполнение программы при возникновении ошибки и вывести сообщение пользователю с ее описанием.
Синтаксис выражений с On Error
Включает алгоритм обнаружения ошибок и, в случае возникновения ошибки, передает управление операторам обработчика ошибок с указанной в выражении строки. Stroka – это метка, после которой расположены операторы обработчика ошибок.
Включает алгоритм обнаружения ошибок и, в случае возникновения ошибки, передает управление оператору, следующему за оператором, вызвавшем ошибку.
Отключает любой включенный обработчик ошибок в текущей процедуре.
Простой обработчик ошибок
Шаблон простейшего обработчика ошибок:
Sub Primer() On Error GoTo Stroka ‘Блок операторов процедуры Exit Sub Stroka: MsgBox «Произошла ошибка: « & Err.Description End Sub |
Оператор On Error GoTo
размещается в начале процедуры, метка и обработчик ошибок – в конце процедуры. Название метки можно сменить на другое, в том числе на кириллице.
Оператор Exit Sub
обеспечивает выход из процедуры, если блок операторов выполнен без ошибок. Для вывода описания ошибки используется свойство Description
объекта Err
.
Примеры обработки ошибок
Пример 1
Деление на ноль:
Sub Primer1() On Error GoTo Инструкция Dim a As Double a = 45 / 0 Exit Sub Instr: MsgBox «Произошла ошибка: « & Err.Description End Sub |
Результат выполнения кода VBA Excel с обработчиком ошибок:
Пример 2
Выход за границы диапазона:
Sub Primer2() On Error GoTo Instr Dim myRange As Range Set myRange = Range(«A1:D4»).Offset(—2) Exit Sub Instr: MsgBox «Произошла ошибка: « & Err.Description End Sub |
Результат выполнения кода VBA Excel с оператором On Error GoTo
:
Пример использования выражений On Error Resume Next
и On Error GoTo 0
смотрите в статье: Отбор уникальных значений с помощью Collection.
Содержание
- Памятка по ошибкам VBA
- Обработка ошибок VBA
- Заявление об ошибке VBA
- VBA IsError
- Если ошибка VBA
- Типы ошибок VBA
- Другие термины ошибок VBA
- Обработка ошибок VBA в Access
Ошибки
ОписаниеКод VBAПри ошибке — код остановки и ошибка отображенияПри ошибке Перейти к 0При ошибке — пропустить ошибку и продолжить работуПри ошибке Возобновить ДалееПри ошибке — перейдите к строке кода [Ярлык]При ошибке Перейти к [ярлык]Сбрасывает (сбрасывает) ошибкуПри ошибке GoTo -1Показать номер ошибкиMsgBox Err.NumberПоказать описание ошибкиMsgBox Ошибка ОписаниеФункция для генерации собственной ошибкиErr.Raise
См. Другие «Шпаргалки» по VBA и бесплатные загрузки в формате PDF.
Обработка ошибок VBA
Обработка ошибок VBA относится к процессу прогнозирования, обнаружения и устранения ошибок времени выполнения VBA. Процесс обработки ошибок VBA происходит при написании кода до того, как на самом деле возникнут какие-либо ошибки.
Ошибки времени выполнения VBA — это ошибки, возникающие во время выполнения кода. Примеры ошибок времени выполнения включают:
- Ссылка на несуществующую книгу, лист или другой объект
- Неверные данные напр. ссылка на ячейку Excel, содержащую ошибку
- Попытка разделить на ноль
Заявление об ошибке VBA
Большая часть обработки ошибок VBA выполняется с помощью О заявлении об ошибке. Оператор On Error сообщает VBA, что делать в случае возникновения ошибки. Есть три О сообщениях об ошибках:
- При ошибке GoTo 0
- При ошибке Возобновить Далее
- При ошибке GoTo Линия
При ошибке GoTo 0
При ошибке GoTo 0 является настройкой VBA по умолчанию. Вы можете восстановить этот параметр по умолчанию, добавив следующую строку кода:
Когда возникает ошибка с При ошибке GoTo 0, VBA прекратит выполнение кода и отобразит стандартное окно сообщения об ошибке.
Часто вы добавляете При ошибке GoTo 0 после добавления При ошибке Возобновить Далее обработка ошибок (следующий раздел):
123456789 | Sub ErrorGoTo0 ()При ошибке Возобновить ДалееActiveSheet.Shapes («Start_Button»). УдалитьПри ошибке GoTo 0’Запустить больше кодаКонец подписки |
При ошибке Возобновить Далее
При ошибке Возобновить Далее сообщает VBA пропустить любые строки кода, содержащие ошибки, и перейти к следующей строке.
1 | При ошибке Возобновить Далее |
Примечание: При ошибке Возобновить Далее не исправляет ошибку и не устраняет ее иным образом. Он просто сообщает VBA действовать, как если бы строка кода, содержащая ошибку, не существовала. Неправильное использование При ошибке Возобновить Далее может привести к непредвиденным последствиям.
Прекрасное время для использования При ошибке Возобновить Далее при работе с объектами, которые могут существовать, а могут и не существовать. Например, вы хотите написать код, который удалит фигуру, но если вы запустите код, когда фигура уже удалена, VBA выдаст ошибку. Вместо этого вы можете использовать При ошибке Возобновить Далее чтобы сообщить VBA об удалении формы, если она существует.
123 | При ошибке Возобновить ДалееActiveSheet.Shapes («Start_Button»). УдалитьПри ошибке GoTo 0 |
Обратите внимание, что мы добавили При ошибке GoTo 0 после строки кода, содержащей потенциальную ошибку. Это сбрасывает обработку ошибок.
В следующем разделе мы покажем вам, как проверить, возникла ли ошибка, используя Err.Number, предоставляя вам более расширенные возможности обработки ошибок…
Err.Number, Err.Clear и перехват ошибок
Вместо того, чтобы просто пропустить строку, содержащую ошибку, мы можем отловить ошибку, используя При ошибке Возобновить Далее а также Err.Number.
Err.Number возвращает номер ошибки, соответствующий типу обнаруженной ошибки. Если ошибки нет, Err.Number = 0.
Например, эта процедура вернет «11», потому что возникает ошибка Ошибка времени выполнения ’11’.
1234567 | Sub ErrorNumber_ex ()При ошибке Возобновить ДалееActiveCell.Value = 2/0MsgBox Err.NumberКонец подписки |
Обработка ошибок с помощью Err.Number
Истинная сила Err.Number заключается в способности определить, произошла ли ошибка (Err.Number 0). В приведенном ниже примере мы создали функцию, которая будет проверять, существует ли лист, с помощью Err.Number.
12345678910111213141516171819 | Sub TestWS ()MsgBox DoesWSExist («тест»)Конец подпискиФункция DoesWSExist (wsName As String) As BooleanDim ws как рабочий листПри ошибке Возобновить ДалееУстановить ws = Sheets (wsName)’Если ошибка WS не существуетЕсли Err.Number 0, тоDoesWSExist = FalseЕщеDoesWSExist = TrueКонец, еслиПри ошибке GoTo -1Конечная функция |
Примечание. Мы добавили При ошибке GoTo -1 до конца, который сбрасывает Err.Number в 0 (см. два раздела ниже).
С участием При ошибке Возобновить Далее а также Err.Number, вы можете воспроизвести «Попробуй поймать» функциональность других языков программирования.
При ошибке GoTo Линия
При ошибке GoTo Линия сообщает VBA «перейти» к помеченной строке кода при обнаружении ошибки. Вы объявляете оператор Go To следующим образом (где errHandler — это метка строки, к которой нужно перейти):
1 | При ошибке GoTo errHandler |
и создайте метку строки следующим образом:
Примечание. Это тот же ярлык, который вы использовали бы с обычным заявлением VBA GoTo.
Ниже мы продемонстрируем использование При ошибке GoTo Линия Выйти из процедуры.
При ошибке Выход из подпрограммы
Вы можете использовать On Error GoTo Line для выхода из подпрограммы при возникновении ошибки.
Вы можете сделать это, поместив метку строки обработчика ошибок в конце вашей процедуры:
12345678 | Sub ErrGoToEnd ()При ошибке GoTo endProc’Некоторый кодendProc:Конец подписки |
или используя команду Exit Sub:
123456789101112131415 | Sub ErrGoToEnd ()При ошибке GoTo endProc’Некоторый кодПерейти Пропустить ВыходendProc:Выйти из подводной лодкиskipExit:Еще немного кодаКонец подписки |
Err.Clear, при ошибке GoTo -1 и сброс Err.Number
После обработки ошибки обычно следует удалить ее, чтобы предотвратить проблемы с обработкой ошибок в будущем.
После возникновения ошибки, оба Err.Clear а также При ошибке GoTo -1 можно использовать для сброса Err.Number до 0. Но есть одно очень важное отличие: Err.Clear не сбрасывает саму ошибку, а только сбрасывает Err.Number.
Что это обозначает? С использованиемErr.Clear, вы не сможете изменить настройку обработки ошибок. Чтобы увидеть разницу, проверьте этот код и замените При ошибке GoTo -1 с участием Err.Clear:
123456789101112131415161718192021 | Sub ErrExamples ()При ошибке GoTo errHandler:»Ошибка, определяемая приложением»Ошибка (13)Выйти из подводной лодкиerrHandler:’Очистить ошибкуПри ошибке GoTo -1При ошибке GoTo errHandler2:Ошибка «Несоответствие типа»Ошибка (1034)Выйти из подводной лодкиerrHandler2:Отладка.Ошибка печати ОписаниеКонец подписки |
Обычно я рекомендую всегда использовать При ошибке GoTo -1, если у вас нет веской причины использовать Err.Clear вместо.
VBA при ошибке MsgBox
Вы также можете отобразить окно сообщения при ошибке. В этом примере будут отображаться разные окна сообщений в зависимости от того, где возникла ошибка:
12345678910111213141516171819202122232425262728 | Sub ErrorMessageEx ()Dim errMsg как строкаПри ошибке GoTo errHandler’Этап 1errMsg = «Произошла ошибка на этапе копирования и вставки.»‘Err.Raise (11)’Этап 2errMsg = «Произошла ошибка на этапе проверки данных.»Err.Raise (11)’Этап 3errMsg = «Произошла ошибка на этапе построения прибылей и убытков и копирования.»Err.Raise (11)’Этап 4errMsg = «Произошла ошибка при попытке зарегистрировать импорт на странице настройки»Err.Raise (11)GoTo endProcerrHandler:MsgBox errMsgendProc:Конец подписки |
Здесь вы должны заменить Err.Raise (11) своим реальным кодом.
VBA IsError
Другой способ обработки ошибок — проверить их с помощью функции VBA IsError. Функция IsError проверяет выражение на наличие ошибок, возвращая ИСТИНА или ЛОЖЬ в случае возникновения ошибки.
123 | Sub IsErrorEx ()MsgBox IsError (Диапазон («a7»). Значение)Конец подписки |
Если ошибка VBA
Вы также можете обрабатывать ошибки в VBA с помощью функции Excel IfError. Доступ к функции IfError должен осуществляться с помощью Класс WorksheetFunction:
1234567 | Sub IfErrorEx ()Dim n As Longn = WorksheetFunction.IfError (Range («a10»). Value, 0)MsgBox nКонец подписки |
Это выведет значение диапазона A10, если значение является ошибкой, вместо этого будет выведено 0.
Типы ошибок VBA
Ошибки времени выполнения
Как указано выше:
Ошибки времени выполнения VBA — это ошибки, возникающие во время выполнения кода. Примеры ошибок времени выполнения включают:
- Ссылка на несуществующую книгу, лист или другой объект
- Неверные данные напр. ссылка на ячейку Excel, содержащую ошибку
- Попытка разделить на ноль
Вы можете «обработать ошибки» ошибок времени выполнения, используя описанные выше методы.
Ошибки синтаксиса
Ошибки синтаксиса VBA это ошибки при написании кода. Примеры синтаксических ошибок:
- Неправильное написание
- Отсутствие или неправильная пунктуация
Редактор VBA выделяет множество синтаксических ошибок красным цветом:
В редакторе VBA также есть опция «Автоматическая проверка синтаксиса»:
Когда этот флажок установлен, редактор VBA сгенерирует окно сообщения, предупреждающее вас об ошибках синтаксиса после ввода строки кода:
Лично меня это очень раздражает, и я отключил эту функцию.
Ошибки компиляции
Прежде чем пытаться запустить процедуру, VBA «скомпилирует» процедуру. Компиляция преобразует программу из исходного кода (который вы видите) в исполняемую форму (вы не видите).
Ошибки компиляции VBA — это ошибки, препятствующие компиляции кода.
Хорошим примером ошибки компиляции является отсутствие объявления переменной:
Другие примеры включают:
- Для без Следующий
- Выбирать без Конец Выбрать
- Если без Конец, если
- Вызов процедура этого не существует
Ошибки синтаксиса (предыдущий раздел) — это подмножество ошибок компиляции.
Отладка> Компиляция
Ошибки компиляции появятся при попытке запустить процедуру. Но в идеале вы должны выявить ошибки компиляции до попытки запустить процедуру.
Сделать это можно, скомпилировав проект заранее. Для этого перейдите в Отладка> Скомпилировать проект VBA.
Компилятор «перейдет» к первой ошибке. Как только вы исправите эту ошибку, снова скомпилируйте проект. Повторяйте, пока все ошибки не будут исправлены.
Вы можете сказать, что все ошибки исправлены, потому что Скомпилировать проект VBA будет неактивным:
Ошибка переполнения
В Ошибка переполнения VBA происходит, когда вы пытаетесь поместить значение в слишком большую переменную. Например, Целочисленные переменные может содержать только значения от -32 768 до 32 768. Если вы введете большее значение, вы получите ошибку переполнения:
Вместо этого вы должны использовать Длинная переменная для хранения большего числа.
Другие термины ошибок VBA
Ошибка перехвата VBA
В отличие от других языков программирования, в VBA нет Заявление о вылове. Однако вы можете воспроизвести оператор Catch, используя При ошибке Возобновить Далее а также Если Err.Number 0, то. Это описано выше в разделе Обработка ошибок с помощью Err.Number.
Ошибка игнорирования VBA
Чтобы игнорировать ошибки в VBA, просто используйте При ошибке Возобновить Далее утверждение:
1 | При ошибке Возобновить Далее |
Однако, как упоминалось выше, вы должны быть осторожны при использовании этого оператора, поскольку он не исправляет ошибку, он просто игнорирует строку кода, содержащую ошибку.
VBA Throw Error / Err.Raise
Чтобы устранить ошибку в VBA, вы используете Err.Raise метод.
Эта строка кода вызовет ошибку времени выполнения ’13’: Несоответствие типов:
Перехват ошибок VBA
Перехват ошибок VBA это просто еще один термин для обработки ошибок VBA.
Сообщение об ошибке VBA
А Сообщение об ошибке VBA выглядит так:
Когда вы нажмете «Отладка», вы увидите строку кода, которая выдает ошибку:
Обработка ошибок VBA в цикле
Лучший способ обработки ошибок в цикле — использовать При ошибке Возобновить Далее вместе с Err.Number чтобы определить, произошла ли ошибка (не забудьте использовать Err.Clear чтобы сбрасывать ошибку после каждого появления).
Пример ниже разделит два числа (столбец A на столбец B) и выведет результат в столбец C. В случае ошибки результатом будет 0.
12345678910111213141516 | Подтест ()Тусклая ячейка как диапазонПри ошибке Возобновить ДалееДля каждой ячейки в диапазоне («a1: a10»)’Установить значение ячейкиcell.Offset (0, 2) .Value = cell.Value / cell.Offset (0, 1) .Value’Если Cell.Value — Error, то по умолчанию 0Если Err.Number 0, тоcell.Offset (0, 2) .Value = 0Err.ClearКонец, еслиСледующийКонец подписки |
Обработка ошибок VBA в Access
Все приведенные выше примеры работают в Access VBA точно так же, как и в Excel VBA.
123456789101112131415161718 | Функция DelRecord (от формы как)’эта функция используется для удаления записи в таблице из формыПри ошибке GoTo заканчиваетсяС frmЕсли .NewRecord Тогда.ОтменитьФункция выходаКонец, еслиКонец сС помощью frm.RecordsetClone.Bookmark = frm.Bookmark.Удалитьfrm.RequeryКонец сФункция выходаокончание:КонецКонечная функция |