2014-10-14 5 views
6

So che è possibile arrestare manualmente una macro VBA in esecuzione con Ctrl + Pausa, ma esiste un modo per interrompere automaticamente il codice se viene soddisfatta una determinata condizione? exit function/exit sub non funzionano, perché stanno solo terminando il metodo con cui sono chiamati all'interno.Come arrestare automaticamente la macro VBA?

Per esempio,

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 

Suppongo che potrei trasformare queste sub 's in function' s e utilizzare i codici di ritorno per sapere se il metodo eseguito con successo, ma c'è un modo più semplice per fare questo?

+0

Proprio come un suggerimento generale, 'goto' è male. Non usarlo –

+0

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

risposta

9

È possibile aumentare il proprio errore definito dall'utente con err.raise. Questo è simile al tuo esempio, ma un po 'più potente in quanto è un errore effettivo che fermerà l'esecuzione del codice, anche se è applicato a una chiamata nidificata.

Ad esempio,

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

La linea err.raise invierà il controllo all'etichetta exitCode: anche se era chiamato fuori di a. È possibile utilizzare qualsiasi condizione per verificare se questo errore personalizzato deve essere generato.

Più sull'oggetto err e l'errore di VBA handling-

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

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

1

Credo che vuole che si vuole fare è alzare di nuovo l'errore nel codice di gestione degli errori. Provare qualcosa di simile (non testato):

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 

Quando si utilizza On Error Goto, è necessario un Exit Sub prima dell'etichetta. Altrimenti il ​​tuo codice passerà al gestore degli errori anche quando non ci sono errori.

La prima gestione degli errori non rileva gli errori effettivi che potrebbero verificarsi durante il runtime diversi da quelli per i quali si sta verificando. Inoltre, non esiste un modo conveniente per segnalare alla funzione chiamante che qualcosa è andato storto a meno che non si aggiungano controlli in tutte le routine di chiamata.

Nota che è generalmente considerata cattiva progettazione anche se per generare un errore solo per il controllo del flusso:

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

Questo è ciò che abbiamo fatto per i nostri progetti vb6. Potresti non averne bisogno per ogni funzione, solo quelle in cui vuoi eseguire il clean up del codice. Dipende solo da te cosa vuoi usare. – Ceres