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

VBA Access Discussion :

Détection erronée de classeurs Excel ouverts via Access [AC-2010]


Sujet :

VBA Access

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2019
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2019
    Messages : 146
    Par défaut Détection erronée de classeurs Excel ouverts via Access
    Bonjour,

    À partir d'un formulaire, j'aimerais savoir si des classeurs Excel spécifiques sont ouverts.

    Lorsqu'un ou plusieurs de ceux-ci ont été ouverts via Excel ou via l'explorateur Windows, ou si un des classeurs seulement a été ouvert via Access, tout fonctionne parfaitement, mais si plusieurs classeurs ont été ouverts via Access, la détection est erronée. La détection est également correcte, lorsqu'aucun des classeurs n'est ouvert.

    Voici la procédure pour ouvrir les classeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Function OuvrirFichierXLS(Fichier As String)
    Dim xl As Object 'Excel Application
    Dim wb As Object 'Excel Workbook
     
        Set xl = CreateObject("Excel.Application")
        Set wb = xl.Workbooks.Open(Fichier)
        xl.Visible = True
     
        Set wb = Nothing
        Set xl = Nothing
    End Function
    Voici la procédure pour vérifier si des classeurs spécifiques sont ouverts :
    Dans un module :

    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
    Function IsExcelWorkbookOpen(wbName As String) As Boolean
        Dim xlApp As Object
        Dim xlWorkbook As Object
     
        On Error Resume Next
        Set xlApp = GetObject(, "Excel.Application")
        On Error GoTo 0
     
        If Not xlApp Is Nothing Then
            For Each xlWorkbook In xlApp.Workbooks
                If xlWorkbook.Name = wbName Then
                    IsExcelWorkbookOpen = True
                    Exit Function
                End If
            Next xlWorkbook
        End If
     
        IsExcelWorkbookOpen = False
     
        Set xlApp = Nothing
        Set xlWorkbook = Nothing
     
    End Function
    Dans une procédure:

    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
    Private Sub cmdCheckWorkbookOpen_Click()
    Dim WorkbookName As String
    Dim OpenWorkbook As Boolean
    Dim i As Integer
    Dim FileList() As Variant ' Liste des fichiers
     
        FileList = Array("Classeur1.xlsm", "Classeur2.xlsm", "Classeur3.xlsm")
     
        For i = LBound(params) To UBound(params)
            WorkbookName = FileList(i)
            If IsExcelWorkbookOpen(WorkbookName) Then
                OpenWorkbook = True
                MsgBox "Le classeur : " & WorkbookName & " est ouvert."
            Else
                MsgBox "Le classeur : " & WorkbookName & " est fermé."
            End If
        Next i
     
    End Sub
    Voici le résultat d'une série de tests effectué. En vert la détection est correcte :

    Nom : Détection classeurs ouverts.jpg
