Résolu Résolu [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. :cool:

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. o_O
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
 
Ce fil a été résolu! Aller à la solution…

_Thierry

XLDnaute Barbatruc
Bonsoir @Anthonymctm , le Forum

Je n'ai pas tout suivi, car le code tel que présenté ne passe en Application.InputBox.
J'ai tout simplement mis en simple InputBox comme suit :

VB:
Option Explicit

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


nDevis = InputBox("Saisir le n° devis", "Save As Devis", "D00-0000-00")

If nDevis = "" 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
Mais pour la gestion d'erreur, tu veux quoi au juste ? Si le fichier existe déjà ? (normalement tu seras prévenu avant d'écraser)

Perso, moi j'incrémenterai le numéro DXX-XXXX-XX automatiquement si il existe une logique de numéros de série ?

Bonne soirée
@+Thierry
 

Anthonymctm

XLDnaute Occasionnel
Bonjour Thierry,

Je n'ai pas tout suivi, car le code tel que présenté ne passe en Application.InputBox.
J'ai tout simplement mis en simple InputBox comme suit :
J'ai mis application car c'est comme ça que j'ai trouvé le code, je ne m'y connais pas plus que ça ^^'
C'est quoi la différence entre avec et sans le application ?
Edit : J'ai vu que le format de la box changeait et que le terme d'annulation était "" au lieux de "Faux"

Mais pour la gestion d'erreur, tu veux quoi au juste ? Si le fichier existe déjà ? (normalement tu seras prévenu avant d'écraser)
Si je le fichier existe déjà je suis prévenu en effet, j'ai une erreur si j'annule la boite de dialogue me demandant d'écraser ou si je dis non.

Perso, moi j'incrémenterai le numéro DXX-XXXX-XX automatiquement si il existe une logique de numéros de série ?
Ca c'est ce que je fais en proposition, mais je veux avoir le choix de modifier la proposition. Ca ça fonctionne bien.

Le cas dont je parlais est une erreur qui se produit si mon nom de fichier n'est pas de la forme DXX-XXXX-XX. Du style "devis client 3" ou "DXX-XXXX-XX remise" dans ce cas la ligne 7 a une erreur puisque les deux dernier caractères ne sont pas des chiffres.
Donc s'il y a cette erreur je voudrais redéfinir ma variable nDevis de sorte du style
VB:
nDevis = Application.InputBox("Saisir le n° devis (n° actuel : " & Left(ThisWorkbook.Name) & ")" & vbCrLf & "Le fichier actuel ne sera pas enregistré." & vbCrLf & "Pensez à enregistrer avant de valider", , "DXX-XXXX-XX", Type:=2)
Et après cette redéfinition il faudrait repartir juste après, à : If nDevis = "Faux" Then
 
Dernière édition:

jmfmarques

XLDnaute Accro
Bonjour
si mon nom de fichier n'est pas de la forme DXX-XXXX-XX
cette vérification ne fait simplement ainsi :
VB:
if nomfic like "D##-####-##" then
Ceci étant dit, je rejoins totalement ce qu'a exposé _Thierry
et irais même plus loin : aucune inputbox nécessaire pour imposer le nomfic valable, pour autant que cette chaîne soit construite logiquement
 

Anthonymctm

XLDnaute Occasionnel
et irais même plus loin : aucune inputbox nécessaire pour imposer le nomfic valable, pour autant que cette chaîne soit construite logiquement
Je suis pas sûr de tout comprendre mais en fait dans mon cas précis tous les devis ne passe pas forcément par ce fichier, ne sont pas forcément tous formaliser ou ne sont pas tous présent dans le même dossier, c'est pour ça que j'ai besoin que l'utilisateur valide que le n° proposé soit le bon. après ce que j'aurais aimé c'est une inputbox avec 3 boutons, un ok (enregistre dans le même dossier), un annuler et un enregistrer sous ou cette fois j'ouvre la fenetre enregistrer sous.

cette vérification ne fait simplement ainsi :
VB:
if nomfic like "D##-####-##" then
Ok, je vais tester ça !
Edit : Ca marche niquel ;)


Il restera juste l'erreur d'annulation de la fenêtre si le fichier existe déjà.
On peut pas avoir une gestion d'erreur qui relance la maccro à la moindre erreur ?
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
bonjour àtous
perso moi non plus je pige pas le besoins de l'inputbox

