Vba игнорировать ошибки

Доброй ночи, форумчане. Такая вот проблемма.По ходу выполнения макроса, он должен выделить непустые строки с последней до первой.  По этому коду:Rows("1:1").Delete        LastRow = Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row   Range(Cells(1, 1), Cells(LastRow, "bd")).SelectВ том случае, если нет ни одной такой строки (пустой лист) появляется сообщение об ошибке (rine time errore 91).Как подправить код, чтобы такая ситуация не...
 

maseur

Пользователь

Сообщений: 282
Регистрация: 22.12.2012

Доброй ночи, форумчане. Такая вот проблемма.
По ходу выполнения макроса, он должен выделить непустые строки с последней до первой.  По этому коду:

Rows(«1:1»).Delete
        LastRow = Cells.Find(What:=»*», SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
   Range(Cells(1, 1), Cells(LastRow, «bd»)).Select

В том случае, если нет ни одной такой строки (пустой лист) появляется сообщение об ошибке (rine time errore 91).
Как подправить код, чтобы такая ситуация не останавливала макрос. Чтобы «ошибка» игнорировалась и он продолжал выполняться.

 

EducatedFool

Пользователь

Сообщений: 3621
Регистрация: 23.12.2012

#2

21.01.2013 03:30:45

Первой строкой в макросе:

Код
On Error Resume Next

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

Изменено: EducatedFool21.01.2013 03:31:23

 

Johny

Пользователь

Сообщений: 2737
Регистрация: 21.12.2012

#3

21.01.2013 08:38:12

Если Вы знаете предполагаемое место, где может быть ошибка, то после этого места необходимо вставить вот эту строку:

Код
On Error GoTo 0

Если не поставить эту строчку, то макрос будет работать в режиме «Ошибка», и если далее в коде опять возникнет ошибка, то VBA не будет на неё реагировать. Другими словами, «On Error GoTo 0» возвращает VBA в нормальный режим.

There is no knowledge that is not power

 

maseur

Пользователь

Сообщений: 282
Регистрация: 22.12.2012

Спасибо за советы.
Выбрал код от EducatedFool, поскольку им проще пользоваться.
Спасибо большое.

 

Johny

Пользователь

Сообщений: 2737
Регистрация: 21.12.2012

#5

23.01.2013 09:24:50

Цитата
maseur пишет:
Выбрал код от EducatedFool,

Код от EducatedFool — единственный в данной теме, поэтому непонятно, из чего Вы выбирали.

Цитата
maseur пишет:
поскольку им проще пользоваться.

А это тут причём? Я лишь предупредил о подводных камнях.

There is no knowledge that is not power

 

iba2004

Пользователь

Сообщений: 1034
Регистрация: 22.12.2012

#6

23.01.2013 09:29:30

off: Кому проще??? Excel’ю??? :о))

Обработка ошибок в 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.

Return to VBA Code Examples

This tutorial will demonstrate how to ensure that VBA Ignores an Error when running your code.

Sometimes when you construct VBA code, you actually want VBA to ignore a line of code when an error occurs. This can actually be quite useful if, for example, you want to delete a sheet if it exists, but ignore that line of code if the sheet doesn’t exist.

(See our Error Handling Guide for more information about VBA Errors)

On Error Resume Next

To ignore a line of code in a procedure, we use the On Error Resume Next statement.

Sub TestErrorIgnore()
On Error Resume Next
  ActiveWorkbook.Sheets("Sheet4").select
  ActiveSheet.Delete
'more code here
End Sub

In the example above, an On Error Resume Next statement has been placed at the top of the procedure. The code is then constructed to select Sheet4 and then delete it.

However, due to the On Error Resume Next statement, if the code does not find Sheet4, it will just carry on to the next line, and delete whichever active sheet it finds.

This can be quite dangerous if it was only Sheet 4 you wanted to delete and not just the Sheet that is active. To prevent this error, we can set a variable to sheet 4 and delete only that sheet IF it exists.

Sub TestErrorIgnore()
  Dim ws As Worksheet
  On Error Resume Next
  Set ws = ActiveWorkbook.Sheets("Sheet4")
  ws.Delete
'more code here
End Sub

Now when the code is run, only Sheet4 will be deleted IF Sheet4 actually exists.  If Sheet 4 does not exist, VBA will ignore the error and carry on going.

Another example of this is if you want to delete all the sheets from your workbook using a loop.   As an Excel workbook has to have at least one sheet, the code will delete all the sheets except one.

Sub DeleteSheets()
 Dim ws As Worksheet 
 For Each ws In ActiveWorkbook.Sheets
  ws.Delete
 Next ws 
End Sub

The code above will stop with an error.

VBAIgnoreError

Clicking Debug will take us into the code with the offending line highlighted!

However, adding the On Error Resume Next line to the code will prevent the error and the routine will always leave one sheet in the workbook.

Sub DeleteSheets()
'add error line here
  On Error Resume Next
  Dim ws As Worksheet 
  For Each ws In ActiveWorkbook.Sheets
    ws.Delete
  Next ws 
End Sub

On Error GoTo 0

Often if you use On Error Resume Next to ignore an error, you want error trapping later on in the code, or you want your code to stop running if an error occurs in the future.   We can re-set the error handling so that the code will once again break on errors by adding the line On Error GoTo 0.

Sub TestErrorIgnore() 
  Dim ws As Worksheet 
  On Error Resume Next 
  Set ws = ActiveWorkbook.Sheets("Sheet4") 
  ws.Delete
  On Error GoTo 0
'more code here 
End Sub

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!
vba save as

Learn More!

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

Простите, но — немного словоблудия :)

