Macro - Ouvrir fichier excel nommé ou le créer s'il n'existe pas [Résolu/Fermé]

Signaler
-
 Thesshad -
Bonjour,


Je suis entrain de m'arracher les cheveux au boulot sur la mise en place d'un logiciel de saisie de données via excel pour mon service.


En somme, J'ai 2 fichiers différents.
Le premier (que je nommerai fichierA) est une trame vierge, un tableau qui ne demande qu'à rentrer des données sur une journée
Le second (que je nommerai fichierB) est le logiciel.


Sur le fichierB
Dans la case A1, il y a une case pour écrire une date. Cela peut-être la date du jour, comme une date quelconque.


Je veux un bouton dans le fichierB, avec un fonction macro qui, lorsque j'appuie dessus, aille me chercher dans un emplacement connu : fichierA-dd-mm-yyyy , avec dd-mm-yyyy la date référencée dans la case A1.
Et que s'il n'existe pas, il m'ouvre le fichierA, et en enregistre une copie vierge appelée fichierA-dd-mm-yyyy


Ce qui fait que chaque jour je peux créer une nouvelle page de données que je remplirait, mais que si je mets une date antérieure, il va me rechercher le fichier correspondant à cette date.


Bien entendu le fichierB rassemble plusieurs boutons pour plusieurs fichierA de toute sortes, etc...


Si vous pouviez, s'il vous plait, me donner des pistes sur les formules BVA à utiliser, ne serait-ce que pour créer un fichier avec dans le nom une date définie dans la case (ça ne marche jamais à cause des /)
Ou encore mettre une condition si le fichier n'existe pas, ouvrir la trame vierge et le créer.


Merci d'avance


David



9 réponses


Bonjour David,

Ceci est juste un petit bout de code pour donner le nom du fichier correct à partir de la date introduite en cellule A1.

==========================================

Cette cellule A1 doit obligatoirement avoir un format de date,
mais celui-ci peut être quelconque.

----------------------------------------------------------------------------

JX contiendra le Jour sur 2 chiffres : dd
MX contiendra le Mois sur 2 chiffres : mm

Je passe par ces 2 variables pour faire un test qui déterminera
s'il faut ajouter ou non un "0" devant.

----------------------------------------------------------------------------

Inutile d'utiliser une variable pour l'Année : comme de toute façon
elle est sur 4 chiffres, elle ne nécessite pas de traitement et peut
être reprise telle que.

==========================================

FX contiendra le nom du fichier complet, mais ATTENTION :

1) Si vous êtes sûr et certain que ni maintenant, ni plus tard,
ce nom de fichier ne contiendra AUCUN ESPACE, vous pouvez
utiliser la 1ère ligne FX = ... ; dans le cas inverse, il faudra
alors utiliser la 2ème ligne FX = ... (celle en commentaire,
car elle ajoute un guillemet au début et un autre à la fin).

Je suis même tenté de vous dire : « Dans le doute ou même
par simple précaution, utilisez plutôt la 2ème ligne ! ».

Pour cette 2ème ligne, FX commence bien par 3 guillemets
consécutifs et se termine bien de la même façon : ce n'est
pas une erreur de frappe, et ça évite d'utiliser Chr$(34) !

----------------------------------------------------------------------------

2) Vous pourrez remarquer que j'ai rajouté l'extension ".xls" ;
vous savez qu'elle est valable pour Excel 2003, MAIS pour
Excel 2007 ou ultérieur, il faudra ajouter :

- "m" pour des classeurs avec macros : *.xlsm
- "x" pour des classeurs sans macros : *.xlsx

Et si en plus vous avez besoin d'ouvrir des classeur modèles,
il faudrait aussi prendre en compte :

- pour Excel 2003 : les *.xlt
- pour Excel 2007 : les *.xltm et *.xltx


Option Explicit

Sub Essai()
  Dim JX As String * 2, MX As String * 2, FX As String
  JX = Day([A1]): If JX < 10 Then JX = "0" & RTrim$(JX)
  MX = Month([A1]): If MX < 10 Then MX = "0" & RTrim$(MX)
  FX = "fichierA-" & JX & "-" & MX & "-" & Year([A1]) & ".xls"
  'FX = """fichierA-" & JX & "-" & MX & "-" & Year([A1]) & ".xls"""
  MsgBox "Date en A1 : " & [A1] & vbLf & "=> Nom du fichier :" & vbLf & vbLf & FX
End Sub



Vous n'aurez donc plus de problème à cause des "/".

