Vba пропустить ошибку

Коллеги, приветствую,Немного запутался в теме про обработчик ошибок, хотя, скорее всего, я нашёл ответ на вопрос в , просто не могу его понять до конца.Необходимо, чтобы в случае ошибки, которая возникает в определенный момент в коде, часть кода пропускалась, появлялся MsgBox с определенным текстом, после чего макрос продолжал бы работать в нормальном режиме (если будет какая-нибудь другая ошибка далее - выскочит диалоговое окно).Знаю, что задача простая, ну вот туплю что-то...       ...
 

Framed

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

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

#1

04.03.2019 19:39:20

Коллеги, приветствую,

Немного запутался в теме про обработчик ошибок, хотя, скорее всего, я нашёл ответ на вопрос в

этой теме

, просто не могу его понять до конца.

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

Знаю, что задача простая, ну вот туплю что-то…

Код
            On Error GoTo ErrorHandler            
            Set iWb = GetObject("C:UsersA670669DesktopSCR_Managers.xlsx")
            iLastRowSCR = iWb.Sheets(1).Cells(Rows.Count, 1).End(xlUp).row
            Set iBodySCR = iWb.Sheets(1).Range("B2:M" & iLastRowSCR)
            iWb.Names.Add Name:="BodySCR", RefersTo:=iBodySCR
            With .ListColumns("Rate").DataBodyRange
                .Formula = "=IFERROR(VLOOKUP(A3,SCR_Managers.xlsx!BodySCR,12,0),0)"
                .Cells.Value = .Cells.Value
            End With
            iWb.Close False
ErrorHandler:
            MsgBox "Произошла ошибка"
            On Error Resume Next

На данный момент все как надо, только вот когда даже ошибки нет вылезает MsgBox.

Заранее спасибо.

P.S. Как-то криво написал название темы, должна была быть VBA: Обработчик ошибок, пропуск кода и продолжение выполнения макроса.

Изменено: Framed05.03.2019 00:54:10

 

Anchoret

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

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

Anchoret

#2

04.03.2019 19:44:33

Код
On Error Resume Next
If Err then Goto ...
 

Framed

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

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

#3

04.03.2019 19:52:06

Anchoret, вот так?

Код
 On Error Resume Next
            MsgBox "Произошла ошибка"
            If Err Then GoTo ErrorHandler
            Set iWb = GetObject("C:UsersA670669DesktopSCR_Managers.xlsx")
            iLastRowSCR = iWb.Sheets(1).Cells(Rows.Count, 1).End(xlUp).row
            Set iBodySCR = iWb.Sheets(1).Range("B2:M" & iLastRowSCR)
            iWb.Names.Add Name:="BodySCR", RefersTo:=iBodySCR
            With .ListColumns("Rate").DataBodyRange
                .Formula = "=IFERROR(VLOOKUP(A3,SCR_Managers.xlsx!BodySCR,12,0),0)"
                .Cells.Value = .Cells.Value
            End With
            iWb.Close False
ErrorHandler:






 

Sanja

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

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

#4

04.03.2019 19:54:37

Цитата
Framed написал: только вот когда даже ошибки нет вылезает MsgBox

Обработчик ошибок поместите в самый конец кода, а перед ним должна быть строка Exit Sub

Код
On Error GoTo ErrorHandler
    Set iWb = GetObject("C:UsersA670669DesktopSCR_Managers.xlsx")
    iLastRowSCR = iWb.Sheets(1).Cells(Rows.Count, 1).End(xlUp).Row
    Set iBodySCR = iWb.Sheets(1).Range("B2:M" & iLastRowSCR)
    iWb.Names.Add Name:="BodySCR", RefersTo:=iBodySCR
    With .ListColumns("Rate").DataBodyRange
        .Formula = "=IFERROR(VLOOKUP(A3,SCR_Managers.xlsx!BodySCR,12,0),0)"
        .Cells.Value = .Cells.Value
    End With
    iWb.Close False
    Exit Sub
'обработчик ошибок
ErrorHandler:
    MsgBox "Произошла ошибка"
End Sub

