Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

[VBA] Gestion d'erreur

Anthonymctm

XLDnaute Occasionnel
Bonjour Le forum,

J'ai créer une petite macro pour me faciliter la vie et indicer mes devis.

Une input box me propose le prochain indice de devis en se basant sur le nom du fichier normalement de la forme DXX-XXXX-XX.
Ensuite je fais une vérification que la saisie respecte bien le format.

L'erreur que j'ai sera générée à la ligne 7 si le nom du fichier ne se prete pas à l'addition +1 ou au format "00".
Ce que j'aurai voulu c'est proposer une autre version de nDevis= en cas d'erreur.
Mais je ne sais pas comment faire (première fois que je fais de la gestion d'erreur), j'ai vu quelque tuto mais j'ai pas un cas comme ça.
Je voudrais réglé ce nDevis différement mais uniquement en cas d’erreur, puis reprendre à la ligne 8 (après la ligne à problème)

VB:
Sub Indicer()
Dim nDevis As String
Dim FirstWord, LastWord, MidWord

On Error GoTo mauvaisTitre

nDevis = Application.InputBox("Saisir le n° devis (n° actuel : " & Left(ThisWorkbook.Name, 11) & ")" & vbCrLf & "Le fichier actuel ne sera pas enregistré." & vbCrLf & "Pensez à enregistrer avant de valider", , Left(ThisWorkbook.Name, 9) & Format(Mid(ThisWorkbook.Name, 10, 2) + 1, "00"), Type:=2)
If nDevis = "Faux" Then
MsgBox "Indiçage annulé"
Exit Sub
End If
 
FirstWord = Mid(nDevis, 1, 4)    ' Returns "DXX-"
MidWord = Mid(nDevis, 5, 4)    ' Returns "XXXX"
LastWord = Mid(nDevis, 9)    ' Returns "-XX"

 If FirstWord Like "D[0-9][0-9]-" And MidWord Like "[0-9][0-9][0-9][0-9]" And LastWord Like "-[0-9][0-9]" Then

 ActiveWorkbook.SaveAs Filename:=Application.ActiveWorkbook.Path & "\" & nDevis
 MsgBox "Devis indicé"
 
Else: MsgBox "Erreur de syntaxe dans le n° de devis"
Indicer
End If
End Sub
 
Solution
Re Bonsoir @Anthonymctm , Patrick, @jmfmarques le Forum

L'avantage avec le VBA c'est son extrême souplesse et flexibilité, les GoTo datent du Basic (Pas du Visual Basic) à l'époque (pour les anciens) c'est comme ça que l'on programmait en numérotant les lignes de codes... Très lourds et surtout ça devient rapidement illisible et incompréhensible...

En Gestion d'erreur avec étiquette: c'est assez courant d'usage, par contre, en pure programmation c'est à éviter car VBA propose des moyens bien plus puissants et sans équivoque sans avoir un Algo qui "rebondit" dans tous les sens quand on fait du Pas à Pas (Touche F8) .... Ca rebondit déjà bien trop sans GoTo

Maintenant comme je disais pour les avantages c'est que VBA...

patricktoulon

XLDnaute Barbatruc
Anthonin
ton problème est simple
tes intentions
  1. faire des devis a partir d'un model vierge x feuille x macros ou pas
  2. avoir la possibilité d'ouvrir un ancien (pour "" je suppose"" à ne pas avoir a retaper toutes les lignes )
  3. enregistrer les nouveau devis ou les anciens en respectant le numéro d'indexation dans le nom
  4. que le vierge le reste autant que possible (c'est juste une planche,un modele)
  5. ton fichier et sur serveur
  6. il est possible (et doit l’être) que plusieurs utilisateur l'utilise en même temps
  7. et j'en passe et bien d'autre

déjà pour ma part ce model devrait être un xltm(voir définition de cette extension)

les fichiers (ancien )ne doivent jamais être réellement ouverts mais se sont les données qui doivent pouvoir être lue
pour cela le format xlsx sans macro convient tout a fait

on crée un devis avec le model 36 feuilles ou une on s'en fout et
on sauve la feuille ou les feuilles devis "Dxx-xxxx-xx......".xlsx(voir 5° plus bas)

pour copier un ANCIEN sous un autre nom (voir incrémentation) on COPIE LES DONNÉES DE L ANCIEN SUR LE MODEL !!!!!!!!!!!!!!!!!!!!!!!!!!

le bouton enregistrer tel que je l'ai présenté fait le reste AUTOMATIQUEMENT EN FONCTION DES NOMS QUI SONT DÉJÀ PRÉSENTS DANS LE DOSSIER sans même que tu es besoins de chercher le bon numéro


qui a il de plus simple que cela ????????????????????????
 

Anthonymctm

XLDnaute Occasionnel
Hormis le fait que je m'appelle Anthony, on est d'accord ^^

On est d'accord pour le 1, j'ai découvert cette fonctionnalité récemment et j'essaierai de l'utiliser.
2 - Je suis mitigé, ya plusieurs macros utiles à l'analyse, d'autre à l'impression, et cette nouvelle pour la dupplication
3 - Pour ne pas sauver le fichier directement du coup ?
4 - Impossible, j'ai un nombre variable d'onglet, des cellules fusionnées, dé-fusionnées et surtout qu'est-ce que j'y gagnerais à tout copier sur un fichier de traitement pour ensuite l'enregistrer ailleurs puis finalement réinitialisé le fichier vierge ?
5 - Dans ma méthode aussi il me trouve le nom à mettre, tout en me permettant de le modifier facilement si besoin et puis surtout je peux choisir facilement dans quel dossier je l'enregistre

En bref, je comprend que ta méthode fonctionnerait très bien, mais je ne vois toujours pas pourquoi la mienne n'est pas sensé fonctionner..
 

_Thierry

XLDnaute Barbatruc
Repose en paix
[parehteses]
a ben voilà on commence déjà avec les goto et même un récursif sur condition si
[parentheses]
Mort de Rire, un peu de Basic en Juin 2020, ca ne fait pas de mal !! LoL !
I GoTo the market, mon p'tit panier sous mon bras... I love you....

Par contre ça me met a chaque fois le msg box erreur imprévue : 0, que j'ai créé une erreur ou non
Tu as oublié le:
Exit Sub
ErrorHandler:
(Juste avant le ErrorHandler...)

J'ai essayé de lire et simplifier le Code du Post #28, mais ce n''est déjà vraiment plus le Goto the Market mais plustôt Goto the 'Souc' , une chatte y perdrait facilement ses petits.... Et sans parler des remarques pertinantes de Patrick, à mon avis là tu te compliques la vie un max, je suis certain qu'un simple code comme ceci devrait faire l'affaire :

VB:
Option Explicit


Sub Indicer()
Dim nDevis As String
Dim FirstWord As String, LastWord As String, MidWord As String

Dim Response As Long

If ThisWorkbook.Name Like "D##-####-##" & ".xlsm" Then
nDevis = InputBox("Saisir le n° devis (n° actuel : " & Left(ThisWorkbook.Name, 11) & ")" & vbCrLf & "Le fichier actuel ne sera pas enregistré." & vbCrLf & "Pensez à enregistrer avant de valider", , Left(ThisWorkbook.Name, 9) & Format(Mid(ThisWorkbook.Name, 10, 2) + 1, "00"))
Else:
nDevis = InputBox("Saisir le n° devis (D" & Right(Year(Now), 2) & "-XXXX-XX)" & vbCrLf & "Le fichier actuel ne sera pas enregistré." & vbCrLf & "Pensez à enregistrer avant de valider", , ThisWorkbook.Name)
End If

If nDevis = "" Then
Exit Sub
End If

    If nDevis Like "D##-####-##" Then
    
            On Error GoTo ErrorHandler 'Voir Label ErrorHandler:
             ActiveWorkbook.SaveAs Filename:=Application.ActiveWorkbook.Path & "\" & nDevis
            On Error GoTo 0            'On anulle le on error
             MsgBox "Devis indicé"
    Else
            Indicer
    End If
    
Exit Sub

ErrorHandler:
If Err.Number = 1004 Then 'Si on annule la Boite de dialog "écraser..."
    Indicer
Else
    MsgBox "Erreur imprévue : " & Err.Number & vbCrLf & Err.Description
End If

End Sub

Bien à toi, à vous
@+Thierry
 

patricktoulon

XLDnaute Barbatruc
par ce que tu n'est pas le seul a l'utiliser et que tu va rencontrer des erreurs avec le temps
ton 2, 3 ,4 me conforte dans mon avis que tu n'a pas compris le procédé

pour ton 2 : reponse = " Et alors???
pour ton 3 et 5 : reponse= rien ne t’empêche de faire un msgbox response = vbyesno.... pour soit incrémentation auto soit sauver sous Tartempion pierre paul jacques
pour ton 4 : reponse = pareil que le 2
 

Anthonymctm

XLDnaute Occasionnel
Ah oui, le exit sub, je te remercie.

Pour la simplification du code je suis tout ouïe, j'ai fait des bricollage de ce que j'ai trouvé sur le net.

Par contre avec ton code j'ai plus la possibilité de faire mon enregistrer sous, l'avantage dans mon code c'est que je garde l'indiçage même si je passe pas un enregistré sous (en faisant annuler)
 

Anthonymctm

XLDnaute Occasionnel
Ce que tu dois comprendre patrick c'est que j'ai pas ton niveau en VBA, donc peut-être qu'une autre solution serait mieux, pour l'instant je vois toujours pas ce qui va pas dans la mienne. Mais même si je voulais la refaire, j'y parviendrais pas et je devrais reposter 10 messages sur le forum et perdre des dizaines d'heures.
Tout va bien sur mon fichier, ça fait plusieurs mois qu'il est utiliser. Les gens font un copier coller du nouveau, quand ils ont besoin de reprendre un ancien il refont un copier coller et puis voilà, moi c'est juste ça que je voulais simplifier
 

_Thierry

XLDnaute Barbatruc
Repose en paix
Re bonjour à tous

J'ai tenté de respecter ton souhait de la Boite de Dialog "GetSaveAsFilename".... Tout en évitant des Goto tous azimuts au milieu des conditions !!! (ca c'est l'horreur à éviter)

VB:
Option Explicit

Sub Indicer()
Dim nDevis As String
Dim Sauvegarde As Variant, Question1 As Long, Question2 As Long


If ThisWorkbook.Name Like "D##-####-##" & ".xlsm" Then
nDevis = InputBox("Saisir le n° devis (n° actuel : " & Left(ThisWorkbook.Name, 11) & ")" & vbCrLf & "Le fichier actuel ne sera pas enregistré." & vbCrLf & "Pensez à enregistrer avant de valider", , Left(ThisWorkbook.Name, 9) & Format(Mid(ThisWorkbook.Name, 10, 2) + 1, "00"))
Else:
nDevis = InputBox("Saisir le n° devis (D" & Right(Year(Now), 2) & "-XXXX-XX)" & vbCrLf & "Le fichier actuel ne sera pas enregistré." & vbCrLf & "Pensez à enregistrer avant de valider", , ThisWorkbook.Name)
End If

If nDevis = "" Then
    Question1 = MsgBox("Votre n° doit être de la forme : D" & Right(Year(Now), 2) & "-XXXX-XX", vbYesNoCancel)
    
        If Question1 = vbOK Then
            Indicer
        ElseIf Question1 = vbNo Then ' Demande ou sauver le doc et le nom à lui donner
                If nDevis = "" Then
                    If ThisWorkbook.Name Like "D##-####-##" & ".xlsm" Then
                        nDevis = Left(ThisWorkbook.Name, 9) & Format(Mid(ThisWorkbook.Name, 10, 2) + 1, "00")
                    Else
                        nDevis = ThisWorkbook.Name
                    End If
                End If
               Sauvegarde = Application.GetSaveAsFilename(ActiveWorkbook.Path & "\" & nDevis & ".xlsm", FileFilter:="XLSM (*.xlsm), *.xlsm", Title:="Enregistrer-sous ...")
              
                If Sauvegarde = False Then Indicer
        
                If Dir(Sauvegarde) <> "" Then ' le fichier renseigné par l'utilisateur existe-t-il ?
                Question2 = MsgBox("Attention le fichier existe déjà" & Chr(13) & "Voulez vous le remplacer ?", vbQuestion + vbYesNo, "Attention...")
                     ' Si oui, faut t-il l'effacer ?
                    If Question2 = vbYes Then ' Oui
                         Kill Sauvegarde ' Efface
                    Else ' Non
                        Indicer
                    End If
                
                 End If
        ThisWorkbook.SaveAs Sauvegarde ' Sauvegarde
        Else
        MsgBox "Indiçage annulé" 'si on clique sur annulé
     End If
End If



If nDevis Like "D##-####-##" Then

        On Error GoTo ErrorHandler 'Voir Label ErrorHandler:
         ActiveWorkbook.SaveAs Filename:=Application.ActiveWorkbook.Path & "\" & nDevis
        On Error GoTo 0            'On anulle le on error
          
         MsgBox "Devis indicé"
        
End If
Exit Sub

ErrorHandler:
If Err.Number = 1004 Then 'Si on annule la Boite de dialog "écraser..."
    Indicer
Else
    MsgBox "Erreur imprévue : " & Err.Number & vbCrLf & Err.Description
End If

End Sub

J'espère que je respecte encore tous tes cas de figures...

Bonne fin de journée
@+Thierry
 

Anthonymctm

XLDnaute Occasionnel
Quand je clique sur oui au deuxième msg box ça se stoppe et bug. Mais franchement le code que j'ai fonctionne très bien là, grace à vous ^^'
Après j'ai 2 GoTo, c'est ça qui poserait problème ?
J'ai découvert cette fonctionnalité aujourd'hui, ça doit être pour ça que je m'en suis servis tout azimut x')
VB:
Sub Indicer()
Dim nDevis As String
Dim FirstWord As String, LastWord As String, MidWord As String
Dim Sauvegarde As Variant, Question As Integer

If ThisWorkbook.Name Like "D##-####-##" & ".xlsm" Then
nDevis = InputBox("Saisir le n° devis (n° actuel : " & Left(ThisWorkbook.Name, 11) & ")" & vbCrLf & "Le fichier actuel ne sera pas enregistré." & vbCrLf & "Pensez à enregistrer avant de valider", , Left(ThisWorkbook.Name, 9) & Format(Mid(ThisWorkbook.Name, 10, 2) + 1, "00"))

Else:
nDevis = InputBox("Saisir le n° devis (D" & Right(Year(Now), 2) & "-XXXX-XX)" & vbCrLf & "Le fichier actuel ne sera pas enregistré." & vbCrLf & "Pensez à enregistrer avant de valider", , ThisWorkbook.Name)

End If

If nDevis = "" Then 'si on clique sur annulé
GoTo msg2

End If

If nDevis Like "D##-####-##" Then

On Error GoTo ErrorHandler 'Voir Label ErrorHandler:
ActiveWorkbook.SaveAs Filename:=Application.ActiveWorkbook.Path & "\" & nDevis
   On Error GoTo 0            'On anulle le on error

MsgBox "Devis indicé"

Else
msg2:
Msg = "Votre n° doit être de la forme : D" & Right(Year(Now), 2) & "-XXXX-XX" & vbCrLf & vbCrLf & "Réessayer      Enregistrer sous" & vbCrLf & "    |                               |" & vbCrLf & "   \/                              \/"
Style = vbYesNoCancel + vbExclamation + vbDefaultButton1
Title = "Erreur dans le numéro de devis"
Help = "DEMO.HLP"
Ctxt = 1000

Response = MsgBox(Msg, Style, Title, Help, Ctxt)

    If Response = vbYes Then
    Indicer
    ElseIf Response = vbNo Then ' Demande ou sauver le doc et le nom à lui donner
        If nDevis = "" Then
            If ThisWorkbook.Name Like "D##-####-##" & ".xlsm" Then
            nDevis = Left(ThisWorkbook.Name, 9) & Format(Mid(ThisWorkbook.Name, 10, 2) + 1, "00")
            Else: nDevis = ThisWorkbook.Name
            End If
            End If
       Sauvegarde = Application.GetSaveAsFilename(ActiveWorkbook.Path & "\" & nDevis & ".xlsm", FileFilter:="XLSM (*.xlsm), *.xlsm", Title:="Enregistrer-sous ...")
     
        If Sauvegarde = False Then GoTo msg2 ' Si click sur annuler, alors on revient a la boite de dialoque

        If Dir(Sauvegarde) <> "" Then ' le fichier renseigné par l'utilisateur existe-t-il ?
        Question = MsgBox("Attention le fichier existe déjà" & Chr(13) & "Voulez vous le remplacer ?", vbQuestion + vbYesNo, "Attention...")
             ' Si oui, faut t-il l'effacer ?
            If Question = 6 Then ' Oui
              Kill Sauvegarde ' Efface
            Else ' Non
             GoTo msg2 ' On revient a la boite de dialoque
            End If
       
         End If
ThisWorkbook.SaveAs Sauvegarde ' Sauvegarde
  Else: MsgBox "Indiçage annulé" 'si on clique sur annulé
  End If
   
End If
Exit Sub

ErrorHandler:
If Err.Number = 1004 Then 'Si on annule la Boite de dialog "écraser..."
    Indicer
Else
    MsgBox "Erreur imprévue : " & Err.Number & vbCrLf & Err.Description
End If

End Sub
 
Dernière édition:

_Thierry

XLDnaute Barbatruc
Repose en paix
Re Bonsoir @Anthonymctm , Patrick, @jmfmarques le Forum

L'avantage avec le VBA c'est son extrême souplesse et flexibilité, les GoTo datent du Basic (Pas du Visual Basic) à l'époque (pour les anciens) c'est comme ça que l'on programmait en numérotant les lignes de codes... Très lourds et surtout ça devient rapidement illisible et incompréhensible...

En Gestion d'erreur avec étiquette: c'est assez courant d'usage, par contre, en pure programmation c'est à éviter car VBA propose des moyens bien plus puissants et sans équivoque sans avoir un Algo qui "rebondit" dans tous les sens quand on fait du Pas à Pas (Touche F8) .... Ca rebondit déjà bien trop sans GoTo

Maintenant comme je disais pour les avantages c'est que VBA est encore un outil "dans le coup" et permet à tout un chacun de s'improviser apprenti-développeur et d'obtenir la grande satisfaction d'avoir créé quelque chose par lui-même... Et comme je dis souvent, le client est "Roi"...

Avec cet outil merveilleux qu'est VBA il y a mille et un chemins, pour arriver au même résultat en fonction des connaissances et des aptitudes de chacun. Certains chemins passent par des détours et ralentissent le code, mais si la tâche est accomplie sans bug and sans perte de données, il n'y a pas de "mauvais" codes, juste des moins optimisés que d'autres... Des plus concis, des tellement concis qu'on arrive plus à les lire, des romans qu'on ne sait même plus ce que c'est sensé faire... Mais bon avec des nuits de galères on finit tous par se mettre à avoir une meilleure appréhension de codification "normalisée" (sinon c'est la calvitie avancée assurée !)

Tant que tu es heureux et que ton programme rempli le job qu'il est censé faire que demande le peuple !

Bien à toi, à vous
@+Thierry
 

patricktoulon

XLDnaute Barbatruc
Bonsoir Thierry
je suis d'accords avec toi sauf le dernier paragraphe
moi je dis si si !!!! un code est MAUVAIS à partir du moment ou
  1. il consomme plus que de raison
  2. dure plus que raison
  3. utilise des fonctions qui ne sont là que par pure soucis de compatibilité entre versions
  4. et pour le rebondit et saut de chamelle je m'abstiendrais de commenter

je croirais presque lire un code pour mon amstrad pc 6128

je comprends bien que quand on débute, certains raccourci sont alléchants
mais certainement pas une solution en tout cas non pérenne
 

Anthonymctm

XLDnaute Occasionnel
Je te remercie pour cette précision, j'avais aucune idée que GoTo ne faisait pas parti du VBA, cette fois je comprend un peu mieux les tracas de Patrick. Après je ne connais pas la parade version VBA..
Pour le F8 je te remercie aussi, je ne connaissais pas, bien pratique !
Comme tu le dis, ça m'a permis de faire un grand nombre de code déjà avec des connaissances limitées et surtout j'ai pu faire des choses fonctionnelles avant de passer des mois à apprendre toute profondeur et toute la nuance du language.

Effectivement mon code est peut-être mauvais et non optimisé, a défaut d'avoir et de savoir faire mieux, il restera en l'état. Patrick, tu ne te dis jamais que si on utilise certains raccourcis mal fait c'est parceque c'est la seule route qu'on a réussi à construire ? Evidemment que si je savais faire mieux j'aurais fait mieux..
 

patricktoulon

XLDnaute Barbatruc
Bonjour Anthonymctm
je sais pas c'est a toi de voir
tu viens sur un forum pour chercher de l'aide
on te dit que le chemin que tu a pris n'est pas si bon que ça
tu es libre d’écouter ou pas
mais ne me me dis pas a moi que "c'est la seule route que ....."
c'est des excuses d'arracheurs de dents
comme je te l'ai dis plus haut tu fait comme tu veux
mais ne t'excuse jamais de prendre l'option de facilité : il n'y en a pas d'excuses
 

Anthonymctm

XLDnaute Occasionnel
Je réitère, à moins de passer des semaines à revoir toute ma conception.
Tu vas pas le faire à ma place je suppose ^^'
Donc jusque là c'est la seule route que j'ai pu construire si
Mon prochain code sera peut-être mieux, et celui d'après encore plus
 

Discussions similaires

Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…