Reputation: 953
I have a series of Excel workbooks that depend on a separate workbook for some of their data. So, I need the data workbook to open automatically when a main workbook is opened. To keep things simple for my non-technical end users, I'm keeping the data workbook hidden. However, I need to be able to work on both workbooks simultaneously. So, I tried to set a flag (links_opened
) to specify whether the data workbook was already opened when the main workbook was opened. For the record, this is my first time messing with VBA, and I'm finding it really odd.
Here's the relevant portion of my code:
Option Explicit
Dim w As Workbooks
Dim links_opened As Boolean
links_opened = False ' This is where VBA reports an error
Function IsWorkBookOpen(FileName As String)
' Code here tests whether the workbook is already open
' Omitted for brevity
End Function
Private Sub Workbook_Open()
Dim fn As String
fn = ThisWorkbook.Path & "\Work Instructions\Links.xlsx"
If !IsWorkBookOpen(fn) Then
Set w = Workbooks
Application.ScreenUpdating = False
w.Open FileName:=fn, UpdateLinks:=False, ReadOnly:=True
ActiveWindow.Visible = False
ThisWorkbook.Activate
Application.ScreenUpdating = True
links_opened = True
End If
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If links_opened Then
w.Item(2).Saved = True
End If
End Sub
When I try to run this code, VBA says, indicating the line I marked above:
Compile error:
Invalid outside procedure
I understand that VBA for some reason doesn't allow variables to be set at the top level. But I don't know any other way to do this. It works fine in the other languages I use regularly.
How can I set a flag to track whether the data file has been opened by my code or manually? Or is there a better way to do this?
Upvotes: 1
Views: 609
Reputation: 71247
links_opened = False ' This is where VBA reports an error
That's an assignment operation, which is an executable statement. In VBA, non-declarative executable statements are illegal outside of a procedure scope. Besides, a Boolean
variable is automatically initialized to False
, so the assignment would be no-op anyway.
If !IsWorkBookOpen(fn)
This will be the next compile error; !
does exist in VBA, but it's either a type hint or a bang operator, neither of which have anything to do with negating a Boolean. You want to use the Not
keyword for this:
If Not IsWorkbookOpen(fn)
And then have the IsWorkbookOpen
function return a Boolean
:
Private Function IsWorkBookOpen(ByVal FileName As String) As Boolean
On Error Resume Next
Dim wb As Workbook
Set wb = Application.Workbooks(FileName) ' throws error 9 if non-existing
Err.Clear
On Error GoTo 0
IsWorkbookOpen = Not wb Is Nothing
End Function
Upvotes: 4