Согласие есть продукт при полном непротивлении сторон.

 

Framed

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

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

#5

04.03.2019 20:03:30

Sanja, спасибо, но разве Exit Sub не остановит выполнение всего макроса, если ошибки не будет?

Я уточню, а то мне кажется, я плохо объяснил в шапке.

Код
'Код
'Код
'Код
 On Error GoTo ErrorHandler
            Set iWb = GetObject("C:UsersA670669DesktopSCR_Managers.xlsx")
            iLastRowSCR = iWb.Sheets(1).Cells(Rows.Count, 1).End(xlUp).row
            Set iBodySCR = iWb.Sheets(1).Range("B2:M" & iLastRowSCR)
            iWb.Names.Add Name:="BodySCR", RefersTo:=iBodySCR
            With .ListColumns("Rate").DataBodyRange
                .Formula = "=IFERROR(VLOOKUP(A3,SCR_Managers.xlsx!BodySCR,12,0),0)"
                .Cells.Value = .Cells.Value
            End With
            iWb.Close False
ErrorHandler:
            MsgBox "Произошла ошибка"
'Код
'Код
'Код

Выполняется макрос, и вот на 5 строке может выскочить ошибка, например, если файла нет, или его имя неверное. Мне нужно, чтобы в этом случае, часть кода 5-13 строка игнорировалась, не выполнялась и выскочил бы MsgBox c текстом, например, «Нет файла или имя некорректно». Далее код, который идет после ErrorHandler должен выполняться в обычном режиме (обычный режим для меня — это когда дальнейшие ошибки не вернут меня к ErrorHandler, простите за убогое объяснение).

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

Изменено: Framed04.03.2019 20:03:53

 

Anchoret

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

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

Anchoret

#6

04.03.2019 20:06:40

Framed,

Код
On Error Resume Next

перед строкой, в которой вероятна ошибка

Код
If Err then Goto ...

после такой строки. Ну и замечание от Sanja,

 

Framed

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

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

Как-то не выходит. Дальнейшие ошибки в коде игнорируются, MsgBox вылезает, даже если ошибки не произошло.

 

БМВ

Модератор

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

Excel 2013, 2016

#8

04.03.2019 20:25:02

только наверно так

Код
'Код
'Код
'Код
 On Error resume next
            Set iWb = GetObject("C:UsersA670669DesktopSCR_Managers.xlsx")
            if err =0 then
                 iLastRowSCR = iWb.Sheets(1).Cells(Rows.Count, 1).End(xlUp).row
                 Set iBodySCR = iWb.Sheets(1).Range("B2:M" & iLastRowSCR)
                iWb.Names.Add Name:="BodySCR", RefersTo:=iBodySCR
                With .ListColumns("Rate").DataBodyRange
                    .Formula = "=IFERROR(VLOOKUP(A3,SCR_Managers.xlsx!BodySCR,12,0),0)"
                    .Cells.Value = .Cells.Value
                End With
                iWb.Close False
           else
                MsgBox "Произошла ошибка"
                err.clear  '  или on error goto 0
          end if
'Код
'Код
'Код
 

По вопросам из тем форума, личку не читаю.

 

Framed

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

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

БМВ, спасибо, все отлично, только теперь в случае ошибки ниже End If, VBA продолжит выполнение кода, даже если, к примеру, название листа out of range и так далее.  

 

БМВ

Модератор

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

Excel 2013, 2016

Framed,  я не зря там написал ‘  или on error goto 0
В зависимости от потребностей или сбросить ошибку или и сбросить и прекратить обработку ошибок.
Конечно и через переход на метки можно сделать, но я отвык.

Изменено: БМВ04.03.2019 20:49:50

По вопросам из тем форума, личку не читаю.

 

Framed

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

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

#11

04.03.2019 20:52:16

БМВ, простите, я проглядел. Спасибо большое за помощь, теперь я понял больше, без вас не разобрался бы.

Цитата
БМВ написал: Конечно и через переход на метки можно сделать, но я отвык.

Я где-то читал, что метки не приветствуются в VBA. Да и мне привычнее с операторами условия  :)  

 