Ошибки в программе

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

  1. Вы обращаетесь к объекту по имени, а объекта с таким именем в коллекции нет

  2. Вы хотите выделить ячеку на одном листе, а этот лист в данный момент не является активным (типичнейшая ошибка новичков в Excel VBA)

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

  4. Вы ссылаетесь на элемент массива, который находится за пределами его границ.

  5. Вы пытаетесь присвоить переменной значение, которое оно не может хранить. Например, переменной типа Long нельзя присвоить строковую константу или переменной типа Integer присвоить знанчение превышающее число 32767.

На любую из этих и сотни других ситуаций среда выполнения реагирует стандартно — прерывает ход выполнения программы на том операторе, где возникла ошибка или, как ещё принято говорить, исключение. На экран выводится информация о возникшей ошибке и предлагаются стандартные варианты для продолжения работы:

  • Continue (продолжить) — этот пункт во время возникновения ошибки всегда не активен. Он активен, когда по ходу выполнения программы вы использовали оператор Stop. Кстати это очень полезный оператор для отладки программы.

  • End (завершить) — завершение исполнения программы

  • Debug (отладка) — переход в режим отладки, в котором можно посмотреть, на каком операторе возникла ошибка, что содержат переменные, можно даже перетащить жёлтую полоску, подсвечивающую текущий оператор, назад, и модифицировать знанчение переменных через окно Immediate window (впрочем это экзотика). В общем случае кнопка Debug позволяет посмотреть, где случилась ошибка и попытаться понять почему так случилось.

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

Почему вообще в коде возникают ошибки?

  1. Много ошибок во время написания кода возникает по невнимательности или не совсем адекватного понимания того, что делаешь. Таких ошибок, как правило, очень много, особенно у начинающих программистов, но эти ошибки довольно легко отловить и исправить, так как, пока вы их не исправите, ничего не работает. Ну, например, вы должны извлечь данные из 5-го столбца, а вы извлекаете из 6-го, а их там банально нет. Ясно, что вы это очень быстро заметите.

  2. Вторая группа ошибок — это ошибки оптимиста. Когда программа написана в целом правильно, но алгоритм не готов к ударам судьбы в виде неожиданных действий со стороны пользователя, ошибок ввода-вывода (вы рассчитывали считать данные из файла, а файла с таким именем не оказалось, либо он заблокирован другим приложением), особенностей конфигурации компьютера (разные версии ОС или офиса, которые в некоторых мелочах отличаются).

  3. Тонкие логические ошибки. Чем сложнее программа, тем больше шансов, что модель задачи в вашей голове, ваша программа и реальность не совсем согласованы между собой. Пока вы не достигните достаточного погружения в задачу вы такие ошибки не найдёте и не исправите. Порой на это уходит много времени. Но это характерно для сложных задач.

  4. Ошибки на стыке вашего приложения и сервисов ОС, приводящие к неожиданным крахам приложения. Такого вообще возникать не должно, но как мы понимаем, и ОС и офис содержат ошибки, да и вы (что более вероятно) можете пользоваться системными вызовами не правильно. Подобные ошибки — сущий кошмар, особенно когда они проявляются лишь на некоторых конфигурациях, при определенных условиях, их трудно поймать и надёжно воспроизвести.

Задачи механизмов обработки ошибок

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

  2. Информирование. Мало обработать ошибку и предотвратить завершение программы. Надо ещё и адекватно проинформировать пользователя о причинах нестандартного поведения программы. Частно причиной ошибок в программе являются некорректные действия пользователя, поэтому важно сообщать ему о них.

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

Файл примера

Скачать

Код без обработки ошибок

Вот простой пример с потолка. Если вызвать Example_00, то она прекрасно отработает без ошибок и вернёт это:

В функцию GetCalories передаётся строка с блюдом, а она должна вернуть его калорийность, сверившись с таблицей в A1:B7.

Давайте поищем слабые места в этом коде. Первое, что должно прийти в голову — если мы ищем, то, что произойдёт, если мы не найдём? А произойдёт, конечно же, ошибка. Её инициирует метод Match.


Ещё одно слабое место этой подпрограммы: функция возвращает вещественный тип Double, и даже, если поиск оказался удачным, то в Cells(intRow, 2) может случайно находиться текстовая строка, а потому, когда вы числовому типу попытаетесь присвоить строковый тип, также произойдёт ошибка. И, если вы второй ошибки сможете избежать за счёт дополнительного оператора if с проверкой через IsNumber(), то избежать первой ошибки таким способом нельзя. Что же делать? А вот тут на сцену выходят операторы обработки ошибок.

Есть 2 подхода к обработке ошибок: автономный подход и выносной. Эти термины я придумал только что, чтобы проще было их обсуждать.

Автономный подход

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

