2014-10-14 29 views
6

Wiem, że można ręcznie zatrzymać działające makro VBA za pomocą Ctrl + Przerwa, ale czy istnieje sposób na automatyczne zatrzymanie kodu, jeśli zostanie spełniony określony warunek? exit function/exit sub nie działają, ponieważ kończą tylko metodę, do której są wywoływane.Jak automatycznie zatrzymać makro VBA?

Na przykład

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 

Przypuszczam mogę wyłączyć te sub „s do function” S i wykorzystać kody powrotne wiedzieć, czy metoda została wykonana pomyślnie, ale czy istnieje prostszy sposób to zrobić?

+0

tylko jako ogólna wskazówka, 'goto' jest złe. Nie używaj go. –

+0

http://stackoverflow.com/q/46586/436282 –

Odpowiedz

9

Można podnieść własny błąd zdefiniowany przez użytkownika za pomocą err.raise. Jest to podobne do twojego przykładu, ale trochę mocniejsze, ponieważ jest faktycznym błędem, który zatrzyma wykonywanie kodu, nawet jeśli jest zastosowany do połączenia zagnieżdżonego.

Na przykład

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... 

Linia err.raise wyśle ​​kontrolę etykiecie exitCode: mimo że był nazywany poza a. Możesz użyć dowolnych warunków, aby sprawdzić, czy ten niestandardowy błąd powinien zostać zgłoszony.

Więcej na obiekcie err i błędów VBA handling-

https://msdn.microsoft.com/en-us/library/ka13cy19(v=vs.90).aspx

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

1

wierzę chcą chcesz zrobić, to podnieść znowu błąd w kodzie obsługi błędów. Spróbuj coś takiego (nie testowane):

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 

Podczas korzystania On Error Goto, potrzebujesz Exit Sub przed etykietą. W przeciwnym razie kod przejdzie do obsługi błędów, nawet jeśli nie wystąpi błąd.

Twoja pierwsza obsługa błędów nie przechwytuje rzeczywistych błędów, które mogą wystąpić podczas działania innego niż testowany. Ponadto nie ma wygodnego sposobu sygnalizowania funkcji wywołującej, że coś poszło nie tak, chyba że dodasz kontrole we wszystkich procedurach wywołujących.

Należy pamiętać, że jest to powszechnie uważane złe projektowanie chociaż podnieść błąd tylko do regulacji przepływu:

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

To jest to, co zrobiliśmy dla naszych projektów vb6. Możesz nie potrzebować go dla każdej funkcji, tylko tych, w których chcesz uruchomić czyszczenie kodu. To naprawdę zależy od Ciebie, czego chcesz użyć. – Ceres