81

In VBA, I opened an MS Excel file named "myWork.XL" programmatically.

Now I would like a code that can tell me about its status - whether it is open or not. I.e. something like IsWorkBookOpened("myWork.XL) ?

0

7 Answers 7

104

Try this:

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 
Sign up to request clarification or add additional context in comments.

12 Comments

+1 I've used this method for sometime to check files on a newtwork drive accessible by other users. I think the code was originally posted on a msft site.
Personally I would feel very uncomfortable using primitive file IO to attempt a file read on an open Excel workbook when IMHO there are better alternatives: but maybe it works?
@Charles Williams: Yes, it may be primitive but it is still a good code with no disadvantages. At least none that I know of. :) Try it maybe you will like it?
I am sure it works, but what do you see as the disadvantages of the simpler more Excel-friendly code? (opening the workbook using Workbooks.Open and checking Workbook.Readonly)
@CharlesWilliams Fair point. Although in my case when I tried something similar the time overhead of actually opening a large model hosted on a overseas server was around 2-3 minutes. Which gave a "grrr" moment when it opened readonly, whereas Sid's function above gave an immediate response. FWIW Bob Phillips listed a similar function at vbaexpress , a more advanced version waiting for the book to be closed elsewhere from Chip Pearson
|
60

For my applications, I generally want to work with a workbook rather than just determine if it's open. For that case, I prefer to skip the Boolean function and just return the workbook.

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 

6 Comments

I agree thats usually what is wanted: if you want to check for the book being already open in another Excel instance you can check if its been opened readonly
This giveme out of bounds error on Workbooks(sFile)
You must not have On Error Resume Next in the code or you have Break on All Errors set under Tools - Options in the VBE.
This version works better for me, the version above seems to not detect workbooks open in read only...
I used to use this, but these days I've been getting a lot of Automation errors in Excel 2017 when the concerned workbook had been closed moments prior to running the macro. The solution was to forgo On Error Resume Next (because wbReturn was not Nothing, but contained an error) and write real error handling. See: pastebin.com/u1LLgPa1
|
23

If its open it will be in the Workbooks collection:

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 

2 Comments

Charles, I already thought of this method. The main drawback on this method is that if the workbook is opened in a different Excel instance then you will always get the value as false :) the alternative would be to add code to loop through all Excel instances and then use your code. Ultimately I realized that I was writing more code and hence I used an alternative approach. Sid
If you want to check for the book being open in another Excel instance (presumably because you won't be able to save it or edit it) why not just check if its Readonly after opening it (If oBk.Readonly ...)
15

I would go with this:

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 

as sFileName you have to provide direct path to the file for example:

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 

Comments

6

What if you want to check without creating another Excel instance?

For example, I have a Word macro (which is run repeatedly) that needs to extract data from an Excel spreadsheet. If the spreadsheet is already open in an existing Excel instance, I would prefer not to create a new instance.

I found a great answer here that I built on: http://www.dbforums.com/microsoft-access/1022678-how-check-wether-excel-workbook-already-open-not-search-value.html

Thanks to MikeTheBike and 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 

Comments

3

This one is a bit easier to understand:

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 

1 Comment

Short and sweet :)
2

Checkout this function

'******************************************************************************************************************************************************************************** '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\UserName\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 

5 Comments

This will capture if the workbook is open in the current instance on the local machine - it wont capture whether the workbook is open in another local instance, or by another user elsewhere.
I think WB.Path & "\" & WBName is WB.FullName
I'd also add Set WB = Nothing before exiting the function
now working with filename only...
How do I call and use this function in the sub? I mean the input of this function is String

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.