IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Excel Discussion :

Comment une macro peut-elle tester l'état d'un fichier (ouvert ou fermé) ? [XL-2007]


Sujet :

Excel

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Planteur
    Inscrit en
    Avril 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Planteur

    Informations forums :
    Inscription : Avril 2020
    Messages : 4
    Points : 5
    Points
    5
    Par défaut Comment une macro peut-elle tester l'état d'un fichier (ouvert ou fermé) ?
    Bonjour,
    J'ai une macro sous Excel qui, parmi d'autres fonctionnalités, ouvre un fichier Excel, le traite, puis le referme. Si le fichier est déjà ouvert, je suis confronté à des choses assez imprévisibles.
    J'aimerais donc que ma macro puisse m'avertir que ledit fichier est ouvert.
    Voici ce que j'utilise, dans ma macro, pour l'ouverture du fichier Excel, puis de la feuille de calcul souhaitée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Workbooks.Open Filename:=RépertoireFichiers + Fichier
    Sheets(1).Select
    Merci d'avance !

    Mes configs : Windows 10 + Office 2007

  2. #2
    Expert éminent sénior Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Points : 32 866
    Points
    32 866
    Par défaut
    Une solution peu subtile mais efficace, en partant du principe que "Fichier" contient le nom de classeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Dim Ouvert As Boolean, WB As Workbook
     
    Ouvert = False
    For WB In Workbooks
        If WB.Name = Fichier Then Ouvert = True
    Next WB
    If Not Ouvert Then Workbooks.Open Filename:=RépertoireFichiers + Fichier
    Sheets(1).Select

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Planteur
    Inscrit en
    Avril 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Planteur

    Informations forums :
    Inscription : Avril 2020
    Messages : 4
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Menhir Voir le message
    Une solution peu subtile mais efficace, en partant du principe que "Fichier" contient le nom de classeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Dim Ouvert As Boolean, WB As Workbook
     
    Ouvert = False
    For WB In Workbooks
        If WB.Name = Fichier Then Ouvert = True
    Next WB
    If Not Ouvert Then Workbooks.Open Filename:=RépertoireFichiers + Fichier
    Sheets(1).Select
    Merci, Menhir, d'avoir bien voulu te pencher sur mon problème.
    Dans un premier temps, la forme For WB In... / Next WB n'a pas été acceptée.
    Je me suis donc rabattu sur la forme For Each WB In... / Next WB qui, elle, est reconnue valide.
    Bizarrement, le test If WB.Name ne veut pas du chemin d'accès au fichier.
    Voici le code testé qui fonctionne parfaitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    Sub AAATestOpenFile()
     
        Dim Car As String, RépertoireFichiers As String
        Dim FichierC1 As String, FichierC2 As String
     
        Dim Ouvert1 As Boolean, Ouvert2 As Boolean, WB As Workbook
     
    ' Définition des noms de fichier traités dans cette macro
     
        FichierC1 = "Compte-ABC.xlsm"
        FichierC2 = "Comptes-BCD.xlsm"
     
        RépertoireFichiers = "C:\Users\Utilisateur\Documents\ComptesXX\"
     
    Ouvert1 = False: Ouvert2 = False
    For Each WB In Workbooks
        If WB.Name = FichierC1 Then Ouvert1 = True
        If WB.Name = FichierC2 Then Ouvert2 = True
    Next WB
    If Ouvert1 And Ouvert2 Then
        MsgBox ("Fichiers " + FichierC1 + " et " + FichierC2 + " ouverts")
        GoTo Fin
    End If
    If Ouvert1 Then MsgBox ("Fichier " + FichierC1 + " ouvert")
    If Ouvert2 Then MsgBox ("Fichier " + FichierC2 + " ouvert")
     
    Fin:
    End Sub
    J'ai tenté de comprendre pourquoi ça marche mais, là, c'est peut-être aller loin en besogne.
    Si tu peux m'éclairer sur ce point, je t'en serais reconnaissant bien que mon problème soit réglé dans l'absolu.

    En tout cas, merci pour ton expertise !

  4. #4
    Expert éminent sénior Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Points : 32 866
    Points
    32 866
    Par défaut
    Je n'ai pas eu le temps de tester mon code (j'aurais dû le signaler). Il y a donc du débugage à faire.
    Citation Envoyé par Hvall Voir le message
    Dans un premier temps, la forme For WB In... / Next WB n'a pas été acceptée.
    Je me suis donc rabattu sur la forme For Each WB In... / Next WB qui, elle, est reconnue valide.
    Effectivement, j'avais oublié le Each.

    Bizarrement, le test If WB.Name ne veut pas du chemin d'accès au fichier.
    Excel ne pouvant pas ouvrir deux classeur de même nom (même s'ils sont enregistrés dans des répertoires différents), il est inutile de tester le chemin si c'est simplement pour savoir si l'on peut ouvrir le fichier.

    Voici le code testé qui fonctionne parfaitement :
    Tant mieux s'il fonctionne mais le Goto dans le code, c'est vraiment pas beau.
    Ca fait 30 ans que cette instruction est à proscrire des programmes.

    Tu n'avais pas signalé dans ta demande que tu voulais contrôler deux fichiers.

    Si tu peux m'éclairer sur ce point, je t'en serais reconnaissant bien que mon problème soit réglé dans l'absolu.
    Pour comprendre un code, utilise l'aide VBA.
    Par exemple, si tu places ton curseur sur un terme du code et que tu appuies sur la touche F1, tu accèderas à l'aide concernant ce mot.

    La boucle For Each scrute la collection Workbooks qui représente tous les classeurs ouvert dans Excel.
    Pour chacun, la macro test si son nom correspond à celui du fichier à ouvrir.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Planteur
    Inscrit en
    Avril 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Planteur

    Informations forums :
    Inscription : Avril 2020
    Messages : 4
    Points : 5
    Points
    5
    Par défaut
    Merci encore une fois !!!
    Tes explications détaillées me permettent de mieux comprendre ce qui se passe. J'ai l'habitude de l'aide VBA mais là, j'avais besoin d'un peu plus.
    Et, effectivement, je ne t'avais pas parlé de 2 fichiers.

    Permets-moi cependant de ne pas partager totalement ton point de vue (largement répandu) s'agissant de l'inesthétique du GOTO.
    Tout programme, quel qu'il soit, se voit transformé en instructions de processeur x86/x64 où les JMP, Jcc (sauts conditionnels) abondent. Il suffit de faire joujou avec un désassembleur pour s'en rendre compte.
    Pour des bouts de programme qui ne dépassent pas une centaine de lignes, je m'assois donc sur ce genre de considération, cela dit sans vouloir t'offenser. J'ai vu ce débat émerger au début des années 90 et je n'ai toujours pas compris le formalisme excessif de certains concepteurs de langage. Mais bon, ça n'empêche pas la Terre de tourner.

  6. #6
    Expert éminent sénior Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Points : 32 866
    Points
    32 866
    Par défaut
    Citation Envoyé par Hvall Voir le message
    J'ai vu ce débat émerger au début des années 90 et je n'ai toujours pas compris le formalisme excessif de certains concepteurs de langage.
    J'ai moi aussi commencé à coder en Basic au début des années 80 en autodidacte, jusqu'à ce que ma route croise quelques langages structurés comme Quick Basic et, surtout, le langage de Dbase (et ses petits frères). Ce dernier n'ayant rien qui corresponde au Goto, j'ai cru que je ne pourrais pas m'en sortir mais je me suis aperçu que, non seulement on pouvait s'en passer sans problème mais qu'en plus, ça donnait des codes beaucoup plus facile à gérer.

    Au début de ma carrière professionnelle, j'ai eu à reprendre le code d'un autre, écrit en HP Basic avec des Goto partout : un vrai plat de spaguetti, une horreur. C'est un peu comme faire 100 km en voiture avec trois potes qui clopent alors que tu n'es pas fumeur : ça te rend allergique à vie.

    Banir les Goto, même pour les petits code, ça oblige à penser autrement, à avoir une vision beaucoup plus structurée du codage.
    Le Goto, c'est plus facile, plus rapide... c'est un peu le côté obscure du Basic.

    La fin de ton code sans Goto :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        If Ouvert1 And Ouvert2 Then
            MsgBox ("Fichiers " + FichierC1 + " et " + FichierC2 + " ouverts")
        ElseIf Ouvert1 Or Ouvert2 Then
            MsgBox ("Fichier " + IIf(Ouvert1, FichierC1, FichierC2) + " ouvert, fichier " + IIf(Ouvert1, FichierC2, FichierC1) + " fermé")
        Else
            MsgBox ("Fichiers " + FichierC1 + " et " + FichierC2 + " sont fermés")
        End If
    Ca se comprend mieux, non ?

  7. #7
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 124
    Points : 55 929
    Points
    55 929
    Billets dans le blog
    131
    Par défaut
    Salut.

    Attention que si les fichiers sont ouverts dans des instances différentes d'Excel, le test de boucler sur les workbooks ouverts d'une instance ne servira à rien. C'est pareil si le fichier est ouvert par quelqu'un d'autre.

    Normalement, on ne devrait avoir à ouvrir un autre fichier que celui dans lequel on travaille que pour en importer rapidement les données, puis on le referme. Idéalement, il faudrait utiliser MSQUery pour importer les données d'un fichier dans un autre.

    Quant au GOTO, je rejoins Menhir. C'est effectivement une horreur, et ce n'est pas au niveau du processeur que c'est une horreur (après tout, les branchements conditionnels, les branchements sur erreur et les appels de procédure sont aussi des "GOTO au niveau du processeur). C'est au niveau de la conception (et de la réflexion) de son code que c'est une horreur, tant pour la maintenance et l'évolution du code que pour sa simple compréhension. Dans la mesure où l'on devrait écrire des petites procédures ou fonctions qui n'ont qu'une seule responsabilité, les GOTO sont inutiles dans un code bien construit. Le formalisme et la systématisation sont les clés d'un code pérenne, évolutif, solide et sans bugs

    Je ne conçois pas bien que l'on puisse écrire des GOTO dans des "petits programmes" (c'est quoi un petit programme) et qu'on s'en passe dans des développements plus importants. On code proprement ou pas, quelle que soit la taille du code ou de l'appli développée.

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Planteur
    Inscrit en
    Avril 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Planteur

    Informations forums :
    Inscription : Avril 2020
    Messages : 4
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Pierre Fauconnier Voir le message
    Salut.

    Attention que si les fichiers sont ouverts dans des instances différentes d'Excel, le test de boucler sur les workbooks ouverts d'une instance ne servira à rien. C'est pareil si le fichier est ouvert par quelqu'un d'autre.

    Normalement, on ne devrait avoir à ouvrir un autre fichier que celui dans lequel on travaille que pour en importer rapidement les données, puis on le referme. Idéalement, il faudrait utiliser MSQUery pour importer les données d'un fichier dans un autre.
    Non, la solution de Menhir me va très bien. Il s'agit d'un traitement court. Je récupère un extrait de comptes reçu de ma banque que j'ouvre. Je déclenche alors une macro qui va m'ouvrir 2 autres fichiers Excel et les charger avec des informations issues du premier mises en forme par la macro. Je laisse ces 2 fichiers ouverts en sortie de macro car je préfère jeter un œil dessus avant de les fermer. Comme ces 2 fichiers peuvent se retrouver ouverts par inadvertance, je souhaite que la macro me le dise et me laisse agir en conséquence. C'est tout et c'est résolu. Et je n'ai pas envie de me prendre la tête avec la super-application du siècle qui n'intéresserait d'ailleurs que moi. C'est pour ça que mon GOTO "peu élégant" ne m'empêche pas de dormir. Evidemment, la formulation IF... ELSEIF...ELSE...END IF me va très bien et je la préfère, même. Mais je ne m'interdis pas de bricoler un peu surtout sachant, par ailleurs, que le code issu du compilateur sera fort peu différent.

    Citation Envoyé par Pierre Fauconnier Voir le message
    Quant au GOTO, je rejoins Menhir. C'est effectivement une horreur, et ce n'est pas au niveau du processeur que c'est une horreur (après tout, les branchements conditionnels, les branchements sur erreur et les appels de procédure sont aussi des "GOTO au niveau du processeur). C'est au niveau de la conception (et de la réflexion) de son code que c'est une horreur, tant pour la maintenance et l'évolution du code que pour sa simple compréhension. Dans la mesure où l'on devrait écrire des petites procédures ou fonctions qui n'ont qu'une seule responsabilité, les GOTO sont inutiles dans un code bien construit. Le formalisme et la systématisation sont les clés d'un code pérenne, évolutif, solide et sans bugs

    Je ne conçois pas bien que l'on puisse écrire des GOTO dans des "petits programmes" (c'est quoi un petit programme) et qu'on s'en passe dans des développements plus importants. On code proprement ou pas, quelle que soit la taille du code ou de l'appli développée.
    Là, nous ne sommes vraiment pas d'accord sauf sur un point : le formalisme est incontournable dès lors que l'on s'attache à la clarté du code (pas toujours synonyme d'efficacité, d'ailleurs). Le recours au GOTO doit, certes, être déconseillé mais l'interdire est inacceptable. Pire, il ne correspond pas à la réalité du fonctionnement du processeur. Pour moi, la bonne maintenabilité d'un code passe, avant tout, par un minimum de formalisme et des commentaires clairs (ces derniers faisant très souvent défaut). Je suis persuadé que l'IA mettra un jour de l'ordre dans ce déni de démocratie informatique (j'ajoute un de peur d'être trop pris au sérieux)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] Comment une formule dans une cellule peut-elle s'effacer ?
    Par P.Sheehy dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 18/09/2015, 15h08
  2. Comment une classe peut se centrer d'elle meme ?
    Par babbu dans le forum ActionScript 3
    Réponses: 3
    Dernier message: 24/09/2008, 09h31
  3. Réponses: 19
    Dernier message: 02/10/2006, 17h19
  4. [C#] Comment une thread peut-elle attendre un evenement?
    Par legillou dans le forum Windows Forms
    Réponses: 4
    Dernier message: 03/07/2006, 15h58
  5. Réponses: 5
    Dernier message: 25/11/2003, 10h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo