Gestion erreur VBA

eriiic

XLDnaute Barbatruc
Bonjour à tous,

Dans le fichier joint je génère 2 erreurs.
La 1ère est bien gérée avec le On Error Goto, pas la 2nde.
Pourquoi ? Que me manque-t-il ?

Merci
eric
 

Pièces jointes

  • Test gestion erreur.xls
    22 KB · Affichages: 157

néné06

XLDnaute Accro
Re : Gestion erreur VBA

Re

@JCGL C'est fort possible, je n'avais testé que sur les feuilles vides de Eriiiic.


@Eriiiic

En plaçant Goto suite, je fait du bricolage, mais pas trop testé.

For Each c In Cells.SpecialCells(xlCellTypeFormulas, 23) ' contrôle des formules
On Error GoTo 0
MsgBox ("test1 ok")
GoTo suite
'
Next c
 

eriiic

XLDnaute Barbatruc
Re : Gestion erreur VBA

Re,

Donc retour à la case départ, les 2 propositions générant une erreur si pas d'erreur en cours.
Je serais absent cette après-midi mais lirait attentivement les contributions à mon retour.
Merci
eric
 
G

Guest

Guest
Re : Gestion erreur VBA

Bonjour,

Proposition:
Code:
Sub test()
    Dim c As Range
    Worksheets("Feuil1").Activate
    
    On Error GoTo GesErr1
    For Each c In Cells.SpecialCells(xlCellTypeFormulas, 23)    ' contrôle des formules
    Next c
    MsgBox ("Boucle test1 terminée")
    
Suivant1:     '
    On Error GoTo GesErr2
    For Each c In Cells.SpecialCells(xlCellTypeConstants, 23)    ' contrôle des constantes
    Next c
    MsgBox ("Boucle test2 terminée")
    Exit Sub

GesErr1:
    MsgBox "Une erreur s'est produite dans la boucle du test1" & vbCrLf & "je m'en vais faire la suivante!"
    Resume Suivant1
    
GesErr2:
    'Rien d'autre à faire, on sort, l'erreur sera invalidée 
    MsgBox "Une erreur s'est produite dans la boucle du test2"

End Sub

A+
 
Dernière modification par un modérateur:

Dranreb

XLDnaute Barbatruc
Re : Gestion erreur VBA

On Error GoTo 0 Invalide dans la procédure en cours tout gestionnaire d'erreurs validé.
Pour moi le On erreur goto suivant aurait dû s'activer dans ces conditions.
Oui mais encore une fois ça n'est pas prévu d'être utilisé dans un gestionnaire actif en plus d'être validé.
C'est un peu, si vous voulez, comme si un On Error GoTo QuelquePart faisait entrer l'exécution dans un mode en quelque sorte stressé : tout nouveau problème survenant par dessus pendant ce temps est fatal. Faut le calmer par un Resume. Mais le plus pratique, de loin, c'est: Calme toi tout de suite: je gère derrière ! : On Error Resume Next
Cela dit, j'ai déjà été embarrassé de ne pouvoir mettre On Erreur GoTo 0 avant d'avoir pu tester Err.
J'avais contourné en écrivant un module dédié commençant comme ça :
VB:
Option Explicit
Public CasOk As Boolean, CasErr As Byte
'

Public Sub PrévoirCas(E As ErrObject, ParamArray Prévu())
Dim N As Long, Z As String
CasOk = E.Number = 0: If CasOk Then CasErr = 0: Exit Sub
For N = 0 To UBound(Prévu)
   If E.Number = Prévu(N) Then CasErr = N + 1: Exit Sub
   Next N
Z = "PrévoirCas Err"
For N = 0 To UBound(Prévu)
   Z = Z & ", " & Prévu(N)
   Next N
Z = Z & ", " & E.Number & vbLf & "Rem. " & N & ") " & E.Description
PressPapier = Z
MsgBox E.Description & vbLf & "_______________________________________________________" & vbLf & vbLf & """" & Z _
   & """ a été mis dans le presse papier !", vbExclamation, "Débogage obligatoire d'erreur " & E.Number
Stop
End Sub
'

Property Let PressPapier(Z As String)
Dim DOb As New DataObject
DOb.SetText Z
DOb.PutInClipboard
End Property
Property Get PressPapier() As String
Dim DOb As New DataObject
DOb.GetFromClipboard
PressPapier = DOb.GetText
End Property
Et, par exemple dans les autres modules:
VB:
      On Error Resume Next: Nom = VBP.Filename: PrévoirCas Err, 76: On Error GoTo 0
      If CasOk Then
Bon, c'est toujours opérationnel dans le classeur où je l'avais fait, je crois bien que je ne l'enlèverai jamais. Mais je n'ai jamais été tenté de le reproduire dans un autre classeur. Il faut croire que c'est quand même un peu plus lourd que de vivre avec l'inconvénient.
À +
 
Dernière édition:

eriiic

XLDnaute Barbatruc
Re : Gestion erreur VBA

Re,

pas encore parti.... :)
Hasco, solution satisfaisante qui fonctionne, merci

@youky(BJ) : solution très satisfaisante aussi puisque plus linéaire. Tu étais perdu au milieu des autres réponses et je ne t'avais pas vu, désolé. Merci :)

On y arrive :) J'ai donc 2 choix : Hasco et Youky.

Maintenant pour bien comprendre, pourquoi cette structure ne fonctionne pas puisque on error goto 0 est sensé invalider tout gestionnaire d'erreur en cours.
Code:
Sub test()
On Error GoTo Suivant1 'active la gestion des erreurs
   ' instruction
On Error GoTo 0 ' désactive le gestionnaire d'erreur
   ' suite d'instructions
: Suivant1
On Error GoTo 0 ' désactive le gestionnaire d'erreur
'
On Error GoTo suivant2 'active la gestion des erreurs
   ' instruction
On Error GoTo 0 ' désactive le gestionnaire d'erreur
   ' suite d'instructions
: suivant2
On Error GoTo 0 ' désactive le gestionnaire d'erreur
End Sub
Est-ce un bug ou c'est ainsi dans tous les langages :
on Error Goto xxx suivi de on Error Goto 0 ne peux pas être utilisé plus d'une fois dans une procédure ?

J'admet qu'actuellement Resume semble obligatoire, mais ma structure de départ ne me paraissait pas illogique.
En l'état de ma réflexion j'arrive donc à un On error Goto 0 qui ne sert à rien ( :confused: ???)
Si quelqu'un a une explication... (mais si vous en avez marre je comprendrais aussi ;-) )

Merci encore à tous pour vos recherches et contributions.
eric
 
G

Guest

Guest
Re : Gestion erreur VBA

Re,

Bernard a amplement répondu à ta question précédement, il me semble. Qu'y-a-t-il d'incomprehensible.

Mais si tu aimes le linéaire, il y a une autre manière d'écrire ta gestion d'erreur (pour l'exemple donné). Toutefois je la déconseillerais pour des projets plus importants car elle porte en elle une grande possibilité de fabrication d'usine à Gaz. Il est toujours préférable de traiter les erreurs hors du cours logique de programation.

Avec l'apparition de la programmation objet et modulaire, le seul truc qui n'ait pas bougé c'est la gestion d'erreur. Il a fallu attendre .net pour avoir quelque chose de plus conséquent et harmonisé avec ce qui ce fait dans d'autres langages.

Code:
Sub test()
    Dim c As Range
    Worksheets("Feuil1").Activate
    
    On Error GoTo Suivant1
    For Each c In Cells.SpecialCells(xlCellTypeFormulas, 23)    ' contrôle des formules
    Next c
    MsgBox ("Boucle test1 terminée")
    
Suivant1:
    If Err.Number <> 0 Then Resume Suivant2
 
Suivant2:
    Debug.Print Err.Number 'Sera toujours 0 ici, qu'il y ait eu ou non erreur précédement
    On Error GoTo Fin
    For Each c In Cells.SpecialCells(xlCellTypeConstants, 23)    ' contrôle des constantes
    Next c
    MsgBox ("Boucle test2 terminée")
    
Fin:
    If Err.Number <> 0 Then MsgBox Err.Number & vbCrLf & Err.Description
End Sub

A+
 
Dernière modification par un modérateur:

eriiic

XLDnaute Barbatruc
Re : Gestion erreur VBA

Re Hasco,

C'est exactement ce que je voulais atteindre.
En fait ce n'est pas vraiment un traitement d'erreur à regrouper à la fin que je voulais, mais bien considérer des erreurs comme 'normales' et sauter une partie du code sur leur survenue.

Ca m'aura permis de lever quelques lacunes que j'avais sur le traitements des erreurs, dont ce Resume obligatoire.
Je peux aller voir mon expo (en extérieur je vous rassure) l'esprit plus libre ;-)
merci à tous
eric
 

job75

XLDnaute Barbatruc
Re : Gestion erreur VBA

Bonjour à tous,

Pas vraiment suivi le fil, mais on peut se passer des étiquettes d'adresses :

Code:
Sub test()
     Dim c As Range
     Worksheets("Feuil1").Activate
     
     On Error Resume Next
     For Each c In Cells.SpecialCells(xlCellTypeFormulas, 23)    ' contrôle des formules
     Next c
     MsgBox IIf(Err, "Une erreur s'est produite dans la boucle du test1" & vbCrLf & _
       "je m'en vais faire la suivante!", "Boucle test1 terminée")
     
     Err = 0 'ou de nouveau : On Error Resume Next
     For Each c In Cells.SpecialCells(xlCellTypeConstants, 23)    ' contrôle des constantes
     Next c
     MsgBox IIf(Err, "Une erreur s'est produite dans la boucle du test1", "Boucle test1 terminée")
 
End Sub
A+
 

job75

XLDnaute Barbatruc
Re : Gestion erreur VBA

Re,

Merci Hasco, alors on peut appeler 2 fois une procédure avec On Error GoTo Machin :

Code:
Sub Test()
Worksheets("Feuil1").Activate
Boucle xlCellTypeFormulas, 1 'contrôle des formules
Boucle xlCellTypeConstants, 2 'contrôle des constantes
End Sub
 
Sub Boucle(x, n As Byte)
Dim c As Range
On Error GoTo 1
For Each c In Cells.SpecialCells(x)
Next c
MsgBox "Boucle test" & n & " terminée"
Exit Sub
1 MsgBox "Une erreur s'est produite dans la boucle du test" & n _
    & IIf(n = 1, vbCrLf & "je m'en vais faire la suivante!", "")
 End Sub
On voit bien que le contrôle d'erreur ne concerne que la procédure en cours.

A+
 
G

Guest

Guest
Re : Gestion erreur VBA

Re Job,

Je ne suis pas sûr de comprendre ce que tu veux dire. Si tu veux parler de la propagation des erreurs, en voici un exemple. Erreur générée dans une Sub et gérée dans la Sub Appelante:

Code:
Sub Test()
Worksheets("Feuil1").Activate
Boucle xlCellTypeFormulas, 1 'contrôle des formules
If Err.Number <> 0 Then MsgBox "Erreur dans Boucle (appel 1)"
err.clear  'Facultatif ici
Boucle xlCellTypeConstants, 2 'contrôle des constantes
If Err.Number <> 0 Then MsgBox "Erreur dans Boucle (appel 2)"
End Sub
 
Sub Boucle(x, n As Byte)
Dim c As Range
Dim plg As Range
On Error Resume Next
Set plg = Cells.SpecialCells(x)
End Sub

A+
 
Dernière modification par un modérateur:

eriiic

XLDnaute Barbatruc
Re : Gestion erreur VBA

Bonjour job75,

Bienvenue à tes propositions :)
En l'occurence celle avec On Error Resume Next ne convient pas car je veux sauter plusieurs lignes de code en cas d'erreur sur le for each, et là la boucle for each s'exécuterait.

