IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Erreur malgré "On Error Goto" [XL-2010]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Finance d'entreprise
    Inscrit en
    Juin 2016
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Finance d'entreprise
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2016
    Messages : 184
    Par défaut Erreur malgré "On Error Goto"
    Bonjour,

    Voici un début de code qui renvoit une erreur (91: "Variable objet ou variable de bloc With non définie") au niveau de la ligne en gras malgré le On Error GoTo Continue2:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    Option Base 1
    
    Sub test()
    
            Dim c As Range
            Dim LEnt() As Integer
    
    Début:
            Set c = Columns(1).Find("Bla :")
            On Error GoTo Continue
            adr = c.Address
            On Error GoTo 0
        Do
            If c.Offset(2) = "Blabla" Then Rows(c.row & ":" & c.row + 2).Delete: GoTo Début
            Set c = Columns(1).FindNext(c)
        Loop While c.Address <> adr
        'supprime les entrées sans contenu
        
    Continue:
    On Error GoTo 0
    
                ReDim LEnt(1)
            LEnt(1) = 2
            Set c = Range("A:A").Find("Bla :")
            On Error GoTo Continue2
            adr = c.Offset(2).Address
            On Error GoTo 0
        Do
            Rows(c.row).Resize(2).Insert
            ReDim Preserve LEnt(UBound(LEnt) + 1)
            LEnt(UBound(LEnt)) = c.row + 1
            Set c = Range("A:A").FindNext(c)
        Loop While c.Address <> adr
        'alimente la table des lignes d'en-tête
            
    Continue2:
    On Error GoTo 0
    
            MsgBox "Fin"
            
    End Sub
    Toute aide est bienvenue.

    Cordialement

  2. #2
    Membre Expert
    Femme Profil pro
    Ingénieur
    Inscrit en
    Octobre 2016
    Messages
    1 703
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2016
    Messages : 1 703
    Par défaut
    Bonjour
    Je suis très loin d'être experte en gestion d'erreurs, mais je pense que les GoTo ne gèrent pas les erreurs de compilation et que ton erreur est une erreur de compilation. Je ne promets rien, mais essaie de déclarer ta variable adr, comme tu le fais pour tes autres variables (avec Dim). Si ça ne marche toujours pas essaie d'utiliser "Set" quand tu attribue une valeur à adr.

  3. #3
    Expert éminent Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Par défaut
    Bonjour

    Quel malheur en voyant ce genre de "code"!

    Tu peux éviter les on error et les goto à tord et à travers en vérifiant à priori les cas d'erreur pour les éviter.

    Regarde l'aide de la méthode Range.Find

    Genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If not c is nothing then
    msgbox c.address
    '....

  4. #4
    Invité
    Invité(e)
    Par défaut
    bonjour,
    si tu continus à utiliser "On Error Goto" tu vas te retrouver en prison!

    trouves l'erreur et arrêtes d'utiliser des choses que tu ne maîtrises pas!

  5. #5
    Membre confirmé
    Homme Profil pro
    Finance d'entreprise
    Inscrit en
    Juin 2016
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Finance d'entreprise
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2016
    Messages : 184
    Par défaut
    Citation Envoyé par riaolle Voir le message
    Bonjour
    Je suis très loin d'être experte en gestion d'erreurs, mais je pense que les GoTo ne gèrent pas les erreurs de compilation et que ton erreur est une erreur de compilation. Je ne promets rien, mais essaie de déclarer ta variable adr, comme tu le fais pour tes autres variables (avec Dim). Si ça ne marche toujours pas essaie d'utiliser "Set" quand tu attribue une valeur à adr.
    L'erreur se déclenche à l'exécution du code et non à la compilation. Sinon, bien vu, j'ai omis de copié la déclaration d'adr. Elle est en fait bien déclarée en tant que variable publique (Public adr as String). Cependant, même sans déclaration, ça ne devrait pas poser de problème, à moins que l'option Explicit soit activée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Sub test2()
     
            bop = "croutch"
            MsgBox bop
     
    End Sub
    Enfin, qu'une erreur se déclenche, c'est normal ici. Ce qui ne l'est pas, c'est que l'embranchement correct vers la ligne Continue2 ne se fasse pas.

    Citation Envoyé par mercatog Voir le message
    Quel malheur en voyant ce genre de "code"!

    Tu peux éviter les on error et les goto à tord et à travers en vérifiant à priori les cas d'erreur pour les éviter.

    Regarde l'aide de la méthode Range.Find

    Genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If not c is nothing then
    msgbox c.address
    '....
    Eh oui! C'est juste. J'avais oublié cette prévention d'erreur bien plus appropriée. L'ironie c'est que je l'utilisais dans la même procédure. Merci de m'avoir rafraîchi la mémoire.

    Cependant, la question reste valable. Pourquoi une deuxième redirection lors d'une erreur ne fonctionne-t-elle pas malgré l'annulation précédente du gestionnaire d'erreur? Ce code plante à la ligne 12:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Sub test3()
            
            Dim i As Byte
            
            On Error GoTo Continue
            MsgBox 1 / i
            
    Continue:
    On Error GoTo 0
            
            On Error GoTo Continue2
            MsgBox 1 / i
            
    Continue2:
    
            MsgBox "Fin"
            
    End Sub

  6. #6
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut

    Bonjour,

    c'est normal comme pourtant détaillé dans l'aide VBA de l'instruction On Error !

    _________________________________________________________________________________________________________
    Je suis Paris, Istanbul, Berlin, Nice, Bruxelles, Charlie, …

  7. #7
    Expert confirmé

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 169
    Billets dans le blog
    5
    Par défaut
    Bonjour,

    je ne pense pas qu'on puisse faire une "gestion d'erreur" dans une "gestion d'erreur", même si on ruse en nettoyant l'erreur précédente et en changeant l'étiquette de renvoi (ou tout obscurentisme visant à faire un Resume, Resume Next ou autre Goto)

    à partir de l'étiquette "Continue:" on entre dans ce qu'on pourrait appeler une "sous-procédure" qui gère l'erreur. Et du coup, si tu modifies le paramètre d'appel de la "sous-procédure" ... tant qu'elle n'est pas terminée elle n'est peut-être pas prise en compte.


    Il faut au possible éviter les Goto "Etiquette" au profit d'autres mécaniques. Car VBA n'est pas fait pour traiter les erreurs de façon complexe comme on pourrait l'avoir dans d'autres langages

    Ca passe donc par deux principes :
    - d'une prévention des erreurs : comme tester si le retour d'un find n'est pas nothing plutôt que de laisse venir l'erreur
    - d'une neutralisation d'erreur sur un bloc bien délimité de lignes de codes (le moins possible) qui sont suceptibles de planter (On Error Resume Next) et tester derrière l'existence d'une erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Sub test3()
    Dim i As Byte
     
    On Error Resume Next
    MsgBox 1 / i
        If Err.Number <> 0 Then
            Err.Clear
            MsgBox "aie erreur"
        Else
            MsgBox "Fin"
        End If
    End Sub

    EDIT : pour faire écho aux propos de Marc-L

    Un gestionnaire d’erreurs est « validé » lorsqu’il a été désigné par une instruction On Error ; un gestionnaire d’erreurs « actif » est un gestionnaire validé qui traite une erreur. Si une erreur se produit alors qu’un gestionnaire d’erreurs est actif (c’est-à-dire entre la ligne où survient une erreur et une instruction Resume, Exit Sub, Exit Function ou Exit Property), le gestionnaire d’erreurs de la procédure en cours ne peut pas gérer l’erreur. Le contrôle revient à la procédure appelante. Si la procédure appelante possède un gestionnaire d’erreurs validé, il est activé afin de gérer l’erreur. Si le gestionnaire d’erreurs de la procédure appelante est également actif, le contrôle est restitué aux procédures appelantes antérieures jusqu’à ce qu’un gestionnaire d’erreurs validé mais inactif soit trouvé. Si aucun gestionnaire d’erreurs validé et inactif n’est trouvé, l’erreur est irrécupérable à l’emplacement où elle s’est produite. Chaque fois que le gestionnaire d’erreurs repasse le contrôle à une procédure appelante, cette procédure devient la procédure en cours. Lorsqu’une erreur est gérée par un gestionnaire d’erreurs dans n’importe quelle procédure, l’exécution reprend dans la procédure en cours à l’emplacement désigné par l’instruction Resume.
    .


    Voici donc une usine à gaze qui fonctionnera parfaitement .... c'est toto qui prend la main
    lance la procédure test2 en pas à pas, et regarde bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Sub test3()
    Dim i As Byte
     
    On Error GoTo Continue
    MsgBox 1 / i
    Exit Sub
     
    Continue:
    MsgBox 1 / i
    End Sub
     
     
    Sub test2()
    On Error GoTo toto
    test3
    Exit Sub
     
    toto:
    MsgBox "Ah je suis là ! i vaut bien 0"
    End Sub

    Bien sûr, je déconseille personnellement tout travail de ce type, sauf un développeur averti qui sait très bien empiler des appels de procédures/sous-procédures .... encore que vu son niveau, il aura réglé en amont les survenances d'erreurs pour ne jamais le laisser arriver !

  8. #8
    Invité
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Private Sub test()
    On Error GoTo MyErr
     Err.Raise 1664, "Microsoft Excel", "Bonjour " & vbCrLf & " va donc boire une bière à ma santé!"
    Continuer:
    MsgBox "Reprise du code"
    Exit Sub
    MyErr:
    MsgBox Err.Number & vbCrLf & vbCrLf & Err.Description
    Resume Continuer
    End Sub

  9. #9
    Membre Expert
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 2 266
    Par défaut
    Bonjour,

    sans renier les conseils précédents que tu devrais suivre.
    On error goto 0 ne réinitialise pas le gestionnaire d'erreur, tu peux le forcer avec On error goto -1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Sub test3()
            Dim i As Byte
            On Error GoTo Continue
            MsgBox 1 / i
    Continue:
    On Error GoTo -1
            On Error GoTo Continue2
            MsgBox 1 / i
    Continue2:
            MsgBox "Fin"
    End Sub
    C'est plus pour t'expliquer le pourquoi et un palliatif qui peut être utile dans certains cas. Reste sur les conseils précédents de bonnes pratiques : sortie du gestionnaire d'erreur avec un Exit Sub.
    eric

  10. #10
    Membre confirmé
    Homme Profil pro
    Finance d'entreprise
    Inscrit en
    Juin 2016
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Finance d'entreprise
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2016
    Messages : 184
    Par défaut
    Tout d'abord, merci à tous de vous être penchés sur ce sujet miné!

    Citation Envoyé par eriiic Voir le message
    On error goto 0 ne réinitialise pas le gestionnaire d'erreur, tu peux le forcer avec On error goto -1
    Merci eriiic! J'aime ce genre de réponse orientée solution

    Citation Envoyé par eriiic Voir le message
    C'est plus pour t'expliquer le pourquoi et un palliatif qui peut être utile dans certains cas. Reste sur les conseils précédents de bonnes pratiques : sortie du gestionnaire d'erreur avec un Exit Sub.
    Citation Envoyé par Marc-L Voir le message
    c'est normal comme pourtant détaillé dans l'aide VBA de l'instruction On Error !
    Citation Envoyé par joe.levrai Voir le message
    Ca passe donc par deux principes :
    - d'une prévention des erreurs : comme tester si le retour d'un find n'est pas nothing plutôt que de laisse venir l'erreur
    - d'une neutralisation d'erreur sur un bloc bien délimité de lignes de codes (le moins possible) qui sont suceptibles de planter (On Error Resume Next) et tester derrière l'existence d'une erreur
    Malgré les apparences, je suis aussi un adepte des bonnes pratiques; je n'ai aucun plaisir à créer des labyrinthes dans mes procédures. Or, lire l'Aide en est une, je l'admets. Je m'étais principalement basé sur l'article La gestion des erreurs dans Excel.

    Cependant, admettez que les nuances sont ardues à saisir. Entre "invalider", "inactiver", "réinitialiser", "annuler", pas facile de s'y retrouver au milieu de cette terminologie plus ou moins officielle.

    Merci à joe.levrai d'avoir bien développé sa réponse et d'avoir averti contre la gestion d'erreurs au carré (super les procédures illustratives!):

    Citation Envoyé par joe.levrai Voir le message
    je ne pense pas qu'on puisse faire une "gestion d'erreur" dans une "gestion d'erreur"
    Maintenant, si je récapitule:

    On Error valide un gestionnaire d'erreurs, c'est-à-dire que si une erreur se produit, ce sont les instructions de ce dernier qui sont exécutées. On dit alors que le gestionnaire d'erreurs est actif ou activé. Si une erreur se produit alors que le gestionnaire d'erreurs est activé, les macros s'arrêtent à moins qu'une procédure appelante n'aie un gestionnaire d'erreurs valide mais inactif.

    Cependant (corrigez-moi pas trop fort si je me trompe), le fait d'invalider le gestionnaire d'erreurs ne le "réinitialise" pas. C'est-à-dire qu'aucun autre gestionnaire d'erreurs ne peut être validé (pas de bol pour la procédure). Heureusement pour les non-développeurs non-aguerris comme moi, il y a l'instruction On Error GoTo -1 qui efface l'ardoise et permet de revalider un autre gestionnaire d'erreurs, même si c'est pas bien du tout je le ferai pas c'est promi

    Bien cordialement

  11. #11
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Heureusement pour les non-développeurs non-aguerris comme moi, il y a l'instruction On Error GoTo -1 qui efface l'ardoise
    c'est également pour cela que les développeurs aguerris évitent d'utiliser le on error ou de façon exceptionnelle, du reste dans d'autre langage on appel ça des exceptions!
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    try{
    
    
    }
    Catch (Exception ex)
     {
     }

    on remplacera ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    On Error Resume Next
    MsgBox 1 / i
    par ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     if i= 0 then MsgBox  "Err"

  12. #12
    Expert confirmé
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 84
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Par défaut
    Bonjour à tous
    Je dirais volontiers, pour tout résumer, que la gestion d'erreur doit être limitée aux cas où l'erreur n'est pas celle générée par un défaut de codage, mais totalement imprévisible et non corrigeable par une correction du code.

  13. #13
    Membre Expert
    Homme Profil pro
    PAO
    Inscrit en
    Octobre 2014
    Messages
    2 576
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : PAO
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Octobre 2014
    Messages : 2 576
    Par défaut
    Bonjour bonjour,

    Pour rejoindre ce que dit @unparia (dont je salue J. au passage, ) :
    - par exemple, il existe aussi des cas où l'on peut prévoir à l'avance la gestion d'erreur, lors de la création d'un dossier sur le disque dur, au cas où ledit dossier existe :
    https://www.developpez.net/forums/d1...t/#post9011859

    - autre exemple, lors de traitements des doublons par une collection on utilise aussi la gestion d'erreur => cf Faq qui traite des doublons avec une collection

    mais tout cela est bien ciblé et maitrisé
    Cordialement
    Ryu

    La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. – Albert Einstein

    Pensez à la Balise [ CODE][/CODE ] - à utiliser via le bouton # => Exemple

    Une fois votre problème solutionné pensez à mettre :resolu: en n'oubliant pas d'indiquer qu'elle est la solution finale choisie ;)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Arret sur erreur malgré gestion On error?
    Par petozak dans le forum VB 6 et antérieur
    Réponses: 10
    Dernier message: 05/10/2007, 17h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo