Return to VBA Code Examples
This tutorial will demonstrate how to get and set the Workbook name in VBA.
We can get or set the name of the Active workbook in VBA, or loop through all the open workbooks in Excel, and get or set the name of each of them using a VBA Loop.
Get Workbook Name
To get the name of the active workbook, we need to use the name property of the workbooks object.
Sub GetWorkbookName()
Dim strWBName As String
strWBName = ActiveWorkbook.Name
MsgBox strWBName
End Sub
If we were to run the code above, we would see a message box appear on the screen with the name of the Active workbook.
To loop through all the active Workbooks, and return the names of the workbooks to Excel, we can run the following code:
Sub GetWorkbookNames()
Dim wb As Workbook
For Each wb In Workbooks
ActiveCell = wb.Name
ActiveCell.Offset(1, 0).Select
Next
End Sub
The examples above will include the extension of the file (eg xlsx). If you do not want to include the extension, there are a few methods we can use to obtain just the filename of the workbook.
Get Workbook Name Without Extension
We can use the LEFT and INSTR functions to remove any characters after the period in the file name:
Sub GetWorkbookName()
Dim strWBName As String
strWBName = Left(ActiveWorkbook.Name, InStr(ActiveWorkbook.Name, ".") - 1)
MsgBox strWBName
End Sub
We can use the LEFT and LEN functions to remove 5 characters from the end of the file name:
Sub GetWorkbookName()
Dim strWBName As String
strWBName = Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 55)
MsgBox strWBName
End Sub
Setting the Workbook Name
To set the name of a workbook in VBA, we still use the Name property of the workbook, however we cannot use this method to change the name of the Active Workbook. This is due to the fact that the Active workbook is open, and a file access error will occur. To overcome this, we can save the file with a new name and then delete the old file.
Public Sub SetWorkbookName()
Dim strPath As String
Dim strNewName As String
Dim strOldName As String
strOldName = ActiveWorkbook.Name
strNewName = InputBox("Please enter new name for workbook")
strPath = ActiveWorkbook.Path
ActiveWorkbook.SaveAs strPath & "/" & strNewName
Kill strPath & "/" & strOldName
End Sub
To rename a workbook that is not open, we can use the Name method.
Public Sub RenameWorkbook()
Name "C:DataMyFile.xlsx" As "C:DataMyNewFile.xlsx"
End Sub
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!
VBA Get Workbook Name in Excel. We can return workbook name using Workbook.Name property. Here workbook represents an object. It is part of Workbooks collection. Returns a string value representing Workbook name. We can find Active Workbook or Current Workbook name using Name property of Workbook.
Table of Contents:
- Overview
- Syntax to return Name of the Workbook VBA in Excel
- Get Name of the Active Workbook using VBA in Excel
- Macro to Get Current Workbook Name using VBA in Excel
- Instructions to Run VBA Macro Code
- Other Useful Resources
Syntax to get current Workbook name using VBA in Excel
Here is the following syntax to get the Name of the Workbook using VBA in Excel.
expression.Name
Where expression: It represents Workbook object which is part of workbooks collection.
Name: It represents property of Workbook object to get Workbook name.
Get Name of the Active Workbook using VBA in Excel
Let us see the following example macro to get current or active workbook name in using VBA in Excel. Where ‘Name’ represents the property of Workbook object. It helps to get the name of the Workbook.
'Get Active Workbook name in Excel using VBA Sub VBA_Get_ActiveWorkbook_Name() 'Variable declaration Dim sActiveWorkbookName As String sActiveWorkbookName = ActiveWorkbook.Name End Sub
Output: Please find the output screenshot of the above macro code.
Macro to Get Current Workbook Name using VBA in Excel
Here is another example macro code to get current workbook name using VBA in Excel.
'Get current workbook name of the Workbook using VBA in Excel Sub VBA_Get_CurrentWorkbook_Name() 'Variable declaration Dim sCurrentWorkbookName As String sCurrentWorkbookName = ThisWorkbook.Name End Sub
Output: Here is the output screenshot of the above macro code.
Instructions to Run VBA Macro Code or Procedure:
You can refer the following link for the step by step instructions to execute VBA code or procedure.
Instructions to run VBA Macro Code
Other Useful Resources:
Click on the following links of the useful resources. These helps to learn and gain more knowledge.
VBA Tutorial VBA Functions List VBA Arrays in Excel Blog
VBA Editor Keyboard Shortcut Keys List VBA Interview Questions & Answers
Get Active Workbook or Worksheet Name Path FullName in Excel VBA
Description:
When we are working with workbooks and worksheets, some times we may required to Get Active Workbook or Worksheet Name, Path of the workbook to know the directory, FullName(Complete path) of the workbook to know the location of the workbook, selected Range address in active sheet or selected Cell address in active sheet using Excel VBA.
Solution(s):
You can get Active Workbook Or Worksheet Name by using Name property of the workbook or worksheet.
Get Active Workbook or Worksheet Name – Example Cases:
- Get an Active Workbook Name
- Get an Active Workbook Path
- Get an Active Workbook FullName
- Get an Active Worksheet Name
- Get an Active Range Address
- Get an Active Cell Address
Get an Active Workbook Name
You can use ActiveWorkbook property to return the active workbook name. You can use the following code to get the name of the Active Workbook
Code:
Sub DisplayWorkbookName() MsgBox ActiveWorkbook.Name, vbInformation, "Workbook Name" End Sub
Output:
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
- Press F5 to see the output
- You should see output as shown above
- Save the file as macro enabled workbook
Get an Active Workbook Path
You can use ActiveWorkbook property to return the active workbook Path.You can use the following code to Get Active Workbook Path to know the workbook directory.
Code:
Sub DisplayWorkbookPath() MsgBox ActiveWorkbook.Path, vbInformation, "Workbook Path" End Sub
Output:
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
- Press F5 to see the output
- You should see output as shown above
- Save the file as macro enabled workbook
Get an Active Workbook FullName
You can use ActiveWorkbook property to return the active workbook FullName. You can use the following code to get Active Workbook FullName to know the location of workbook.
Code:
Sub DisplayWorkbookFullName() MsgBox ActiveWorkbook.FullName, vbInformation, "Workbook Complete Path" End Sub
Output:
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
- Press F5 to see the output
- You should see output as shown above
- Save the file as macro enabled workbook
Get an Active Worksheet Name
You can use ActiveSheet property to return the ActiveSheet Name. You can use the following code to get Active Worksheet Name.
Code:
Sub DisplayWorkSheetName() MsgBox ActiveSheet.Name, vbInformation, "Active Sheet Name" End Sub
Output:
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
- Press F5 to see the output
- You should see output as shown above
- Save the file as macro enabled workbook
Get an Active(Selected) Range Address
You can use Address property of the selected range(Selection Method). You can use the following code to get the selected range address in active sheet.
Code:
Sub SelectedRangeAddress() 'Variable Declaration Dim MyRange As String 'Assign Selected Range Address to variable MyRange = Selection.Address 'Display Output MsgBox MyRange, vbInformation, "Range Address" '-----------------------(OR)------------------ MsgBox Selection.Address, vbInformation, "Range Address" End Sub
Output:
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
- Select a range from B2 to E11 in active sheet
- Goto code window and Press F5 to see the output
- You should see output as shown above
- Save the file as macro enabled workbook
Get an Active(Selected) Cell Address
You can use Address property of the selected cell(Selection Method). By using the following code you can get the selected cell address in active sheet.
Code:
Sub SelectedCellAddress() 'Variable Declaration Dim MyCell As String 'Assign Selected Range Address to variable MyCell = Selection.Address 'Display Output MsgBox MyCell, vbInformation, "Cell Address" '-----------------------(OR)------------------ MsgBox Selection.Address, vbInformation, "Cell Address" End Sub
Output:
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
- Select a cell F5 in active sheet
- Goto code window and Press F5 to see the output
- You should see output as shown above
- Save the file as macro enabled workbook
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:
One Comment
-
Prabhaker
July 5, 2017 at 4:10 PM — Replythank you this is helpful
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
Joe4
MrExcel MVP, Junior Admin
-
#2
If you kick off the Macro from the workbook holding the VBA code, this should work:
Code:
Sub CloseAllWorkbooks()
Dim McrWkbkName As String
Dim WkbkName As Object
' Capture name of macro workbook before looping through open workbooks
McrWkbkName = ActiveWorkbook.Name
For Each WkbkName In Application.Workbooks()
WkbkName.Save
If WkbkName.Name <> McrWkbkName Then WkbkName.Close
Next
End Sub
-
#3
Hi, Thanks for the quick reply.
I don’t think I make myself clear in my first post. I am looking to change the code to get the open workbook file name of the second file only (that doesn’t host the via script) only, I don’t want to save or close it.
i won’t need the
what do I need to change on the
Code:
If WkbkName.Name <> McrWkbkName Then WkbkName.Close
to ensure it only returns the name of the second workbook?
Code:
If WkbkName.Name <> McrWkbkName Then WkbkName.Name
gives me an error
-
#4
If all you want is to see the workbook name use a message box.
Code:
If WkbkName.Name <> McrWkbkName Then MsgBox WkbkName.Name
If you want to do more with the name and/or the workbook itself we’ll need more info.
Last edited: Oct 18, 2017
-
#5
Hi,
not wanting the filename to display as a MessageBox. would just like to have a reference for the FileName
This code works, however it loops through both so I don’t know if its good luck that it ends up on the file name that doesn’t host the vba script or not.
Code:
Dim WkbkName As Object Dim GetFileName As String
For Each WkbkName In Application.Workbooks()
GetFileName = WkbkName.Name
Next
Joe4
MrExcel MVP, Junior Admin
-
#6
It looks like you have your VBA code to loop through ALL open workbooks. So conceivably, you could have more than 2 workbooks open.
If that is the case, how exactly are we to determine which workbook name you want to capture?
Note that I showed you how to capture the name of the ActiveWorkbook above like this:
Code:
' Capture name of macro workbook before looping through open workbooks
McrWkbkName = ActiveWorkbook.Name
If you run that RIGHT after you open a workbook by VBA code, it will capture the name of the newly opened workbook (as when you open a workbook, it, by default, becomes the active workbook).
Last edited: Oct 18, 2017
-
#7
Apologies if I’m making this more complicated than it needs to be.
i will have an open workbook that will hold the vba script. I will then manually open a second workbook, what I am looking for is to return the second file name.
what I am trying to ensure is the file name returned is not the one holding the vba script. As I noted the last script I posted appears to do this but I don’t know if it’s good luck or if the loop starts with the file that’s hosting it, and therefore will always return the filename of the second file that is open.
-
#8
The workbook with the code can be referred to with ThisWorkbook so if there are only 2 workbooks open you can get a reference to the other workbook, i.e. the one opened manually, with this code.
Code:
Dim wbOtherWB As Workbook
For Each wbOtherWB In Application.Workbooks
If Not wbOtherWB Is ThisWorkbook Then
Exit For
End If
Next wbOtherWB
If wbOtherWB Is Nothing Then
MsgBox "No other workbooks open!", vbExclamation
Exit Sub
End If
' this next line is just an example/confirmation
MsgBox "The workbook opened manually is named " & wbOtherWB.Name & "."
' you can now do whatever you want with the workbook opened manually using the reference wbOtherWB
Note, if there are more than the 2 workbooks open this code will return the first one that VBA finds that isn’t the workbook with the code in it but it will never return the workbook with the code in it — if that makes sense.
-
#9
Belated response Norie, but thats ideal. Thanks very much.
-
#10
Good Day,
I’m using the vba code referenced in post #8 and Excel provides that:
Is there a way expressed through vba to prevent this workbook from being opened manually?
Please let me know!
Thank you,
pinaceous
“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.)