检测Excel工作簿是否已经打开[关闭]


72

在VBA中,我以编程方式打开了一个名为“ myWork.XL”的MS Excel文件。

现在,我想要一个可以告诉我其状态的代码-无论它是否打开。即像IsWorkBookOpened("myWork.XL)什么?

Answers:


92

尝试这个:

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

1
+1我已经使用此方法一段时间来检查其他用户可以访问的newtwork驱动器上的文件。我认为代码最初是在msft网站上发布的。
brettdj

4
就个人而言,当恕我直言有更好的选择时,使用原始文件IO尝试在打开的Excel工作簿上读取文件会感到非常不舒服:但是也许行得通吗?
查尔斯·威廉姆斯

2
@Charles Williams:是的,它可能是原始的,但它仍然是一个好的代码,没有任何缺点。至少我不知道。:)试试吧,也许您会喜欢?
Siddharth Rout 2012年

我确定它可以正常工作,但是您认为更简单,更易于使用Excel的代码的缺点是什么?(使用Workbooks.Open打开工作簿,并检查Workbook.Readonly)
Charles Williams

5
@CharlesWilliams公平点。尽管就我而言,当我尝试类似的操作时,实际打开在海外服务器上托管的大型模型的时间开销约为2-3分钟。当它以只读方式打开时,这给出了一个“ grrr”时刻,而上面的Sid函数给出了立即响应。FWIW鲍勃·菲利普斯(鲍勃·菲利普斯)在vbaexpress上列出了类似的功能,是一个更高级的版本,等待该书在Chip Pearson的
brettdj

54

对于我的应用程序,我通常希望使用工作簿,而不仅仅是确定它是否已打开。对于这种情况,我更喜欢跳过布尔函数,而只返回工作簿。

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
我同意通常这就是想要的:如果您要检查该书是否已在另一个Excel实例中打开,则可以检查该书是否已打开(只读)
Charles Williams

这giveme出来的边界错误Workbooks(sFile)
motobói

您必须没有On Error Resume Next代码,或者您在VBE中的“工具”-“选项”下设置了“在所有错误上都出错”。
Dick Kusleika 2014年

这个版本对我来说更好,上面的版本似乎无法检测到以只读方式打开的工作簿...
Lowpar

我曾经使用过此功能,但最近这些天我在Excel 2017中遇到了很多自动化错误,当时相关的工作簿在运行宏之前已关闭。解决的办法是放弃On Error Resume Next(因为wbReturn没有 Nothing的,但包含一个错误),并写入真正的错误处理。请参阅:pastebin.com/u1LLgPa1
安德烈Chalella

19

如果打开,它将在工作簿集合中:

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

10
查尔斯,我已经想到了这种方法。这种方法的主要缺点是,如果在不同的Excel实例中打开工作簿,则始终会得到false值:)替代方法是添加代码以遍历所有Excel实例,然后使用您的代码。最终,我意识到自己正在编写更多的代码,因此我使用了另一种方法。Sid
Siddharth Rout 2012年

4
如果要检查是否在另一个Excel实例中打开了这本​​书(大概是因为您将无法保存或编辑该书),为什么不只在打开它后检查它是否为只读(如果是oBk.Readonly ...)
Charles Williams

11

我会这样:

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

作为sFileName,您必须提供文件的直接路径,例如:

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

5

如果要检查而不创建另一个Excel实例怎么办?

例如,我有一个Word宏(反复运行),需要从Excel电子表格中提取数据。如果电子表格已在现有Excel实例中打开,则我不希望创建新实例。

我在这里建立了一个很好的答案: http //www.dbforums.com/microsoft-access/1022678-how-check-wether-excel-workbook-already-open-not-search-value.html

感谢MikeTheBike和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

3

这一点比较容易理解:

Dim location As String
Dim wbk As Workbook

location = "c:\excel.xls"

Set wbk = Workbooks.Open(location)

'Check to see if file is already open
If wbk.ReadOnly Then
  ActiveWorkbook.Close
    MsgBox "Cannot update the excelsheet, someone currently using file. Please try again later."
    Exit Sub
End If

简短而甜蜜的:)
Linga

0

签出此功能

'********************************************************************************************************************************************************************************
'Function Name                     : IsWorkBookOpen(ByVal OWB As String)
'Function Description             : Function to check whether specified workbook is open
'Data Parameters                  : OWB:- Specify name or path to the workbook. eg: "Book1.xlsx" or "C:\Users\Kannan.S\Desktop\Book1.xlsm"

'********************************************************************************************************************************************************************************
Function IsWorkBookOpen(ByVal OWB As String) As Boolean
    IsWorkBookOpen = False
    Dim WB As Excel.Workbook
    Dim WBName As String
    Dim WBPath As String
    Err.Clear
    On Error Resume Next
    OWBArray = Split(OWB, Application.PathSeparator)
    Set WB = Application.Workbooks(OWBArray(UBound(OWBArray)))
    WBName = OWBArray(UBound(OWBArray))
    WBPath = WB.Path & Application.PathSeparator & WBName
    If Not WB Is Nothing Then
        If UBound(OWBArray) > 0 Then
            If LCase(WBPath) = LCase(OWB) Then IsWorkBookOpen = True
        Else
            IsWorkBookOpen = True
        End If
    End If
    Err.Clear
End Function

如果工作簿是在本地计算机上的当前实例中打开的,这将捕获-它不会捕获工作簿是在另一个本地实例中还是由其他位置的其他用户打开的。
brettdj

我认为WB.Path & "\" & WBNameWB.FullName
Winand

我还要在退出函数之前添加Set WB = Nothing
Mor Sagmon

现在仅使用文件名...
Bhanu Pratap '18

如何在子菜单中调用和使用此功能?我的意思是该函数的输入是字符串
FabioSpaghetti
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.