I am starting to write a code that will become applicable to multiple workbooks, but always uses the same reference workbook. The code will have many subs, and as I am trying to avoid to dim a variable to the reference workbook in every sub I would like to declare them Global.
First I had:
Global Locations As Excel.Workbook
Set Locations = Workbooks.Open("M:\My Documents\MSC Thesis\Italy\Merged\locXws.xlsx")
Which gave me:
"Compile error: Invalid outside procedure"
After some googling I found the following bit of code somewhere:
Public Const Locations As Excel.Workbook = "Workbooks.Open("M:\My Documents\MSC Thesis\Italy\Merged\locXws.xlsx")"
Which gave me:
"Compile error: Expected: type name"
Using:
Public Const Locations As Excel.Workbook = "Workbooks.Open('M:\My Documents\MSC Thesis\Italy\Merged\locXws.xlsx')"
(Single quotation marks within the Workbooks.Open statement) results as the same error as when using double quotation marks.
Who knows what I am doing wrong?
I also tried to declare the variables in the "ThisWorkbook", following this answer using:
Private Sub Workbook_Open()
Dim Locations As Excel.Workbook
Dim MergeBook As Excel.Workbook
Dim TotalRowsMerged As String
Locations = Workbooks.Open("M:\My Documents\MSC Thesis\Italy\Merged\locXws.xlsx")
MergeBook = Workbooks.Open("M:\My Documents\MSC Thesis\Italy\Merged\DURUM IT yields merged.xlsm")
TotalRowsMerged = MergeBook.Worksheets("Sheet1").UsedRange.Rows.Count
End Sub
But then it returns an
"Object Required"
within my module.
I now have this which works, but has the downside of having to copy the SET lines into every Sub, there has to be a better way to do this?
Global Locations As Workbook
Global MergeBook As Workbook
Global TotalRowsMerged As String
Sub Fill_CZ_Array()
Set Locations = Application.Workbooks("locXws.xlsx")
Set MergeBook = Application.Workbooks("DURUM IT yields merged.xlsm")
TotalRowsMerged = MergeBook.Worksheets("Sheet1").UsedRange.Rows.Count
What are Global Variables in Excel VBA? VBA global variables are variables declared before any macro in the module starts. When the variables are declared using either “Public” or “Global,” it becomes a global variable. Sub Procedure Variables Cannot Use Anywhere.
Global variables, as the name implies, are variables that are accessible globally, or everywhere throughout the program. Once declared, they remain in memory throughout the runtime of the program. This means that they can be changed by any function at any point and may affect the program as a whole.
I think the most universal way for workbook global variable would be creating a module with a Public Property Get
procedure. You can refer to it without calling any code first, and you don't have to worry if the file is open or not.
Here is the sample module code for one of the variables:
Private wLocations As Workbook
Public Property Get Locations() As Workbook
Const sPath As String = "M:\My Documents\MSC Thesis\Italy\Merged\locXws.xlsx"
Dim sFile As String
If wLocations Is Nothing Then
'extract file name from full path
sFile = Dir(sPath)
On Error Resume Next
'check if the file is already open
Set wLocations = Workbooks(sFile)
If wLocations Is Nothing Then
Set wLocations = Workbooks.Open(sPath)
End If
On Error GoTo 0
End If
Set Locations = wLocations
End Property
You can use it anywhere in the code as a global variable:
Sub Test()
Debug.Print Locations.Worksheets.Count
End Sub
Your question implies that you want a global workbook constant, not a variable. Because VBA doesn't allow objects to be initialised outside of a procedure, you can't have an object constant. The best you can do is have a public workbook variable that's initialised in an event.
You can declare a global variable, but you can't execute code to assign a value outside of a procedure:
Public myBook As Excel.Workbook
Sub AssignWorkbook()
Set myBook = Workbooks.Open("C:\SomeBook.xlsx") '// <~~ valid, inside sub
End Sub
Sub TestItWorked()
MsgBox myBook.Name
End Sub
So in a normal module you could have:
Public myBook As Excel.Workbook
And in your Workbook_Open()
event:
Private Sub Workbook_Open()
Set myBook = Workbooks.Open("C:\SomeOtherBook.xlsx")
End Sub
Then you can use myBook
elsewhere in your code without having to re-assign it.
It might be worth having a look at Chip Pearson's article about variable scope in VBA here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With