Итак, что тут сделано:

  1. Сразу после объявления функции GetCalories_v1 идёт оператор on error resume next, который в случае возникновения в каком-либо месте ошибки, предписывает VBA просто передавать управление на следующий оператор, идущий после ошибочного.

  2. Мы объявили переменные. Необъявленные переменные получают тип Variant и значение по умолчанию Empty. Объявленные переменные числовых типов инициируются нулём, строковые — пустой строкой, то есть я наперёд знаю, что они содержат, а это хорошо для обработки ошибок.

  3. На вызове метода WorksheetFunction.Match у нас возникает ошибка, так как искомого значения в таблице нет. А это, между прочим, был оператор присваивания ( = ). Прежде, чем левой части оператора присваивания (intRow) что-то будет присвоено, необходимо вычислить правую часть оператора присваивания (WorksheetFunction.Match…), а поскольку в процессе этого вычисления возникает ошибка, то переменная intRow остаётся такой, какой была! А, как я уже сказал, VBA автоматически её инициализирует нулём до начала исполнения подпрограммы. Получается, что, если в этом операторе возникнет ошибка, то в intRow будет ноль. Если ошибки во время поиска не возникнет, то ноля там не будет ни при каких раскладах, так как строки на листе нумеруются с единицы.

  4. И вот этот ноль мы и контролируем, добавляя оператор If. Если intRow больше нуля, то WorksheetFunction.Match отработала штатно, а если нет — то работу подпрограммы надо прерывать, но об этом чуть позже.

  5. Далее мы помним, что Cells(intRow, 2) может теоретически вернуть строковое значение, которое вызовет ошибку Type missmatch при присвоении переменной типа Double (GetCalories_v1), поэтому мы вставляем дополнительную проверку промежуточной переменной varTemp тому, что она числовая. И если это так, то присваиваем GetCalories_v1 значение из varTemp.

  6. В случае возникновения любой ошибки внутри GetCalories_v1 она просто вернёт ноль. Почему ноль? Потому что переменная GetCalories_v1 тоже инициализируется нулём и об этом не надо заботиться, а в случае ошибки она останется в неприкосновенности.

  7. Соответственно родительский код (в нашем случае его роль играет процедура Example_01) должен проверить, а не вернёт ли GetCalories_v1 ноль, и быть готовым к этой ситуации.

  8. А вот теперь тонкий момент, который не все понимают. Почему я использовал промежуточные переменные intRow и varTemp? Вроде бы есть очевидный ответ — чтобы не вычислять значение выражений с Match и Cells 2 раза. Отчасти это, конечно, так. Но это, в данном случае, не главная причина. Главная причина в том, что такой код

    вызовет неправильное поведение программы. Если у нас Match вызовет исключение, то VBA передаст управление на СЛЕДУЮЩИЙ оператор, а следующий оператор в данном случае это то, что идёт после Then — присваивание переменной varTemp значения. Таким образом наша проверка на наличие ошибки сработает с точностью до наоборот, передав управление в ту часть кода, которая должна быть защищена от ситуации, когда Match не нашла строку в таблице. Вот почему важно в операторе If не иметь ничего такого, что могло бы вызвать ошибку.

  9. Как видите, в этом подходе мне зачастую даже нет необходимости проверять объект Err, чтобы понять, что произошла ошибка, так как я ориентируюсь на то, что промежуточные переменные остаются неинициализированными, что является показателем наличия ошибки.

Выносной подход

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

Обратите внимание, что:

  1. Оператор on error теперь в случае ошибки предписывает передавать управление на метку ErrorHandler, которая объявлена в конце кода процедуры GetCalories_v2

  2. В коде мы никак не заботимся о каких-либо проверках. Возникла ошибка? Иди на метку — там разберутся.

  3. Если ошибки не случилось, то, чтобы программа не стала исполнять строчки, предназначенные для обработки ошибок, перед меткой ErrorHandler обычно ставят оператор Exit Sub или Exit Function (в зависимости от типа подпрограммы).

  4. Принципиальный момент — наличие оператора On Error Resume Next сразу после метки ErrorHandler. Дело в том, что после того, как вы перешли на метку ErrorHandler, очень опасно иметь действующим оператор On Error GoTo ErrorHandler, так как, если у вас в обработчике ошибки случится любая ошибка, то управление будет передано опять на метку и, как нетрудно понять, образуется бесконечный цикл. Поэтому сразу после метки мы возможность возникновения цикла ликвидируем оператором On Error Resume Next.

Что лучше?

Какой метод лучше применять зависит от ваших предпочтений и конкретных ситуаций. Грамотную обработку ошибок можно сделать и так и эдак. Вот несколько соображений по преимуществам и недостакам данных подходов:

Автономный подход

Преимущества Недостатки
Есть возможность точно идентифицировать каждую конкретную проблему (если вы её предусмотрели), возникающую во время исполнения, что позволит вам дать самые точные инстркции пользователю для предотвращения появления исключения в будущем. Достаточно трудоёмок, так как подразумевает наличие большого количества проверок в коде. Каждое потенциально опасное действие должно быть снабжено соответствующим оператором If, в котором контролируется значение переменной или код ошибки.
Надо хорошо представлять себе ситуации, где могут возникнуть ошибки, в противном случае ряд ошибок вы просто не заметите на этапе отладки.
Необходимо больше кода, а также требуется опыт и фантазия.
Необходимо больше промежуточных переменных

Выносной подход

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

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

Операторы

On Error { GoTo label | Resume Next | GoTo 0 }

Оператор on error управляет тем, на какой участок вашего кода будет передано управление в случае возникновения ошибки. Данный оператор можно вставить в любое место вашей программы или подпрограммы. Есть 3 варианта:

  1. On error goto label — после того, как этот оператор выполнен, ошибка, возникшая на других операторах программы приведёт к переходу на метку label.

  2. On error resume next — после такого оператора, VBA будет игнорировать возникшую ошибку и передавать управление на следующий оператор, стоящий за тем, в котором возникла ошибка.

  3. On error goto 0 — это режим по-умолчанию. В случае возникновения ошибки данный режим приведёт к появлению на экране стандартного обработчик ошибок VBA с кнопками End и Debug.

Resume { label | Next | [0] }

Данный оператор возобновляет выполнение программы. Применяется в выносном методе обработки ошибок.

  1. resume label— возобновление с метки label

  2. resume next — возобновление со следующего оператора

  3. resume или resume 0 — возобновление с оператора, вызвавшего ошибку. Это имеет смысл, если вы устранили ошибку в своём обработчике. На мой взгляд, на практике такое применяется крайне редко.

Goto label

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

Exit { Do | For | Function | Sub }

Досрочный выход из циклов (Do или For) и досрочный выход из подпрограмм (функции или процедуры). Могут пригодиться при обработке ошибок, но вообще это операторы и без того чрезвычайно полезны.