БМВ

Модератор

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

Excel 2013, 2016

По вопросам из тем форума, личку не читаю.

 

vikttur

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

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

#13

05.03.2019 00:23:09

Цитата
Framed написал: метки не приветствуются в VBA.

Метки не беда, если не злоупотреблять и если они не нарушаюют (

не сильно нарушают

) структуру кода

 

Nordheim

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

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

Причина ошибки в данном куске кода в чем заключается?

«Все гениальное просто, а все простое гениально!!!»

 

Framed

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

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

Nordheim, потенциально ошибка в том, что файл с таким названием может отсутствовать на рабочем столе у юзера. Этот файл (если он есть) в моем коде открывается, оттуда ВПР-ом подтягивается информация, после чего он закрывается. Если такого файла нет — мне нужно было, чтобы:

1. Выводилось сообщение со специальным текстом, т.е. MsgBox;
2. Пропускался кусок кода (который открывает файл, создает именной диапазон для ВПР, подтягивает куда надо данные с этого листа с помощью ВПР, превращает формулы в значения и закрывает книгу);
3. Макрос снова бы работал в обычном режиме (то есть в режиме «on error go to 0»).

Вообще, мне помогли и тему можно было закрывать, но раз уж вы спросили :)

БМВ, да, и я даже прочитал это несколько раз перед тем, как создать тему. Просто, откровенно говоря, не доходило до меня, как это правильно использовать; примеры из гугла не добавили ясности. Одним словом, еще учиться и учиться.

Изменено: Framed05.03.2019 14:33:07

 

Nordheim

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

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

#16

05.03.2019 14:45:40

Цитата
Framed написал:
Nordheim , потенциально ошибка в том, что файл с таким названием может отсутствовать на рабочем столе у юзера.

А если так:

Код
Sub test()
    Dim fname$, iPath$
    iPath = "C:UsersA670669DesktopSCR_Managers.xlsx"
    fname = Dir(iPath)
    If fname <> "" Then
        'обработка если файл существует
    Else: MsgBox "Произошла ошибка"
    End If
End Sub

Никакого On Error

PS:
Обработчик ошибок это конечно хорошо, вставил в начало и никаких проблем с кодом, зато потом вылезет какая ни-будь

«бяка»

в отчетах.

Изменено: Nordheim05.03.2019 14:48:24

«Все гениальное просто, а все простое гениально!!!»

 

Jack Famous

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

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

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#17

05.03.2019 15:02:02

Framed, очень много чего вам посоветовали — лень читать всё))
1. В большинстве случаев от меток можно абсолютно безболезненно избавится, но иногда они помогают. Например, можно избежать «ветвления» кода далеко «вправо» — вот

ссылка

на тему с холиваром)))

Итак, в чём проблема… Всё просто — код доходит до строки ErrorHandler: MsgBox «Произошла ошибка» и выводит сообщение об ошибке (как и должен). Чтобы этого избежать, я обычно делаю, как в #4 (Sanja), но можно и «в лоб» обойти:

Код
GoTo nx
            iWb.Close False
ErrorHandler:
            MsgBox "Произошла ошибка"
nx:

— в таком случае, если мы дошли до GoTo nx, то просто «перепрыгиваем» ErrorHandler на метку nx. Если же произойдёт ошибка, то макрос «перепрыгнет» уже к метке ErrorHandler, минуя GoTo nx.

P.S.:

скорее всего, в вашем случае никакого On Error GoTo ErrorHandler не нужно — это подтверждает и наличие примеров, где легко без него можно обойтись. Я использую метки в основном, если нужно вернуться «выше по коду» (повтор ввода информации пользователем в случае ошибки) или, как уже сказал, чтобы избежать «ветвления» (многоуровневых вложенных «If—Else—End If»).
Но дело (как кодить) исключительно ВАШЕ  ;)

Изменено: Jack Famous05.03.2019 15:34:40

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

БМВ

Модератор

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

Excel 2013, 2016

#18

05.03.2019 15:21:22

Nordheim,
тут есть подвох, я с таким встречаюсь регулярно (правда не со скриптамии, но не суть)

Код
    iPath = "C:UsersA670669DesktopГод 2019Документы раздолбая" _
          & "Результаты совещания по вопросам бездумного использования длинных имен файлов и каталогов" _
          & "Выступление главного систематизатора……SCR_Managers.xlsx"

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

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

Jack Famous, так как я родом из VBS, а там нет Resume, то перешел на метку по ошибке, обратно не вернешься, что означает не продолжить с того же места. а это означает или куча меток и отдельные обработчики для каждой ошибки или …..

По вопросам из тем форума, личку не читаю.

 

Jack Famous

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

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

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#19

05.03.2019 15:32:09

Цитата
БМВ: я родом из VBS

а я, стало быть, из VBA и могу использовать крутые штуки типа возврата наверх))

Вот такая, например

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

Nordheim

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

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

#20

05.03.2019 15:32:29

БМВ, На сколько я понимаю в данном случае путь прописывается руками, и визуально видно сколько символов.

Цитата
БМВ написал:
при полном пути более 260 символов, файл есть, он виден, но открыть его не возможно

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

«Все гениальное просто, а все простое гениально!!!»

 

БМВ

Модератор

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

Excel 2013, 2016

#21

05.03.2019 16:15:03

Цитата
Nordheim написал:
На сколько я понимаю в данном случае путь прописывается руками, и визуально видно сколько символов

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

По вопросам из тем форума, личку не читаю.

 

Казанский

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

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

#22

05.03.2019 16:56:51

Цитата
БМВ написал:
так как я родом из VBS, а там нет Resume, то перешел на метку по ошибке, обратно не вернешься

Забыл, забыл ты свою родину ;) Нет там меток, и GoTo только в конструкции On Error GoTo 0.

 

Framed

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

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

Jack Famous, спасибо за разъяснения;
Nordheim, вам тоже большое спасибо, на самом деле, мне очень понравилось это решение, как и решение участника БМВ.
БМВ, спасибо за полезную информацию про ограничение.

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

 

БМВ

Модератор

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

Excel 2013, 2016

#24

05.03.2019 18:47:08

Цитата
Казанский написал:
Забыл, забыл ты свою родину

:-) вооот , там даже шанса не было :-) По сему и не применяю :-)

По вопросам из тем форума, личку не читаю.

 

Nordheim

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

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

#25

05.03.2019 19:11:54

Цитата
Framed написал:
(а вот это им придется делать в любом случае самим, увы)

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

«Все гениальное просто, а все простое гениально!!!»

 

RAN

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

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

#26

05.03.2019 19:48:22

Цитата
БМВ написал:
Короче, при полном пути более 260 символов

Еще короче. Для Exsel, кажется, 218 символов. Попадал.  :D

 

БМВ

Модератор

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

Excel 2013, 2016

#27

06.03.2019 08:03:50

Off

Цитата
RAN написал:
Для Exsel, кажется, 218 символов

Это не совсем про файл, а скорее про обращение к нему из самого Excel

https://support.microsoft.com/en-us/help/213983/error-message-when-you-open-or-save-a-file-in-microsoft-excel-filename

This behavior is based on a 256-character limitation in Excel for creating links to another file. This limit of 218 characters for the path name is based on the following:•Up to 31 characters in a sheet name.

•Apostrophes and brackets used to denote the workbook name.

•An exclamation point.

•A cell reference.

For example, the path for a file might resemple the following:

  ‘c:excelpersonal…[my workbook.xls]up_to_31_char_sheetname’!$A$1

Если перевести кратко, то, для работы с другой книгой, ссылка не может быть больше 256 символов, включая дополнительные символы (скобки,апострофы, восклицательный знак), имя листа  и диапазон.   если учесть что  Адрес может быть $AAA$1000000 (12 сим) +31 на имя листа + 5 на спец символы, то на путь останется менее 218ти
256-12-31-5=208

По вопросам из тем форума, личку не читаю.

 

Nordheim

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

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

#28

06.03.2019 08:54:26

В дополнении  

