Как остановить макрос VBA автоматически?

Я знаю, что вы можете вручную остановить запущенный макрос VBA с Ctrl+перерыв, но есть ли способ, чтобы автоматически остановить код, если выполняется определенное условие? exit function / exit sub не работают, потому что они только завершают метод, который они вызывают внутри.

например,

sub a
    call b
    msgbox "a complete"
end sub

sub b
    call c
    msgbox "b complete"    'this msgbox will still show after the `exit sub` in 'c'
end sub

sub c
    msgbox "entering c"
    exit sub               'this will only `exit sub` 'c', but not 'a' or 'b'
    msgbox "exiting c"
end sub

'OUTPUT:

'entering c
'b complete
'a complete

полагаю, я мог бы превратить эти subв functionи использовать коды возврата, чтобы узнать, если метод выполнен успешно, но есть более простой способ сделать это?

2 ответов


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

например,

sub a
on error goto exitCode
    call b
    msgbox "a complete"
    exit sub       'you need this to prevent the error handling code from always running
exitCode:
    msgbox "code is exiting..."
    'clean up code here
end sub

sub b
    call c
    msgbox "b complete"
end sub

sub c
    msgbox "entering c"
    err.raise 555, "foo", "an error occurred"
    msgbox "exiting c"
end sub

'OUTPUT:

'entering c
'code is exiting...

на err.raise строки вышлем управление exitCode: ярлык, хотя он был вызван за пределами a. Вы можете использовать любые условия, чтобы проверить, должна ли быть вызвана эта пользовательская ошибка.

больше на the err обработка ошибок объекта и VBA -

https://msdn.microsoft.com/en-us/library/ka13cy19 (v=против 90).aspx

http://www.cpearson.com/excel/errorhandling.htm


Я считаю, что вы хотите сделать, это снова вызвать ошибку в коде обработки ошибок. Попробуйте что-то вроде этого (не проверял):

Private Sub Test
    On Error Goto bad
    x = 0
    debug.print 1/x
    Exit Sub

    bad:
        'Clean up code
        Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End Sub

при использовании On Error Goto вам понадобится Exit Sub перед подписью. В противном случае ваш код попадет в обработчик ошибок, даже если ошибки нет.

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

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

Private Sub Test
    If x = 0 Then
        Err.Raise 
    End If
End Sub