Подтвердить что ты не робот

Разница между 'on error goto 0' и 'on error goto -1' - VBA

Может ли кто-нибудь найти разницу между 'On error goto -1' и 'on error goto 0' в VBA? Я пробовал google и msdn, но мне не повезло.

4b9b3361

Ответ 1

On Error GoTo 0 отключает любое обнаружение ошибок, присутствующее в данной процедуре.

On Error GoTo -1 очищает обработку ошибок и устанавливает ее в ничто, что позволяет создать другую ловушку ошибок.

Пример: при ошибке GoTo -1

После того, как первая ошибка будет поднята, она будет GoTo ErrorFound, которая затем очистит процедуру обработки ошибок и установит новую, которая будет GoTo AnotherErrorFound при обнаружении ошибки.

Sub OnErrorGotoMinusOneTest()

    On Error GoTo ErrorFound

    Err.Raise Number:=9999, Description:="Forced Error"

    Exit Sub

ErrorFound:

    On Error GoTo -1 'Clear the current error handling
    On Error GoTo AnotherErrorFound 'Set a new one
    Err.Raise Number:=10000, Description:="Another Forced Error"

AnotherErrorFound:

    'Code here

End Sub

Пример: при ошибке GoTo 0

После того, как первая ошибка будет поднята, вы получите сообщение об ошибке при отключении обработки ошибок.

Sub OnErrorGotoZeroTest()

    On Error GoTo 0

    Err.Raise Number:=9999, Description:="Forced Error"

End Sub

Ответ 2

В этом ответе рассматривается путаница между объектом ошибки и обработчиком ошибок.

Объект можно очистить с помощью Err.Clear. Это не влияет на обработчик ошибок.

Обработчик ошибок активируется с помощью On Error Goto <label>. Он становится активным при возникновении ошибки.

В то время как обработчик ошибок активен, вы не можете назначить новый обработчик ошибок. On Error Goto <label> не будет иметь эффекта. VBA просто игнорирует попытку назначить новый обработчик ошибок.

Использование Err.Clear не отменяет обработчик ошибок.

Переход на другое место в коде с помощью Goto <label> не отменяет обработчик ошибок. Использование Goto <label> в блоке обработки ошибок может вызвать путаницу и его следует избегать. Вы можете подумать, что обработчик ошибок больше не активен, поскольку на самом деле он все еще активен.

Эффект активного обработчика ошибок заключается в том, что вы не можете назначить новый обработчик ошибок. On Error Goto <label> не будет иметь эффекта. VBA просто игнорирует попытку назначить новый обработчик ошибок. Любые дополнительные ошибки будут необработаны, пока обработчик ошибок активен.

Единственный способ выхода из активного обработчика ошибок:

  • Resume
  • Resume Next
  • Resume <label>
  • On error goto -1
  • выйти из процедуры

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

Отличный источник: Обработка ошибок Pearson в VBA Чип Пирсон не упоминает On error goto -1 в своей статье. Процитировать его:

Я намеренно не включал On Error GoTo -1, потому что он не обслуживает реальной цели и может заблокировать все приложение Excel, если оно не используется точно так же. Да, On Error GoTo -1 синтаксически действительно, но это похоже на то, что пистолет пил подросток. Ничего хорошего придет от него.

Вы также можете обрабатывать ошибки inline без использования обработчика ошибок с использованием объекта ошибки: MSDN Inline Error Handling

Ответ 4

Важно осознать, что в VBA возникают ошибки, связанные с ошибкой.

  • У объекта ошибки есть его набор свойств (например, err.number, err.desciption, err.source и т.д.)

  • Следующая строка, которая будет выполнена, изменится.
    Какая строка выполняется, определяется последним оператором "On Error Goto" , который был выполнен - ​​если есть.

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

Когда возникает ЛЮБАЯ ошибка или вы используете Err.Raise, объект Err устанавливается ВСЕГДА. Даже если используется "On Error Resmue next" или любой другой оператор On error.

Таким образом, такой код можно использовать ВСЕГДА:

Dim i as integer 
On error resume next 
i = 100/0  ' raises error
if err.number <> 0 then 
   ' respond to the error
end if

Очень важно понять, что, когда объект ошибки имеет ненулевое значение для err.number, было поднято исключение И что если вы затем попытаетесь выполнить любое действие "On Error Goto" , это приведет к возникновению ошибки и выполнение будет передано любому коду, который вызывает текущую процедуру. (или где не вызывается каким-либо кодом, предоставляется обычный диалог ошибок VBA). Обратите внимание, что в этом случае "On Error Goto ALabel1" НЕ изменит следующую строку, чтобы быть строкой с Label1: на ней.

eg

Sub ErrorTest()

    Dim dblValue        As Double

    On Error GoTo ErrHandler1
    dblValue = 1 / 0

ErrHandler1:
    debug.print "Exception Caught"
    debug.print Err.Number

    On Error GoTo ALabel1
    dblValue = 1 / 0

Exit sub
ALabel1:
    debug.print "Again caught it."

End Sub

Как только свойство err.number будет установлено на ноль, вы можете reset его на ноль, используя

On Error Goto -1 

Обратите внимание, что Err.Clear также сбрасывает его до нуля, но на самом деле это эквивалентно:

On Error Goto -1 
On Error Goto 0

т.е. Err.Clear удаляет "On Error Goto" , который в настоящее время существует. Поэтому лучше всего использовать:

On Error Goto -1   

как использование Err.clear Вам часто нужно писать

Err.Clear
On Error Goto MyErrorHandlerLabel

Стоит отметить, что Err.Clear неявно выполняется VBA всякий раз, когда он выполняет любой оператор Resume, Exit Sub, Exit Function, Exit Property или любой оператор On Error.

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

Err.Raise Number: =, Источник: =, Описание: =

Err.Raise очень важен, так как он позволяет распространять ошибку на вызывающую программу. И повышайте свои собственные номера ошибок, известные как "пользовательские ошибки", которые предоставляют способ сообщить вызывающей программе, что она не может продолжить логическая причина. (например, бизнес-правило было нарушено).

Вы можете управлять тем, какая строка кода выполняется следующим, используя выражения типа

Вкл. Ошибка Перейти к ALabelName По ошибке Перейти к ANONZeroLineNumber а также On Error Goto 0 'Это особый случай, когда он говорит "внутри текущей области (как правило, sub или function)), в случае, если произошла ошибка, возвращает объект ошибки обратно к коду, который вызывает текущую подфункцию или функцию.

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