Объект Err

  1. Err — глобальный объект (его не надо объявлять, а можно сразу пользоваться), который содержит информацию о последней ошибке, случившейся в вашей программе. Проверяя Err сразу после возникновения исключения или после ситуации, которая могла привести к исключению, вы можете понять, что имело место на самом деле.

  2. Свойство Err.Number — содержит числовой код ошибки, по которому их различают в программе. Поскольку Number — свойство по умолчанию, то вы можете его опускать, то есть Err и Err.Number — это эквиваленты. Значение ноль говорит о том, что ошибки не произошло.

  3. Err.Description — содержит англоязычное краткое описание ошибки

  4. Err.Source — возвращает имя модуля, в котором возникла ошибка

  5. Err.Clear — сбрасывает последнюю ошибку. Err сбрасывается также при выполнении оператором Resume, Exit (любого типа кроме Do и For) и On Error.

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

P.S.

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

Читайте также:

  • Работа с объектом Range

  • Работа с объектом Range (часть 2)

  • Sheet happens

  • Поиск границ текущей области

  • Массивы в VBA

  • Структуры данных и их эффективность

  • Автоматическое скрытие/показ столбцов и строк

VBA On Error Resume Next is an error handler statement. If the error occurs while running the code, you can use this statement to resume the next line of code by ignoring the error message instead of showing an error.

Those who write codes regularly in excel VBA know they may get errors even after writing proficient codes, but they want to ignore that error and keep running with the next lines of code. An example of getting an error message is when the VLOOKUP worksheet functionThe VLOOKUP excel function searches for a particular value and returns a corresponding match based on a unique identifier. A unique identifier is uniquely associated with all the records of the database. For instance, employee ID, student roll number, customer contact number, seller email address, etc., are unique identifiers.
read more
does not find the lookup value from the table array. Therefore, it would not return the #N/A error. Rather, it will throw the error: “Unable to get the VLOOKUP property of the worksheet function class.”

Table of contents
  • Excel VBA On Error Resume Next
    • What does On Error Resume Next Do in VBA?
      • Example #1
      • Example #2
    • Things to Remember here
    • Recommended Articles

VBA on Error Resume Next Example 2.4

It is very difficult to fix the bug if you do not know why we are getting this error. In VBA, we have a feature called “On Error Resume Next.”

What Does On Error Resume Next Do in VBA?

There are certain areas as a coder. First, we know this will surely give an error message, but we need to ignore this error to keep going through the code. So, how to ignore that error is a common doubt everybody has.

We can ignore the error using the VBA On Error Resume Next statement and resume the next line of code.

You can download this VBA On Error Resume Next Excel Template here – VBA On Error Resume Next Excel Template

Example #1

Assume you have many worksheets, and you are hiding some of them as part of the VBA project. For example, below are the worksheets we have in our worksheet.

VBA on Error Resume Next Example 1

We have written codes to hide “Sales” and “Profit” sheets, and below is the code.

Code:

Sub On_Error()

    Worksheets("Sales").Visible = xlVeryHidden
    Worksheets("Profit 2019").Visible = xlVeryHidden
    Worksheets("Profit").Visible = xlVeryHidden

End Sub

Example 1.1

We will start running the code line by line using the F8 key.

VBA on Error Resume Next Example 1.2

If we press the F8 key one more time, it will hide the sheet named “Sales.”

Example 1.3

VBA on Error Resume Next Example 1.4

Now, press the F8 key one more time and see what happens.

VBA on Error Resume Next Example 1.5

We have got a “Subscript out of rangeSubscript out of range is an error in VBA that occurs when we attempt to reference something or a variable that does not exist in the code. For example, if we do not have a variable named x but use the msgbox function on x, we will receive a subscript out of range error.read more” error because the current line of code says the below.

Worksheets("Profit 2019").Visible = xlVeryHidden

It is trying to hide the worksheet named “Profit 2019,” but there is no worksheet by the name of “Profit 2019”.

In these cases, if the worksheet doesn’t exist in the workbook, we need to ignore the error and continue to run the code by ignoring the “Subscript out of range” error.

The next line in the code says

Worksheets("Profit").Visible = xlVeryHidden

This worksheet exists in this workbook, so we cannot move to this line of code without ignoring the error.

We need to add the “On Error Resume Next” statement to ignore this error.

Code:

Sub On_Error()

    On Error Resume Next
    Worksheets("Sales").Visible = xlVeryHidden
    Worksheets("Profit 2019").Visible = xlVeryHidden
    Worksheets("Profit").Visible = xlVeryHidden

End Sub

 Example 1.6

As you can see above, we have added the statement at the top of the code before any lines start. Now, run the code and see what happens.

VBA on Error Resume Next Example 1.7

Now, we are in the line given the error previously, press the F8 key, and see what happens.

Example 1.8

We have jumped to the next line of code without showing any error because of the statement we have added at the top, which is the “On Error Resume Next” VBA statement.

Example #2

We will see how to use this statement with one more example. Look at the below data structure for this example.

VBA on Error Resume Next Example 2.0.1

We have two tables above. The first table has “Emp Name” and their salary details in the second table. Unfortunately, we have only “Emp Name.” So by using VLOOKUP, we need to fetch the salary details from the left side table.

Below is the code we had written to fetch the details.

Code:

Sub On_Error1()

  Dim k As Long

  For k = 2 To 8
   Cells(k, 6).Value = WorksheetFunction.VLookup(Cells(k, 5), Range("A:B"), 2, 0)
  Next k

End Sub

Example 2.1

Now, run the code line by line and see what happens.

VBA on Error Resume Next Example 2.2

Example 2.3

Upon running the first cell code, we got the result for the first employee. Repeat the same for the second employee as well.

VBA on Error Resume Next Example 2.4

This time we got the error message. Let us look at the second employee’s name on the table.

 Example 2.5

The second employee’s name is “Gayathri,” but this name does not exist in the first table, so the VBA VLOOKUP functionThe functionality of VLOOKUP in VBA is similar to that of VLOOKUP in a worksheet, and the method of using VLOOKUP in VBA is through an application. Method WorksheetFunctionread more does not return a #N/A error when the VLOOKUP does not find the lookup value from the table. Rather, it gives the above error message.

Our aim is if the employee name is unfound in the table, then we need an empty cell for that employee, ignore the error, and give results for the remaining names.

We need to add the “On Error Resume Next” statement inside the loop.

Code:

Sub On_Error1()

  Dim k As Long

  For k = 2 To 8
   On Error Resume Next
   Cells(k, 6).Value = WorksheetFunction.VLookup(Cells(k, 5), Range("A:B"), 2, 0)
  Next k

End Sub

VBA on Error Resume Next Example 2.6

Now, run the code and see the result.

 Example 2.7

The two employee names: “Gayathri” and “Karanveer,” are not on the list. So, those line codes must have encountered an error since we have added an error handler statement of “On Error Resume Next.” It has ignored that line of code and resumed for the next employee.

Things to Remember here

  • The “On Error Resume Next” is the error handler statement when we need to ignore the known error.
  • If we want to ignore the error message only for a specific code set, close the On Error Resume Next statement by adding the “On Error GoTo 0” statement.

Recommended Articles

This article has been a guide to VBA On Error Resume Next. Here, we discuss how to ignore errors and resume the next line of code in Excel VBA with examples and a downloadable Excel template. You can learn more about VBA functions from the following articles: –

  • VBA Split String into Array
  • VBA Square Root
  • Type Mismatch Error in VBA
  • 1004 Error in VBA

Содержание

  1. Оператор On Error
  2. Синтаксис
  3. Примечания
  4. Пример
  5. См. также
  6. Поддержка и обратная связь
  7. On Error Resume Next seemingly not working
  8. 6 Answers 6
  9. Ошибки в макросе
  10. Краткое руководство по обработке ошибок
  11. Введение
  12. Ошибки VBA
  13. Заявление об ошибке
  14. Err объект
  15. Логирование
  16. Другие элементы, связанные с ошибками
  17. Простая стратегия обработки ошибок
  18. Полная стратегия обработки ошибок

Оператор On Error

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

Синтаксис

On Error GoTo line
On Error Resume Next
On Error GoTo 0

Синтаксис оператора On Error может принимать любую из следующих форм:

Statement Описание
On Error GoTo line Включает процедуру обработки ошибок, которая начинается в строке, указанной в аргументе обязательной строки .

Аргумент line представляет собой любую метку строки или любой номер строки.

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

Указанная строка должна быть в той же процедуре, что и оператор On Error; в противном случае происходит ошибка во время компиляции.

On Error Resume Next Указывает, что при ошибке во время выполнения управление переходит к заявлению сразу после утверждения, где произошла ошибка, и выполнение продолжается. Используйте эту форму вместо On Error GoTo при доступе к объектам.
On Error GoTo 0 Отключает любой включенный обработчик ошибок в текущей процедуре.

Примечания

Если оператор On Error не используется, любая случившаяся ошибка выполнения является неустранимой; то есть в этом случае отображается сообщение об ошибке и выполнение прекращается.

«Включенный» обработчик ошибок — это обработчик, включенный оператором On Error; «активный» обработчик — это включенный обработчик, который находится в процессе обработки ошибки. Если ошибка возникает при активном обработнике ошибок (между возникновением ошибки и резюме, выходом из подгруппы , функцией exit или exit Property ), обработник ошибки текущей процедуры не может справиться с ошибкой. Управление возвращается к вызывающей процедуре.

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

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

Процедура обработки ошибок не является процедурой Sub или Функцией . Это раздел кода, помеченный меткой строки или номером строки.

Процедуры обработки ошибок зависят от значения в свойстве Номер объекта Err для определения причины ошибки. Программа обработки ошибок должна проверить или сохранить соответствующие значения свойства в объекте Err, прежде чем может произойти любая другая ошибка или прежде чем будет вызвана процедура, которая может вызвать ошибку. Значения свойства в объекте Err отражают только самую последнюю ошибку. Сообщение об ошибке, связанное с Err.Number, содержится в Err.Description.

On Error Resume Next вызывает продолжение выполнения с оператора, сразу же следующего за оператором, вызвавшим ошибку выполнения, или с оператора, сразу же следующего за последним вызовом процедуры, содержащей оператор On Error Resume Next. Этот оператор разрешает продолжать выполнение несмотря на ошибку выполнения. Можно поместить программу обработки ошибок туда, где может произойти ошибка, вместо того чтобы переносить управление в другое местоположение в процедуре. Оператор On Error Resume Next становится неактивным, когда вызывается другая процедура, поэтому следует выполнять оператор On Error Resume Next в каждой вызываемой программе, если нужно обрабатывать внутренние ошибки в этой программе.

При обработке ошибок, возникающих при обращении к другим объектам, конструкция On Error Resume Next предпочтительнее, чем On Error GoTo. Проверка объекта Err после каждого взаимодействия с объектом позволяет устранить неоднозначность в плане того, к какому объекту обращался код. Вы можете точно определить, какой объект поместил код ошибки в свойство Err.Number, а также какой объект изначально сгенерировал ошибку (объект, указанный в свойстве Err.Source).

Оператор On Error GoTo 0 отключает обработку ошибок в текущей процедуре. Он не указывает строку 0 в качестве начала кода обработки ошибки, даже если процедура содержит строку с номером 0. Без оператора On Error GoTo 0 обработчик ошибок автоматически отключается, когда выполняется выход из процедуры.

Чтобы не допустить выполнения кода обработки ошибки, когда ошибка не произошла, поместите оператор Exit Sub, Exit Function или Exit Property непосредственно перед программой обработки ошибок, как показано в следующем фрагменте:

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

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

Если создается объект, имеющий доступ к другим объектам, следует попытаться обработать ошибки, передаваемые из этих объектов необработанными. Если вам не удается обрабатывать такие ошибки, сопоставьте код ошибки в Err.Number с одной из собственных ошибок и затем передайте их обратно вызывающей стороне объекта. Следует указать ошибку, добавив код ошибки в константу vbObjectError. Например, если код вашей ошибки — 1052, назначьте его следующим образом:

Системные ошибки во время вызовов Windows динамических библиотек ссылок (DLL) или ресурсов кода Macintosh не вызывают исключений и не могут быть заблокированы с помощью Visual Basic ошибок. При вызове функций DLL необходимо проверить каждое возвращаемого значения на успешность или сбой (в соответствии со спецификациями API), а в случае сбоя проверьте значение в свойстве lastDLLError объекта Err. Свойство LastDLLError всегда возвращает ноль в Macintosh.

Пример

В этом примере сначала используется оператор On Error GoTo для указания местоположения программы обработки ошибок в процедуре. В примере попытка удалить открытый файл генерирует ошибку номер 55. Ошибка обрабатывается в программе обработки ошибок, и затем управление возвращается к оператору, вызвавшему ошибку. Оператор On Error GoTo 0 выключает перехват ошибок.

Затем заявление On Error Resume Next используется для отсрочки улавливания ошибок, чтобы можно было точно знать контекст ошибки, порожденной следующим утверждением. Обратите внимание, что Err.Clear используется для очистки свойств объекта Err после обработки ошибки.

См. также

Поддержка и обратная связь

Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.

Источник

On Error Resume Next seemingly not working

I have the following two lines of code:

I’ve stepped into the macro and executed the line On Error Resume Next and then on the next line myWorkbook. it does the following:

Why doesn’t the compiler resume the next line of code?

On Error has been liberally used throughout the procedures code; I realize best practice is to use this as little as possible but it seems to fit the purpose of this macro.

Reading this SO QUESTION it says that you can’t have one set of error trapping within another. How can I guarantee that one set of error trapping has been «closed off» before the code moves on — does On Error Goto 0 reset the error trapping? If it does reset then why doesn’t resume work in the following?:

6 Answers 6

There is also a VBA setting that will cause On Error . statements to be ignored and that dialog box to always appear. See this answer for more details on checking/changing the option: https://stackoverflow.com/a/3440789/381588

An example of an error when the initial error is not closed out.

As you have found, within the same function or subroutine, On Error Resume Next doesn’t override On Error Goto . if it’s still active.

You are correct that On Error Goto 0 restores the default error handler.

There are some cases where On Error is the most appropriate way to handle an exceptional condition. I prefer to use the following structure:

This keeps everything together, but in other cases a generic error handler at the end of the procedure can be better.

I’ve found that in functions/subs that iterates over nested objects, errorhandling might be a drag in VBA. A solution that works for me to better handle complex iterations is separating setting of objects in their own functions, e.g.

main function/sub: set FSOfolder = SetFSOFolder(FSOobject, strFolder)

and then in the next line in main function:

I agree using On Error Resume Next is not best practice but most/many of my Access apps are not overly sensitive to minor nuances in data integrity (i.e. analytical or reporting, not transactions and not audited). For this reason I use OERN quite often because VBA is very sensitive to some situations that you cannot anticipate entirely. 1 — will the error cause data corruption. If yes handle it. Many routines I use are just crunching a large volume of records and there may be errors in imported data that haven’t been fixed. Usually I have a lot of conversion processes that will let the system clean up its own data eventually.

2 — is the error frequent and non-critical (ie not a key). If yes it’s OERN otherwise the error may not be predicable and you end up crashing out or have to write a bunch of I-T-E or Select Case logic to trap it.

Don’t use On Error Resume Next instead write code that shouldn’t crash.

Note: I am being careful how I phrase that because you never guaranty code doesn’t crash. But if you use On Error Resume Next then part of the natural flow of your code is for it to crash, which is wrong, big time wrong.

Источник

Ошибки в макросе

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

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

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

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

Пункт Описание
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 есть три типа ошибок

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

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

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

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

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

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

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

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

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

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

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

  • Оператор 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 отобразит ошибку, когда ваш код попытается открыть его.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

On Error Goto 0

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

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

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

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

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

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

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

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

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

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

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

On Error Resume Next

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

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

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

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

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

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

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

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

On Error Goto [label]

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

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

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

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

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.

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

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

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

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

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

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

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

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

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

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

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

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

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

Err объект

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Логирование

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

“Programmatic Access to Visual Basic Project is not trusted”

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

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

Источник

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

VBA Error Handling

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

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

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

Содержание

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

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

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

Введение

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

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

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

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

VBA Error Handling

Ошибки VBA

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

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

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

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

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

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

VBA Error Handling

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

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

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

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

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

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

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

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

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

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

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

VBA Error Handling

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

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

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

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

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

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

Debug->Compile Error Summary

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

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

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

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

Debug-> Compile Usage

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

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

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

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

VBA Error Handling

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

On Error Goto 0

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

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

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

Sub IspDefault()

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

End Sub

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

VBA Error Handling

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

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

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

VBA Error Handling

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

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

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

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

On Error Resume Next

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

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

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

Sub UsingResumeNext()

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

End Sub

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

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

Sub OtprSoobsch()

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

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

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

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

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

On Error Goto [label]

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

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

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

Sub IspGotoLine()

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

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

VBA Error Handling

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

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

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

On Error Goto -1

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

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

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

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

Sub DveOshibki()

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

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

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

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

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

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

Sub DveOshibki()

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

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

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

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

Sub DveOshibki()

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

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

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

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

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

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

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

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

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

Sub ErrorSostoyaniya()

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

Err объект

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

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

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

Sub IspErr()

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

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

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

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

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

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

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

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

Sub IspErr()

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

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

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

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

Sub IspErr()

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

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

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

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

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

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

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

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

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

Public Const ERROR_INVALID_DATA As Long = vbObjectError + 513

Sub ReadWorksheet()

    On Error Goto eh
    
    If Len(Sheet1.Range("A1")) <> 5 Then
        Err.Raise ERROR_INVALID_DATA, "ReadWorksheet" _
            , "Значение в ячейке A1 должно иметь ровно 5 символов."
    End If
    
    ' продолжить, если ячейка имеет действительные данные
    Dim id As String
    id = Sheet1.Range("A1")
    

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

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

