All about worksheets
Add new worksheet with name
The code below shows how you can create a new Worksheet and give it a name. Note that with Add the new sheet
always becomes the active sheet.
Dim wb As Workbook: Set wb =
Dim strName As String: strName =
Dim ws As Worksheet
Set ws = wb.Worksheets.Add(Type:=xlWorksheet)
With ws
.Name = strName
End With
The below sections discuss the arguments you can use to control how worksheets are added with specified
position: Before and After, Count and what Type possibly using a template Template. At the end there is a macro you
can use to Insert sheet with name specified by the user.
Before or After arguments
An object that specifies the sheet Before or After which the new sheet is added. If Before and After are both omitted, the
new sheet is inserted before the active sheet.
As an example, below code adds a new worksheet After the active sheet in the active workbook
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim ws As Worksheet
Set ws = wb.Sheets.Add(Type:=xlWorksheet, After:=Application.ActiveSheet)
The following code puts the new sheet at the beginning:
Set ws = wb.Worksheets.Add(Before:=wb.Worksheets(1), Type:=xlWorksheet)
The following code puts the new sheet at the end:
Set ws = wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count), Type:=xlWorksheet)
Count
The number of sheets to be added. The default value is one.
Type
Specifies the sheet type. Can be one of the following XlSheetType constants: xlWorksheet or xlChart - or template file
path. The default value is xlWorksheet.
Use Template
You can also insert sheets based on an existing template, see below.
Dim wb As Workbook: Set wb = ActiveWorkbook
Dim ws As Worksheet
Dim strTemplate As String: strTemplate = "C:\temp\tpt.xlsx"
Set ws = wb.Sheets.Add(Type:=strTemplate)
Insert sheet with name specified by the user
If you often have to insert a worksheet and give it a name the macro below can be handy. The code is build up as
follows:
1. Uses InputBox to ask for the name of the worksheet to be inserted
o The Title argument gives the pupose of the current action;
o The Prompt argument specifies what input is required. Some details are added concerning not allowed
characters
o You could use Default argument to automatically fix errors in previously not ok sheet name, or pick up a
proposed name somewhere else.
2. Validates the string returned by the InputBox :
o If empty string the sheet insertion is aborted.
o If there already is a sheet with this name
o If the string does not comply with excel sheet naming rules
a MsgBox informs the user about any problems and lets the user either Abort or Retry.
2. Inserts a worksheet and gives it the name specified in the inputbox.
Sub AddNewWorksheet()
Const cstrTitle As String = "Add new worksheet"
Const cstrPrompt As String = "Give the name for the new worksheet." & vbCrLf & "Not
allowed are the characters: : \ / ? * [ and ]"
Dim strInput As String
Dim strDefault As String: strDefault = "" 'setting initial value for inputbox can be
useful
Dim strInputErrorMessage As String
Dim booValidatedOk As Boolean: booValidatedOk = False
On Error GoTo HandleError
Do
strInput = InputBox(Prompt:=cstrPrompt, Title:=cstrTitle, Default:=strDefault)
If Len(strInput) = 0 Then GoTo HandleExit
GoSub ValidateInput
If Not booValidatedOk Then
If vbCancel = MsgBox(strInputErrorMessage & "Retry?", vbExclamation + vbOKCan
cel) Then GoTo HandleExit
End If
Loop While Not booValidatedOk
Dim wb As Workbook: Set wb = ActiveWorkbook
Dim shts As Sheets: Set shts = wb.Sheets
Dim obj As Object
Set obj = shts.Add(Before:=ActiveSheet, Count:=1, Type:=XlSheetType.xlWorksheet)
obj.Name = strInput
HandleExit:
Exit Sub
HandleError:
MsgBox Err.Description
Resume HandleExit
ValidateInput:
If SheetExists(strSheetName:=strInput) Then
strInputErrorMessage = "Sheet already exists. "
ElseIf Not IsValidSheetName(strSheetName:=strInput) Then
strInputErrorMessage = "Sheetname not allowed. "
Else
booValidatedOk = True
End If
Return
End Sub
Activate a worksheet using VBA
Calling the Activate method of a Worksheet object makes that sheet the active sheet, meaning it visually is on top and all macro actions that
use ranges without explicitly specifying which sheet will use the ActiveSheet.
Dim wb As Workbook: Set wb =
Dim ws As Worksheet: Set ws = wb.Sheets("Sheet2")
ws.Activate
Activate and Select
You can Select multiple sheets at the same time ...
Dim wb As Workbook: Set wb =
wb.Sheets(Array("Sheet1", "Sheet2", "Sheet3")).Select
... but you can only Activate one
With Activate, if you presently have more than one sheet selected, the ActiveSheet will change, but all selected sheets will remain selected.
With Select, the selected sheet becomes the ActiveSheet. If more sheets are selected (as above), the first in the array is made active sheet.
Copy a worksheet
The Copy method of the Worksheet object copies the sheet and its contents into an open or new workbook.
Notes
The copied worksheet keeps the Name and CodeName properties of the source worksheet.
If the copied worksheet held a worksheet code sheet in a VBA project, that is also carried into the new
workbook.
Copy a worksheet into the active or another open
workbook
To copy Before a specified worksheet:
Dim ws As Worksheet: Set ws =
Dim wsBefore As Worksheet: Set wsBefore =
ws.Copy Before:=wsBefore
As an example, assuming Book1.xslx is open in Excel, the following code copies the Active sheet from the workbook containing the macro
into Book1.xlsx before Sheet1
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.ActiveSheet
Dim wbBefore As Workbook: Set wbBefore = Application.Workbooks("Book1.xlsx")
Dim wsBefore As Worksheet: Set wsBefore = wbBefore.Sheets("Sheet1")
ws.Copy Before:=wsBefore
To copy After a specified worksheet:
Dim ws As Worksheet: Set ws =
Dim wsAfter As Worksheet: Set wsBefore =
ws.Copy After:=wsAfter
Copy a worksheet to a new workbook
Excel creates a new workbook that contains the copied sheet object that contains the copied Worksheet object. The newly created
workbook becomes the ActiveWorkbook and contains a single worksheet.
Dim ws As Worksheet: Set ws =
ws.Copy
Copying multiple sheets in one go
An array selection of multiple worksheets can be copied in a similar manner.
wb.Worksheets(Array("Sheet1", "Sheet2", "Sheet4")).Copy
Delete worksheet using VBA
Deleting a worksheet using VBA can be simple...
Dim ws As Worksheet: Set ws =
ws.Delete
The problem with this code is that the process gets interupted by a confirmation prompt, which may not be what you want.
Delete worksheet without confirmation prompt
The code below uses Application.DisplayAlerts = False to prevent the warning. Don't forget to set DisplayAlerts to True again.
Dim ws As Worksheet: Set ws =
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
Ways to hide a worksheet using VBA
By default, worksheets are visible. Some worksheets however contain data not intended to be seen by the user in which case the
worksheets property visibility can be changed.
If you want to easily change the visiblity of the worksheet via the menu:
Dim ws As Worksheet: Set ws =
ws.Visible = XlSheetVisibility.xlSheetHidden
Note
At least one worksheet must be visible at all times
If you want to allow the users to make the worksheet visible via the menu:
Dim ws As Worksheet: Set ws =
ws.Visible = XlSheetVisibility.xlSheetVeryHidden
If you want to unhide / make the sheet visible using vba:
Dim ws As Worksheet: Set ws =
ws.Visible = XlSheetVisibility.xlSheetVisible
Protect a worksheet using VBA
When you protect a worksheet, you are preventing the user from changing values in cells and making other changes to the worksheet.
Protecting a worksheet can be as simple as calling
Dim ws As Worksheet: Set ws =
Dim strPassword As String: strPassword =
ws.Protect Password:=strPassword
or, the Password being optional,
ws.Protect
By default, all cells are locked, but this does not take effect until you protect the worksheet. When you protect the sheet, all cells are locked
except those that you have specifically unlocked.
To unprotect, depending on whether Password was supplied during protection.
Dim strPassword As String: strPassword =
ws.Unprotect Password:=strPassword
If the password is omitted, you can unprotect the worksheet or workbook without specifying a password.
Warning
If you forget the password, you cannot unprotect the worksheet or
workbook.
Protect options
When inserting the code using the Code VBA add-in all arguments are set explicitly. This makes it clear which features are protected (by
default) and which not. This makes it easier to decide in which case you want to deviate from the defaults.
Dim ws As Worksheet: Set ws =
Dim strPassword As String: strPassword =
ws.Protect Password:=strPassword, DrawingObjects:=True, Contents:=True, Scenarios:=True, _
UserInterfaceOnly:=True, AllowFormattingCells:=False, AllowFormattingColumns:=False, _
AllowFormattingRows:=False, AllowInsertingColumns:=False, AllowInsertingRows:=False, _
AllowInsertingHyperlinks:=False, AllowDeletingColumns:=False, AllowDeletingRows:=False, _
AllowSorting:=False, AllowFiltering:=False, AllowUsingPivotTables:=False
Give your macros access to locked cells - the UserInterfaceOnly Option
When you lock cells on a worksheet, that protection applies to VBA operations as well as user actions. If your VBA code attempts to modify
a locked cell, you will get a runtime error 1004. One way to work around this is to unprotect the sheet before the relevant VBA runs and then
reprotect it after the VBA is finished. This is sort of a messy solution. The better way is to use the UserInterfaceOnly flag when you protect
the sheet via VBA. You can specify UserInterfaceOnly only in VBA code. There is no user interface element (command bar, menu, etc) for
this option; you must use VBA. When you protect a sheet with UserInterfaceOnly, protection is applied to user actions (basically, keyboard
and mouse operations), but VBA is free to modify the worksheet as if there was no protection. The UserInterfaceOnly setting is not saved
when you close the workbook, so you need to set it when the workbook is opened. The best place to do this is in the Workbook_Open event
procedure in module ThisWorkbook.
Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ws.Protect UserInterfaceOnly:=True
Next ws
End Sub
You don't need to protect the sheet with a password just to use the user interface option. If the sheet already is protected with a password
just use the userinterfaceonly line.
Protection object and worksheet Protection property
You can also view a protection settings via the Protection object associated with the Worksheet and if it does not have the required value
change it by calling the Protect method the appropriate argument set, e.g.
If ActiveSheet.Protection.AllowInsertingColumns = False Then
ActiveSheet.Protect AllowInsertingColumns:=True
End If
Worksheet properties to check if feature is protected
You can check if contents are protected using:
Dim booProtectContents As Boolean
booProtectContents = ws.ProtectContents
Similarly, you can check protection of Scenarios (ws.ProtectScenarios and DrawingObjects (ws.ProtectDrawingObjects)
DrawingObjects
True to protect shapes. The default value is True.
Contents
Protects the locked cells.
Scenarios
True to protect scenarios. This argument is valid only for worksheets. The default value is True.
AllowFormattingCells
True allows the user to format any cell on a protected worksheet. The default value is False.
AllowFormattingColumns
True allows the user to format any column on a protected worksheet. The default value is False.
AllowFormattingRows
True allows the user to format any row on a protected. The default value is False.
AllowInsertingColumns
True allows the user to insert columns on the protected worksheet. The default value is False.
AllowInsertingRows
True allows the user to insert rows on the protected worksheet. The default value is False.
AllowInsertingHyperlinks
True allows the user to insert hyperlinks on the worksheet. The default value is False.
AllowDeletingColumns
True allows the user to delete columns on the protected worksheet
AllowDeletingRows
True allows the user to delete rows on the protected worksheet
AllowSorting
True allows the user to sort on the protected worksheet. Every cell in the sort range must be unlocked or unprotected. The default value is
False.
AllowFiltering
True allows the user to set filters on the protected worksheet. Users can change filter criteria but can not enable or disable an auto filter.
Users can set filters on an existing auto filter. The default value is False.
AllowUsingPivotTables
True allows the user to use pivot table reports on the protected worksheet. The default value is False.
How to test if a sheet name is valid
Sometimes you need to automatically add sheets to a workbook. This will cause problems if the name used for the
worksheet does not comply to Excel's rules for valid sheet names. A string can be used for naming a sheet if:
1. The number of characters is not greater than 31 (and not 0)
2. It does not contain illegal characters: : \ / ? * [ or ]
Below shows code that implements the test IsValidSheetName. It is included in Code VBA module
modSheetProcedures.bas in folder \Documents\VBA Code\Excel\Worksheet .
Private Const ciMaxLenSheetName As Integer = 31
Private Function SheetNameIllegalCharacters() As Variant
SheetNameIllegalCharacters = Array("/", "\", "[", "]", "*", "?", ":")
End Function
Public Function IsValidSheetName(strSheetName As String) As Boolean
IsValidSheetName = False
If Len(strSheetName) = 0 Then Exit Function
If Len(strSheetName) > ciMaxLenSheetName Then Exit Function
Dim varSheetNameIllegalCharacters As Variant: varSheetNameIllegalCharacters = SheetNa
meIllegalCharacters
Dim i As Integer
For i = LBound(varSheetNameIllegalCharacters) To UBound(varSheetNameIllegalCharacters
)
If InStr(strSheetName, (varSheetNameIllegalCharacters(i))) > 0 Then Exit Function
Next i
IsValidSheetName = True
End Function
Function to test if excel sheet exists
The function below checks if an excel sheet exists with given name. The function works both with Worksheets and Charts
sheets. It is included in Excel VBA under both Worksheet and Chart in module modSheetProcedures which is
automatically inserted when the function is selected.
Public Function SheetExists(strSheetName As String, Optional wbWorkbook As Workbook) As B
oolean
If wbWorkbook Is Nothing Then Set wbWorkbook = ActiveWorkbook 'or ThisWorkbook -
whichever appropriate
Dim obj As Object
On Error GoTo HandleError
Set obj = wbWorkbook.Sheets(strSheetName)
SheetExists = True
Exit Function
HandleError:
SheetExists = False
End Function
UsedRange in Worksheet using VBA
UsedRange returns a Range object representing the area of a worksheet that is being used. You will use the UsedRange to work with a
range of cells in a worksheet whose size you have no control over. The UsedRange property represents the area described by the farthest
upper-left and farthest lower-right used cells in a worksheet and includes all cells in between.
As an example, with the active workheet as in the image above, running the code
?ActiveSheet.UsedRange.Address
in the Immediate window will return $B$2:$C$4. From this we can conclude that UsedRange:
is a rectangle range,
includes cells containing data or being formatted and possibly other things,
does NOT automatically include topleft cells such as A1,
does NOT consider the active cell as 'used'.
Warning
If you are only inserted in data you must be aware that not all rows actually contain data - there may be other reasons a row is included,
as in the above example includes the formatted cell C4.