81 votes

Détecter si un classeur Excel est déjà ouvert

En VBA, j'ai ouvert un fichier MS Excel nommé "myWork.XL" de manière programmatique.

Maintenant, je voudrais un code qui puisse m'indiquer son statut - s'il est ouvert ou non. Par exemple, quelque chose comme IsWorkBookOpened("myWork.XL) ?

105voto

Siddharth Rout Points 63935

Essayez ça :

Option Explicit

Sub Sample()
    Dim Ret

    Ret = IsWorkBookOpen("C:\myWork.xlsx")

    If Ret = True Then
        MsgBox "File is open"
    Else
        MsgBox "File is Closed"
    End If
End Sub

Function IsWorkBookOpen(FileName As String)
    Dim ff As Long, ErrNo As Long

    On Error Resume Next
    ff = FreeFile()
    Open FileName For Input Lock Read As #ff
    Close ff
    ErrNo = Err
    On Error GoTo 0

    Select Case ErrNo
    Case 0:    IsWorkBookOpen = False
    Case 70:   IsWorkBookOpen = True
    Case Else: Error ErrNo
    End Select
End Function

2 votes

+1 J'utilise cette méthode depuis un certain temps pour vérifier les fichiers d'un disque de travail accessible par d'autres utilisateurs. Je pense que le code a été initialement posté sur un site msft.

5 votes

Personnellement, je me sentirais très mal à l'aise à l'idée d'utiliser une interface de fichier primitive pour tenter de lire un fichier sur un classeur Excel ouvert alors qu'il existe de meilleures alternatives : mais peut-être que cela fonctionne ?

3 votes

@Charles Williams : Oui, c'est peut-être primitif mais c'est quand même un bon code sans inconvénient. Du moins, aucun que je connaisse. :) Essayez-le, peut-être l'aimerez-vous ?

59voto

Dick Kusleika Points 15230

Pour mes applications, je veux généralement travailler avec un classeur plutôt que de simplement déterminer s'il est ouvert. Dans ce cas, je préfère sauter la fonction booléenne et renvoyer simplement le classeur.

Sub test()

    Dim wb As Workbook

    Set wb = GetWorkbook("C:\Users\dick\Dropbox\Excel\Hoops.xls")

    If Not wb Is Nothing Then
        Debug.Print wb.Name
    End If

End Sub

Public Function GetWorkbook(ByVal sFullName As String) As Workbook

    Dim sFile As String
    Dim wbReturn As Workbook

    sFile = Dir(sFullName)

    On Error Resume Next
        Set wbReturn = Workbooks(sFile)

        If wbReturn Is Nothing Then
            Set wbReturn = Workbooks.Open(sFullName)
        End If
    On Error GoTo 0

    Set GetWorkbook = wbReturn

End Function

2 votes

Je suis d'accord que c'est généralement ce que l'on veut : si vous voulez vérifier si le livre est déjà ouvert dans une autre instance d'Excel, vous pouvez vérifier s'il a été ouvert en lecture seule.

0 votes

Cela me donne une erreur hors limites sur Workbooks(sFile)

1 votes

Vous ne devez pas avoir On Error Resume Next dans le code ou vous avez défini l'option Break on All Errors sous Tools - Options dans le VBE.

22voto

Charles Williams Points 9147

S'il est ouvert, il se trouve dans la collection Workbooks :

Function BookOpen(strBookName As String) As Boolean
    Dim oBk As Workbook
    On Error Resume Next
    Set oBk = Workbooks(strBookName)
    On Error GoTo 0
    If oBk Is Nothing Then
        BookOpen = False
    Else
        BookOpen = True
    End If
End Function

Sub testbook()
    Dim strBookName As String
    strBookName = "myWork.xls"
    If BookOpen(strBookName) Then
        MsgBox strBookName & " is open", vbOKOnly + vbInformation
    Else
        MsgBox strBookName & " is NOT open", vbOKOnly + vbExclamation
    End If
End Sub

11 votes

Charles, j'ai déjà pensé à cette méthode. Le principal inconvénient de cette méthode est que si le classeur est ouvert dans une instance Excel différente, vous obtiendrez toujours la valeur false :) l'alternative serait d'ajouter du code pour boucler toutes les instances Excel et ensuite utiliser votre code. En fin de compte, je me suis rendu compte que j'écrivais plus de code et j'ai donc utilisé une autre approche. Sid

4 votes

Si vous voulez vérifier que le livre est ouvert dans une autre instance d'Excel (vraisemblablement parce que vous ne pourrez pas l'enregistrer ou le modifier), pourquoi ne pas simplement vérifier si le livre est en lecture seule après l'avoir ouvert (If oBk.Readonly ...).

15voto

user2267971 Points 28

J'irais avec ça :

Public Function FileInUse(sFileName) As Boolean
    On Error Resume Next
    Open sFileName For Binary Access Read Lock Read As #1
    Close #1
    FileInUse = IIf(Err.Number > 0, True, False)
    On Error GoTo 0
End Function

comme sFileName, vous devez fournir le chemin direct du fichier, par exemple :

Sub Test_Sub()
    myFilePath = "C:\Users\UserName\Desktop\example.xlsx"
    If FileInUse(myFilePath) Then
        MsgBox "File is Opened"
    Else
        MsgBox "File is Closed"
    End If
End Sub

6voto

Derek Johnson Points 201

Que faire si vous voulez vérifier sans créer une autre instance Excel ?

Par exemple, j'ai une macro Word (qui est exécutée à plusieurs reprises) qui doit extraire des données d'une feuille de calcul Excel. Si la feuille de calcul est déjà ouverte dans une instance Excel existante, je préfère ne pas créer une nouvelle instance.

J'ai trouvé ici une excellente réponse sur laquelle je me suis basé : http://www.dbforums.com/microsoft-access/1022678-how-check-wether-excel-workbook-already-open-not-search-value.html

Merci à MikeTheBike et à kirankarnati.

Function WorkbookOpen(strWorkBookName As String) As Boolean
    'Returns TRUE if the workbook is open
    Dim oXL As Excel.Application
    Dim oBk As Workbook

    On Error Resume Next
    Set oXL = GetObject(, "Excel.Application")
    If Err.Number <> 0 Then
        'Excel is NOT open, so the workbook cannot be open
        Err.Clear
        WorkbookOpen = False
    Else
        'Excel is open, check if workbook is open
        Set oBk = oXL.Workbooks(strWorkBookName)
        If oBk Is Nothing Then
            WorkbookOpen = False
        Else
            WorkbookOpen = True
            Set oBk = Nothing
        End If
    End If
    Set oXL = Nothing
End Function

Sub testWorkbookOpen()
    Dim strBookName As String
    strBookName = "myWork.xls"
    If WorkbookOpen(strBookName) Then
        msgbox strBookName & " is open", vbOKOnly + vbInformation
    Else
        msgbox strBookName & " is NOT open", vbOKOnly + vbExclamation
    End If
End Sub

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X