Err.Raise vbObjectError + 513

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

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

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

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

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

Sub IspErrClear()

    Dim count As Long, i As Long

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

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

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

Логирование

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

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

Sub Logger(sType As String, sSource As String, sDetails As String)
    
    Dim sFilename As String
    sFilename = "C: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. В этом разделе я покажу вам, как
реализовать простую стратегию обработки ошибок, которую вы можете использовать
во всех своих приложениях.

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

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

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

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

error-handling

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

Public Const ERROR_NO_ACCOUNTS As Long = vbObjectError + 514

Sub BuildReport()

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

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

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

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

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

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

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

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

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

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

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

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

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

Error Handling – bubbling

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

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

Option Explicit

Public Const MARKER As String = "NOT_TOPMOST"

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

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

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

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

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

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

Sub Topmost()

    On Error Goto EH
    
    Level1

Done:
    Exit Sub
EH:
    DisplayError Err.source, Err.Description, "Module1.Topmost"
End Sub

Sub Level1()

    On Error Goto EH
    
    Level2

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

Sub Level2()

    On Error Goto EH
    
    ' Ошибка здесь
    Dim a As Long
    a = "7 / 0"

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

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

error handling output

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

error handling output line

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

“Programmatic Access to Visual Basic Project is not trusted”

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

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

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

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

Excel VBA при ошибке Возобновить Далее

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

Те, кто регулярно пишет код в Excel VBA, знают, что они могут получать ошибки даже после написания профессионального кода, но они хотят игнорировать эту ошибку и продолжать работать со следующими строками кода. Типичным примером получения сообщения об ошибке является Функция рабочего листа ВПРФункция Excel ВПР ищет определенное значение и возвращает соответствующее совпадение на основе уникального идентификатора. Уникальный идентификатор однозначно связан со всеми записями базы данных. Например, идентификатор сотрудника, номер списка учащихся, контактный номер клиента, адрес электронной почты продавца и т. д. являются уникальными идентификаторами.
читать далее
не находит искомое значение в массиве таблиц. Он не вернет ошибку #N/A; скорее, он выдаст ошибку. Как «Невозможно получить свойство VLOOKUP класса функций рабочего листа».

VBA при ошибке Возобновление следующего примера 2.4

Если вы не знаете, почему мы получаем эту ошибку, то исправить ошибку очень сложно. В VBA у нас есть функция под названием «При ошибке Возобновить Далее».

Что делает при ошибке возобновление в VBA?

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

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

Вы можете скачать этот шаблон VBA On Error Resume Next Excel здесь – VBA при ошибке Возобновить следующий шаблон Excel

Пример №1

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

VBA при ошибке Возобновить следующий пример 1

Я написал коды, чтобы скрыть листы «Продажи и прибыль», и ниже приведен код.

Код:

Sub On_Error()

    Worksheets("Sales").Visible = xlVeryHidden
    Worksheets("Profit 2019").Visible = xlVeryHidden
    Worksheets("Profit").Visible = xlVeryHidden

End Sub

Пример 1.1

Теперь я начну выполнять код построчно, используя F8 ключ.

VBA при ошибке Возобновление следующего примера 1.2

Если я нажму на F8 ключ еще раз, он скроет лист с именем «Продажи».

Пример 1.3
VBA при ошибке Возобновление следующего примера 1.4

Теперь нажмите клавишу F8 еще раз и посмотрите, что произойдет.

VBA при ошибке Возобновление следующего примера 1.5

У нас есть «Индекс вне диапазонаИндекс вне диапазона — это ошибка в VBA, которая возникает, когда мы пытаемся сослаться на что-то или на переменную, которых нет в коде. Например, если у нас нет переменной с именем x, но мы используем функцию msgbox для x, мы получим ошибку нижнего индекса вне диапазона.читать далее», потому что текущая строка кода говорит следующее.

Worksheets("Profit 2019").Visible = xlVeryHidden

Он пытается скрыть рабочий лист с именем «Прибыль 2019,», но листа с названием «Прибыль 2019» нет.

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

Следующая строка в коде говорит

Worksheets("Profit").Visible = xlVeryHidden

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

Чтобы игнорировать эту ошибку, нам нужно добавить оператор «При ошибке возобновить дальше».

Код:

Sub On_Error()

    On Error Resume Next
    Worksheets("Sales").Visible = xlVeryHidden
    Worksheets("Profit 2019").Visible = xlVeryHidden
    Worksheets("Profit").Visible = xlVeryHidden

End Sub

  Пример 1.6

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

VBA при ошибке Возобновление следующего примера 1.7

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

Пример 1.8

Я перешел к следующей строке кода, не показав никакой ошибки из-за оператора, который мы добавили вверху, который является оператором VBA «При ошибке возобновить следующий».

Пример #2

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

VBA при ошибке Возобновить следующий пример 2.0.1

У нас есть две таблицы над первой таблицей, в которых есть Emp Name и данные о зарплате во второй таблице, и у нас есть только Emp Name, поэтому с помощью VLOOKUP нам нужно получить данные о зарплате из левой таблицы.

Ниже приведен код, который я написал для получения деталей.

Код:

Sub On_Error1()

  Dim k As Long

  For k = 2 To 8
   Cells(k, 6).Value = WorksheetFunction.VLookup(Cells(k, 5), Range("A:B"), 2, 0)
  Next k

End Sub

Пример 2.1

Теперь запустите код построчно и посмотрите, что произойдет.

VBA при ошибке Возобновление следующего примера 2.2
Пример 2.3

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

VBA при ошибке Возобновление следующего примера 2.4

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

  Пример 2.5

Имя второго сотрудника — «Гаятри», но его нет в первой таблице, поэтому Функция ВПР VBAФункция ВПР в VBA аналогична функции ВПР на листе, а метод использования ВПР в VBA — через приложение. Рабочий лист методаФункциячитать далее не возвращает ошибку «#Н/Д», когда функция ВПР не находит искомое значение в таблице; скорее, это дает вышеуказанное сообщение об ошибке.

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

Нам нужно добавить оператор «При ошибке возобновить дальше» внутри цикла.

Код:

Sub On_Error1()

  Dim k As Long

  For k = 2 To 8
   On Error Resume Next
   Cells(k, 6).Value = WorksheetFunction.VLookup(Cells(k, 5), Range("A:B"), 2, 0)
  Next k

End Sub

VBA при ошибке Возобновление следующего примера 2.6

Теперь запустите код и посмотрите результат.

  Пример 2.7

Два имени сотрудника, “Гаятри и Каранвир,» нет в списке, поэтому эти коды строк, должно быть, столкнулись с ошибкой, так как мы добавили оператор обработчика ошибок «При ошибке Возобновить Далее” он проигнорировал эту строку кода и возобновил работу для следующего сотрудника.

Что нужно помнить здесь

  • «On Error Resume Next» — это оператор обработчика ошибок, когда нам нужно игнорировать известную ошибку.
  • Если вы хотите игнорировать сообщение об ошибке только для определенного набора кода, закройте следующий оператор при ошибке, добавив «При ошибке Перейти к 0» утверждение.

УЗНАТЬ БОЛЬШЕ >>

Post Views: 688

While writing Excel Macros we generally put more focus on the coding part and getting the desired result but during this process, we forget an important thing i.e. Error handling. Error handling is an important part of every code and VBA On Error Statement is an easy way for handling unexpected exceptions in Excel Macros.

A well-written macro is one that includes proper exception handling routines to catch and tackle every possible error. Error handling is important because in case of any unexpected exceptions your code doesn’t break. Even if any fatal unexpected error occurs in the code then also you should ensure that the code should terminate gracefully.

VBA On Error

Definition of VBA On Error Statement:

On Error statement instructs VBA Compiler, what to do in case any runtime exception is thrown.

Syntax of On Error Statement:

Basically, there are three types of On Error statement:

  1. On Error Goto 0
  2. On Error Resume Next
  3. On Error Goto<label>:

On Error Goto 0

This is also called VBA default exception handling. When On Error Goto 0 is in effect, it is the same as having no error handler in the code. Here we are instructing the program to display the standard runtime message box with ‘Continue’, ‘End’, ‘Debug’, and ‘Help’ buttons.

Standard-Runtime-Error-Msgbox

This message box will give you four options:

a. Continue: This will ignore the exception and continue the code, only if it is possible to do so.

b. End: This will terminate the program.

c. Debug: This option will bring the program control back to the statement from where the exception has occurred. This helps you to debug the code.

d. Help: This button will open Microsoft MSDN help pages for that exception.

On Error Resume Next

It is the second form of the On Error statement. This statement tells the VBA program to ignore the error and resume the execution with the next line of code.

On Error Resume Next statement doesn’t fix the runtime errors but it simply means that program execution will continue from the line following the line that caused the error. However, it is the sole responsibility of the programmer to make sure that any handled error should not have any side effects (like uninitialized variables or null objects) on the program execution.

This can be ensured by using the VBA Err object. Err object in VBA comes into the picture whenever any runtime error occurs. The Err object preserves information about one exception at a time. When an exception occurs, the Err object is updated to include information about that exception.

For instance:

For example, I have a simple macro as follows:

Sub GetErr()
On Error Resume Next
N = 1 / 0 ' Line causing divide by zero exception
For i = 1 To N
'SomeSet of Statements
Next i
End Sub

Now as you can clearly see, that in this macro Line 3 causes an exception. But as we are using the On Error Resume Next statement so this line will be skipped and the control will flow to the next statement. But the next statement is a loop that is dependent on the value of ‘N’, and at this step ‘N’ is uninitialized so this will have a side effect on the whole flow of the program.

Now, have a look at the same program after exception handling:

Sub GetErr()
On Error Resume Next
N = 1 / 0 ' Line causing divide by zero exception
If Err.Number <> 0 Then
N = 2 ' Some minimum value of N if there is some exception in the code.
End If
For i = 1 To N
'SomeSet of Statements
Next i
End Sub

Now, here in this code, we are checking the Err. Number property, if it is not equal to zero that means there is some exception in the code. And hence we have set ‘N’ to its minimum value so that there are no side effects in the code due to uninitialized variables.

On Error Goto<label>:

This is the third form in which VBA On Error statement can be used. This statement tells the VBA to transfer the program control to the line followed by the label, in case any runtime errors are encountered. In such cases, all the statements between the exception line and the label will not be executed.

This method is more suitable for exiting the program gracefully if any fatal error occurs during the execution.

Example:

Below is a self-explanatory example of ‘On Error Goto<label>:’ where I have used the label name as ‘Error_handler’.

Sub GetErr()
On Error GoToError_handler:
N = 1 / 0 ' cause an error
MsgBox "This line will not be executed"
Exit Sub
Error_handler:
MsgBox "exception handler"
End Sub

In this code as soon as the exception occurs at Line 3, the program transfers the control to Line 6.

Notice that here I have used ‘Exit Sub’ just before the ‘Error_handler:’ label, this is done to ensure that the Error handler block of code doesn’t execute if there is no error. If you omit the ‘Exit Sub’ statement then the Error handler code block will always execute even if no exception is encountered.

So, this was all about the On Error statement in Excel VBA.

Понравилась статья? Поделить с друзьями:
  • Vba runtime error 462 word
  • Vba runtime error 429 activex component can t create object
  • Vba runtime error 2147467259
  • Vba runtime error 13 type mismatch как исправить
  • Vba run time error 76 path not found