Цитата
Nordheim написал:
А если написать юзерам что бы сохранили файл с макросом и файл из которого берутся данные, в одну папку

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

Прикрепленные файлы

  • Книга1.xlsm (16.3 КБ)

«Все гениальное просто, а все простое гениально!!!»

 

Framed

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

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

#29

13.03.2019 17:36:49

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

Цитата
Nordheim написал:
А если написать юзерам что бы сохранили файл с макросом

Файлы не с макросом, потому что модуль с ним находится в личной книге макросов.

Цитата
Nordheim написал:
Как вариант, можно сделать выбор файла.

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

Зачем это нужно: планируются, что такие вспомогательные файлы будут отправляться юзерам раз в месяц, соответственно, можно их просто назвать одним именем и заменять один другим (как и реализованно в данный момент), но было бы лучше, если бы они сохранялись в специально созданной для этого папке, а юзеры могли бы просто «переключаться» между файлами, из которых нужно брать инфу.  

 

Jack Famous

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

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

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#30

13.03.2019 18:02:32

Framed, если вопрос не связан с темой (Обработчик ошибок, пропуск куска кода), то создавайте новую

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

In this Article

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

VBA Errors Cheat Sheet

Errors

On Error – Stop code and display error

On Error Goto 0

On Error – Skip error and continue running

On Error Resume Next

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

On Error Goto [Label]

Clears (Resets) Error

On Error GoTo1

Show Error number

MsgBox Err.Number

Show Description of error

MsgBox Err.Description

Function to generate own error

Err.Raise

See more VBA “Cheat Sheets” and free PDF Downloads

VBA Error Handling

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

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

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

VBA On Error Statement

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

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

On Error GoTo 0

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

On Error GoTo 0

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

vba runtime error 13

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

Sub ErrorGoTo0()

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

'Run More Code

End Sub

On Error Resume Next

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

On Error Resume Next

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

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

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

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

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

VBA Coding Made Easy

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

automacro

Learn More

Err.Number, Err.Clear, and Catching Errors

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

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

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

Sub ErrorNumber_ex()

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

End Sub

vba run-time error 11 err.number

Error Handling with Err.Number

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

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

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

    On Error GoTo -1
End Function

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

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

On Error GoTo Line

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

On Error GoTo errHandler

and create a line label like this:

errHandler:

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

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

On Error Exit Sub

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

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

Sub ErrGoToEnd()

On Error GoTo endProc

'Some Code
    
endProc:
End Sub

or by using the Exit Sub command:

Sub ErrGoToEnd()

On Error GoTo endProc

'Some Code
GoTo skipExit
    
endProc:
Exit Sub

skipExit:

'Some More Code

End Sub

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

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

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

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

Sub ErrExamples()

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

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

VBA On Error MsgBox

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

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

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

    GoTo endProc
    
errHandler:
    MsgBox errMsg
   
endProc:
End Sub

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

VBA IsError

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

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

VBA Programming | Code Generator does work for you!

If Error VBA

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

Sub IfErrorEx()

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

MsgBox n
End Sub

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

VBA Error Types

Runtime Errors

As stated above:

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

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

vba runtime error 13

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

Syntax Errors

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

  • Mispelling
  • Missing or incorrect punctuation

The VBA Editor identifies many syntax errors with red highlighting:

vba syntax error example

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

vba syntax error option

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

vba syntax compile error

I personally find this extremely annoying and disable the feature.

Compile Errors

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

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

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

vba compile error variable

Other examples include:

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

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

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

Debug > Compile

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

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

vba debug compile

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

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

vba compile vbaproject

OverFlow Error

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

vba overflow error

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

Other VBA Error Terms

VBA Catch Error

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

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

VBA Ignore Error

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

On Error Resume Next

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

VBA Throw Error / Err.Raise

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

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

Err.Raise (13)

vba runtime error 13

VBA Error Trapping

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

VBA Error Message

A VBA Error Message looks like this:

vba runtime error 13

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

vba raise error

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

VBA Error Handling in a Loop

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

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

Sub test()
Dim cell As Range

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

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

VBA Error Handling in Access

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

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