Affichages : 110
Taille : 253,6 Ko

    Si quelqu’un a une piste...

  2. #2
    Membre Expert Avatar de Thumb down
    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2019
    Messages
    1 574
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juin 2019
    Messages : 1 574
    Par défaut
    Bonjour,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Function IsWorkbookOpen(filePath As String) As Boolean
        Dim fileNum As Integer
        fileNum = FreeFile ' Obtenir un numéro de fichier gratuit
     
        On Error Resume Next
        ' Essayer d'ouvrir le fichier en lecture seule avec verrouillage
        Open filePath For Input Lock Read As fileNum
        IsWorkbookOpen = (Err.Number <> 0) ' S'il y a une erreur, le fichier est déjà ouvert
        Close fileNum
        On Error GoTo 0
    End Function

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2019
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2019
    Messages : 146
    Par défaut
    Bonjour Thumb down,

    Ma-gni-fique, ça marche à merveille et en plus c'est concis!

    Merci et bonne journée,
    Gaston

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 508
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 508
    Par défaut
    Salut,

    Pas une piste mais une explication, problème de multi-instances:

    Une instance d'Excel peut contenir plusieurs classeurs, mais:
    CreateObject, comme son nom l'indique, créer une nouvelle insrtance.
    GetObject renvoie une instance, à priory, la première créée, donc ne gère pas le multi-instances.

    Ca peut être mis en évidence par le code suivant:
    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
    29
    30
    31
    32
    33
    34
    35
    Private Instances As Collection
     
    Public Sub test()
        Set Instances = New Collection
     
            '// créé une instance
        Dim Instance As Object
        Set Instance = CreateInstance
     
            '// ajoute 3 classeurs
        Dim i As Integer
        For i = 1 To 3
            Instance.workbooks.Add "C:\........\Classeur" & i & ".xlsx"
        Next
            '// ajoute l'instance à la collection
        Instances.Add Instance
     
            '// créé une seconde instance
        Set Instance = CreateInstance
        Instance.workbook.Add "C:\........\Classeur4.xlsx"
        Instances.Add Instance
     
            '// recupère une instance
        Set Instance = GetObject(Class:="Excel.Application")
            '// affiche le nombre de classeurs ouverts par l'instance récupérée
            '// 3 (ou 1) classeurs sont comptés, alors qu'il y en a 4 ouverts
        Debug.Print Instance.workbooks.Count
    End Sub
     
    Private Function CreateInstance() As Object
        Dim Instance As Object
        Set Instance = CreateObject("Excel.Application")
        Instance.Visible = True
        Set CreateInstance = Instance
    End Function

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 508
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 508
    Par défaut
    @Thumb down:
    A ma connaissance, Excel ne verrouille pas les fichier (l'ouverture en multi-utilisateurs serait impossible sinon).

    Testé en ouvrant au préalable un fichier en lecture seule ou mode protégé, la fonction retourne faux.

  6. #6
    Membre confirmé
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2019
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2019
    Messages : 146
    Par défaut
    Bonjour deedolith,

    Merci pour cette explication, mais pourrais-tu me dire comment mettre le test en pratique?

    Le "Public Sub test" dans un bouton de commande et "Private Function CreateInstance() As Object" dans le module en cours ou dans un module séparé ?

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 508
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 508
    Par défaut
    1) Tu copies le code dans un module standard quelconque (un nouveau de préférence vu que ce n'est pas destiné à être pérennisé),
    tu places le curseur de saisie dans la fonction Test (ou click dans son code source) et tu appuies sur F5.

    2) Tu entres le nom de la fonction dans la fenêtre d'exécution.

    Note:
    Les fonctions privées ne sont pas destinées a être executées manuellement, ni depuis l'extérieur du module dans lequel elles sont déclarées.

  8. #8
    Membre confirmé
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2019
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2019
    Messages : 146
    Par défaut
    Citation Envoyé par deedolith Voir le message
    1) Tu copies le code dans un module standard quelconque (un nouveau de préférence vu que ce n'est pas destiné à être pérennisé),
    tu places le curseur de saisie dans la fonction Test (ou click dans son code source) et tu appuies sur F5.

    2) Tu entres le nom de la fonction dans la fenêtre d'exécution.

    Note:
    Les fonctions privées ne sont pas destinées a être executées manuellement, ni depuis l'extérieur du module dans lequel elles sont déclarées.
    OK, je teste ça et reviens vers toi !

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2019
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2019
    Messages : 146
    Par défaut
    Bonjour deedolith,

    J'ai testé ton code et effectivement la nouvelle instance n'est pas prise en compte.
    Ce test m'a permis de mieux comprendre le fonctionnement et les problèmes que l'on peut rencontrer avec les "multi-instances".

    Juste une petite erreur dans la ligne 20 : Workbook devrait-être Workbooks
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Instance.workbook.Add "C:\........\Classeur4.xlsx"
    Merci pour cet éclairage bien utile!

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

Discussions similaires

  1. [XL-2007] Fermer un classeur excel ouvert sur un autre poste
    Par Didpa dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 31/03/2013, 15h59
  2. Classeur excel en vba access
    Par zebi42 dans le forum VBA Access
    Réponses: 3
    Dernier message: 14/03/2011, 16h55
  3. [SP-2007] Ouvrir classeur Excel Service via Infopath
    Par HttpPointCom dans le forum SharePoint
    Réponses: 0
    Dernier message: 28/05/2009, 10h55
  4. Fermeture fichier Excel déjà ouvert via Access
    Par Jaymerry dans le forum VBA Access
    Réponses: 2
    Dernier message: 22/07/2008, 08h27
  5. Classeurs excell inaccessibles depuis Access
    Par Geache dans le forum Access
    Réponses: 1
    Dernier message: 04/06/2008, 09h27

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