Cordialement.
Messages postés
16084
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
23 février 2020
2 878
Bonjour

pour "enregistrer sous" avec date du jour

chemin = "D:\docus\"
nomfich = "azerty"
jour = Format(Sheets(1).Range("A1"), "dd-mm-yyyy")
nomfich = chemin & nomfich & "_" & jour & ".xlsm"
'
ActiveWorkbook.SaveAs Filename:=nomfich


comme tu lances à partir d'une macro le nouveau classeur est donc en suffixe xlsm ou xltm

tu as intérêt à installer des variables (chemin, nomfich..) pour éviter le cauchemar des guillemets simples ou doubles dand activeworkbok?save as...

 Michel
J'ai suivi le conseil d'albkan

Cela fonctionne parfaitement ! Cette macro est donc résolue.

Sub Enregistrer()

Dim Chemin As String, Fichier As String, JX As String, MX As String

Chemin = "L:\Laboratoire\TestMacro\Archives\"
JX = Day([C3]): If JX < 10 Then JX = "0" & RTrim$(JX)
MX = Month([C3]): If MX < 10 Then MX = "0" & RTrim$(MX)
Fichier = "ExempleA" & "-" & Year([C3]) & "-" & MX & "-" & JX & ".xlsm"

ActiveWorkbook.SaveCopyAs Chemin & Fichier

Application.Quit
ActiveWorkbook.Close False


End Sub


Merci beaucoup.

Il me reste plus qu'à coder maintenant l'autre macro, sur l'autre fichier excel.
Pareil, sur ce fichier y'a une case avec la date à écrire.
Et quand j'applique la macro, cela ouvrir le fichier crée grace à la macro ci-dessous , et s'il n'existe pas encore, à la place, il m'ouvre le fichier ExempleA.xlsm

Vous auriez une idée de comment procéder?
J'ai essayer une bricole du genre :

Sub TestCrea()

Dim Test As String, JX As String, MX As String, Tramevierge As String

JX = Day([C3]): If JX < 10 Then JX = "0" & RTrim$(JX)
MX = Month([C3]): If MX < 10 Then MX = "0" & RTrim$(MX)
Test = "L:\Laboratoire\TestMacro\Archives\ExempleA" & "-" & Year([C3]) & "-" & MX & "-" & JX & ".xlsm"
Tramevierge = "L:\Laboratoire\TestMacro\TrameVierge\ExempleA.xlsm"

If Dir(Test) Then
Workbooks.Open Test

Else
Workbooks.Open Tramevierge

End Sub


Mais ça m'envoie dans le mur :)

Merci d'avance.

Bonjour David,

J'ai oublié que sur le forum, la règle est de se tutoyer, dans le respect et avec courtoisie. Tu peux donc me tutoyer toi aussi.

Je suis content que ma solution t'aie plu ; cependant :

----------------------------------------------------------------------------

1) J'avais utilisé RTrim$(JX) uniquement parce que j'avais déclaré JX comme une chaîne de caractères de longueur fixe, de 2 caractères : Dim JX As String * 2

C'est le * 2 final qui indique la longueur d'une chaîne fixe ; ce n'était pas 2 caractères ajoutés en plus par erreur.

Or dans ton code, tu utilises : JX As String (ce qui est possible aussi pour ce petit exercice).

Comme il n'y a pas, à la fin, de * nombre, c'est donc une chaîne de caractères de longueur variable.

Dans ce cas, le RTrim$() n'est plus nécessaire, et tu peux écrire plus simplement : JX = "0" & JX

Même chose, bien sûr, pour MX : pas de RTrim$() ; MX = "0" & MX

----------------------------------------------------------------------------

2) michel_m a indiqué dans son message 2 ci-dessus une solution encore meilleure que la mienne, en utilisant la fonction Format() ; mais lis d'abord la suite avant d'aller lire son message :

Je connaissais déjà la fonction Format(), mais je n'ai pas pensé à l'utiliser ici, alors que ça simplifie encore plus :

a) Utiliser cette fonction Format() évite le test < 10 et l'ajout éventuel d'un 0 devant.

b) Pour ton 1er code et ton 2ème code :

- dans ta ligne Dim, enlève les 2 déclarations JX As String et
MX As String

- Enlève les 2 lignes entières qui commencent par JX = et MX =

c) Dans ton 1er code, réécris la ligne Fichier = comme suit :
Fichier = "ExempleA" & "-" & Format([C3], "yyyy-mm-dd") & ".xlsm"

d) Dans ton 2ème code, réécris la ligne Test = comme suit :
Test = "L:\Laboratoire\TestMacro\Archives\ExempleA" & "-" & Format([C3], "yyyy-mm-dd") & ".xlsm"

Pour c) et d) j'ai volontairement évité "dd-mm-yyyy", car ça aurait donné jour-mois-an.

Ton choix de l'ordre des éléments est très bon, car c'est plus utile en cas de tri ; j'ai mis "yyyy-mm-dd" pour respecter cet ordre :
an-mois-jour.

Tu verras que cette solution aussi marche parfaitement, avec un code VBA beaucoup plus court (optimisé) !

----------------------------------------------------------------------------

Un grand merci à michel_m pour son très judicieux message :
Message #2 de michel_m

----------------------------------------------------------------------------

Pour ce que tu demandes ensuite, j'y réfléchirai plus tard, mais je ne te promets rien ; et michel_m te fournira peut-être une réponse.
 

Bonsoir David,

Lis d'abord mon message 4 ci-dessus, avant celui-ci.
Voici maintenant la solution pour ta 2ème partie.

ATTENTION !

Une ligne On Error Goto ... doit obligatoirement être la 1ère
de la Sub ! Elle doit donc être AVANT même la ligne Dim ...


Sub TestCrea()
  On Error GoTo ErrFile
  Dim Test As String, Tramevierge As String
  Test = "L:\Laboratoire\TestMacro\Archives\ExempleA" & "-" & Format([C3], "yyyy-mm-dd") & ".xlsm"
  Tramevierge = "L:\Laboratoire\TestMacro\TrameVierge\ExempleA.xlsm"
  Workbooks.Open Test: Exit Sub
ErrFile:
  Workbooks.Open Tramevierge
End Sub



Explications

Le premier Workbooks.Open va tenter d'ouvrir le fichier Test.

S'il existe bien, pas de problème : ouverture du fichier Test, et sortie de la Sub (grâce à Exit Sub).

S'il n'existe pas, une erreur d'ouverture de fichier se produit, et sans le On Error GoTo ... la Sub planterait tout bêtement et simplement !

Heureusement, ce On Error Goto ... permet de « récupérer l'erreur », ce pourquoi on peut dire que dans cette Sub, on a implémenté un « Gestionnaire d'erreurs ».

Donc quand l'erreur se produit, au lieu de planter, la Sub passe le contrôle de l'exécution du programme à l'endroit indiqué par ce qui suit le On Error GoTo, donc à l'étiquette ErrFile.

Pour le dire plus simplement : en cas d'erreur, ça va à la ligne ErrFile: pour exécuter la 1ère ligne qui suit : ouverture du fichier Tramevierge. Et voilà, le tour est joué !

Mais ATTENTION de ne pas oublier de mettre un Exit Sub juste avant l'étiquette ErrFile: sinon, après ouverture réussie du fichier Test, l'exécution du programme continuerait à la suite et rentrerait dans le gestionnaire d'erreur !

J'ai nommé l'étiquette ErrFile: mais tu peux choisir un autre nom si tu préfères ; par exemple : OuvrirFichierModèle:

Remarques bien qu'il y a un signe ":" (deux-points) à la fin de l'étiquette, alors qu'il n'en faut pas sur la ligne On Error Goto !
 
Utilisateur anonyme
Autre amélioration

J'ai laissé un petit défaut dans le code ci-dessus.

La ligne 7 : Tramevierge = ... est tout à fait correcte ; mais à l'endroit où elle est placée, si l'instruction Workbooks.Open Test réussit, cette affectation est alors exécutée inutilement !

Il vaudrait donc mieux la déplacer un peu plus bas, juste avant la ligne 10 où elle est utilisée ; mais ne pas le faire car on va fusionner ces 2 lignes et ne plus utiliser la variable Tramevierge.

On peut même se passer aussi de la variable Test, sans que ça pose de problème pour les guillemets (car il n'y a aucun espace dans le nom).

Cela donne :


Sub TestCrea()
  On Error GoTo ErrFile
  Workbooks.Open "L:\Laboratoire\TestMacro\Archives\ExempleA" & "-" & Format([C3], "yyyy-mm-dd") & ".xlsm"
  Exit Sub
ErrFile:
  Workbooks.Open "L:\Laboratoire\TestMacro\TrameVierge\ExempleA.xlsm"
End Sub


Les lignes 4 et 5 doivent bien sûr être sur la même ligne.
Utilisateur anonyme
f894009 vient de proposer d'utiliser la fonction Dir() ; après essai, je pense que c'est la solution la plus SIMPLE et la MEILLEURE, car ça évite d'utiliser un Gestionnaire d'erreur ; donc en adaptant pour cet exercice, ça donne :

Sub TestCrea()
  Const LTM As String * 25 = "L:\Laboratoire\TestMacro\"
  Dim FX As String
  FX = LTM & "Archives\ExempleA" & "-" & Format([C3], "yyyy-mm-dd") & ".xlsm"
  If Dir(FX) = "" Then FX = LTM & "TrameVierge\ExempleA.xlsm"
  Workbooks.Open FX
End Sub

Les lignes 4 et 5 doivent être sur la même ligne.

Commentaires

1) FX contient d'abord le nom du fichier que tu veux ouvrir (celui du dossier Archives, avec la date).

2) Si Dir(FX) retourne une chaîne vide, c'est que le fichier n'existe pas ; dans ce cas, on remplace la valeur de FX par le nom du fichier modèle, celui du dossier Tramevierge.

3) Maintenant, il n'y a plus qu'une seule instruction Workbooks.Open !

Voici le lien vers l'article sur l'instruction Dir() : Message 8 de f894009
Messages postés
23271
Date d'inscription
mardi 11 septembre 2007
Statut
Contributeur
Dernière intervention
22 février 2020
5 930
Bonjour tous,

ici une fonction qui permet non seulement de voir si le fichier existe, mais permet aussi de savoir s'il est déjà ouvert par qq'un pour traiter et éviter l'ouverture en lecture seule :
https://support.microsoft.com/en-us/help/291295
Sinon la proposition d'albkan suffit.
eric
Messages postés
15011
Date d'inscription
dimanche 25 novembre 2007
Statut
Membre
Dernière intervention
24 février 2020
1 222
Bonjour a tous,
petite incruste sans pretention

Juste pour en revenir au test Dir
Sub test()
    If Dir("d:\_acsv1\classeur2.xls") <> "" Then
        MsgBox "Fichier existe"
    Else
        MsgBox "Fichier n'existe pas"
    End If
End Sub


Peut etre complete avec test ouvert ou pas avec le lien de eriiic
Ce code pouvant faire tout en modifiant un peu pour recuperer l'erreur 53 (file not found) car il ne teste pas cette option
Utilisateur anonyme
Bonjour f894009,

Je viens d'essayer ta solution avec la fonction Dir() et je la trouve PARFAITE !

Ça évite d'utiliser un gestionnaire d'erreur comme je l'avais fait avant,
car même avec un fichier qui n'existe pas, l'erreur 53 (file not found)
ne s'est pas produite, ni aucune autre !

Je pense que tu as trouvé la solution la plus SIMPLE et la MEILLEURE !
Merci beaucoup pour nous l'avoir indiqué !

Bonjour David,

Ton problème est maintenant entièrement résolu :

A) Partie 1 : la date du fichier selon la cellule C3, au bon format ;
    version améliorée qui utilise la fonction Format() ;
    ceci grâce à une indication de michel_m.

B) Partie 2 : l'ouverture du fichier Test ou du fichier Tramevierge ;
    version améliorée qui utilise la fonction Dir() ;
    ceci grâce à une indication de f894009.

Depuis ton dernier message 3, il y a eu beaucoup d'autres messages, et je crois bien que tu risques de ne plus t'y retrouver ! Voici donc
les indications nécessaires :

==========================================

Le code définitif et complet est celui du message suivant :
Mon message #10

==========================================

Mais tu devrais quand même lire d'abord ce message, qui est très instructif pour la fonction RTrim$(), la différence entre les chaînes de caractères de longueur fixe / variable, l'utilisation de Format() :

Mon message #4 : c'est uniquement pour le format de date.

---------------------------------------------------------------------------

Puis les 2 messages suivants, qui sont très instructifs pour la mise
en place d'un gestionnaire d'erreur (avec On Error Goto ...) :

Mon message #5 : c'est mon 1er essai de résolution de la partie 2.
Mon message #7 : amélioration du code du message #5.
 
Merci pour toutes vos réponses.

J'ai enfin terminé mon fichier avec toutes les macros nécessaire et cela marche nickel avec toutes les solutions que chacun a proposé !

Ce problème est donc [résolu]
Mais je ne trouve pas le bouton pour cloturer ce topic...