VBA 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

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

Избегание условий ошибки

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

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


Избежать ошибки времени выполнения 91 — Объект или С заблокированной переменной блока:

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

Private Sub DoSomething(ByVal target As Worksheet)
    Debug.Print target.Name
End Sub

Если target не назначена ссылка, приведенный выше код вызовет ошибку, которую легко избежать, проверяя, содержит ли объект фактическую ссылку на объект:

Private Sub DoSomething(ByVal target As Worksheet)
    If target Is Nothing Then Exit Sub
    Debug.Print target.Name
End Sub

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

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


Избегайте ошибки времени выполнения 9 — Подкласс вне диапазона:

Эта ошибка возникает при доступе к массиву за пределами его границ.

Private Sub DoSomething(ByVal index As Integer)
    Debug.Print ActiveWorkbook.Worksheets(index)
End Sub

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

Private Sub DoSomething(ByVal index As Integer)
    If index > ActiveWorkbook.Worksheets.Count Or index <= 0 Then Exit Sub
    Debug.Print ActiveWorkbook.Worksheets(index)
End Sub

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

Оператор Error

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

Линейные метки обозначают подпрограммы : потому что подпрограммы исходят из устаревшего кода BASIC и используют GoSub GoTo и GoSub и Return чтобы вернуться к «основной» процедуре, довольно легко написать жесткий код спагетти, если все не строго структурировано , По этой причине лучше всего:

  • процедура имеет одну и только одну подпрограмму обработки ошибок
  • подпрограмма обработки ошибок работает только в состоянии ошибки

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

Private Sub DoSomething()
    On Error GoTo CleanFail

    'procedure code here

CleanExit:
    'cleanup code here
    Exit Sub

CleanFail:
    'error-handling code here
    Resume CleanExit
End Sub

Стратегии обработки ошибок

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

CleanExit:
    Exit Sub

CleanFail:
    Select Case Err.Number
        Case 9
            MsgBox "Specified number doesn't exist. Please try again.", vbExclamation
            Resume
        Case 91
            'woah there, this shouldn't be happening.
            Stop 'execution will break here
            Resume 'hit F8 to jump to the line that raised the error
        Case Else
            MsgBox "An unexpected error has occurred:" & vbNewLine & Err.Description, vbCritical
            Resume CleanExit
    End Select
End Sub

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

Private Sub DoSomething(CheckValue as Long)

    If CheckValue = 0 Then
        On Error GoTo ErrorHandler   ' turn error handling on
        ' code that may result in error
        On Error GoTo 0              ' turn error handling off - same level
    End If

CleanExit:
    Exit Sub

ErrorHandler:
    ' error handling code here
    ' do not turn off error handling here
    Resume

End Sub

Номера строк

VBA поддерживает номера строк в стиле legacy (например, QBASIC). Скрытое свойство Erl можно использовать для идентификации номера строки, которая вызвала последнюю ошибку. Если вы не используете номера строк, Erl только вернет 0.

Sub DoSomething()
10 On Error GoTo 50
20 Debug.Print 42 / 0
30 Exit Sub
40
50 Debug.Print "Error raised on line " & Erl ' returns 20
End Sub

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

Sub DoSomething()
10 On Error GoTo 50
   Debug.Print 42 / 0
30 Exit Sub

50 Debug.Print "Error raised on line " & Erl 'returns 10
End Sub

Имейте в виду, что Erl также имеет только Integer точность и будет бесшумно переполняться. Это означает, что номера строк за пределами целочисленного диапазона дадут неверные результаты:

Sub DoSomething()
99997 On Error GoTo 99999
99998 Debug.Print 42 / 0
99999
      Debug.Print Erl   'Prints 34462
End Sub

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

Резюме ключевого слова

Подпрограмма обработки ошибок будет либо:

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

Ключевое слово Resume должно использоваться только в подпрограмме обработки ошибок, потому что если VBA встречает Resume не находясь в состоянии ошибки, возникает ошибка времени выполнения 20 «Возобновить без ошибок».

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

  • Resume используется отдельно, выполнение продолжается в инструкции, вызвавшей ошибку . Если ошибка на самом деле не обрабатывается , прежде чем делать это, то та же ошибка будет поднят снова, и выполнение может войти в бесконечный цикл.
  • Resume Next продолжает выполнение инструкции сразу после инструкции, вызвавшей ошибку. Если ошибка на самом деле не обрабатывается , прежде чем делать это, то выполнение разрешается продолжать с потенциально недействительными данными, которые могут привести к логическим ошибкам и неожиданному поведению.
  • Resume [line label] продолжает выполнение на указанной метке строки (или номер строки, если вы используете номера строк в стиле устаревшего стиля). Обычно это позволяет выполнить некоторый код очистки до того, как будет чисто выйти из процедуры, например, чтобы закрыть соединение с базой данных, прежде чем вернуться к вызывающему.

Вкл.

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

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

Вышеупомянутый акцент не может быть особо подчеркнут. On Error Resume Next эффективно игнорирует все ошибки и выталкивает их под ковер . Программа, которая взрывается с ошибкой во время выполнения с учетом недопустимого ввода, — это более эффективная программа, чем программа, которая работает с неизвестными / непреднамеренными данными — будь то только потому, что ошибка намного легче идентифицируется. On Error Resume Next можно легко скрыть ошибки .

Оператор On Error является областью действия процедур — поэтому в данной процедуре обычно должен быть только один , такой оператор On Error .

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

On Error Resume Next
[possibly-failing statement]
Err.Clear 'resets current error
On Error GoTo 0

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

Public Sub Caller()
    On Error GoTo Handler
    
    Callee
    
    Exit Sub
Handler:
    Debug.Print "Error " & Err.Number & " in Caller."
End Sub

Public Sub Callee()
    On Error GoTo Handler
    
    Err.Raise 1     'This will be handled by the Callee handler.
    On Error GoTo 0 'After this statement, errors are passed up the stack.
    Err.Raise 2     'This will be handled by the Caller handler.    
    
    Exit Sub
Handler:
    Debug.Print "Error " & Err.Number & " in Callee."
    Resume Next
End Sub

Пользовательские ошибки

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

Option Explicit
Public Enum FoobarError
    Err_FooWasNotBarred = vbObjectError + 1024
    Err_BarNotInitialized
    Err_SomethingElseHappened
End Enum

Используя встроенную константу vbObjectError пользовательские коды ошибок не перекрываются с зарезервированными / существующими кодами ошибок. Необходимо явно указать только первое значение перечисления, поскольку базовое значение каждого члена Enum 1 больше, чем предыдущий элемент, поэтому базовое значение Err_BarNotInitialized неявно является vbObjectError + 1025 .

Повышение собственных ошибок времени выполнения

Ошибка выполнения может быть повышена с Err.Raise оператора Err.Raise , поэтому пользовательская ошибка Err_FooWasNotBarred может быть повышена следующим образом:

Err.Raise Err_FooWasNotBarred

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

Private Const Msg_FooWasNotBarred As String = "The foo was not barred."
Private Const Msg_BarNotInitialized As String = "The bar was not initialized."

А затем создайте выделенный частный метод для повышения каждой ошибки:

Private Sub OnFooWasNotBarredError(ByVal source As String)
    Err.Raise Err_FooWasNotBarred, source, Msg_FooWasNotBarred
End Sub

Private Sub OnBarNotInitializedError(ByVal source As String)
    Err.Raise Err_BarNotInitialized, source, Msg_BarNotInitialized
End Sub

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

Public Sub DoSomething()
    'raises the custom 'BarNotInitialized' error with "DoSomething" as the source:
    If Me.Bar Is Nothing Then OnBarNotInitializedError "DoSomething"
    '...
End Sub

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


Примечание: наследие Error ключевое слово также может быть использован вместо Err.Raise , но это устаревшее / осуждается.

Понравилась статья? Поделить с друзьями:
  • Vba проверка ошибок
  • Vba если ошибка msgbox
  • Vba перехват ошибок
  • Vba ошибка compile error
  • Vba word run time error 4605