2015-05-27 17 views
18

Ho cercato il più possibile online (ad eccezione del sito Web di supporto Microsoft, che è bloccato al lavoro per qualche motivo). Sto cercando di saltare semplicemente un errore. Il mio codice scritto qui è semplificato ma dovrebbe funzionare nello stesso modo.VBA Excel semplice Gestione degli errori

ciò che si suppone il mio codice di fare: Uno dei miei sottomarini crea forme in un ciclo e nomi di loro (btn_1, btn_2, ecc). Ma prima di crearli, chiama un sub che tenta di eliminarli in modo da non creare duplicati. Questa sotto scorre (btn_1, btn_2, ecc) ed elimina le forme utilizzando:

for i = 1 to (a certain number) 
    Set shp = f_overview.Shapes("btn_" & i) 
    shp.delete 
next 

Naturalmente, accade che tale forma non può essere eliminato perché semplicemente non esiste. Ho trovato che la maggior parte delle volte la correzione consigliata consiste nell'aggiungere (per errore riprendere successivamente) prima di impostare la forma, in quanto ricevo un errore che dice che non esiste. Ho provato all'interno del ciclo, prima del ciclo, ecc, in questo modo:

for i = 1 to (a certain number) 
    On Error Resume Next 
    Set shp = f_overview.Shapes("btn_" & i) 
    shp.delete 
next 

Per quanto ho capito si suppone ciclo proprio attraverso se la forma non esiste, ma ho ancora ottenere lo stesso errore se aggiungo o meno l'errore On resume next! Che cosa sto facendo di sbagliato?

MODIFICA: non vi sono errori quando le forme esistono.

risposta

8

Sembra che avete l'errore sbagliato intrappolando set di opzioni. Nell'editor VBA, selezionare Tools -> Options. Nella finestra che si apre, selezionare General tab e selezionare il pulsante di opzione Break on Unhandled Errors. Ciò dovrebbe consentire a Excel di elaborare correttamente il comando On Error Resume Next.

Ho il sospetto che sia selezionato Break on All Errors.

+0

Grazie! Ho continuato a provare i suggerimenti degli altri rispondenti e tutti hanno fallito. Questo è il motivo per cui anche loro hanno fornito informazioni preziose! –

+0

@ DavidGrand'Maison Concordo sul fatto che la gestione degli errori nelle altre risposte sia più pulita e migliore. Ma il tuo codice originale avrebbe dovuto funzionare. – Degustaf

2

Prova:

On Error Resume Next 

for i = 1 to (a certain number) 
    Set shp = f_overview.Shapes("btn_" & i) 
    if err<>0 then err.clear else shp.delete 
next 

on Error Goto 0 
14

Invece di cercare di eliminare ciecamente forme e errori saltando, perché non scorrere l'elenco delle forme conosciute ed eliminarle. Quindi non devi preoccuparti di un On Error Resume Next che spesso finisce per essere abusato.

Sub Test(TheSheet As Worksheet) 

Dim Shp as Shape 

For Each Shp in TheSheet.Shapes 
    If left(Shp.Name, 4) = "btn_" Then 
    Shp.Delete 
    End if 
Next 

End Sub 

Se si desidera eliminare tutte le forme, rimuovere l'istruzione If. Se si desidera eliminare un numero di forme con un nome diverso, modificare l'istruzione If in modo appropriato.

+0

++ Un altro buon modo per eliminare le forme :) –

+0

AH eccellente! Questo è il modo in cui scelgo di farlo. Grazie per la correzione. +1 per la risposta anche se non spieghi come usare la gestione degli errori :-) –

+0

Sei corretto sulla mancanza di dettagli di gestione degli errori - questo ciclo non lo richiede, specialmente non nel modo in cui stavi pensando. [Mat's Mug] (http://stackoverflow.com/a/30489275/2344413) fa un buon lavoro di copertura della gestione degli errori in generale. – FreeMan

22

Ho riscontrato che la maggior parte delle volte la correzione consigliata consiste nell'aggiungere (per errore riprendere successivamente) prima di impostare la forma, poiché viene visualizzato un errore che dice che non esiste.

NO!

Il metodo consigliato per maniglia errori di runtime è non a tirarle sotto il tappeto e continuare l'esecuzione come se nulla fosse successo - che è esattamente ciò On Error Resume Next fa.

Il modo più semplice per evitare errori di runtime è per controllare le condizioni di errore, e di evitare l'esecuzione di codice che determina tasso di fallimento 100%, come tentativo di eseguire un metodo su un riferimento a un oggetto che è Nothing:

For i = 1 To (a certain number) 
    Set shp = f_overview.Shapes("btn_" & i) 
    If Not shp Is Nothing Then shp.Delete 
Next 

Nei casi in cui non è possibile verificare la presenza di condizioni di errore e must errori maniglia, il metodo consigliato è quello di maniglia loro:

Private Sub DoSomething() 
    On Error GoTo CleanFail 

    '...code... 

CleanExit: 
    'cleanup code here 
    Exit Sub 

CleanFail: 
    If Err.Number = 9 Then 'subscript out of range 
     Err.Clear 
     Resume Next 
    Else 
     MsgBox Err.Description 
     Resume CleanExit 
    End If 
End Sub 
+1

++ sulla corretta gestione degli errori :) –

+0

@SiddharthRout sì, tranne che non l'ho provato e ora più ci penso, più credo che l'assegnazione genererebbe un errore di 'indice fuori intervallo', nel qual caso [La risposta di FreeMan] (http://stackoverflow.com/a/30489225/1188513) ha una soluzione migliore. –

+0

Questo è ok :) Modifica il tuo codice sopra. Il mio commento è stato il corretto trattamento degli errori che hai mostrato in fondo al post. ne ho parlato anche nel mio post :) –

13

Non c'è nulla di sbagliato nell'uso OERN (On Error Resume Next) a condizione di capire che cosa si sta facendo e come sta andando a influenzare il vostro codice.

Nel tuo caso è perfettamente normale da usare OERN

Dim shp As Shape 

For i = 1 To (a certain number) 
    On Error Resume Next 
    Set shp = f_overview.Shapes("btn_" & i) 
    shp.Delete 
    On Error GoTo 0 
Next 

Allo stesso tempo assicurare che non si fa qualcosa di simile

On Error Resume Next 
<Your Entire Procedure> 
On Error GoTo 0 

Questo evita di visualizzare tutti gli errori. Usare una corretta gestione degli errori, come illustrato da Matt

Edit:

Ecco un altro bellissimo esempio su come utilizzare OERN controlla questa funzione se un particolare foglio di lavoro esista o meno.

Function DoesWSExist(wsName As String) As Boolean 
    Dim ws As Worksheet 

    On Error Resume Next 
    Set ws = ThisWorkbook.Sheets(wsName) 
    On Error GoTo 0 

    If Not ws Is Nothing Then DoesWSExist = True 
End Function 

Se lo si desidera si può anche scorrere tutti i fogli da controllare è il foglio esiste o no!

+0

Grazie per la spiegazione! La ragione per cui stava fallendo, però, era perché avevo le impostazioni sbagliate (vedi la risposta scelta). –

+3

++ ma sfortunatamente la maggior parte non capisce le implicazioni dell'utilizzo di OERN. Mi piace l'acronimo btw.Lo tengo. – RubberDuck