In this Article
- The Workbook Object
- Workbook Index Number
- Activate Workbook, ActiveWorkbook, and ThisWorkbook
- Activate Workbook
- ActiveWorkbook
- ThisWorkbook
- Open Workbook
- Open and Assign to Variable
- Open File Dialog
- Create New (Add) Workbook
- Add New Workbook to Variable
- Close Workbook
- Close & Save
- Close without Save
- Workbook Save As
- Other Workbook VBA Examples
- Workbook Name
- Protect Workbook
- Loop Through all Open Workbooks
- Workbook Activate Event
This guide will introduce you working with the Workbook Object in VBA.
The Workbook Object
First, in order to interact with workbooks in VBA, you must understand the Workbook Object.
With the workbook object, you can reference workbooks by their name like this:
Workbooks("Book2.xlsm").Activate
However, this code will only work if the workbook is open. If the workbook is closed, you will need to provide the full workbook path:
Workbooks.Open ("C:UsersStevePC2Downloadsbook2.xlsm")
Instead of typing out the full path, if your desired workbook is in the same directory as the workbook where your code is stored, you could use this line code to open the workbook:
Workbooks.Open (ThisWorkbook.Path & "book2.xlsm")
This makes use of the ThisWorkbook object that we will discuss in the next section.
Workbook Index Number
Last, you can reference workbooks by their “Index Number”. The index number of a workbook corresponds to the order that the workbook was opened (technically its the workbook’s position in the Workbooks Collection).
Workbooks(1).Activate
This is useful if you want to do something like close the first (or last) opened workbook.
Activate Workbook, ActiveWorkbook, and ThisWorkbook
If a workbook is NOT ACTIVE, you can access the Workbook’s objects like this:
Workbooks("Book2.xlsm").Sheets("Sheet1").Range("A1").value = 1
However, if the workbook is Active, you can omit the workbook object:
Sheets("Sheet1").Range("A1").value = 1
And if you want to interact with the workbook’s active sheet, you can also ommit the sheets object:
Range("A1").value = 1
Activate Workbook
To activate a workbook, use the Activate Method.
Workbooks("Book2.xlsm").Activate
Now you can interact with Book2’s object’s without explicitly stating the workbook name.
ActiveWorkbook
The ActiveWorkbook object always refer to the active workbook. This is useful if you’d like to assign the ActiveWorkbook to a variable to use later.
Dim wb As Workbook
Set wb = ActiveWorkbook
ThisWorkbook
The ThisWorkbook object always refers to the workbook where the running code is stored. To activate ThisWorkbook, use this line of code:
ThisWorkbook.Activate
VBA Coding Made Easy
Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!
Learn More
Open Workbook
To open a workbook, use the Open Method:
Workbooks.Open ("C:UsersStevePC2Downloadsbook2.xlsm")
The newly opened workbook will always become the ActiveWorkbook, allowing you to easily interact with it.
ActiveWorkbook.Save
The Open Method has several other arguments, allowing you to open read-only, open a password-protected workbook, and more. It’s covered here in our article about Opening / Closing Workbooks.
Open and Assign to Variable
You can also open a workbook and assign it to a variable at the same time:
Dim wb As Workbook
Set wb = Workbooks.Open("C:UsersStevePC2Downloadsbook2.xlsm")
Open File Dialog
You can also trigger the Open File Dialog Box like this:
Sub OpenWorkbook ()
Dim strFile As String
strFile = Application.GetOpenFilename()
Workbooks.Open (strFile)
End Sub
VBA Programming | Code Generator does work for you!
Create New (Add) Workbook
This line of code will create a new workbook:
Workbooks.Add
The new workbook now becomes the ActiveWorkbook, allowing you to interact with it (ex. save the new workbook).
Add New Workbook to Variable
You can also add a new workbook directly to a variable:
Dim wb As Workbook
Set wb = Workbooks.Add
Close Workbook
Close & Save
To close a workbook with saving, use the Close Method with SaveChanges set to TRUE:
ActiveWorkbook.Close SaveChanges:=True
Close without Save
To close without saving, set SaveChanges equal to FALSE:
ActiveWorkbook.Close SaveChanges:=False
AutoMacro | Ultimate VBA Add-in | Click for Free Trial!
Workbook Save As
The SaveAs Method is used to save a workbook as.
To save a workbook with a new name, in the same directory, you can imply use this:
ActiveWorkbook.SaveAs "new"
where “new” is the new file name.
To save a workbook in a new directory with a specific file extension, simply specify the new directory and file name:
ActiveWorkbook.SaveAs "C:UsersStevePC2Downloadsnew.xlsm"
Other Workbook VBA Examples
Workbook Name
To get the name of a workbook:
MsgBox ActiveWorkbook.Name
Protect Workbook
To protect the workbook structure from editing, you can use the Protect Method (password optional):
Workbooks("book1.xlsm").Protect "password"
To unprotect a workbook use the UnProtect Method:
Workbooks("book1.xlsm").Unprotect "password"
AutoMacro | Ultimate VBA Add-in | Click for Free Trial!
Loop Through all Open Workbooks
To loop through all open workbooks:
Sub LoopThroughWBs()
Dim wb As Workbook
For Each wb In Workbooks
MsgBox wb.Name
Next wb
End Sub
Workbook Activate Event
You can run some code whenever a specific workbook is opened with the Workbook Open Event.
Place this procedure your workbook’s ThisWorkbook Module:
Private Sub Workbook_Open()
Sheets("sheet1").Activate
End Sub
This procedure will activate Sheet1 every time the workbook is opened.
“We are drowning in information but starved for knowledge.” – John Naisbitt
This post provides a complete guide to using the VBA Workbook.
If you want to use VBA to Open a Workbook then check out Open Workbook
If you want to use VBA to create a new workbook go to Create New Workbook
For all other VBA Workbook tasks, check out the quick guide below.
A Quick Guide to the VBA Workbook
The following table provides a quick how-to guide on the main VBA workbook tasks
Task | How to |
---|---|
Access open workbook using name | Workbooks(«Example.xlsx») |
Access open workbook (the one opened first) | Workbooks(1) |
Access open workbook (the one opened last) | Workbooks(Workbooks.Count) |
Access the active workbook | ActiveWorkbook |
Access workbook containing VBA code | ThisWorkbook |
Declare a workbook variable | Dim wk As Workbook |
Assign a workbook variable | Set wk = Workbooks(«Example.xlsx») Set wk = ThisWorkbook Set wk = Workbooks(1) |
Activate workbook | wk.Activate |
Close workbook without saving | wk.Close SaveChanges:=False |
Close workbook and save | wk.Close SaveChanges:=True |
Create new workbook | Set wk = Workbooks.Add |
Open workbook | Set wk =Workbooks.Open («C:DocsExample.xlsx») |
Open workbook as read only | Set wk = Workbooks.Open («C:DocsExample.xlsx», ReadOnly:=True) |
Check Workbook exists | If Dir(«C:Docsbook1.xlsx») = «» Then MsgBox «File does not exist.» EndIf |
Check Workbook is open | See Check Workbook Open section below |
List all open workbooks | For Each wk In Application.Workbooks Debug.Print wk.FullName Next wk |
Open workbook with the File Dialog | See File Dialog section below function below |
Save workbook | wk.Save |
Save workbook copy | wk.SaveCopyAs «C:Copy.xlsm» |
Copy workbook if closed | FileCopy «C:file1.xlsx»,«C:Copy.xlsx» |
SaveAs workbook | wk.SaveAs «Backup.xlsx» |
VBA Workbook Webinar
If you are a member of the website, click on the image below to access the webinar.
(Note: Website members have access to the full webinar archive.)
Getting Started with the VBA Workbook
We can access any open workbook using the code Workbooks(“Example.xlsm“). Simply replace Example.xlsm with the name of the workbook you wish to use.
The following example shows you how to write to a cell on a worksheet. You will notice we had to specify the workbook, worksheet and range of cells.
' https://excelmacromastery.com/ Public Sub WriteToA1() ' Writes 100 to cell A1 of worksheet "Sheet1" in MyVBA.xlsm Workbooks("MyVBA.xlsm").Worksheets("Sheet1").Range("A1") = 100 End Sub
This example may look a little be confusing to a new user but it is actually quite simple.
The first part up to the decimal point is the Workbook, the second part is the Worksheet and the third is the Range. Here are some more examples of writing to a cell
' https://excelmacromastery.com/ Public Sub WriteToMulti() ' Writes 100 to cell A1 of worksheet "Sheet1" in MyVBA.xlsm Workbooks("MyVBA.xlsm").Worksheets("Sheet1").Range("A1") = 100 ' Writes "John" to cell B1 of worksheet "Sheet1" in MyVBA.xlsm Workbooks("MyVBA.xlsm").Worksheets("Sheet1").Range("B1") = "John" ' Writes 100 to cell A1 of worksheet "Accounts" in MyVBA.xlsm Workbooks("MyVBA.xlsm").Worksheets("Accounts").Range("A1") = 100 ' Writes the date to cell D3 of worksheet "Sheet2" in Book.xlsc Workbooks("Book.xlsx").Worksheets("Sheet2").Range("D3") = "112016" End Sub
You can see the simple pattern here. You can write to any cell in any worksheet from any workbook. It is just a matter of changing the workbook name, worksheet name and the range to suit your needs.
Take a look at the workbook part
Workbooks("Example.xlsx")
The Workbooks keyword refers to a collection of all open workbooks. Supplying the workbook name to the collection gives us access to that workbook. When we have the object we can use it to perform tasks with the workbook.
Troubleshooting the Workbooks Collection
When you use the Workbooks collection to access a workbook, you may get the error message:
Run-time Error 9: Subscript out of Range.
This means that VBA cannot find the workbook you passed as a parameter.
This can happen for the following reasons
- The workbook is currently closed.
- You spelled the name wrong.
- You created e new workbook (e.g. Book1) and tried to access it using Workbooks(“Book1.xlsx”). It’s name is not Book1.xlsx until it is saved for the first time.
- (Excel 2007/2010 only) If you are running two instances of Excel then Workbooks() only refers to to the workbooks open in the current Excel instance.
- You passed a number as Index and it is greater than the number of workbooks open e.g. you used Workbooks(3) and only two workbooks are open.
If you cannot resolve the error then use either of the functions in the section Finding all open Workbooks. These will print the names of all open workbooks to the Immediate Window(Ctrl + G).
Examples of Using the VBA Workbook
The following examples show what you can do with the workbook.
Note: To try this example create two open workbooks called Test1.xlsx and Test2.xlsx.
' https://excelmacromastery.com/ Public Sub WorkbookProperties() ' Prints the number of open workbooks Debug.Print Workbooks.Count ' Prints the full workbook name Debug.Print Workbooks("Test1.xlsx").FullName ' Displays the full workbook name in a message dialog MsgBox Workbooks("Test1.xlsx").FullName ' Prints the number of worksheets in Test2.xlsx Debug.Print Workbooks("Test2.xlsx").Worksheets.Count ' Prints the name of currently active sheet of Test2.xlsx Debug.Print Workbooks("Test2.xlsx").ActiveSheet.Name ' Closes workbook called Test1.xlsx Workbooks("Test1.xlsx").Close ' Closes workbook Test2.xlsx and saves changes Workbooks("Test2.xlsx").Close SaveChanges:=True End Sub
Note: In the code examples I use Debug.Print a lot. This function prints values to the Immediate Window. To view this window select View->Immediate Window from the menu( Shortcut is Ctrl + G)
Accessing the VBA Workbook by Index
You can also use an Index number with Workbooks(). The index refers to the order the Workbook was open or created.
Workbooks(1) refers to the workbook that was opened first. Workbooks(2) refers to the workbook that was opened second and so on.
' First workbook that was opened Debug.Print Workbooks(1).Name ' Third workbook that was opened Debug.Print Workbooks(3).Name ' The last workbook that was opened Debug.Print Workbooks(Workbooks.Count).Name
In this example, we used Workbooks.Count. This is the number of workbooks that are currently in the Workbooks collection. That is, the number of workbooks currently open. So using it as the Index gives us the last workbook that was opened
Using the index is not really useful unless you really need to know the order. For this reason, you should avoid using it. You should use the workbook name with Workbooks() instead.
Finding all Open Workbooks
Sometimes you may want to access all the workbooks that are open. In other words, all the items in the Workbooks() collection.
You can do this using the For Each loop.
' https://excelmacromastery.com/ Public Sub PrintWrkFileName() ' Prints out the full filename of all open workbooks Dim wrk As Workbook For Each wrk In Workbooks Debug.Print wrk.FullName Next wrk End Sub
You can also use the standard For loop to access all the open workbooks
' https://excelmacromastery.com/ Public Sub PrintWrkFileNameIdx() ' Prints out the full filename of all open workbooks Dim i As Long For i = 1 To Workbooks.Count Debug.Print Workbooks(i).FullName Next i End Sub
For accessing workbooks, either of these Loops is fine. The standard For loop is useful if you want to use a different order or you need to use a counter.
Note: Both examples read in the order of the first opened to the last opened. If you want to read in reverse order(last to first) you can do this
' https://excelmacromastery.com/ Public Sub PrintWrkFileNameIdxRev() ' Prints out the full filename of all open workbooks ' in reverse order. Dim i As Long For i = Workbooks.Count To 1 Step -1 Debug.Print Workbooks(i).FullName Next i End Sub
Open Workbook
So far we have dealt with workbooks that are already open. Of course, having to manually open a workbook before running a Macro, defeats the purpose of automating tasks. The Open Workbook task should be performed by VBA.
The following VBA code opens the workbook “Book1.xlsm” in the “C:Docs” folder
' https://excelmacromastery.com/ Public Sub OpenWrk() ' Open the workbook and print the number of sheets it contains Workbooks.Open ("C:DocsBook1.xlsm") Debug.Print Workbooks("Book1.xlsm").Worksheets.Count ' Close the workbook without saving Workbooks("Book1.xlsm").Close saveChanges:=False End Sub
It is a good idea to check a workbook actually exists before you try to open it. This will prevent you getting errors. The Dir function allows you to easily do this .
' https://excelmacromastery.com/ Public Sub OpenWrkDir() If Dir("C:DocsBook1.xlsm") = "" Then ' File does not exist - inform user MsgBox "Could not open the workbook. Please check it exists" Else ' open workbook and do something with it Workbooks.Open("C:DocsBook1.xlsm") End If End Sub
Check For Open Workbook
If you are opening a workbook as Read-Only, it doesn’t matter if it is already open. However, if you’re going to update data in a workbook then it is a good idea to check if it is already open.
The function below can be used to check if the workbook is currently open. If not, then it will open the workbook. In either case you will end up with the workbook opened.
(The code below is taken from this StackOverFlow entry.)
' https://excelmacromastery.com/ Function GetWorkbook(ByVal sFullFilename As String) As Workbook Dim sFilename As String sFilename = Dir(sFullFilename) On Error Resume Next Dim wk As Workbook Set wk = Workbooks(sFilename) If wk Is Nothing Then Set wk = Workbooks.Open(sFullFilename) End If On Error Goto 0 Set GetWorkbook = wk End Function
You can use this function like this
' https://excelmacromastery.com/ Sub ExampleOpenWorkbook() Dim sFilename As String sFilename = "C:DocsBook2.xlsx" Dim wk As Workbook Set wk = GetWorkbook(sFilename) End Sub
This code is fine is most situations. However, if the workbook could be currently open in read-only mode or could be currently opened by another user then you may want to use a slightly different approach.
An easy way to deal this with this scenario is to insist that the file must be closed for the application to run successfully. You can use the function below to simply check is the file already open and if so inform the user that it must be closed first.
(The code below is also taken from this StackOverFlow entry)
' https://excelmacromastery.com/ ' Function to check if workbook is already open Function IsWorkBookOpen(strBookName As String) As Boolean Dim oBk As Workbook On Error Resume Next Set oBk = Workbooks(strBookName) On Error GoTo 0 If Not oBk Is Nothing Then IsWorkBookOpen = True End If End Function
An example of using this function is shown below. In this case, if the workbook is already open then you inform the user that is must be closed for the macro to proceed.
' https://excelmacromastery.com/ Sub ExampleUse() Dim sFilename As String sFilename = "C:tempwritedata.xlsx" If IsWorkBookOpen(Dir(sFilename)) = True Then MsgBox "File is already open. Please close file and run macro again." Exit Sub End If ' Write to workbook here End Sub
If you need to check if the workbook is open in another instance of Excel you can use the ReadOnly attribute of the workbook. It will be set to true if it is open in another instance.
Close Workbook
To Close a Workbook in Excel VBA is very simple. You simply call the Close method of the workbook.
wk.Close
Normally when you close a workbook in VBA, you don’t want to see messages from Excel asking if you want to save the file.
You can specify whether to save the workbook or not and then the Excel messages will not appear.
' Don't save changes wk.Close SaveChanges:= False ' Do save changes wk.Close SaveChanges:= True
Obviously, you cannot save changes to a workbook that is currently open as read-only.
Save Workbook
We have just seen that you can save a workbook when you close it. If you want to save it any other stage you can simply use the Save method
wk.Save
You can also use the SaveAs method
wk.SaveAs "C:Backupsaccounts.xlsx"
The Workbook SaveAs method comes with twelve parameters which allow you to add a password, set the file as read-only and so on. You can see the details here.
You can also use VBA to save the workbook as a copy using SaveCopyAs
wk.SaveCopyAs "C:DocsCopy.xlsm"
Copy Workbook
If the workbook is open you can use the two methods in the above section to create a copy i.e. SaveAs and SaveCopyAs.
If you want to copy a workbook without opening it then you can use FileCopy as the following example demonstrates
Public Sub CopyWorkbook() FileCopy "C:DocsDocs.xlsm", "C:DocsExample_Copy.xlsm" End Sub
Using the File Dialog To Open a Workbook
The previous section shows you how to open a workbook with a given name. Sometimes you may want the user to select the workbook. You can easily use the Windows File Dialog shown here.
The Windows File Dialog
The FileDialog is configurable and you can use it to
- Select a file.
- Select a folder.
- Open a file.
- “Save As” a file.
If you just want the user to select the file you can use the GetOpenFilename function.
The following function opens a workbook using the File Dialog. The function returns the full file name if a file was selected. If the user cancels it displays a message and returns an empty string.
' https://excelmacromastery.com/ Public Function UserSelectWorkbook() As String On Error Goto ErrorHandler Dim sWorkbookName As String Dim FD As FileDialog Set FD = Application.FileDialog(msoFileDialogFilePicker) ' Open the file dialog With FD ' Set Dialog Title .Title = "Please Select File" ' Add filter .Filters.Add "Excel Files", "*.xls;*.xlsx;*.xlsm" ' Allow selection of one file only .AllowMultiSelect = False ' Display dialog .Show If .SelectedItems.Count > 0 Then UserSelectWorkbook = .SelectedItems(1) Else MsgBox "Selecting a file has been cancelled. " UserSelectWorkbook = "" End If End With ' Clean up Set FD = Nothing Done: Exit Function ErrorHandler: MsgBox "Error: " + Err.Description End Function
When you call this function you have to check for the user cancelling the dialog. The following example shows you how to easily call the UserSelectWorkbook function and handle the case of the user cancelling
' https://excelmacromastery.com/ Public Sub TestUserSelect() Dim userBook As Workbook, sFilename As String ' Call the UserSelectworkbook function sFilename = UserSelectWorkbook() ' If the filename returns is blank the user cancelled If sFilename <> "" Then ' Open workbook and do something with it Set userBook = Workbooks.Open(sFilename) End If End Sub
You can customise the dialog by changing the Title, Filters and AllowMultiSelect in the UserSelectWorkbook function.
Using ThisWorkbook
There is an easier way to access the current workbook than using Workbooks(). You can use the keyword ThisWorkbook. It refers to the current workbook i.e. the workbook that contains the VBA code.
If our code is in a workbook call MyVBA.xlsm then ThisWorkbook and Workbooks(“MyVBA.xlsm”) refer to the same workbook.
Using ThisWorkbook is more useful than using Workbooks(). With ThisWorkbook we do not need to worry about the name of the file. This gives us two advantages:
- Changing the file name will not affect the code
- Copying the code to another workbook will not require a code change
These may seem like very small advantages. The reality is your filenames will change all the time. Using ThisWorkbook means your code will still work fine.
The following example shows two lines of code. One using ThisWorkbook and one using Workbooks(). The one using Workbooks will no longer work if the name of MyVBA.xlsm changes.
' https://excelmacromastery.com/ Public Sub WriteToCellUsingThis() ' Both lines do the same thing. Debug.Print ThisWorkbook.FullName Debug.Print Workbooks("MyVBA.xlsm").FullName End Sub
Using the ActiveWorkbook
ActiveWorkbook refers to the workbook that is currently active. This is the one that the user last clicked on.
This can seem useful at first. The problem is that any workbook can become active by a simple mouse click. This means you could easily write data to the wrong workbook.
Using ActiveWorkbook also makes the code hard to read. It may not be obvious from the code which workbook should be the active one.
I hope I made it clear that you should avoid using ActiveWorkbook unless you really have to. If you must then be very careful.
Examples of the Accessing the Workbook
We’ve looked at all the ways of accessing a workbook. The following code shows examples of these ways
' https://excelmacromastery.com/ Public Sub WorkbooksUse() ' This is a workbook that is already open and called MyVBA.xlsm Debug.Print Workbooks("MyVBA.xlsm").FullName ' The workbook that contains this code Debug.Print ThisWorkbook.FullName ' The open workbook that was opened first Debug.Print Workbooks(1).FullName ' The open workbook that was opened last Debug.Print Workbooks(Workbooks.Count).FullName ' The workbook that is the currently active one Debug.Print ActiveWorkbook.FullName ' No workbook mentioned - the active one will be used Debug.Print Worksheets("Sheet1").Name ' A closed workbook called Book1.xlsm in folder C:Docs Workbooks.Open ("C:DocsBook1.xlsm") Debug.Print Workbooks("Book1.xlsm").FullName Workbooks("Book1.xlsm").Close End Sub
Declaring a VBA Workbook variable
The reason for declaring a workbook variable is to make your code easier to read and understand. It is easier to see the advantage of using an example
' https://excelmacromastery.com/ Public Sub OpenWrkObjects() Dim wrk As Workbook Set wrk = Workbooks.Open("C:DocsBook1.xlsm") ' Print number of sheets in each book Debug.Print wrk.Worksheets.Count Debug.Print wrk.Name wrk.Close End Sub
You can set a workbook variable with any of the access methods we have seen.
The following shows you the same code without a workbook variable
' https://excelmacromastery.com/ Public Sub OpenWrkNoObjects() Workbooks.Open ("C:DocsBook1.xlsm") Debug.Print Workbooks("Book2.xlsm").Worksheets.Count Debug.Print Workbooks("Book2.xlsm").Name Workbooks("Book2.xlsm").Close End Sub
In these examples the difference is not major. However, when you have a lot of code, using a variable is useful particularly for worksheet and ranges where the names tend to be long e.g. thisWorkbook.Worksheets(“Sheet1”).Range(“A1”).
You can name the workbook variable to be something like wrkRead or wrkWrite. Then at a glance you can see what this workbook is being used for.
Create New Workbook
To create a new workbook you use the Workbooks Add function. This function creates a new blank workbook. It is the same as selecting New Workbook from the Excel File menu.
When you create a new workbook you will generally want to save it. The following code shows you how to do this.
' https://excelmacromastery.com/ Public Sub AddWordbook() Dim wrk As Workbook Set wrk = Workbooks.Add ' Save as xlsx. This is the default. wrk.SaveAs "C:TempExample.xlsx" ' Save as a Macro enabled workbook wrk.SaveAs "C:TempExample.xlsm", xlOpenXMLWorkbookMacroEnabled End Sub
When you create a new workbook it normally contains three sheets. This is determined by the property Application.SheetsInNewWorkbook.
If you want to have a different number of sheets in a new workbook then you change this property before you create the new workbook. The following example shows you how to create a new workbook with seven sheets.
' https://excelmacromastery.com/ Public Sub AddWordbookMultiSheets() ' Store SheetsInNewWorkbook value so we can reset it later Dim sheetCnt As Long sheetCnt = Application.SheetsInNewWorkbook ' Set sheets in a new workbook to be 7 Application.SheetsInNewWorkbook = 7 ' Workbook will be created with 7 sheets Dim wrk As Workbook Set wrk = Workbooks.Add ' Display sheet count Debug.Print "number of sheets: " & CStr(wrk.Worksheets.Count) ' Reset to original value Application.SheetsInNewWorkbook = sheetCnt End Sub
The With keyword and the Workbook
The With keyword makes reading and writing VBA code easier. Using With means you only need to mention the item once. With is used with Objects. These are items such as Workbooks, Worksheets and Ranges.
The following example has two Subs. The first is similar to code we have seen so far. The second uses the With keyword. You can see the code is much clearer in the second Sub. The keywords End With mark the finish of a section code using With.
' https://excelmacromastery.com/ ' Not using the With keyword Public Sub NoUsingWith() Debug.Print Workbooks("Book2.xlsm").Worksheets.Count Debug.Print Workbooks("Book2.xlsm").Name Debug.Print Workbooks("Book2.xlsm").Worksheets(1).Range("A1") Workbooks("Book2.xlsm").Close End Sub ' Using With makes the code easier to read Public Sub UsingWith() With Workbooks("Book2.xlsm") Debug.Print .Worksheets.Count Debug.Print .Name Debug.Print .Worksheets(1).Range("A1") .Close End With End Sub
Summary
The following is a brief summary of the main points of this post
- To get the workbook containing the code use ThisWorkbook.
- To get any open workbook use Workbooks(“Example.xlsx”).
- To open a workbook use Set Wrk = Workbooks.Open(“C:FolderExample.xlsx”).
- Allow the user to select a file using the UserSelectWorkbook function provided above.
- To create a copy of an open workbook use the SaveAs property with a filename.
- To create a copy of a workbook without opening use the FileCopy function.
- To make your code easier to read and write use the With keyword.
- Another way to make your code clear is to use a Workbook variables
- To run through all open Workbooks use For Each wk in Workbooks where wk is a workbook variable.
- Try to avoid using ActiveWorkbook and Workbooks(Index) as their reference to a workbook is temporary.
You can see a quick guide to the topic at the top of this post
Conclusion
This was an in-depth post about a very important element of VBA – the Workbook. I hope you found it beneficial. Excel is great at providing many ways to perform similar actions but the downside is it can lead to confusion at times.
To get the most benefit from this post I recommend you try out the examples. Create some workbooks and play around with the code. Make changes to the code and see how the changes affect the outcome. Practice is the best way to learn VBA.
If you found this post useful then feel free to share it with others using the bar at the side.
What’s Next?
Free VBA Tutorial If you are new to VBA or you want to sharpen your existing VBA skills then why not try out the The Ultimate VBA Tutorial.
Related Training: Get full access to the Excel VBA training webinars and all the tutorials.
(NOTE: Planning to build or manage a VBA Application? Learn how to build 10 Excel VBA applications from scratch.)
Often when working with Excel files we want to introduce certain features which are supposed to be fired in the circumstance of certain events. Say we have a Excel worksheet that is time-sensitive, that needs to be updated based on some web-resource or database. Should we hope that the user will leverage our Refresh button. Fortunately Microsoft introduced Excel Workbook Events – events which are fired in very specific situation in reaction to user interaction. This
Introduction
Excel VBA Events such as the VBA Open Workbook event are very useful in organizing your Workbooks functionality and ease of use. Although VBA events have many advantages, be aware of one significant setback – whenever a VBA Event is fired VBA Code is executed! So? Isn’t that the point? Of course but that has some repercussions – as Excel (and other MS Office Applications) delete the Undo/Redo stack of events once VBA code is executed. This means that whenever a VBA Macro is executed the user will not be able to undo any previous changes to the Workbook using i.e. CTRL+Z.
Therefore be sure to limit your VBA Event handlers to the bare minimum as you may find users annoyed instead of impressed with your Excel GUI.
The VBA Open Workbook and other Workbook events are fired whenever an event in scope of the entire Workbook happens. This can include Activating, Saving, Opening or Closing the Workbook.
Adding Workbook Events
Let’s learn how to add Workbook events:
Select the Workbook module
Select the Workbook module from your Project – VBAProject window as shown below.
Select Workbook from the Object list
To view all available events associated with your Workbook select the Workbook value from the Object list in the Code window. This should automatically include the VBA Open Workbook event into your Workbook module.
Select the desired event from the available list of events
By selecting the Workbook Object from the previous list you will now have access to the available list of events associated with your Workbook. Simply select the desired VBA event from the list and the code will be added automatically.
List of Workbook Events (VBA Open Workbook etc.)
Below is a complete list of VBA Workbook Events available from Excel:
Event Name | Descriptions |
---|---|
ActivateEvent | Workbook is activated |
AddinInstall | Workbook is installed as an add-in |
AddinUninstall | Workbook is uninstalled as an add-in |
AfterSave | Workbook is saved |
AfterXmlExport | Excel saves or exports data from the workbook to an XML data file |
AfterXmlImport | An existing XML data connection is refreshed or after new XML data is imported into the workbook |
BeforeClose | Before the workbook closes. If the workbook has been changed, this event occurs before the user is asked to save changes |
BeforePrint | Before the workbook (or anything in it) is printed |
BeforeSave | Before the workbook is saved |
BeforeXmlExport | Before Excel saves or exports data from the workbook to an XML data file |
BeforeXmlImport | Before an existing XML data connection is refreshed or before new XML data is imported into the workbook |
Deactivate | Workbook is deactivated |
New | New workbook is created |
NewChart | New chart is created in the workbook |
NewSheet | New sheet is created in the workbook |
Open | Workbook is opened |
PivotTableCloseConnection | After a PivotTable report closes the connection to its data source |
PivotTableOpenConnection | After a PivotTable report opens the connection to its data source |
RowsetComplete | The user navigates through the recordset or invokes the rowset action on an OLAP PivotTable |
SheetActivate | When any sheet is activated. |
SheetBeforeDoubleClick | When any worksheet is double-clicked, before the default double-click action. |
SheetBeforeRightClick | When any worksheet is right-clicked, before the default right-click action. |
SheetCalculate | After any worksheet is recalculated or after any changed data is plotted on a chart |
SheetChange | When cells in any worksheet are changed by the user or by an external link. |
SheetDeactivate | When any sheet is deactivated |
SheetFollowHyperlink | When you click any hyperlink in a workbook |
SheetPivotTableAfterValueChange | After a cell or range of cells inside a PivotTable are edited or recalculated (for cells that contain formulas) |
SheetPivotTableBeforeAllocateChanges | Before changes are applied to a PivotTable |
SheetPivotTableBeforeCommitChanges | Before changes are committed against the OLAP data source for a PivotTable |
SheetPivotTableBeforeDiscardChanges | Before changes to a PivotTable are discarded |
SheetPivotTableChangeSync | After changes to a PivotTable |
SheetPivotTableUpdate | After the sheet of a PivotTable report has been updated |
SheetSelectionChange | When the selection changes on any worksheet. Does not occur if the selection is on a chart sheet |
Shutdown | When the workbook host item shuts down |
Startup | After the workbook is running and all the initialization code in the assembly has been run |
SyncEvent | When the local copy of a worksheet that is part of a Document Workspace is synchronized with the copy on the server |
WindowActivate | When any workbook window is activated |
WindowDeactivate | When any workbook window is deactivated |
WindowResize | When any workbook window is resized |
Worksheet VBA Events
Adding Worksheet Events
The VBA Open Workbook and other Workbook events are fired whenever an event in scope of the entire Workbook happens. This can include Activating, Saving, Opening or Closing the Workbook.
Adding Workbook Events
Let’s learn how to add Worksheet events:
Select a Worksheet module
Select the Worksheet module from your Project – VBAProject window as shown below. Be sure to select the Worksheet in which you want to add the event handler!:
Select Worksheet from the Object list
To view all available events associated with your Worksheet select the Worksheet value from the Object list in the Code window. This should automatically include the VBA SelectedChange Worksheet event into your Worksheet module.
Select the desired event from the available list of events
By selecting the Worksheet Object from the previous list you will now have access to the available list of events associated with your Worksheet. Simply select the desired VBA event from the list and the code will be added automatically.
List of Worksheet Events
Event Name | Descriptions |
---|---|
Activate | When a workbook, worksheet, chart sheet, or embedded chart is activated. |
BeforeDelete | |
BeforeDoubleClick | When a worksheet is double-clicked, before the default double-click action. |
BeforeRightClick | When a worksheet is right-clicked, before the default right-click action. |
Calculate | After the worksheet is recalculated, for the Worksheet object. |
Change | When cells on the worksheet are changed by the user or by an external link. |
Deactivate | When the chart, worksheet, or workbook is deactivated. |
FollowHyperlink | When you click any hyperlink on a worksheet. For application- and workbook-level events, see theSheetFollowHyperlink event and SheetFollowHyperlink event. |
LensGalleryRenderComplete | When a callout gallery’s icons (dynamic & static) have completed rendering. |
PivotTableAfterValueChange | After a cell or range of cells inside a PivotTable are edited or recalculated (for cells that contain formulas). |
PivotTableBeforeAllocateChanges | Before changes are applied to a PivotTable. |
PivotTableBeforeCommitChanges | Before changes are committed against the OLAP data source for a PivotTable. |
PivotTableBeforeDiscardChanges | Before changes to a PivotTable are discarded. |
PivotTableChangeSync | After changes to a PivotTable. |
PivotTableUpdate | After a PivotTable report is updated on a worksheet. |
SelectionChange | When the selection changes on a worksheet. |
TableUpdate | After a Query table connected to the Data Model is updated on a worksheet. |
Chart VBA Events
Adding Chart Events
Let’s learn how to add Chart events:
Select a Chart module
Select the Chart module from your Project – VBAProject window as shown below. Be sure to select the Chart to which you want to add the event handler!:
Select Chart from the Object list
To view all available events associated with your Chart select the Chart value from the Object list in the Code window. This should automatically include the VBA Activate Chart event into your Chart module.
Select the desired event from the available list of events
By selecting the Chart Object from the previous list you will now have access to the available list of events associated with your Chaet. Simply select the desired VBA event from the list and the code will be added automatically.
List of Chart Events
Event Name | Descriptions |
---|---|
Activate | chart sheet, or embedded chart is activated. |
BeforeDoubleClick | when a chart element is double-clicked, before the default double-click action. |
BeforeRightClick | when a chart element is right-clicked, before the default right-click action. |
Calculate | after the chart plots new or changed data, for the Chart object. |
Deactivate | when the chart, worksheet, or workbook is deactivated. |
MouseDown | when a mouse button is pressed while the pointer is over a chart. |
MouseMove | when the position of the mouse pointer changes over a chart. |
MouseUp | when a mouse button is released while the pointer is over a chart. |
Resize | when the chart is resized. |
Select | when a chart element is selected. |
SeriesChange | when the user changes the value of a chart data point by clicking a bar in the chart and dragging the top edge up or down thus changing the value of the data point. |
Use Cases
I decided to list some interesting examples of Workbook VBA events usage:
- Before save notification – if you don’t want to overwrite your current file version you may want to override the BeforeSave Workbook VBA event to add an additional prompt to confirm if you want to overwrite your current file. Code below:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) Cancel = (MsgBox("Are you sure?", vbYesNo, "Question") = vbNo) End Sub
- Refresh all PivotTables and QueryTables on VBA Open Workbook Event – if you want to make sure your Pivot Tables are up to date whenever someone opens your Workbooks add a simple piece of code:
Private Sub Workbook_Open() ActiveWorkbook.RefreshAll End Sub
- Prevent Changes to certain Cells – say you want to prompt a user when changing a certain cell value and revert to a default value otherwise. Simply override the VBA Change Event as follows:
Private Sub Worksheet_Change(ByVal Target As Range) If Target = Range("A1") And Target.Value <> 100 Then If MsgBox("Are you sure you want to change this cell?", vbYesNo) = vbNo Then 'Revert Target value Application.EnableEvents = False Target.Value = 100 Application.EnableEvents = True End If End If End Sub
Run a Macro Automatically on Opening Excel Workbook
Description:
Sometimes you may need to run a macro automatically on opening excel workbook. Following are the few cases where you are required to run a macro while opening your excel workbook.
Run a Macro Automatically on Opening Excel Workbook – Solution(s):
We can use Workbook_Open() method or Auto_Open() method to achieve this.
Run a Macro Automatically – Example Cases:
Following are the list of situations where we need to run a macro automatically on opening an excel workbook.
- Show a welcome message to the user
- Run some starting scripts on opening the workbook
- Fill or populate the drop-down lists or other ActiveX Control while opening the workbook
- Activate a particular sheet while opening the workbook
- Show a user form while opening the workbook
- Clear the specific worksheets or ranges while opening the workbook
- Download and see it practically
Showing a welcome message to the user
When you open a workbook, you may want to pass some instructions to the user. Or you can show a welcome message with specific text or user name. The following code will show you how to Run a Macro Automatically.
Code:
Private Sub Workbook_Open() Msgbox "Welcome to ANALYSIS TABS" End Sub
Output:
Instructions:
- Open an excel workbook
- Press Alt+F11 to open VBA Editor
- Double click on ThisWorkbook from Project Explorer
- Copy the above code and Paste in the code window
- Save the file as macro enabled workbook
- Open the workbook to test it, it will Run a Macro Automatically. You should see a message box as shown above
Using Auto open method to run a macro automatically:
You can INSERT a new module and place the following code in the newly created module
Code:
Sub Auto_Open() Msgbox "Welcome to ANALYSIS TABS" End Sub
Instructions:
- Open an excel workbook
- Press Alt+F11 to open VBA Editor
- Insert a New Module from Insert Menu
- Copy the above code and Paste in the code window
- Save the file as macro enabled workbook
- Open the workbook to test it, it will Run a Macro Automatically. You should see a message box as shown above
Running some starting scripts on opening the workbook
The following example runs a script to count the number of worksheets in workbook and list out them in the sheet1.
Code:
Sub Auto_Open() Dim sh Dim iCntr iCntr = 1 For Each sh In ThisWorkbook.Sheets Sheet1.Cells(iCntr, 1) = sh.Name iCntr = iCntr + 1 Next End Sub
Instructions:
- Open an excel workbook
- Press Alt+F11 to open VBA Editor
- Insert a New Module from Insert Menu
- Copy the above code and Paste in the code window
- Save the file as macro enabled workbook
- Open the workbook to test it, it will Run a Macro Automatically. You should see the list of sheet names in the Sheet1
You may use following code to Populate a Combo Box or a List Box in worksheet
The following example shows how to populate regions(East,West,North,South) in a ComboBox and a List Box
Code:
Sub Auto_Open() Sheet1.ComboBox1.AddItem "East" Sheet1.ComboBox1.AddItem "West" Sheet1.ComboBox1.AddItem "North" Sheet1.ComboBox1.AddItem "South" With Sheets("Sheet1").ListBox1 .AddItem "East" .AddItem "West" .AddItem "North" .AddItem "South" End With End Sub
Instructions:
- Open an excel workbook
- Insert a Combobox (activex control from developer ribbon) in the Sheet1. And Name the Combo Box (right click on it and change the name in the properties) as ComboBox1
- Insert a Listbox (activex control from developer ribbon) in the Sheet1. And Name the List Box (right click on it and change the name in the properties) as Listbox1
- Press Alt+F11 to open VBA Editor
- Double click on ThisWorkbook from Project Explorer
- Copy the above code and Paste in the code window
- Save the file as macro enabled workbook
- Open the workbook to test it, it will Run a Macro Automatically. You should see the Combo Box and List Box in the Sheet1 are filled with items
You may use following code to Activate a Sheet or Show an UserForm
The following example shows to activate a sheet (named “Home”) and show an userform (UserForm1). This code will activate the “Home” worksheet and then display the UserForm1
Code:
Sub Auto_Open() 'Activate a Sheet Sheets("Home").Activate 'Show an UserForm UserForm1.Show End Sub
Instructions:
- Open an excel workbook
- Press Alt+F11 to open VBA Editor
- Insert a userform from Insert menu (UserForm1)
- Double click on ThisWorkbook from Project Explorer
- Copy the above code and Paste in the code window
- Save the file as macro enabled workbook
- Open the workbook to test it, it will Run a Macro Automatically. You should see the Userform which you have created
You may want to clear the specific worksheets or ranges while opening the workbook
The following example clears the all worksheets in the workbook on workbook open.
Code:
Sub Auto_Open() Dim sh For Each sh In ThisWorkbook.Sheets sh .Cells.Clear Next End Sub
Instructions:
- Open an excel workbook
- Enter some sample data in each workbook
- Press Alt+F11 to open VBA Editor
- Double click on ThisWorkbook from Project Explorer
- Copy the above code and Paste in the code window
- Save the file as macro enabled workbook
- Open the workbook to test it, it will Run a Macro Automatically. You should see all the worksheets are cleared
You can download the example file and see how it’s working.
Please note: We may comment have commented some code as we can write only one auto_open() or Workbook_open() procedure.
ANALYSISTABS – Run a Macro Automatically
A Powerful & Multi-purpose Templates for project management. Now seamlessly manage your projects, tasks, meetings, presentations, teams, customers, stakeholders and time. This page describes all the amazing new features and options that come with our premium templates.
Save Up to 85% LIMITED TIME OFFER
All-in-One Pack
120+ Project Management Templates
Essential Pack
50+ Project Management Templates
Excel Pack
50+ Excel PM Templates
PowerPoint Pack
50+ Excel PM Templates
MS Word Pack
25+ Word PM Templates
Ultimate Project Management Template
Ultimate Resource Management Template
Project Portfolio Management Templates
Related Posts
VBA Reference
Effortlessly
Manage Your Projects
120+ Project Management Templates
Seamlessly manage your projects with our powerful & multi-purpose templates for project management.
120+ PM Templates Includes:
15 Comments
-
Haobo
December 30, 2013 at 4:32 AM — ReplyThank you for the examples. Just wonder that after Dim syntax, should you declare the data type?
Sub Auto_Open()Dim sh as worksheet
For Each sh In ThisWorkbook.Sheets
sh .Cells.Clear
NextEnd Sub
-
PNRao
December 30, 2013 at 10:08 PM — ReplyHi Haobo,
Thanks for your comments.
Yes, it is good practice to declare the data type of the variable always.However, Excel can automatically define internally based on the data assigned to that particular variable in the program.Thanks-PNRao!
-
Fauzan
May 15, 2014 at 12:11 PM — ReplyActually I want to create a macro but didnt have the information of VBA to create that.
Could some one plz help me!!!!!!!!!!!
I want that if any mail comes to me with a subject of completed so i want a reminder should remind me within 5 mins and it should go on for a day as I am continuosly receiving this type of emails
-
Gabor Horvath
October 7, 2014 at 6:49 PM — ReplyExcellent help, thanks. Gabor
-
lokesh reddy
July 22, 2015 at 7:40 AM — ReplyHi,
I think we need explanation about coding in depth. example :dim sh, dim icntr
-
Prabhu
October 5, 2015 at 10:52 AM — ReplyHi I have a macro file,it wil automatically run wen the excel open up but sometime the code is not working the macro is not automatically run,plsss somebody help
anyone know what is the issue in this
-
RAHUL
April 18, 2016 at 5:26 PM — ReplyHello, I want that with out opening the workbook the macros will run by taking the system date and it will send the mail .
Can anybody help me on this ?? -
Venkat
May 24, 2016 at 7:46 PM — ReplyDear Mr.P.N Rao ..
Hello !
1. Can a macro be enabled automatically with a code inside sub auto_open() to avoid the prompt by macro security level settings prompting the user to press enable macro to run the auto_open() macro ??..Thanks in advance… -
gurunath
March 10, 2017 at 10:20 AM — ReplyHi,
I want to create one macro, in one Excel file more than 30 sheets are there. when ever i opens excel file it should open home sheet and also while opening o dont want to show all other sheets list.any one help me on this.
-
Phani Ch
March 31, 2017 at 9:35 AM — ReplyI have written a macro for my department. Now my requirement is when we generate the excel from the application, Macro should automatically run by cross checking the Worksheet Name.
Eg:- “DailyDetails”. If the generated sheet has a name like “DailyDetails_31/3/2017” it should run automatically without any shortcuts and if the generated sheet name is not as per criteria it should not run the macro. -
Alaine
September 7, 2018 at 3:10 PM — ReplyHi, i would want to ask, how can i automatically run macros on a hyperlink form upon opening an excel file?
I’m thinking of setting a specific date in outlook where it would open an excel file then run the macro automatically, but i don’t know how to call a specific hyperlink macro.
hope you can help me.
-
Aniket Shinde
May 13, 2019 at 1:26 PM — ReplyI Have a Data of Total Employees, Need to create VBA code on Employee Code. When I click on “Generate” need to show Total details of That seprate Employee.
Please help with Code
-
algae
June 5, 2019 at 12:24 PM — ReplyMy workbook has a macro name “Main”. How do I run it whenever the workbook is opened?
-
PNRao
July 4, 2019 at 5:56 PM — ReplyPaste the below code in the workbook code module:
Private Sub Workbook_Open()
Call Main
End Sub
-
Devmode
May 11, 2020 at 11:35 PM — ReplyHow would I make it auto-run a macro ONLY when I open documents from a particular folder on my desktop?
Effectively Manage Your
Projects and Resources
ANALYSISTABS.COM provides free and premium project management tools, templates and dashboards for effectively managing the projects and analyzing the data.
We’re a crew of professionals expertise in Excel VBA, Business Analysis, Project Management. We’re Sharing our map to Project success with innovative tools, templates, tutorials and tips.
Project Management
Excel VBA
Download Free Excel 2007, 2010, 2013 Add-in for Creating Innovative Dashboards, Tools for Data Mining, Analysis, Visualization. Learn VBA for MS Excel, Word, PowerPoint, Access, Outlook to develop applications for retail, insurance, banking, finance, telecom, healthcare domains.
Page load link
Go to Top
March 31, 2014/
Chris Newman
Triggering A Macro Via An Event
There are many events that Excel keeps track of while you carry out tasks in your workbook. Events that are tracked range from tracking if you saved your project to any change in a cells value. By triggering your VBA code based on a specific event done by a user you can do some pretty nifty things.
In this post we will focus on the Open and BeforeClose events. The image below shows how you can navigate to the Workbook Object within the Visual Basic Editor. The Workbook Object is where workbook events can be accessed through VBA code.
Steps To Access Workbook Events With VBA
-
Open the Visual Basic Editor (shortcut key: Alt+F11)
-
Locate your Workbook Project in the Project Window and double click on ThisWorkbook within the Microsoft Excel Objects folder
-
Select Workbook from the Object drop down (first drop down)
-
Insert any event subroutine by selecting your desired event from the Procedure drop down menu (second drop down)
Adding Macro Code To A Workbook Event
Once you have your desired subroutine declared, you can then add some VBA code within the Sub statement to carry out what ever tasks you want to occur when the respective event is triggered by the user. This can be a Call to another subrountine or you can simply write your macro within the event procedure.
The below code displays a message box to the user when the workbook is opened and right before the workbook closes. Environ(«Username») retrieves the user’s computer login name.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
MsgBox «Goodbye » & Environ(«Username») & «!»
End Sub
Private Sub Workbook_Open()
MsgBox «Hello » & Environ(«Username») & «!»
End Sub
The following code runs a macro called AddTodaysDate when the workbook is opened.
Private Sub Workbook_Open()
Call AddTodaysDate
End Sub
What Will You Use Events For?
I use events for a lot of different reasons. I’ve used event triggers to make sure a workbook is password protected before it is closed and there have been instances where I have used events to automatically open up specific files when the workbook is opened. There are so many really creative ways you can use events to automate your tasks. I want to hear from you and learn what you use event triggers for! I look forward to reading your comments.
About The Author
Hey there! I’m Chris and I run TheSpreadsheetGuru website in my spare time. By day, I’m actually a finance professional who relies on Microsoft Excel quite heavily in the corporate world. I love taking the things I learn in the “real world” and sharing them with everyone here on this site so that you too can become a spreadsheet guru at your company.
Through my years in the corporate world, I’ve been able to pick up on opportunities to make working with Excel better and have built a variety of Excel add-ins, from inserting tickmark symbols to automating copy/pasting from Excel to PowerPoint. If you’d like to keep up to date with the latest Excel news and directly get emailed the most meaningful Excel tips I’ve learned over the years, you can sign up for my free newsletters. I hope I was able to provide you with some value today and I hope to see you back here soon!
— Chris
Founder, TheSpreadsheetGuru.com