si le fichier porte déjà un nom du style "D21-4523-37 blablabla.xlsm"
il est facile d'en extraire la chaîne numérique non formatée , d’incrémenter (+1),reformater ,sauver

et puis quand on se sert d'un model même si ça n'est pas un xltm on copie puis sauve le active workbook

on a même pas besoins de dialogue pour ça
selon moi c'est un simple boucle dir recup de la chaîne numérique sur les noms garder la MAX
a la fin +1 reformatage de la chaîne ,et enregistrement
 

Anthonymctm

XLDnaute Occasionnel
bonjour àtous
perso moi non plus je pige pas le besoins de l'inputbox

si le fichier porte déjà un nom du style "D21-4523-37 blablabla.xlsm"
il est facile d'en extraire la chaîne numérique non formatée , d’incrémenter (+1),reformater ,sauver

et puis quand on se sert d'un model même si ça n'est pas un xltm on copie puis sauve le active workbook
En fait la macro a pour but d'indicer certes mais de renommer également exemple : je prend un vieux devis d'il y a 3ans parcequ'il correspond assez précisément à ce que je souhaite faire maintenant je vais donc en faire une copie sous un tout autre nom :D

et puis quand on se sert d'un model même si ça n'est pas un xltm on copie puis sauve le active workbook
J'ai pas compris cette partie là :oops:
Je sauve bien le activeworkbook non ?

Si je récapitule ma demande, faudrait juste une gestion d'erreur dès le début qui redemarre la macro.

Et la ligne de code pour enregistrer sous (avec ouverture de la fenetre de dialogue classique) avec par défaut le dossier du fichier et le titre saisie dans l'input box nDevis. Avec ça je devrais pouvoir bidouiller un message box qui me demandera de recommence ou enregistrer sous
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
oui mais c'est le fichier model que tu sanve sous un autre nom
ce qui fait qu’après le seul classeur actif est le nouveau fichier ,le model lui bye bye!!!
pour peut qu'a minima tu veuille le vider ben t'est obliger de le ré ouvrir
ou meme si tu voulais incrémenter le nom par rapport au model (ce que tu essaie de faire justement) t'oblige a tester si le nom du futur fichier existe ou pas

conclusion
travaillons proprement
  1. 1 model
  2. une boucle dir et récup du dernier numéro (le plus grand) incrémentation: copy du model,enregistrement de la copie avec le nom reformaté
c'est d'une simplicité absolue ;)
 

Anthonymctm

XLDnaute Occasionnel
oui mais c'est le fichier model que tu sanve sous un autre nom
Non non pas du tout ^^'
Le fichier model lui a sa propre macro à l'ouverture pour le copier sous un autre nom.
Là c'est une macro pour renommer ou indicer un devis réel déjà émis au client.

Je reprecise que je souhaite pouvoir lui donner le numéro que je souhaite, d'où l'inputbox. Ne serait-ce que pour passer d'une version 1 à une version 5 par exemple ou pour recupérer un ancien devis et remplacer tout le nom.

En tout cas ma demande ne concerne pas ce point ^^'
 

_Thierry

XLDnaute Barbatruc
Bonjour @Anthonymctm @patricktoulon , @jmfmarques , le Forum

Bon si notre ami a son "cahier des charges" on ne va pas tout lui bouleverser ;)

Voici updaté avec la simplification proposée de JmfMarques et donc une gestion d'erreur avec "Etiquette" (à l'ancienne, façon Basic Commodore LoL)

Bien @ vous
VB:
Sub Indicer()
Dim nDevis As String


nDevis = InputBox("Saisir le n° devis", "Save As Devis", "D00-0000-00")

If nDevis = "" Then
MsgBox "Indiçage annulé"
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
    MsgBox "Erreur de syntaxe dans le n° de devis"
    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
@+Thierry

PS : Dans l'aide de vba si tu recherches inputbox tu verras qu'il y en a 2 avec leurs différences et possibilités :
Application.InputBox, Method
et
InputBox, Function
 

patricktoulon

XLDnaute Barbatruc
re
juste un exemple vite fait comme ca
demo4.gif

le code du bouton sur la feuille