Je regarde tranquillement ta 2nde proposition après une petite pause... :)

Merci
eric

EDIT :
Et bien la 2nde proposition réagit parfaitement.
Le fait de sortir du 2nd sub lui remet les idées en place pour bien traiter le 2nd passage :)

EDIT2 :
Eriiic voulais appronfondir les "On error goto Machin" ou "0" et a découvert l'obligation du "Resume Bidule".
Et est déçu d'avoir un On Error Goto 0 qui ne sert à rien d'autre qu'à enduire avec de l'erreur ;-)

eric

 
Dernière édition:

youky(BJ)

XLDnaute Barbatruc
Re : Gestion erreur VBA

Re, bonjour à tous
Eric m'a proposition poste #6 avec On Error Resume Next fait exactement ce que tu souhaites.
Dès erreur on quitte le for en annulant l'erreur et on passe au for suivant et idem on quitte le for si erreur
Bruno
 

eriiic

XLDnaute Barbatruc
Re : Gestion erreur VBA

Re,

@youky:
Oui, tout à fait :) Elle faisait même partie des 2 solutions retenues (bien que je ne l'avais vue qu'avec retard en rebalayant toutes les réponses).
Je n'ai pas été complet, je parlais de celle de job75 au post 24.

Sinon rebondissement :

En continuant mes recherches sur le traitement des erreurs avec On Error Goto je suis tombé sur cette page :
Ce lien n'existe plus
Il existe un On Error Goto -1 qui Désactive l'exception activée dans la procédure en cours et la réinitialise à la valeur Nothing et permet un fonctionnement comme je l'imaginais :

Code:
Sub test()
    Dim c As Range
    Worksheets("Feuil1").Activate
    On Error GoTo Suivant1
    For Each c In Cells.SpecialCells(xlCellTypeFormulas, 23)    ' contrôle des formules
        On Error GoTo -1    ' réinitialise le gestionnaire d'erreur
        MsgBox ("test1 ok")
        '
    Next c
Suivant1:
    On Error GoTo -1  ' réinitialise le gestionnaire d'erreur
    On Error GoTo Suivant2
    For Each c In Cells.SpecialCells(xlCellTypeConstants, 23)    ' contrôle des constantes
        On Error GoTo -1  ' réinitialise le gestionnaire d'erreur
        MsgBox ("test2 ok")
    Next c
Suivant2:
    On Error GoTo -1  ' réinitialise le gestionnaire d'erreur
    '....
    '....
End Sub
Ce qui permet des branchements sur une erreur 'normale' qui ne nécessite pas de traitement particulier, juste sauter quelques lignes.

eric
 
Dernière édition:

Statistiques des forums

Discussions
312 366
Messages
2 087 634
Membres
103 626
dernier inscrit
Valentino76