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

_Thierry

XLDnaute Barbatruc
Repose en paix
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:

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
Repose en paix
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
Regarde 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 ? ^^'
 

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
 

Discussions similaires

Réponses
3
Affichages
2 K

Statistiques des forums

Discussions
311 734
Messages
2 082 020
Membres
101 872
dernier inscrit
Colin T