Excel VBA Events

What are VBA events?

Events are happening all the time when a user opens an Excel workbook and starts doing various actions such as entering data into cells or moving between sheets

Within the Visual Basic Editor (ALT+F11), sub routines are already set up which can get fired off when the user does something e.g. entering data into a cell.  The sub routine does not provide any action code, merely a ‘Sub’ statement and an ‘End Sub’ statement with no code between them. They are effectively dormant so nothing happens until you enter some code.

Here is an example based on the ‘Change’ event in a worksheet:

PIC 01

As a VBA programmer, you can add in code to make certain things happen when the user takes a specific action.  This gives you the chance to control the user, and to prevent them taking actions that you do not want them to do and which might damage your workbook.  For example, you may want them to save off their own individual copy of the workbook under another name, so that they do not affect the original, which may be being used by a number of users.

If they close the workbook, then they will automatically be prompted to save their changes.  However, the workbook has a ‘BeforeClose’ event and you can enter code to prevent the workbook being closed and firing off a ‘Save’ event.  You can then add a button to the worksheet itself and put your own ‘Save’ routine onto it.  You can also disable the ‘Save’ routine using the ‘BeforeSave’ event

An understanding of how events work is absolutely essential to a VBA programmer.

 

Types of Events

Workbook Events – these events are fired off based on what the user does with the workbook itself. They include user actions such as opening the workbook, closing the workbook, saving the workbook, adding or deleting sheet

Worksheet Events – these events are fired off by a user taking actions on a specific worksheet.  Every worksheet within the workbook has an individual code module, which contains various events specifically for that worksheet (not for all the worksheets).  These include user actions such as changing the contents of a cell, double clicking on a cell, or right clicking on a cell.

Active X Control Events – Active X controls can be added to a worksheet using the ‘Insert’ icon on the ‘Developer’ tab in the Excel ribbon.  These are often button controls to enable the user to take various actions under control of your code, but they can also be objects such as drop downs.  Using Active X controls as opposed to Form controls on the worksheet gives a whole scope for programmability. Active X controls give you far more flexibility from a programming point of view over using form controls in a worksheet.

For example, you could have two drop down controls on your worksheet.  You want the available list in the second drop down to be based on what the user chose in the first drop down. Using the ‘Change’ event on the first drop down, you can create code to read what the user has selected and then update the second drop down.  You could also de-activate the second drop down until the user has made a selection in the first drop down

UserForm Events – You can insert and design a professional looking form to use as a pop-up.  All the controls that you place on your form are Active X controls and they have the same events as the Active X controls that you might place on a worksheet

Chart Events – These events are only related to a chart sheet and not to a chart appearing as part of a worksheet. These events include resizing the chart or selecting the chart.

Application Events – These use the Application object in VBA. Examples would allow code to be fired off when a certain key is pressed or when a certain time is reached.  You could program a situation where the workbook is left open 24/7 and it imports data from an external source overnight at a pre-determined time.

 

Dangers of Using Code in Events

When you write code to do something when the user takes a certain action, you need to bear in mind that your code could be triggering other events, which could put your code into a continuous loop.

For example, suppose that you use the ‘Change’ event on a worksheet so that when the user puts a value into a cell, a calculation based on that cell is placed into the cell immediately to the right of it.

The problem here is that the placing of the calculated value into the cell triggers another ‘Change’ event, which then in turn triggers yet another ‘Change’ event, and so on until your code has run out of columns to use, and throws up an error message.

You need to think carefully when writing the code for the event to ensure that other events will not be triggered inadvertently

Disable Events

You can use code to disable events to get around this problem.  What you will need to do is to incorporate code to disable events whilst your event code is running and then re-enable events at the end of the code.  Here is an example of how to do it:

Sub DisableEvents()
Application.EnableEvents = False
Application.EnableEvents = True
End Sub

Bear in mind that this disables all events right across the Excel application, so this would also affect other functions within Excel.  If you use this for any reason, make sure that events are switched back on afterwards.

Importance of Parameters in Events

Events usually have parameters which you can use to find out more about what the user is doing and the cell location that they are in.

For example, the Worksheet Change event looks like this:

Private Sub Worksheet_Change(ByVal Target As Range)

By using the range object, you can find out the cell row/column coordinates that the user is actually in.

Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox Target.Column
MsgBox Target.Row
End Sub

If you only want your code to work on a certain column or row number, then you add a condition that exits the subroutine if the column is not the required one.

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column <> 2 Then Exit Sub
End Sub

This gets around the problem of your code triggering multiple events, since it will only work if the user has changed a cell in column 2 (column B)

Workbook Events Examples (not exhaustive)

The workbook events are found under the ‘ThisWorkbook’ object in the VBE Project Explorer.  You will need to select ‘Workbook’ on the first drop down on the code window and then the second drop down will show you all the events available

Pic 02

 

Workbook Open Event

This event is fired off whenever the workbook is opened by a user.  You could use it to put a welcome message to a user by capturing their username

Private Sub Workbook_Open()
MsgBox "Welcome " & Application.UserName
End Sub

You could also check their username against a list held on a hidden sheet to see if they are authorised to access the workbook.  If they are not an authorised user, then you can display a message and close the workbook so that they cannot use it.

Workbook New Sheet Event

This event is triggered when a user adds a new sheet to the workbook

You could use this code to only allow yourself to add a new sheet, rather than have different users all adding sheets and making a mess of the workbook

Private Sub Workbook_NewSheet(ByVal Sh As Object)
Application.DisplayAlerts = False
If Application.UserName <> "Richard" Then
        Sh.Delete
End If
Application.DisplayAlerts = True
End Sub

Note that you need to switch off the alerts as a user warning will appear when the sheet is deleted which allows the user to circumvent your code.  Make sure that you turn the alerts back on afterwards!

Workbook Before Save Event

This event is triggered when the user clicks on the ‘Save’ icon, but before the ‘Save’ actually takes place

As described earlier, you may want to prevent users saving their changes to the original workbook, and force them to create a new version using a button on the worksheet.  All that you need to do is to change the ‘Cancel’ parameter to True, and the workbook can never be saved by the conventional method.

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Cancel = True
End Sub

Workbook Before Close Event

You can use this event to prevent users closing down the workbook, and again force them to exit through a worksheet button. Again, you set the ‘Cancel’ parameter to ‘True’.  The red X in the top right-hand corner of the Excel window no longer works any more.

Private Sub Workbook_BeforeClose(Cancel As Boolean)
Cancel = True
End Sub

Worksheet Event Examples (not exhaustive)

The worksheet events are found under the specific sheet name object in the VBE Project Explorer.  You will need to select ‘Worksheet’ on the first drop down on the code window and then the second drop down will show you all the events available

PIC 03

 

Worksheet Change Event

This event is triggered when a user makes a change to a worksheet, such as entering a new value into a cell

You can use this event to put an additional value or comment in next to the changed cell, but as discussed earlier, you do not want to start setting off a loop of events.

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column <> 2 Then Exit Sub
ActiveSheet.Cells(Target.Row, Target.Column + 1). Value = _
ActiveSheet.Cells(Target.Row, Target.Column). Value * 1.1
End Sub

In this example, the code will only work if the value is entered into Column B (column 2).  If this is true then it will add 10% to the number and place it into the next available cell

Worksheet Before Double Click Event

This event will fire off code if a user double clicks on a cell.  This can be extremely useful for financial reports such as a balance sheet or profit & loss account where numbers are likely to be challenged by managers, especially if the bottom line is negative!

You can use this to provide a drill-down facility, so that when the manager challenges a particular number, all they have to do is double click on the number, and the breakdown appears as part of the report.

This is very impressive from a user’s point of view, and saves them constantly asking ‘why is this number so high?’

You would need to write code to find out the heading / criteria for the number (using the Target object properties) and then filter the tabular data and then copy it into the report.

Worksheet Activate Event

This event occurs when the user moves from one sheet to another.  It applies to the new sheet that the user is moving to.

It could be used to ensure that the new sheet is completely calculated before the user starts doing anything on it.  It can also be used to only re-calculate that particular sheet without re-calculating the entire workbook.  If the workbook is large and has complicated formula in it, then re-calculating one sheet saves a lot of time

Private Sub Worksheet_Activate()
ActiveSheet.Calculate
End Sub

Active X Control Events (not exhaustive)

As discussed earlier, you can add Active X controls directly onto a worksheet.  These can be command buttons, drop downs, and list boxes

The Active X events are found under the specific sheet name object (where you added the control)  in the VBE Project Explorer.  You will need to select the name of the Active X control on the first drop down on the code window and then the second drop down will show you all the events available

PIC 04

Command Button Click Event

When you have put a command button onto a spreadsheet, you will want it to take some action.  You do this by putting code on the Click event.

You can easily put an ‘Are you sure message?’ on this so that a check is made before your code runs

Private Sub CommandButton1_Click ()
Dim ButtonRet As Variant
ButtonRet = MsgBox("Are you sure that you want to do this?", vbQuestion Or vbYesNo)
If ButtonRet = vbNo Then Exit Sub
End Sub

Drop Down (Combo Box) Change Event

An Active X drop down has a change event, so that if a user selects a particular item from the drop-down list, you can capture their choice using this event and then write code to adapt other parts of the sheet or workbook accordingly.

Private Sub ComboBox1_Change ()
MsgBox "You selected " & ComboBox1.Text
End Sub

Tick Box (Check Box) Click Event

You can add a tick or check box to a worksheet so as to provide option choices for the user.  You can use the click event on it to see if the user has changed anything on this.  The values returned are True or False according to whether it has been ticked or not.

Private Sub CheckBox1_Click ()
MsgBox CheckBox1.Value
End Sub

UserForm Events (not exhaustive)

Excel provides the ability for you to design your own forms.  These can be very useful to use as pop-ups to collect information or to provide multiple choices to the user.  They use Active X controls as described previously and have exactly the same events, although the events depend very much on the type of control.

Here is an example of a simple form:

PIC 05

When it is displayed this is what it looks like on screen

PIC 06

You would use events on the form to do things like enter a default company name when the form is opened, to check the company name input agrees to one already in the spreadsheet and has not been mis-spelt, and to add code to the click events on the ‘OK’ and ‘Cancel’ buttons

The code and events behind the form can be viewed by double clicking anywhere on the form

The first drop down gives access to all the controls on the form. The second drop down will give access to the events

PIC 07

UserForm Activate Event

This event is triggered when the form is activated, normally when it is displayed.  This event can be used to set up default values e.g. a default company name in the company name text box

Private Sub UserForm_Activate()
TextBox1.Text = "My Company Name"
End Sub

Change Event

Most of the controls on the form have a change event, but in this example, the company name text box can use the event to put a restriction on the length of the company name being entered

Private Sub TextBox1_Change ()
If Len (TextBox1.Text) > 20 Then
    MsgBox "The name is restricted to 20 characters", vbCritical
    TextBox1.Text = ""
 End If
End Sub

Click Event

You can use this event to take action from the user clicking on controls on the form, or even the form itself

On this form there is an ‘OK’ button, and having collected a company name, we would want to place it in a cell on the spreadsheet for future reference

Private Sub CommandButton1_Click ()
ActiveSheet.Range("A1"). Value = TextBox1.Text
Me.Hide
End Sub

This code acts when the user clicks the ‘OK’ button.  It puts the value in the company name input box into cell A1 on the active sheet and then hides the form so that user control is returned back to the worksheet.

 

Chart Events

Chart events only work on charts that are on a separate chart sheet, and not on a chart that is incorporated into a standard worksheet

Chart events are somewhat limited and cannot be used on a worksheet where you might well have multiple charts.  Also, users do not necessarily want to switch from a worksheet containing numbers to a chart sheet – there is no immediate visual impact here

The most useful event would be to find out the component of a chart that a user has clicked on e.g. a segment in a pie chart, or a bar in a bar chart, but this is not an event available on the standard range of events.

This problem can be solved by using a class module to add a ‘Mouse Down’ event which will return details of the chart component that the user has clicked on. This is used on a chart within a worksheet.

This involves some very complicated coding, but the results are spectacular.  You can create drill downs e.g. the user clicks on a pie chart segment and instantly that chart is hidden and a second chart appears in its place showing a pie chart of detail for the original segment, or you could produce the tabular data supporting that segment of the pie chart.

 

Application Events

You can use the Application object in VBA to fire off code according to a particular event

Application.OnTime

This can enable you to fire off a piece of code at regular intervals for as long as the workbook is loaded into Excel.  You may want to auto-save your workbook to a different folder every 10 minutes, or leave the worksheet running overnight so as to bring in the latest data from an external source.

In this example, a sub routine is entered into a module.  It displays a message box to every 5 minutes, although this could easily be another coded procedure.  At the same time, it resets the timer to the current time plus 5 more minutes.

Every time it runs, the timer resets to run the same sub routine in another 5 minutes time.

Sub TestOnTime()
MsgBox "Testing OnTime"
Application.OnTime (Now () + TimeValue("00:05:00")), "TestOnTime"
End Sub

Application.OnKey

This function enables you to design your own hot keys.  You can make any key combination call a sub routine of your creation.

In this example the letter ‘a’ is redirected so that instead of placing an ‘a’ in a cell, it will display a message box.  This code needs to be placed in an inserted module.

Sub TestKeyPress()
Application.OnKey "a", "TestKeyPress"
End Sub
Sub TestKeyPress()
MsgBox "You pressed 'a'"
End Sub

You run the sub routine ‘TestKeyPress’ first of all.  You only need to run this once. It tells Excel that every time the letter ‘a’ is pressed it will call the sub routine ‘TestKeyPress’.  The sub routine ‘TestKeyPress’ just displays a message box to tell you that you pressed key ‘a’.  It could of course load a form or do all sorts of other things.

You can use any key combination that you can use with the ‘SendKeys’ function

To cancel this functionality, you run the ‘OnKey’ statement without the ‘Procedure’ parameter.

Sub CancelOnKey()
Application.OnKey "a"
End Sub

Everything is now back to normal.