VB:
Private Sub CommandButton1_Click()
    Dim dossier$, fichiers$, newnom$, num&
    dossier = ThisWorkbook.Path
    fichiers = Dir(dossier & "\D*.xlsx")
    If fichiers = "" Then
        num = 1
    Else
        Do While fichiers <> ""
            num = Application.Max(num,Val(Replace(Mid(fichiers, 2), "-", ""))) + 1
            fichiers = Dir
        Loop
    End If
    newnom = "D" & Format(Right("00000000" & num, 8), "00-0000-00") & " blablabla.xlsx"

    With Application:
        .DisplayAlerts = False: ScreenUpdating = False
        Sheets("Feuil1").Copy
        ActiveWorkbook.SaveAs Filename:= _
                              dossier & "\" & newnom, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False: ActiveWindow.Close
        .DisplayAlerts = True: ScreenUpdating = True
    End With
End Sub
et voila ;)
pas d'inputbox,pas de dialogue
et les numéros sont bien incrémentés et formatés dans le nom


édit:
j'oubliais !!!!!!
et pas besoins de contrôle d’existence du futur fichier ;)
 
Dernière édition:

Anthonymctm

XLDnaute Occasionnel
re
juste un exemple vite fait comme ca
Voir la pièce jointe 1069727

le code du bouton sur la feuille

VB:
Private Sub CommandButton1_Click()
    Dim dossier$, fichiers$, newnom$, num&
    dossier = ThisWorkbook.Path
    fichiers = Dir(dossier & "\D*.xlsx")
    If fichiers = "" Then
        num = 1
    Else
        Do While fichiers <> ""
            num = Application.Max(num,Val(Replace(Mid(fichiers, 2), "-", ""))) + 1
            fichiers = Dir
        Loop
    End If
    newnom = "D" & Format(Right("00000000" & num, 8), "00-0000-00") & " blablabla.xlsx"

    With Application:
        .DisplayAlerts = False: ScreenUpdating = False
        Sheets("Feuil1").Copy
        ActiveWorkbook.SaveAs Filename:= _
                              dossier & "\" & newnom, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False: ActiveWindow.Close
        .DisplayAlerts = True: ScreenUpdating = True
    End With
End Sub
et voila ;)
pas d'inputbox,pas de dialogue
et les numéros sont bien incrémentés et formatés dans le nom


édit:
j'oubliais !!!!!!
et pas besoins de contrôle d’existence du futur fichier ;)
Du coup a quel moment je choisis le nom de mon fichier ? ^^'
 

patricktoulon

XLDnaute Barbatruc
pourquoi choisir ça se fait automatiquement
tu peut eventuellement remplacer "blabla" par la valeur d'une cellule par exemple
a moins que je n’eusse pas compris ton souhait dans ce cas l'exprimer clairement ;)
 

Anthonymctm

XLDnaute Occasionnel
pourquoi choisir ça se fait automatiquement
tu peut eventuellement remplacer "blabla" par la valeur d'une cellule par exemple
a moins que je n’eusse pas compris ton souhait dans ce cas l'exprimer clairement ;)
Je le reprecise encore une fois, c'est une macro d'indiçage ET de renommage ^^'
Je peux avoir besoin que mon devis passe de D20-1234-01 à D21-4568-03
La plus part du temps ce sera indiçage donc D20-1234-02, et ça c'est fait dans l'inputbox par défaut.

Ce que j'avais juste besoin c'était de gérer l'erreur qui se produisait si le fichier existait déjà et que je dois annuler ou l'erreur si la formule du calcul par défaut dans l'inputbox fonctionne pas (et la réponse de thierry va bien pour ça)

En tout cas je te remercie de ton implication :D
 

patricktoulon

XLDnaute Barbatruc
re
ok je ne connais pas la raison de la réindexation mais bon
mon truc ne fera jamais d'erreur d'indexation lors du l enregistrement
perso des documents indexé et ré indexé ça sent pas bon
 

Anthonymctm

XLDnaute Occasionnel
re
ok je ne connais pas la raison de la réindexation mais bon
mon truc ne fera jamais d'erreur d'indexation lors du l enregistrement
perso des documents indexé et ré indexé ça sent pas bon
Oui je comprend bien et je partage ton point de vue !
C'est juste que dans ma boite si on a un devis proche d'un autre on va préféré repartir d'un ancien plutot qu'en refaire un nouveau, quitte a avoir des erreurs parfois.
Ya aussi des fois ou on va faire un devis autrement (par exemple direct sur word, sans passer par le fichier excel). Ou même à l'oral ou dans un mail parfois. C'est pour ça que j'ai besoin de cette souplesse.
 

patricktoulon

