5 Intro Excel VBA - August 2016
5 Intro Excel VBA - August 2016
Excel VBA
Version 2
This document is produced by the Centre for Staff and Educational Development at UEA.
It provides instruction in more advanced techniques using Excel (part of the Microsoft Office
suite of programs) for those who have some experience of Excel.
CONTENTS
1 - Introduction ................................................................................. 1
Using these notes .................................................................................... 1
Setting up course files ............................................................................ 1
Conventions and symbols used in this tutorial ....................................... 1
Practical work ......................................................................................... 2
Ribbons ................................................................................................... 2
Disclaimer .............................................................................................. 2
1 - Introduction
Using these notes
This document provides self-paced tuition in the use of VBA in Excel for Windows, previous
significant experience of using Excel spreadsheets is assumed and a basic understanding of
Microsoft Windows is required.
Practical work
At various points in the course you are expected to do practical work in Excel and these
places are indicated by boxed and shaded text like this. Numbered instructions should be
followed in sequence and care should be exercised not to miss any lines of instruction.
NOTE: If you open an example file containing macros you must enable active content in
order to be able to use the examples in the workbook.
Ribbons
Ribbons provide access to the various features available. The Ribbon is a band that runs across
the top of the window and it contains commands that are divided into sets of commonly used
features. Ribbons are selected by clicking on a tab. For example, the main set of frequently used
commands is displayed on the Ribbon selected by the Home tab.
When isolated reference is made to controls on Ribbons the Ribbon name will be given
followed by the Group and then the Control name e.g.
Home, Font, Bold
References to controls made in the text of an exercise or example will give information according
to the context so if the font is being modified the ribbon and group would be assumed and
reference will just be made to Bold, Italic or Underline.
Disclaimer
The information in this document and the accompanying course is provided in good faith and
has been tested thoroughly in Excel 2010 and 2013 on Windows 7. Due to the nature of VBA it
is possible that some of the procedures will not work with other combinations of operating
system and Office version and may yield unexpected results.
VBA is a powerful programming language and can cause serious loss of data and/or functionality
if misused, the reader is advised to make sure that suitable backups of important work have been
made and that care is taken to follow instructions accurately. Neither CSED or the author can be
held responsible for losses caused by not following this advice.
Worksheets("Sheet1").Range("G14")
The Editor
The VBA editor is embedded in Excel, you may have already seen, or even used it when
recording and editing macros.
Your editor may look slightly different to the one shown here but there are several main
components which will be present and which we will be using throughout this course.
The editor is available from the Developer ribbon which is an optional ribbon. If the Developer
ribbon is not displayed on your Excel profile use the following procedure to turn it on.
2. Click on Options
5. Click on OK
With the Developer ribbon selected you can open the VBA editor by clicking on the
Visual Basic control, alternatively you can use the keyboard shortcut which is
[ALT]+F11.
5. Make sure that View – Toolbars – Standard and Edit are selected
6. Close any other windows within the editor using the close button on each individual title
bar.
The editor is now ready for us to start exploring some of the features of Excel VBA
1. Add another sheet to the workbook, then make sure that Sheet1 is selected
2. In the Immediate Window type this line of text below what you already typed
Range("A1:B4") = "Hello"
3. Press Enter or Return at the end of the typing
4. Observe the result on Sheet1 then select Sheet2 in Excel
5. Click anywhere in the line you just typed in the Immediate Window
6. Press Enter or Return
The text now appears in Sheet2
Because we didn’t specify a sheet, VBA uses the active sheet.
Notice how we can type numbers directly into code, but literal text (that is text used as a value
rather than an instruction) has to be enclosed in quotes.
The question mark instructs the editor to display the result of the following code, in this case the
word Hello which we previously entered. We can use this effect to check the value of expressions
in our code without having to assign them to anything.
Range has different syntaxes which can be used to achieve different outcomes.
Range("A1") refers to the cell A1 as we have already seen.
Range("A1:B4") refers to the range A1:B4 as we have already seen.
Range("A1","B4") refers to A1:B4 – using two separate addresses to define the range.
Range("A1,B4") refers to A1 and B4 as two cells
Range("A1:A3,B2:B4") refers to A1:A3 and B2:B4 as multiple ranges
Try these two examples in the Immediate Window still using Sheet2
4. Range("A1,B4") = "Goodbye"
5. Range("A1:A3,B2:B4") = "Goodnight"
4. Using the Immediate Window, set the colour of the font in A2 to UEA orange using this
line of code:
Range("A2").Font.Color = RGB(250,166,26)
You can experiment with different values of red, green and blue, remembering to only use
values between 0 and 255. There are over 16 million possible combinations so subtle
changes may not be very easy to see.
5. Use ? Range("A2").Font.Color to see the single decimal value created by the three
RGB values
RGB is a built in function which has three arguments, or values, passed to it as it is a function
the arguments are enclosed in brackets and separated with commas.
Active Object
Certain components of Excel are considered to be active at any one time, for example there is an
active sheet which contains the active cell.
In VBA we often find it useful to refer to the active object in a collection as this is where the
operator is expecting something to happen or where they are entering data to be processed.
1. In the immediate window type the following line and press enter
? ActiveCell.Address
The absolute address of the currently active cell is returned
2. Type the following line in the immediate window and press enter
? ActiveSheet.Name
The name of the active sheet is returned
3. Experiment with these commands by changing the active cell and sheet.
We now understand the principle involved in setting and reading properties in Excel using VBA.
We have used the Immediate Window to enter and run single lines of code and we have identified
part of the hierarchical structure of objects which make up Excel.
In the next chapter we will start to use the Code Window to generate repeatable sequences of
VBA code, unlocking more of the capabilities of this powerful and versatile language.
3 – VBA sub-routine
One of the easiest ways to start understanding the structure of VBA in Excel is to record
something using the macro recorder and then to examine the code.
The code which you recorded is now displayed in the Code Window
The use of the formula property rather than simply setting the value of the cell is interesting as
it means that any value; number, text or formula, can be entered using the same basic structure
in VBA.
Selecting the cell and then entering the formula in the active cell is analogous to the actual
keystrokes and mouse clicks we used, although it may not be the most efficient code it does make
sense for the recorder to use a standard system.
R1C1
The formula using R1C1 notation may look a little confusing but it is recorded this way in VBA
mainly because numbers are easier to manipulate than letters. R[-2] means the row two above
this one, C (no square brackets or number) means this column, R[-1] means the row above this
one so the whole formula reads; concatenate the cell two above this one and the cell above this
one, exactly the same meaning as =B3&B4 used in this cell.
After the line containing the words End Sub type the following lines of code
Sub Macro2()
Range("B3") = "text"
Range("B4") = 123
Range("B5") = "=B3&B4"
Range("B6").Select
End Sub
This simple routine does exactly the same job as the recorded macro, you can even see it in the
macro dialogue box and run it like a recorded macro, but it uses the simpler, more direct,
commands we used in the Immediate Window earlier.
This is an example of a simple sequence of code, it runs from top to bottom and carries out the
instructions on each line before moving on to the next.
We have already seen that we can read values using the question mark in the Immediate Window,
and we can also read the value from cell or cells using simple VBA code in the Code Window.
Add these lines of code to the Code Window below the End Sub line of macro2
Sub Macro3()
Range("C3") = Range("B3")
Range("C4") = Range("B4")
Range("C5") = Range("B5")
Range("C6").Select
End Sub
This macro copies the values of the three cells in column B to the equivalent cells in column C.
In C5 it places the value of B5 which is the result of the formula, this may be what we wanted
but if it isn’t then we need to use a different property.
Methods
We can make our latest macro copy the formula using Excel’s copy and paste to retain the benefit
of relative referencing. To do this we introduce a few new lines of code.
Range("B5").Copy will copy the specified range. Copy is a method, which means that it does
something unlike Value which is a property meaning it is a characteristic of something
Range("C5").Select selects C5 using the Select method
ActiveSheet.Paste uses another object, the active sheet, in this case simply as a container for the
Paste method.
Finally Application.CutCopyMode = False is the instruction to turn off the copy mode (just
like pressing the Escape key) and introduces both a new Object and a new type of data. The
Application object is Excel itself and the CutCopyMode property is a Boolean or binary
property which can only be true or false. If the property is true then there is an active selection
on the clipboard, if it is false then the selection is cancelled.
If we apply these lines of code to Macro3 the code looks like this:
Sub Macro3()
Range("C3") = Range("B3")
Range("C4") = Range("B4")
Range("B5").Copy
Range("C5").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Range("C6").Select
End Sub
This is working code but it is a little clumsy, try the code shown below which uses just the copy
and paste technique to copy the whole range of cells. Often when developing code you will want
to refine what you have written, even if it works, as you identify new techniques.
Sub Macro4()
Range("B3:B5").Copy
Range("C3").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Range("C6").Select
End Sub
This code can be reduced even further if we use the destination range as an argument to the Copy
method. This also speeds up the code because we no longer need to actually select the destination.
Arguments in this case do not need to be enclosed in brackets, simply typed after the method
they apply to.
Try this version:
Sub Macro5()
Range("B3:B5").Copy Range("C3")
Range("C6").Select
End Sub
If we need to use the earlier structure of setting values with the equals sign we can still produce
the relative reference effect by using the same type of code as Excel did when we recorded our
first macro earlier in this chapter. The R1C1 notation, using offset numbers in square brackets,
produces properly structured relative references, based on the location of the formula.
Range("C5").FormulaR1C1 = Range("B5").FormulaR1C1
This code will copy the formula from B5 as an R1C1 formula into C5 where it will be interpreted
as =C3&C4, exactly what we needed.
Code Windows
We have been using the Code Window attached to the Module where the original macro was
recorded, but if you look in the Project Window on the left of the editor you will see each sheet
and the workbook listed. All of these objects have their own code window which you can open
by double clicking on the object in the Project Window. It doesn’t matter which code window is
open when you use the Immediate Window but it will affect the scope of any code you type in
the Code Window.
In this chapter we have explored the structure of a VBA sub-routine, seen how macros and VBA
are very closely related to each other and delved further into the Object model and the VBA
Editor. We have seen how objects have both properties and methods and we have seen how using
the macro recorder can give us a head start when we write code, although it often produces code
which is more complex than we need.
Types of variable
The variables we will be using will generally be numbers or text but a whole range of possible
types are available to us, including several different numeric types although just two of these
will suffice for all normal purposes.
This table shows some of the types commonly encountered and describes each.
Type Prefix Description
String str Text, up to a maximum of about 63,000 characters
Date dte A date or time which Excel will interpret as a formatted date/time
Integer int A whole number from -32,768 to +32,767
Long lng A whole number from -2,147,483,648 to 2,147,483,647
Single sng 7 digit accuracy decimal numbers (roughly ±3.4*1038)
Double dbl 15 digit accuracy decimal numbers (roughly ±1.8*10308)
Declaring variables
Before we use a variable we should (or in some cases, we must) declare it by name and type
using a Dim (short for dimensioning) statement. This is done at the very beginning of the code
just after the Sub statement where the name of the routine is declared.
Loops
One of the most common reasons to use code is to create a loop which performs the same
operation many times. There are several types of loop available in VBA, we will concentrate
here on some of the common ones starting with the For…Next loop.
This type of loop uses a variable which is assigned an initial value, an end value, and an
incremental value. This determines how much the variable is incremented in each iteration of
the loop from the start value until it reaches the end value.
The line of code looks like this:
For intLoopCounter = 1 to 101 step 5
In this line of code the variable intLoopCounter which would have already been declared starts
with a value of 1, has a maximum value of 101 and is incremented by 5 in every iteration of the
loop.
The lines of code following this line will then be executed until a line which looks like this is
reached:
Next intLoopCounter
Once this line is reached the variable is incremented by the set amount and the code returns to
the initial line to repeat the process, this will happen until the maximum value is reached at which
point the code simply continues after the line containing the Next instruction.
This code is slightly longer than the examples we have used previously so it has been pre entered
in the Sheet3 code window, but it serves to show how several simple techniques can be combined
to create a functional sub-routine.
2. In the Sheet3 Code Window the following subroutine has been entered
Sub looping2()
'Declare variables
Dim intLoopCounter As Integer
Dim intLoopStep As Integer
Dim intLoopEnd As Integer
Dim strText As String
'Set variables
intLoopStep = Range("B1")
intLoopEnd = Range("B2")
strText = Range("B3")
'Main loop
For intLoopCounter = 1 To intLoopEnd Step intLoopStep
Cells(intLoopCounter, 3) = strText & " row " & intLoopCounter
Next
End Sub
Notice the use of comments prefixed with an apostrophe, empty lines between sections of
code and the indented action within the For…Next loop, these are all techniques used to
make code easier to read.
We have also chosen to omit the variable name in the Next line as there is no possible
ambiguity here.
1. Enter the code below in the code window for Sheet4 of the VBALoops workbook
You can omit the comment lines to save typing if you prefer
Sub Colours()
‘Two nested loops to select the row and column of each cell
For intRow = 1 To 25
For intColumn = 1 To 25
‘Set the interior colour of each cell to an RGB value determined by its position
Cells(intRow, intColumn).Interior.Color = RGB(intRow * 10, intColumn * 10, 0)
Next intColumn
Next intRow
End Sub
Run the code from the Editor by clicking on the “play” button
2. Observe the effect on the worksheet
Note: You could use the macro dialogue to run the code but the button in the editor is often
a convenient alternative, for those who prefer it F5 is the keyboard shortcut for the play
button. Running the code in this way will run whatever subroutine the cursor is in at the time
so care must be taken if you have several macros in one window.
This code works on the range of cell A1:Y25 which is 25 columns wide by 25 rows deep.
We used two variables, both integers, to represent the row and column. These variables are called
intRow and intColumn.
We set the Interior.Color property of the cells, notice the American spelling of colour as it was
in the earlier example of Font.Color.
In operation the two loops are nested so that for every row every column is set. It would make
no difference if we used them the other way round and looped through the columns then the rows
but this way is more logical given the Cells statement uses row followed by column. The red and
green values are determined using the row and column variables multiplied by ten, this gives a
good spread within the range of 0-255 which is the range allowed in RGB. The blue value is set
to zero but feel free to experiment with any value between 0 and 255 if you want to change it.
For…Each…In
A particularly useful variation on the For…Next loop is the For…Each…In loop which loops
through all the items in a collection, Cells in a Range, Worksheets in a Workbook, etc.
To use this type of loop we must first understand the structure we are working with, the object
hierarchy described in chapter 1. The worksheets collection comprises all the worksheets in the
workbook, This is not the same as the Workbook object which contains all the worksheets but
can also contain other objects such as chart sheets and the code window.
This example shows a subroutine which places the names of all the worksheets in to the first row
of Sheet2.
Then we add 1 to the value of the intCol variable and go round the loop again using the next
column until we have worked through all the sheets in the collection.
This type of loop is useful because it does not require us to know how many items there are in
the collection, add a few more sheets and run the code again to see what happens.
When referring to cells in a collection we use an object variable dimensioned as a range because
a cell is a specific instance of a range.
Sub HowMany1()
Dim intRow As Integer
intRow = 0
Do While Cells(intRow + 1, 1) <> ""
intRow = intRow + 1
Loop
Range("C1") = "There are " & intRow & " consecutive occupied rows."
End Sub
Sub HowMany2()
Dim intRow As Integer
intRow = 0
Do
intRow = intRow + 1
Loop While Cells(intRow, 1) <> ""
Range("C2") = "There are " & intRow -1 & " consecutive occupied rows."
End Sub
Selection
There is a special range object called Selection, this is the selected range (as opposed to the active
cell).
5. With a range of cells selected, try these commands in the Immediate Window:
? Selection.Row
? Selection.Rows.Count
? Selection.Address
These properties allow you to use the Selection object in a routine like this
6. The code window for Sheet7 contains this code:
Sub AlternateRows()
Dim intRow As Integer
Dim intRowStart As Integer
Dim intColStart As Integer
Dim intRowEnd As Integer
Dim intColEnd As Integer
intRowStart = Selection.Row
intRowEnd = Selection.Row + Selection.Rows.Count - 1
intColStart = Selection.Column
intColEnd = Selection.Column + Selection.Columns.Count - 1
End Sub
7. Select a range on Sheet7 and run the code to see the result
Note the use of a space followed by an underscore character at the end of one of the lines to
indicate that the code continues on the next line, this is another useful tool when writing more
complex code as it allows long lines of text to be used without horizontal scrolling. If you prefer
to keep the line together just miss out the underscore and the carriage return/new line.
This routine shades alternate rows in the selected range, spend a little while examining the code
and seeing how it works. Observe the structure; declare and then initialise the variables then
perform the actions, this is a very common structure in programming.
In this chapter we have learned how to write a sequence of code to be repeated a fixed number
of times, until a condition is met, or once for each object in a collection. We have seen how to
declare and then use variables to hold values within a subroutine, and how to lay out code in the
code windows to make it easier to follow and understand.
As an illustration of the technique we will arrange some code to highlight the rows and columns
in a ten by ten grid where the value of the intersecting cell is 100 like this:
We will need to use two nested loops from 1 to 10 to test all the cells, when we find a cell which
equals 100 we will need to set the interior colour of the cells from 1 to 10 in that row and 1 to 10
in that column to yellow. The code will look like this:
Sub Target100()
'Declare variables for row and column
Dim intRow As Integer
Dim intColumn As Integer
'Loop through the Rows
For intRow = 1 To 10
'Loop through the Columns
For intColumn = 1 To 10
'Test the intersecting cell
If Cells(intRow, intColumn) = 100 Then
'if the cell =100
'Highlight the row
Range(Cells(intRow, 1), Cells(intRow, 10)).Interior.Color = RGB(255, 255, 0)
'Highlight the column
Range(Cells(1, intColumn), Cells(10, intColumn)).Interior.Color = RGB(255, 255, 0)
End If
'End the nested Loops in the right order
Next intColumn
Next intRow
End Sub
Notice how we have omitted some of the code; we have not set a step value so this will default
to one, and we have not used Else or ElseIf in the IF…Then structure because we are only
concerned with what to do if the condition is true, the Else and ElseIf lines would be superfluous
as there are no instructions to follow them.
1. The code above has been entered in the code window of Sheet1 in the VBABranching
workbook
2. Numbers have been entered in the first ten rows and columns of Sheet1 including the
number 100
3. Run the code to test it
4. Delete the number 100 from the sheet or change it to another value
5. Run the code again
We can improve the code by adding a line to clear the formatting before starting to test the cells,
this way we can avoid having highlights left over after the number has changed.
Goto
Another type of branching in code uses the keyword Goto. Early versions of Basic used line
numbers and the Goto statement caused the code to jump forwards or backwards to the line
number required. VBA does not use line numbers but we can still use Goto with labels which
we define with the colon character. Like this:
Label:
Goto is often an action within an If…Then structure allowing the same labelled block of code
to be used for several outcomes.
We can also use the Goto statement to create loops in code, maybe using an If…Then to test for
the end of the looped code. This can seem easier than using Do…While but it is not seen as good
practice as you can easily create a loop of code like this:
Sub ProblemCode()
StartOfLoop:
Goto StartOfLoop
End Sub
This code will simply repeat the second and third lines ad infinitum locking the workbook and
preventing you from doing anything else. It is best to avoid this type of problem altogether but
if you do accidentally create a loop like this you can usually break out of it, or any procedure
which is taking longer than expected, by pressing CTRL + Break. Be warned however that
occasionally the break key doesn’t work and the only way to regain control is to shut down Excel
forcibly, which can cause work to be lost.
Message Boxes
The message box is a fundamental tool for user interaction, providing a means for the programme
to instruct the operator or request confirmation of an action. In VBA the message box command
is MsgBox and the basic syntax is:
MsgBox prompt, buttons, title
There are two other arguments which allow advanced users to attach helpfiles in a particular
context but we will not use those in this course.
The only required argument is the prompt, or message, itself, the other two may be omitted if
they are not needed.
Prompt is literal text with a maximum of about 1,000 characters being allowed, it should be
enclosed in double quotes just like any other literal text.
Buttons is a numeric argument which is often replaced by the built in constant representing the
value required.
The more common values are:
Group Constant Value Description
vbOKOnly 0 Display OK button only.
vbOKCancel 1 Display OK and Cancel buttons.
vbAbortRetryIgnore 2 Display Abort, Retry, and Ignore buttons.
A
vbYesNoCancel 3 Display Yes, No, and Cancel buttons.
vbYesNo 4 Display Yes and No buttons.
vbRetryCancel 5 Display Retry and Cancel buttons.
A message box returns a value to the code which indicates which of the buttons has been clicked,
this allows the code to branch to the appropriate action using If...Then and GoTo.
These are the values returned by the various buttons and the associated VB constants:
Button Constant Value Button Constant Value
OK vbOK 1 Ignore vbIgnore 5
Cancel vbCancel 2 Yes vbYes 6
Abort vbAbort 3 No vbNo 7
Retry vbRetry 4
To display one of the message box icons in the box, add one of the constants from group B in
the table above.
The message box combined with a label, a GoTo statement, and a couple of If...Then statements,
allows us to write code which interacts with the operator. Try out this example:
Let’s look at this code bit by bit to see how it was put together:
This code could be written in several ways; it could use just one If…Then rather than two, or it
could use the variables in a different way, but it is a suitable illustration of the way in which code
can be made to interact with the operator.
intLoop = 10
NextVerse:
strVerse = intLoop & " green bottles hanging on a wall"
Range("A1:A2") = strVerse
Range("A3") = "And if 1 green bottle should accidentally fall..."
intLoop = intLoop - 1
Range("A4") = "There'll be " & intLoop & " bottles hanging on a wall"
intMore = MsgBox("Another verse?", vbYesNo, "Another?")
If intMore = vbYes And intLoop > 0 Then
GoTo NextVerse
End If
End Sub
Read the code above carefully, it is in the code window for Sheet3 if you want to see it
working.
Note the use of concatenation (&) with numbers and text.
Note the line which decrements the variable by one each time; intLoop=intLoop-1, this is a
common structure when loops are made in this way.
Note the If…Then statement checking to see if there are any bottles left as well as whether the
operator requests another verse using And to combine the two conditions. The And operation
means that both conditions must be true for the overall IF condition to be true.
As the GoTo statement is regarded as weak programming we may decide to use an alternative.
The same code could be written using a For…Next loop but we want to be able to leave the loop
using a message box as we can in the example above so we need a new command, Exit For,
which will leave the loop at any point.
You can try these alternative versions as well from the same code window.
Sub TenGreen_mk2()
Dim intLoop As Integer
Dim strVerse As String
Dim intMore As Integer
For intLoop = 10 to 1 step -1
strVerse = intLoop & " green bottles hanging on a wall"
Range("A1:A2") = strVerse
Range("A3") = "And if 1 green bottle should accidentally fall..."
Range("A4") = "There'll be " & intLoop -1 & " bottles hanging on a wall"
intMore = MsgBox("Another verse?", vbYesNo, "Another?")
If intMore = vbNo Then
Exit For
End If
Next intLoop
End Sub
This code does the same thing but without the Goto by using the Exit For to leave the loop at
will.
We could also use Do…While like this with an Exit Do command to leave the loop when there
are no bottles left:
Sub TenGreen_mk3()
Dim intLoop As Integer
Dim strVerse As String
Dim intMore As Integer
intLoop=10
intMore=vbYes
Do
strVerse = intLoop & " green bottles hanging on a wall"
Range("A1:A2") = strVerse
Range("A3") = "And if 1 green bottle should accidentally fall..."
intLoop = intLoop - 1
Range("A4") = "There'll be " & intLoop & " bottles hanging on a wall"
intMore = MsgBox("Another verse?", vbYesNo, "Another?")
If intloop=0 Then
Exit Do
End If
Loop While intMore = vbYes
End Sub
Note that the condition is placed at the end of the loop so we see at least the first verse.
Input Box
Another way to get input from an operator is by using the VBA InputBox function. There is an
application based alternative to this function which allows different data types to be entered but
the standard VBA version always returns a string or text input and that is what we will use.
The simple syntax for InputBox is:
InputBox Prompt, Title, Default
Again further arguments can be used, this time to set the position of the box and to add a helpfile
and context. We will not be using these extra arguments in this course.
Prompt, this is the text displayed in the box as an instruction to the operator.
Title is again the heading displayed at the top of the box.
Default is the text which is loaded in to the part of the input box where the user types, if the user
simply clicks on OK the default is the value returned by the input box.
Just like MsgBox, InputBox also has an alternative syntax using brackets when the value is to
be returned, in the case of input boxes however this is almost always a requirement so the
bracketed syntax is the one we will explore.
End Sub
When you run this code VBA checks the resulting string using If…Then to see if it is either still
the default text or is empty, in either case cell B2 is set with an appropriate greeting to an
anonymous operator. If the variable contains any other value this is assumed to be the requested
name and the greeting is set accordingly.
The OR between the two conditions means that either or both must be true to appear as a true
condition to the If…Then statement. And and Or are frequently used to create combined
conditions like this and you can use them as many tines as you require, combining AND and OR
using brackets will determine the sequence in which the conditions are combined.
For example; an If…Then which needs to test that a person is over 17 and is a member, or is
under 18 and accompanied by a member, or has paid an entrance fee, might look like this:
If (intAge >17 And strMember = "Yes") Or (intAge <18 And strAccompMember <>"") Or _
dblFeePaid >0 Then
This, rather complicated, condition could be expressed differently as an If...Then followed by
two Else If…Then lines each with a GoTo action referring to the rest of the code. Either
structure is acceptable and the choice of which to use may depend on the surrounding code,
maybe the fee needs to be processed or the accompanying member needs to be checked against
a list, in which case it may be more practical to break the If...Then into smaller parts.
1. In a new Workbook
2. Open the VBA editor
3. Click on Insert, Module to add a module to the Project Window
4. In the code window for the new module type the following two variable declarations:
Public intCol As Integer
Public intRow As Integer
Note the use of Public rather than Dim to indicate that these variables are to be made
available to any code in the workbook.
5. Add the following sub routine below these declarations
Sub SetColours(Red As Integer, Green As Integer, Blue As Integer)
Cells(intRow, intCol).Interior.Color = RGB(Red, Green, Blue)
End Sub
Note the three arguments inside the brackets, defined as integers and named Red Green
and Blue, they are used just like variables in the RGB statement which follows.
This sub-routine is in the Module Code Window rather than a Sheet Code Window so it
is also available from anywhere in the workbook.
6. In the code window for Sheet1 add the following sub routine
Sub D4Red()
intRow = 4
intCol = 4
Call SetColours(255, 0, 0)
End Sub
Note the Call to the sub routine SetColours in the module, which includes the three values
to pass to that sub routine as arguments.
7. Run the code on Sheet1 and observe the effect which depends on Global variables and
passing arguments between routines
8. Experiment with similar code on another sheet to show that the SetColours routine is
available from any project in this workbook
In this example the code in the module, which sets the colour, does not specify the sheet, so it is
applied to the active sheet. This means that if you make Sheet2 active and then run the code on
Sheet1 it is Sheet2!D4 which is formatted. If this behaviour is not what you want you can make
the code specific to the sheet or you can pass another argument to the SetColours sub routine to
specify which sheet is intended.
In this chapter we have explored some of the techniques used to interact with the operator
producing code which responds to input and allows the flexibility of different processes for
different situations. We have seen alternative types of loop and introduced the concept of
constants which can make code easier to understand.
Buttons
Running a macro from a button is a simple process in Excel
5. Add a control button to the worksheet by clicking somewhere near the top left corner
6. In the resulting Assign Macro dialogue box select your subroutine from above and click
on OK
7. Drag the sizing handles to make the button as large as you want it
9. Replace the default text with a suitable label for the button
Shortcut Keys
Macros can also be assigned to a shortcut key, not technically a control but another useful way
to run your code, particularly for code which formats or populates the active cell.
3. Click on Options
4. Assign a key combination to your macro
Here we have assigned Ctrl + Shift + A, the Ctrl key is already selected, so you just type an
upper case A to assign the shortcut key
5. Click on OK
6. Close the Macro Dialogue box
Select a cell and type Ctrl + Shift + A to test the key assignment, again this is a very ‘user
friendly’ way to run code for people who may not be comfortable using the macro dialogue, as
well as a quick way for you to access your routines.
Objects as Controls
Drawing objects in Excel can also be used as controls to run a macro.
5. Study the following lines of code in the Code Window for Sheet2
Sub SetColourRed()
ActiveCell.Interior.Color = RGB(255, 0, 0)
End Sub
Sub SetColourGreen()
ActiveCell.Interior.Color = RGB(0, 255, 0)
End Sub
Sub SetColourBlue()
ActiveCell.Interior.Color = RGB(0, 0, 255)
End Sub
6. These three routines will colour the active cell red, green or blue respectively
7. Right click on the red circle and select Assign Macro
8. Using the procedure used above to assign a macro to a button, assign the SetColourRed
macro to the red circle
9. Repeat the above steps to assign the SetColourGreen and SetColourBlue macros to the
appropriate coloured circles
The circles now act as controls and clicking on one will assign the chosen colour to the active
cell. Test the effect by selecting various cells and colouring them.
Events
Excel has a limited number of events which are accessible to VBA, particularly when compared
to Access where some individual objects have ten or more events associated with them, but there
are still some useful techniques to be employed.
Workbook Events
When an event occurs such as the location of the active cell being changed, a new sheet being
added, or an existing one being selected, Excel checks to see if any code is associated with that
event and runs it if there is.
7. Drop down the right list (probably now with Open in it)
8. Select NewSheet
You should see some code like this in the code window:
Private Sub Workbook_NewSheet(ByVal Sh As Object)
End Sub
There may also be a similar block of code for the Workbook_Open event, you can ignore or
delete this.
Any code which we add between the Private Sub… and End Sub lines will be run whenever a
new sheet is created.
With…End With
The code we used above repeatedly refers to the range A1, this means that we have to type this
value several times and when the code runs Excel must evaluate the range each time. We can
make the code quicker and perhaps easier to type by using the With…End With structure.
This structure defines a block of code which all refers to a particular object, in this case the range
A1, and allows us to just use the properties and methods of that object without referring to it
every time.
We can rewrite the code using a With…End With structure like this:
1. After the line which merges the cells add a new line containing the command:
With Range("A1")
This instructs VBA to use the value Range("A1") in the following lines until the End With is
reached
Modify the following five lines by removing the reference to the range, they should look like
this when you’ve finished:
.Value = "This information is confidential"
.Font.Bold = True
.Font.Size = 18
.RowHeight = 24
.HorizontalAlignment = xlCenter
Note that they all start with the dot and we have used the Value property in the first line as
the default no longer applies
2. Add the End With line after the rows you just edited
The final code should look like this:
This structure will speed up code where it saves VBA processing references multiple times, the
saving in this case is negligible but it could be significant in a long loop or if the reference was
longer.
Worksheet Events
The events above all operate at the workbook level and therefore apply to every worksheet, if
you want code to run on just one sheet you use the code window for that sheet in a similar way.
4. In the right hand drop down list select SelectionChange (this may already be selected)
Two lines of code are generated as before but this time the event procedure is
Worksheet_SelectionChange which means that the event is triggered only when address of the
selected cell on this worksheet changes.
We will write a routine to highlight any cells containing the same value as the selected cell within
the range A1:T40. This represents 40 rows and 20 columns; 800 cells in all.
This range has already been populated with random numbers between 1 and 10 for testing.
5. In the code window for Sheet3, between the two existing lines of code, type
Dim intX As Integer
Dim intY As Integer
Range("A1:T40").Interior.ColorIndex = xlColorIndexNone
Range("A1:T40").Font.ColorIndex = xlColorIndexAutomatic
For intY = 1 To 40
For intX = 1 To 20
If Cells(intY, intX) = ActiveCell Then
Cells(intY, intX).Interior.Color = RGB(255, 255, 0)
Cells(intY, intX).Font.Color = RGB(255, 0, 255)
End If
Next intX
Next intY
Test the code by selecting any cell in the range A1:T40 and observe all the cells with the same
value changing colour
This is a breakdown of how the code works; remember it runs every time you select a different
cell on this sheet.
In the last example we saw several of the techniques we have been practicing being used together;
the nested loops, the If…Then, constants, variables, and both the Range and Cells techniques for
selecting cells.
In this chapter we have explored ways in which we can run our code either ‘on demand’ using a
mouse click or key stroke, or automatically using the built in events in Excel, we have added to
the properties and methods we can use and seen several new actions in use. We have also begun
to explore ways to optimise our code using structures such as With…End With.
In this course we have provided a very basic introduction to the use of VBA, it is not intended
to describe best practice in programming or to offer solutions to practical problems. Many of the
techniques can be applied in different ways to achieve the same results and often there is no
preference indicated for one procedure over another.
Properties of Interior
Name Description
Color Sets or reads the foreground colour of the font using a decimal
number or sets it using RGB values as described below.
ColorIndex Uses a constant to define colour properties such as Automatic or
None
Properties of Font
Name Description
Bold Boolean value (true or false) corresponding to the Bold setting of
the font used in the range. Returns Null if the range contains some
bold and some normal cells.
Italic As above but for the Italic setting of the font.
Underline This property can be set using true or false but also accepts and
returns numeric values representing the various types of underlining
available in Excel.
Color Sets or reads the foreground colour of the font using a decimal
number or sets it using RGB values as described below.
ColorIndex Uses a constant to define colour properties such as Automatic or
None
Size The size of the font in points
Name The name of the font e.g. Calibri as a literal string
When a colour is to be read or set using decimal values the number represents the red, green and
blue proportions as numbers between 0 and 255 where 0 is none of that colour and 255 is fully
saturated colour. When the three numbers are the same the colour is a shade of grey somewhere
between black (all zero) and white (all 255).
The decimal number can be calculated using this formula:
(red value) + (256*green value) + (256*256*blue value)
Pure red is 255
Pure green is 65280
Pure Blue is 16711680
White is therefore 255+256*255+256*256*255 or 255+65280+16711680 or 16777215
Fortunately VBA has a function to calculate these values for us, we can use RGB(#,#,#) to
specify any of the available colours using the three values between 0 and 255. If you have a very
large number of RGB functions you could speed your code up slightly be replacing them with
the decimal equivalents at the expense of making it harder to read the code.
Our small team of skilled tutors comprises computing practitioners who actually use
the IT in their work, so the sessions are based not only on theory but on practical
experience. Our IT workbooks, which are designed for self-paced learning, are
available from the ‘Resources’ section of our website.