gestione degli errori



  • gestione degli errori
    di nichicanta data: 10/01/2015 20:11:55

    Buona sera amici, dopo tanto (non smetto mai di seguirvi con entusiasmo e interesse, voi mi avete aiutato a muovere i primi passi con vba) sento il piacere di chiedere il vostro aiuto e la vostra competenza per poter capire una cosa che non mi entra nella capoccia.
    Desidererei tanto che mi insegnaste a capire come fare per poter gestire eventuali errori che si potrebbero verificare in un codice mal progettato, io l'unica cosa che sono riuscito a capire è questo On Error resume next che mi salta l'eventuale errore e mi fa andare avanti.
    Vi pregherei di insegnarmelo con degli esempi pratici proprio perchè a breve dovrò progettare un Databse di Access dove avrò la necessità di gestire gli errori.
    Grazie come sempre, vi saluto con affetto e immensa stima.
    Ciao Nicola.



  • di mabolsie (utente non iscritto) data: 10/01/2015 21:06:09

    Ciao nichi, ti dico quello che so in merito : all' inizio del codice , come ben saprai, dichiari ON ERROR però metti l'istruzione GOTO, quindi ON ERROR GOTO poi sulla stessa riga aggiungi il nome di una istruzione che indicherà la destinazione al GOTO. Percio ON ERROR GOTO ERRORE. In fondo al codice metterai come istruzione ERRORE : (CON I DUE PUNTI) vai a capo e metti il codice che dovrà eseguire la macro, quindi in caso di errore nel codice primario la macro salta a ERRORE: eseguendo il codice secondario che tu avrai scritto.
    Spero di esserti stato utile

    Ciao Max
     
    option explicit     ' facciamo contento Vecchio Frac
    sub IndividuaErrore
    On Error GoTo Errore
    ......
    codice
    .....
    Errore :
    'codice ' da eseguire in caso di errore
    MsgBox( codice errato)
    Exit Sub
    end sub



  • di mabolsie (utente non iscritto) data: 10/01/2015 21:29:13

    Ti allego un codicino fatto al volo, provalo

    Ciao Max
     
    Option Explicit
    Sub GestErr()
    On Error GoTo Errore
    Range("A15") = Range("a14") / 0
    
    Errore:
    Msg = MsgBox("La divisione per 0 non si puo fare", , "Errore")
    Exit Sub
    End Sub
    



  • di Vecchio Frac data: 10/01/2015 21:50:03

    Ciao nichi, un db di Access? molto bene, ecco una cosa che conosco benino ormai :)
    Sulla gestione degli errori c'è un mondo e purtroppo VBA non li gestisce per niente bene, non come altri linguaggi più evoluti.
    Però lo spunto che ti è stato dato da max è buono.

    @max
    "option explicit ' facciamo contento Vecchio Frac"
    ---> questo mi ha fatto divertire :)





  • di mabolsie (utente non iscritto) data: 10/01/2015 22:11:52

    @Vecchio Frac
    ahahah... Buona domenica .
    Piacerebbe anche a me progettare in Access ma non ce l'ho in Office 2003.
    Ho acquistato qualche libro in merito nel lontano 2002/2003 ma se non hai la piattaforma per testarlo non ci capisci niente specialmente con le relazioni.
    se cambierò il computer impegnerò la casa ( di mia moglie ) e metterò anche Access.

    Ciao Max



  • di Vecchio Frac data: 10/01/2015 22:56:08

    Un esempio simile a quello di max ma leggermente diverso, all'attenzione di nichi.
    Se togli Exit Sub che cosa succede? :)
    E se togli Resume Next?

    p.s. max esagera perchè mette option explicit anche se non usa variabili... ma è meglio metterlo di default, c'è l'opzione nell'editor :)

     
    Option Explicit
    
    Sub GestErr()
    Dim a As Integer, b As Integer
    
        a = 15
        b = 5
        On Error GoTo Errore
    
        Range("A1") = "a / 0 = " & (a / 0)
        Range("A2") = a & " / " & b & " = " & (a / b)
    
        Exit Sub        'istruzione importante... se la togli che cosa succede?
        
    Errore:
        MsgBox "La divisione per 0 non si può fare", vbOKOnly + vbInformation, "Errore"
        Resume Next
    
    End Sub






  • di nichicanta (utente non iscritto) data: 11/01/2015 18:31:17

    Ciao Max, ciao V.Frac innanzitutto grazie come sempre per il vostro prezioso contributo.
    Ho fatto varie prove con il codice che mi avete postato, seguendo i due modi di V. Frac ed ho notato i due cambiamenti, cioè remmando Exit Sub il messaggio di errore compare 3 volte; remmando Resume Next il messaggio compare una volta ed esce dalla procedura.
    Vi ringrazio e vi saluto con stima e sincero affetto.




  • di scossa data: 11/01/2015 19:51:34

    Ciao,

    io sarei per una gestione degli errori più "cautelativa", quindi niente Resume Next nella parte di codice di gestione dell'errore, perché l'errore potrebbe avere ripercussioni "imprevedibili" sui risultati prodotti dal resto del codice.
    Altra considerazione: la gestione proposta da V.F. in un codice che preveda l'utilizzo di variabili oggetto renderebbe complicata la loro distruzione alla chiusura del codice, per esempio



    Sub GestErr()
    Dim a As Integer, b As Integer
    Dim ws As Worksheet
    Set ws = ThisWorkbook.ActiveSheet
    a = 15
    b = 5
    On Error GoTo Errore
    Range("A1") = "a / 0 = " & (a / 0)
    Range("A2") = a & " / " & b & " = " & (a / b)
    Set ws = Nothing
    Exit Sub 'istruzione importante... se la togli che cosa succede?
    Errore:
    MsgBox "La divisione per 0 non si può fare", vbOKOnly + vbInformation, "Errore"
    Set ws = Nothing
    End Sub



    Quindi proporrei qualcosa del genere:



    Sub GestErrScossa()
    Dim a As Integer, b As Integer
    Dim ws As Worksheet

    Set ws = ThisWorkbook.ActiveSheet
    a = 15
    b = 5
    On Error GoTo Uscita__
    ws.Range("A1") = "a / 0 = " & (a / 0)
    ws.Range("A2") = a & " / " & b & " = " & (b / 0)
    Uscita__:
    Set ws = Nothing
    If Err.Number <> 0 Then
    MsgBox Err.Description, vbOKOnly + vbInformation, "Errore"
    End If
    End Sub






    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di nichicanta (utente non iscritto) data: 12/01/2015 08:12:02

    Ciao scossa, buongiorno a tutti, se ho capito bene, in base a quanto voi mi avete postato la gestione degli errori la devo impostare sempre in questo modo, intendo con On Error GoTo Errore
    oppure come tu hai fatto (penso che sia la stessissima cosa, tu l'hai chiamata On Error GoTo Uscita__), oppure cambia tra questo: On Error GoTo Errore e quello da te indicato:On Error GoTo Uscita__.
    Grazie e buona giornata a tutti.



  • di scossa data: 12/01/2015 09:23:08

    cit. X: "....intendo con On Error GoTo Errore oppure come tu hai fatto (penso che sia la stessissima cosa, tu l'hai chiamata On Error GoTo Uscita__)..."

    Non è assolutamente la stessa cosa: nel modo che suggerisco io, il flusso del codice è comunque lineare e si conclude in modo "naturale" (senza Exit Sub). Questo permette di non dovere duplicare le istruzioni di chiusura (vedi Set ws = Nothing nel mio esempio precedente), oltre a rendere più "leggibile" il flusso stesso.
    Personalmente non ho simpatia per Exit Sub e tra i due:

    	......
    If a <> b then Exit Sub
    msgbox "bla bla"
    ......
    End Sub

    e

    	If a = b then
    msgbox "bla bla"
    .....
    End If
    End Sub


    preferisco il secondo.

    Poi, ovviamente, ognuno opera come meglio crede.
    Io ho provato sulla mia pelle le conseguenze nefaste della mancata distruzione delle istanze di variabili oggetto per omettere, solo per pigrizia, qualche riga di Set variabile = Nothing ....

    Ribadisco che sono solo opinioni personali, non devo insegnare nulla a nessuno.

    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Vecchio Frac data: 12/01/2015 09:31:48

    @scossa
    cit. "Non è assolutamente la stessa cosa:"
    ---> Nichi intende riferirsi solo all'etichetta, perchè prima leggeva "On Error goto Errore" e il tuo esempio diceva "On Error Goto uscita__".
    Per l'annientamento delle variabili, è giusto come dici anche se nella maggior parte dei casi Excel non è così schizzinoso e riesce a distruggere le istanze dei /propri/ oggetti (ho verificato anch'io problemi con istanze rimaste appese ma accade soprattutto smanettando con istanze di Word).
    Su Exit Sub, vabbè... non è così inutile e a volte è anche inevitabile :)

    Per inciso, io la gestione degli errori non la implemento quasi mai. Preferisco, se riesco, costruire codice che non permetta il verificarsi degli errori (in questo senso differisce da python dove il costrutto try...catch, invece, è ampiamente utilizzato come modo normale di eseguire istruzioni alternative, ad esempio per gestire l'import di librerie di sistema).





  • di nichicanta (utente non iscritto) data: 12/01/2015 09:52:36

    @Ribadisco che sono solo opinioni personali, non devo insegnare nulla a nessuno.
    Ciao scossa, il proverbio dalle mie parti recita: è meglio seguire o informarsi da chi ha vissuto un'esperienza x che non ascoltarla dal saccente (non saggio), quindi io seguo sempre i consigli di chi, prima di me e nel modo più competente e professionale me li propone.

    @Preferisco, se riesco, costruire codice che non permetta il verificarsi degli errori.
    V.Frac anch'io cerco sempre di creare codice che non permetta il verificarsi degli errori, ma ho molta difficoltà perchè il codice lo riesco ad interpretare ma non riesco a crealo da solo ( intendo funzioni e o altro, mi aiuto molto con copia e incolla e riscorso ai vari forum, nonchè a voi esperti).
    Vi saluto.





  • di scossa data: 12/01/2015 10:11:55

    cit. V.F.: "Nichi intende riferirsi solo all'etichetta".
    Probabilmente hai ragione, ma comunque mi sembrava importante chiarire la differenza tra le due "gestioni".

    Riguardo a "Su Exit Sub, vabbè... non è così inutile e a volte è anche inevitabile", sono pure d'accordo, ma se c'è un'alternativa valida per evitarla la evito.

    cit. V.F.: "Per inciso, io la gestione degli errori non la implemento quasi mai. Preferisco, se riesco, costruire codice che non permetta il verificarsi degli errori".

    Costruire codice che non permetta il verificarsi di errori credo sia la linea guida (speranza ) di ogni programmatore.
    Io in genere preferisco ipotizzare l'imprevisto (sarò pessimista) e di solito la implemento, anche perché può aggiungere flessibilità al codice (vedi il metodo Raise dell'oggetto Err).
    Ma al solito non esiste solo il bianco ed il nero, l'importante è saper valutare e scegliere la soluzione migliore per quel determinato contesto, che richieda o meno la gestione degli errori, che richieda o meno Exit Sub.

    @Vecchio Frac P.S.(OT): pure in Transact-SQL il costrutto try...catch è indispensabile, ad esmpio, per gestire commit/rollback delle transcation.

    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)