XLDnaute Barbatruc
d'accords
pour que je comprenne dis moi si je me trompe
tu ouvre un devis (un ancien)
avec ton inputbox et tout ton toin toin tu souhaite re sauver ce même devis après avoir fait quelque modif avec l'index +1

sauf que!!!!!
  1. si le devis que tu copie a été suivi de 36 autres ben ton index+1 walouh!!! walouh !!!!
  2. ça implique qu'il faut du vba dans chaque devis (inacceptable conceptuellement)
  3. ca implique que après test échoué du +1 il faille aller chercher le bon index avec une boucle dir (comme je le fait dès départ )
j’arrête là la liste des défauts car il y en a bien d'autre dans ta conception

conclusion nous n'avons pas a même définition de la souplesse
je suis étonné que le responsable accepte cela par ce que c' est LE DEFAUT N° 1 je dirais ;) :D :rolleyes:

et je dis cela hors contexte vba , il s'agit là de regles élémentaires de tenue de dossier en intégrité totale


rien empêche cela dit et !!!!dans les règles de l'art ,d'avoir:
  1. un model devis vierge(celui toujours utilisé)
  2. avec un bouton donnant la possibilité de copier le contenu d'un ancien (je dis bien copier le contenu et non le fichier )
  3. utiliser mon model précédemment donné (plus haut dans la discussion)pour enregistrer
voila ma conception de la souplesse ;)
A méditer
 

Anthonymctm

XLDnaute Occasionnel
ça implique qu'il faut du vba dans chaque devis (inacceptable conceptuellement)
Pourquoi c'est inacceptable ? Dans son fonctionnement mon fichier devis a plein de macro et de vba.

tu ouvre un devis (un ancien)
avec ton inputbox et tout ton toin toin tu souhaite re sauver ce même devis après avoir fait quelque modif avec l'index +1
En fait je le sauve avant d'avoir fait les modifs (sinon elles ne seront pas enregistrées)

Ci-joint ma macro pour l'indiçage / renommage
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

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
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

End Sub
J'ai testé tous les cas de figure et tout fonctionne correctement, j'ai du mal à comprendre ce qui va pas dans ma conception :rolleyes:

je suis étonné que le responsable accepte cela par ce que c' est LE DEFAUT N° 1 je dirais
Le responsable de ça c'est moi donc ça va, je l'accepte :rolleyes:
Plus sérieusement, c'est de quel défaut dont tu parles ?

  1. un model devis vierge(celui toujours utilisé)
  2. avec un bouton donnant la possibilité de copier le contenu d'un ancien (je dis bien copier le contenu et non le fichier )
  3. utiliser mon model précédemment donné (plus haut dans la discussion)pour enregistrer
C'est justement comme ça que je compte faire, laisser aux commerciaux le fichier vierge en tant que modèle et ensuite il se le récupère, à l'ouverture le fichier detecte qu'il est le fichier vierge et propose donc à peu près la fonctionnalité pour saisir un nom de fichier ou un enregistrer sous.


Le seul cas qui amène à une erreur dans ma macro Indicer est le cas ou dans le premier input box je saisie un code qui existe déjà, alors il me demande si je veux l'ecraser et là, si je refuse ou que j'annule j'ai une erreur. (ce cas là est prévu quand je passe par l'enregistrer sous au deuxième msgbox.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
erreur. (ce cas là est prévu quand je passe par l'enregistrer sous aux deuxième msgbox.
oui!! sauf qu'il y en a 36 qui ont été rédiger avant aujourd’hui comment tu fait 36 msgbox :D
laisse moi 5 minutes je fait une maquette tu va comprendre
 

_Thierry

XLDnaute Barbatruc
Re Bonjour
Sans me méler du pour ou contre "liberté" de l'inputbox...

Le seul cas qui amène à une erreur dans ma macro Indicer est le cas ou dans le premier input box je saisie un code qui existe déjà, alors il me demande si je veux l'ecraser et là, si je refuse ou que j'annule j'ai une erreur.
Dans mon précédent exemple, je t'avais montré cette gestion d'erreur, il me semble ?
Et je ne vois pas la suggestion de simplification proposée par JmfMarques

Bien à toi, à vous
@+Thierry
 

Créez un compte ou connectez vous pour répondre

Vous devez être membre afin de pouvoir répondre ici

Créer un compte

Créez un compte Excel Downloads. C'est simple!

Connexion

Vous avez déjà un compte? Connectez vous ici.

Haut Bas