Excel VBAExcel 2003
Excel VBAExcel 2003
Introduction
Prepared By
Daniel Lamarche
ComboProjects
Excel VBA
Last Update: 21 June 2011
Introduction
Prepared by Daniel Lamarche
[email protected]
Table of contents
INTRODUCTION .................................................................................................................................... 4
DIFFERENCE WITH MACROS AND VBA ..................................................................................................... 4
WHAT DO I DO WITH VBA? .................................................................................................................. 5
Recording a new Macro................................................................................................................ 5
Where are all my macros?............................................................................................................ 6
Inserting a new module ................................................................................................................ 6
About projects and modules ........................................................................................................ 6
Removing a module...................................................................................................................... 7
About the Personal macro workbook .......................................................................................... 7
WANT TO KNOW MORE ABOUT VBA? .................................................................................................... 8
Where should I start? ................................................................................................................... 8
MY FIRST MACRO................................................................................................................................. 9
Recording the MyReport macro ................................................................................................... 9
Running the Macro ....................................................................................................................... 9
Viewing the macro ....................................................................................................................... 9
About The Object Model ............................................................................................................ 11
PART 1 - INTRODUCTION TO VBA.......................................................................................................... 12
Sub Procedures........................................................................................................................... 12
Functions .................................................................................................................................... 12
VARIABLES ......................................................................................................................................... 13
Forcing the declaration of variables ........................................................................................... 14
Reasons to declare all variables ................................................................................................. 14
Scope of variables....................................................................................................................... 14
THE IMMEDIATE WINDOW ................................................................................................................... 15
Date - Time functions ................................................................................................................. 16
Working with numbers ............................................................................................................... 16
String functions .......................................................................................................................... 16
Concatenation ............................................................................................................................ 17
Excel objects ............................................................................................................................... 17
Useful keyboard shortcuts in the Immediate Window .............................................................. 19
Useful keyboard shortcuts in the Code Window ....................................................................... 19
Maybe the most common use of the Immediate Window ........................................................ 19
COMMENTING YOUR CODE .................................................................................................................. 20
INDENTATION..................................................................................................................................... 21
THE CONTINUATION CHARACTER........................................................................................................... 22
CONDITIONAL STRUCTURES .................................................................................................................. 23
The If – End If structure .............................................................................................................. 23
The Select Case structure ........................................................................................................... 24
Important difference between the If and the Select Case structure ......................................... 25
Nesting If – End If statements .................................................................................................... 25
LOOPING STRUCTURES......................................................................................................................... 26
The Do – Loop structure ............................................................................................................. 26
The For – Next structure ............................................................................................................ 28
Nested For Loop ......................................................................................................................... 29
The For Each – Next flavour ....................................................................................................... 29
PASSING PARAMETERS ........................................................................................................................ 30
Supplying a parameter to a function .......................................................................................... 30
Supplying a parameter to a Sub ................................................................................................. 31
NAMED PARAMETERS.......................................................................................................................... 32
THE WITH STATEMENT ........................................................................................................................ 33
Nested With Statements ............................................................................................................ 34
DEBUGGING YOUR CODE ..................................................................................................................... 34
The Debug.Print statement ........................................................................................................ 35
Using Breakpoints to stop the code ........................................................................................... 35
The Current Line of Execution .................................................................................................... 35
About the Immediate Window................................................................................................... 36
Adding a Watch .......................................................................................................................... 36
ERROR HANDLING............................................................................................................................... 37
The On Error Statement ............................................................................................................. 37
The Resume Next Statement...................................................................................................... 38
UNDERSTANDING ARRAYS .................................................................................................................... 39
About arrays and index .............................................................................................................. 39
Looping through an array ........................................................................................................... 39
Declaring Arrays ......................................................................................................................... 40
What is the size of an array? ...................................................................................................... 41
Dumping an array in a worksheet .............................................................................................. 41
About dynamic arrays ................................................................................................................ 42
About the Redim statement ....................................................................................................... 42
Two dimensional arrays ............................................................................................................. 42
In conclusion............................................................................................................................... 43
PART 2 - MORE ABOUT EXCEL’S OBJECT MODEL...................................................................................... 44
About The Term Object .............................................................................................................. 44
About The Term Collection......................................................................................................... 45
About Properties and Methods .................................................................................................. 46
Specifying an Item in a Collection .............................................................................................. 47
Looping Through Items in a Collection ....................................................................................... 48
ENTERING FORMULAS IN A RANGE......................................................................................................... 49
The R1C1 Notation ..................................................................................................................... 49
EXPLORING THE RANGE OBJECT ............................................................................................................. 51
Referencing a Range ................................................................................................................... 51
The CurrentRegion property ...................................................................................................... 52
The Columns and Rows Properties............................................................................................. 52
The Resize Property .................................................................................................................... 53
The Offset property .................................................................................................................... 54
The Cells property ...................................................................................................................... 54
Multiple Ranges Selections ........................................................................................................ 56
IN CONCLUSION ................................................................................................................................. 57
CONTINUE YOUR EXPLORATION ............................................................................................................ 58
Excel VBA Introduction – Part 1
Introduction
Excel VBA1 is a programming language used to automate Excel actions. You probably have heard that
this was the job of macros. Although it is associated with programming the word macro is often
misinterpreted and should be used sparingly.
The term ‘Macro’ comes from an archaic language used in the 80’s to group many commands into one
macro (literally 'large') command. Microsoft has perpetuated a major confusion with the users by still
referring to them as "macros" instead of VBA procedures.
Running a macro command would run all the application’s commands associated with this macro. For
instance a PrintReport macro would:
1) Import Data from an external file
2) Eliminate extraneous columns
3) Bold column headings
4) Add subtotals at the bottom and other summary
5) Print the report
All these tasks would be carefully planned and rehearsed by the developer then recorded (or written)
using the ‘Macro Language’ native to the application. All these tasks would then be grouped under the
name PrintReport.
When the user would run the PrintReport macro, the application would execute each command
starting with the first one down to the last one. Finally the macro would terminate.
1
This document uses the Excel 2003 command interface. When appropriate a note will indicate the
Excel 2007 alternative.
4
Excel VBA Introduction – Part 1
If - Then - Else ............. Allow alternate statements to be run based on the result of a condition.
Select Case .................. Executes one of several groups of statements, depending on the value of one
expression.
Do While - Loop .......... Execute one of several groups of statements as long as a condition remains
true.
For - Next .................... Run one or several groups of statements a specified number of times.
For Each – Next ........... Run one or several groups of statements on each element (object) in a
collection of objects. For example all Worksheets in a Workbook.
With – End With.......... The With statement allows you to perform a series of statements on a specified
object without qualifying the name of the object over again.
VBA is also much more procedural in the sense that existing code can be reused; something that was
technically inexistent in the macro language.
This mean that if, for example, you create a command that alerted the user about a situation, you
could built it in such a way that the same statements could be used for a variety of situations by using
the same procedure over and over again.
In conclusion, you can create macros that will repeat what you taught them to do or you can create
new tools that don’t exist in Excel and use them to intelligently automate your everyday tasks
2
In this document we will use the mixed case notation to name all VBA objects. In the mixed case
notation all characters are in lowercase except for the first letter of each word.
5
Excel VBA Introduction – Part 1
The Web site www.comboprojects.com contains a link to a guided project using the macro recorder. In
the Handout link click the Excel VBA Files in the Excel 2003 section or Excel 2007 to download a zip file
contain a PDF file, three workbooks and two text file. The tutorial in the PDF file will give you a solid
basis in what VBA is all about.
Where are all my macros?
All macros are saved in modules inside the workbook where they were created. They exist in a parallel
environment called VBE (Visual Basic Editor).
These modules can only be seen using the VBE. To access the VBE press Alt+F11 on your keyboard. In
the Project window you see the names of all the open workbooks. Each workbook has a Microsoft
Excel Objects item that you can expand or collapse. If you have created a macro in a workbook, it will
also have a Module item. Below is a screenshot of the VBE with the name of its major component.
Split Bar
Project window
Ctrl+R Code window
F7
Properties window
F4
Immediate window
Ctrl+G
7
Excel VBA Introduction – Part 1
Depending on your Windows setup, you may also find it under the Program Files folder:
C:\Program Files\Microsoft Office\Office11\XLSTART
In Windows 7 the folder is C:\Users\AppData\Roaming\Microsoft\Excel\XLSTART
The PERSONAL workbook is not visible in the Excel interface. It will be visible in VBE though. To see the
PERSONAL workbook in Excel, choose Window > Unhide. In the Unhide dialog box select
PERSONAL.XLS and click OK.3 If you followed the steps above to create the PERSONAL macro workbook
you may want to delete its Module1 since it only contains a dummy macro.
It is a good idea to keep this macro workbook hidden because it will be in the way every time you open
Excel and you (or a user) run the chance of modifying it accidentally. To hide the PERSONAL.XLS
workbook make it the active workbook then choose Window > Hide.
If you make any change to the PERSONAL.XLS macro workbook you will be asked to save the changes
upon exiting Excel.
3
In Excel 2007 the workbook name is PERSONAL.XLSB. You can toggle its visibility using the Unhide
and Hide commands in the View tab then the Window group.
8
Excel VBA Introduction – Part 1
My First Macro
In this section we are going to use the Macro Recorder to generate the VBA code for a small report.
Then we are going to look at the code and amend it so that it looks better and runs smoother.
It is important to remember that there are many things the Macro Recorder cannot record. For
instance it knows nothing about variables, how to use IF structures and DO loops. On the other hand
the Macro Recorder will show you some basic VBA code allowing you to access and manipulate Excel
objects.
Recording the MyReport macro
In Excel 2003 display the Visual Basic toolbar. The first two buttons
allow you to run and record macro respectively. In Excel 2007 click
the Developer tab to find the corresponding commands.
Follow these steps:
1. While in a new workbook click Record Macro.
2. In the Macro Name box type ‘MyReport’.
3. In the Shortcut key box type an uppercase ‘M’. This will assign the Ctrl+Shift+M keystroke to the
macro. Click OK.
4. Click cell A1 (even if are already in A1) and type your company name and hit Ctrl+Enter.
5. Select A1:D1 and click Merge and Center.
6. Increase the font size of cell A1 to 16 pts.
7. In A2 type ‘Prepared by’ and type your name.
8. In A4 type ‘Travel’ and in A5 type ‘Meals’.
9. In A6 type ‘Total’ and hit Arrow Right.
10. In B6 type '=SUM(B4:B5)' and hit Ctrl+Enter.
11. Format B4:B6 as 'Currency'
12. Format A5:B5 with a Bottom Border.
13. Select cell B4
14. Click Stop Recording.
Running the Macro
Move to a blank worksheet and press Ctrl+Shift+M. A report similar
to the one on the right appears. Type a value in B4 and another
one in B5 to complete the report.
One problem with this sort of macro is that they will always
reproduce the same report. What if, for example, we wanted
another report using another name in cell A2. Using the Macro Recorder this simple task would be
impossible. If you require different names in the report then you will need to create one macro for
each name! Not practical.
Viewing the macro
To view the code recorded by the macro display the VBE window by hitting Alt+F11.
If the Project window is not visible press Ctrl+R. Expand the Module branch and double-click Module1
to open it in the Code window. If necessary maximize your Code window.
9
Excel VBA Introduction – Part 1
10
Excel VBA Introduction – Part 1
VBA communicates with Excel’s object model to access different objects in a Workbook. In other
words Excel exposes its object hierarchy to VBA through its object model. Since all objects in a
workbook (including Excel itself) are tied to this model they can be entirely manipulated from VBA.
To see how VBA knows about Excel's objects choose Tools > References while in Excel's VBE. The
second item that is checked should be Microsoft Excel 11.0 Object Library. This library contains the
information about where each object is in the hierarchy of Excel objects.
For example a worksheet has a Name property that allows you to read or change its name. A cell has
Font and ColorIndex properties allowing you to examine or change the font and colour for that cell.
The first time you save the workbook you use the SaveAs method of the Workbooks object to specify
a name. Then you can use the Save method to update your changes or the Close method to close the
workbook.
As you can see, properties and methods names often resemble Excel commands but it is not always
the case. You will need to learn a new vocabulary to be able to talk to Excel through its object model.
This takes a while.
With what we have learned above can you guess if the last word of each of these statements is a
method or a property? Ask yourself if the last word sounds like an action (Method) or an attribute
(Property).
Worksheets.Add
Charts("Sales2007").HasTitle
Sheets.Count
Range("A1:C3").Select
Range("C1:C5").Copy
ActiveCell.CurrentRegion.Address
11
Excel VBA Introduction – Part 1
Variables
A variable is an object represented by a single word that will hold a value while the procedure (Sub or
Function) is running. They lose their value once the procedure is over. Sounds simple? It is.
It is exactly like the good old time when your math teacher said “OK let x equal 10.” So for the duration
of the problem x = 10. Once the problem was solved ‘x’ disappeared from the board. It became out of
scope or nonexistent.
In VBA you need to create a variable and assign it a data type before you assign a value to it. This is
because a variable can refer to a whole number, a decimal number, a text string, an array of values,
even a whole workbook!
Creating a variable is called declaring a variable. When you declare a variable you also specify its data
type. When you become more familiar with VBA in Excel (or in any applications) you will fully
appreciate why you need to declare all variables.
To declare a variable use the Dim statement with As to specify the data type. Here are a couple of
examples:
Dim intQuantity As Integer ' A whole number
Dim strAnswer As String ' Some text
Dim sngDiscount As Single ' A number with decimals
Dim wksJanuary As Worksheet ' Do we need to explain?
Dim rngTable As Range ' A selection in a sheet
The first three variables will simply hold data: A whole number, some characters and a decimal
number. The last two are Object Variables designed to hold objects in the Excel object model: A
Worksheet and a Range object. Once a variable is declared you can assign a value (or an object) to that
variable.
Here are some easy examples:
intQuantity = 20
strAnswer = "VBA is fun to learn"
sngDiscount = 0.05
Set wksJanuary = Worksheets("January")
Set rngTable = Range("A1:C5")
13
Excel VBA Introduction – Part 1
Once initialised, you can use a variable’s value simply by using its name. You can even change its value
to suit the current need.
You will note that variables assigned to objects (as opposed to data) need to use the Set statement
otherwise you will get an error and your procedure will stop.
Forcing the declaration of variables
By default VBA does not enforce variable declaration; it is an option that you can set. Do yourself a
favour and enable this option once and for all by following these steps:
In VBE choose Tools > Options
In the Editor tab enable Require Variable Declaration.
In the future, all new modules you create will have the following line in the Declaration section (at the
top):
Option Explicit
Reasons to declare all variables
Here are a couple of reasons why all variables should be declared in all procedures:
1. It saves memory usage. The amount of memory reserved for a variable will correspond to its data
type.
2. Once declared you can use an amazing feature called Complete Word that will automatically
complete the variable names for you. To use Complete Word simply type the first three or four
characters and press Ctrl+Space.
3. If you type a variable name and make a typo you will get a “Variable Not Defined” error as soon as
you attempt to execute the code and VBA will highlight the unknown variable. This is because,
being a typo, this variable was not declared. So you should take advantage of the Complete Word
feature discussed above.
4. With Object variables you will able to benefit from the AutoList feature. For example typing
ActiveSheet and a period will not activate the AutoList feature. This is because there are different
types of sheets in Excel. It could be a normal worksheet or a chart sheet.
Declaring a variable as Worksheet object and assigning it to the ActiveSheet will display the
AutoList associated to a worksheet.
5. Finally VBA will often warn you if you accidentally assign the wrong type of value to a variable. For
example you cannot assign a text string to a numeric variable unless the string is exclusively made
of numeric digits. This becomes even more important with object variables.
Most experienced programmer will tell you that if a language allows variable declaration then by all
means you should use this feature.
Scope of variables
The scope of a variable determines how a variable can be accessed and how it can be used by the
procedures.
The most common type of scope is the procedure scope. This simply means that all variables declared
within a procedure can only be accessed by the statements within the procedure where they are
created.
Sub MyProcedure()
Dim Value As Integer
14
Excel VBA Introduction – Part 1
15
Excel VBA Introduction – Part 1
To learn more about a statement move the insertion point in the VBA function name and hit the F1 key
(Help). Sometimes the Help feature contains a short example containing code. You can copy this
example and paste it in a module to try it.
Date - Time functions
?Date
?Time
?Now
?Month(Date)
?MonthName(Month(Date))
?Weekday(Date)
?WeekdayName(2)
?DateAdd("d",15,Date)
?DateDiff("ww",#09/15/2007#,Date)
(VBA dates must be entered as month/day/year)
?Format(Date,"dddd dd-mmm-yy")
?Format(Date,"mmmm-yy")
?DateSerial(Year(date),Month(Date)+1,1)
Working with numbers
?FormatPercent(0.05,1)
?FormatCurrency(1200,0)
?Abs(-5)
?Sqr(144)
?Fix(3.14159)
?25 Mod 5 also try ?25 Mod 6
?25 \ 6
?Sgn(-2) also try ?Sgn(2)
?Cint("3.6")
?IsNumeric("12") try with "Day"
?Round(17.268,2) try with 1 or 0
String functions
x="Learning VBA can be fun"
?x
?Len(x)
?Left(x,8)
?Right(x,3)
?Mid(x,10,3)
?InStr(1,x,"can")
16
Excel VBA Introduction – Part 1
?Replace(x,"VBA","Piano")
?LCase(left(x,8))
?UCase(Right(x,3))
?InStr(1,”Know-it-All","-") try 5 an 8
?Trim(" Wow ")
?StrConv("VISUAL BASIC",vbProperCase)
?StrConv("VISUAL BASIC",vbLowerCase)
?Choose(2,"Mouse","Screen","Printer")
?LTrim(" Sky ") try with RTrim
?String(15,"-")
?CurDir
Concatenation
a=<replace with your first name>
b=<replace with your surname>
c=<replace with your suburb>
?a & b & c
?a & " " & b & " lives in " & c
?UCase(b) & " " & Left(a,1) & "."
d = UCase(b) & " " & Left(a,1) & "."
?d
?d & "(" & c & ")"
Excel objects
Choose Insert > Module to create a new module in your workbook. In the module type the following
lines:
Sub LearningExcel()
Dim wkb As Workbook
Dim wks As Worksheet
Dim rng As Range
End Sub
While the insertion point is inside the procedure, press F8 on your keyboard twice. Type lines below in
the Immediate Window and hit Enter after each one. Note the result for each on the right. Some lines
will not display a value in the Immediate Window.
You might need to press Alt+F11 to toggle between Excel and VBE to see the result or view Excel and
the VBE window simultaneously.
Set wkb = ActiveWorkbook
?wkb.Name
?wkb.Sheets.Count
wkb.Worksheets.Add
17
Excel VBA Introduction – Part 1
ActiveSheet.Move After:=Sheets(Sheets.Count)
?wkb.Saved (That is Saved)
wkb.SaveAs("MyWorkbook")4
?wkb.Saved
?wkb.Name
?wkb.FullName
wkb.Worksheets("Sheet1").Activate
wkb.Sheets("Sheet1").Range("A1")="Hello"
Set wks=wkb.Sheets("Sheet2")
?wks.Name
wks.Name = "January"
wks.Activate
wks.Range("A1")="January Sales"
wks.Range("A1").Font.Bold=True
Set rng = wkb.Sheets(wks.name).Range("A2:C2")
rng.Interior.ColorIndex=37
rng.Cells(1,1)="Name"
rng.Cells(1,2)="Qty"
rng.Cells(1,3)="Amount"
set rng = rng.Offset(1,0)
rng.Cells(1,1)="Bob"
rng.Cells(1,2)=5
rng.Cells(1,3).Formula="=B3*45"
set rng = rng.Offset(1,0)
rng.Cells(1,1)="Dan"
rng.Cells(1,2)=7
rng.Cells(1,3).FormulaR1C1="=RC[-1]*45"
set rng = rng.Offset(1,0)
rng.Cells(1,1)="Total"
rng.Range(Cells(1,2),Cells(1,3)).Select
Selection.FormulaR1C1="=SUM(R[-2]C:R[-1]C)"
wkb.Save
4
In Excel 2007 you need to use wkb.SaveAs "MyWorkbook",52. This number forces the
workbook to be saved as a Macro Enabled Workbook (.xlsm).
18
Excel VBA Introduction – Part 1
Click in the code window and press F5 to terminate the procedure. This will annihilate the three
variables.
Useful keyboard shortcuts in the Immediate Window
In the Immediate Window there are a few keyboard shortcuts that you should know about. Some also
work in the Code Window as well. Do not attempt to learn all these shortcuts in one day. Keep them
close and adopt them one at a time.
Keyboard shortcuts will allow you to focus on the task you want to do and you will be doing it faster.
Do not attempt to learn all these shortcuts in one day. Keep them close and adopt them one at a time.
Keyboard shortcuts will allow you to focus on the task you want to do and you will be doing it faster.
Maybe the most common use of the Immediate Window
Since the Immediate Window is also known as the Debug Window (it used to be called that way) it
must also be useful for debugging. For instance you can print a variable value in the Immediate
Window by using the Debug.Print statement anywhere in your code.
19
Excel VBA Introduction – Part 1
The Debug.Print statement will print the value of a variable so that you can see if it is what you
would expect it to be. For example a variable can change value many times in a loop. The
Debug.Print statement followed with the variable name will allow you to keep a temporary record
of the value. For instance in the Code Window type the following simple procedure:
Sub AsciiChar()
Dim i As Integer
For i = 1 To 10
Debug.Print i + 64; Chr(i + 64)
Next i
End Sub
This not-too-useful procedure will print in the Immediate Window the first 10 letters of the alphabet
along with their ASCII value. For example A is ASCII 65, B is ASCII 66 and so on.
Make sure the Immediate Window is opened
and empty (Press Ctrl+A then Delete). While
the insertion point is anywhere in the
procedure hit F8. The first line is highlighted.
The procedure runs in Break Mode. This means that each line will be executed only when you hit F8.
Hit F8 two times. You are now in the line with the Debug.Print statement. Press F8 once and look
in the Immediate Window. You see the number 65 along with the letter A.
Continue pressing F8 and the procedure will execute the For loop again. The second
time the loop is executed the values 66 and the letter B are printed in the Immediate
Window.
Reset
Continue pressing F8 until the loop is executed 10 times or click Reset in the
Standard toolbar to stop the execution of the procedure.
There are a few other techniques that can be used to debug your procedures. We will get familiar with
some of them later in this document.
20
Excel VBA Introduction – Part 1
End Sub
Use comment to document updates and revisions to your code. At the top of the module you could,
for example, briefly describe each procedure in the module with an example of how to use it. An
interesting use of comments is to stop a line from being executed. You might want to test a procedure
without running a few lines but you don’t want to delete them.
VBE has an Edit toolbar with two buttons Comment Block and Uncomment Block allowing you to
comment and uncomment multiple lines. Choose View > Toolbars > Edit to make the toolbar visible.
Indentation
Indentation has nothing to do with code execution but all to do with readability. As you might expect
you increase indentation with the Tab key and decrease it using Shift+Tab or Backspace.
In VBA many constructs have a begin statement and an end statement. All lines of code inside such
constructs should (maybe must) be indented. By default the Tab is set to four spaces.
The following is a list of the most common constructs that use the Begin and End pair of statements.
In the following (incomplete) example of a Sub procedure you can see how indentation allows you to
see where each pair of statements starts and ends (don’t worry about the code. Consider the
indentation instead):
Sub SelectACell()
Dim myRange As Range
On Error Resume Next
Set myRange = Application.InputBox("Select a cell please.")
If Not myRange Is Nothing Then
Debug.Print myRange.Address(0, 0)
Range(myRange.Address).Select
Else
Debug.Print "Cancelled by user."
End If
End Sub
Can you see how the If-Else-End If structure is easy to locate visually? Imagine if there was
more constructs of that type embedded inside one another.
Now look at the same as the one above but without indentation. Can you see how difficult it is to
decipher its structure?
Sub SelectACell()
Dim myRange As Range
On Error Resume Next
Set myRange = Application.InputBox("Select a cell please.")
If Not myRange Is Nothing Then
Debug.Print myRange.Address(0, 0)
21
Excel VBA Introduction – Part 1
Range(myRange.Address).Select
Else
Debug.Print "Cancelled by user."
End If
End Sub
One of the nice features of VBE is indenting multiple lines in one operation. Select a few consecutive
lines and hit Tab to indent or Shift+Tab (do not use Backspace with multiple lines) to decrease
indentation of the selection.
The procedure above uses only three levels but it is not uncommon to see much more than that. The
next example uses fake code to show even more levels of indentation:
Sub ShowIndentation ()
' This fake example illustrate well the use
' of indentation in code.
If Value > 100 Then
If Weight < 25 then
Do While Duration < 12
Update each value
Loop
Else
Select Case Weight
Case 1 to 15
Message = "To high!"
Case 16 to 24
Message = "Careful Now!"
End Select
End IF
Else
Value = Value * 1.1
End If
End Sub
22
Excel VBA Introduction – Part 1
The continuation character gives you the possibility to break a line where you want. Your printouts will
therefore be easier to read. In the next example a long concatenation is broken in multiple lines to
make it easier to read (and print):
strMessage = "Do you really want to delete customer " _
& varCustomer & " from your list?" & vbLf _
& "This customer has " & varCount & " pending items to ship."
Normally this line would too long for your screen. Breaking it in shorter lines makes it easier to read
and print. The Visual Basic constant vbLf stands for Line Feed. The message is broken in two lines.
Normally the continuation character is added after a closing talking marks or after a VBA constant.
Another good place is after a comma used for separating parameters. The two examples above use the
continuation character after a comma, a closing talking mark and a VBA constant.
The following example is invalid:
strMessage = "Do you really want to _
delete this customer?"
Conditional Structures
Of all the control structures available in VBA, conditional structures may be the most common ones.
There are basically two different conditional structures:
If – End If
Select Case – End Select
Both of them allow you to execute some lines of VBA code depending on the result of some condition.
Let’s see a few examples of If – End If structures.
The If – End If structure
The following straightforward If – End If statements will execute some code if the variable intValue
is greater than or equal to 10.
If intValue >= 10 Then
<VBA code to run if True>
End If
Note that if the value is less than 10 no code is executed in this If – End If. For some alternative code
add the Else statement to the structure. In this case we should call it an If – Else – End If structure.
If intValue >= 10 Then
<VBA code to run if True>
Else
<VBA code to run if False>
End If
In the example above if the number is less than 10 then the statements following the Else keyword
will be executed.
If you have more than two conditions you can use the ElseIf key word. For example:
If Performance = 1 Then
Bonus = Salary * 0.1
ElseIf Performance = 2 Then
23
Excel VBA Introduction – Part 1
24
Excel VBA Introduction – Part 1
Discount = 0.10
End If
Else
Discount = 0.04
End If
If the variable Suburb is equals to Geelong then there is an additional test to do: Check if the quantity
is below 20 (for a discount of 6%) or 20 or more (for a discount of 10%). If the suburb is not Geelong
then the discount is 4%.
Looping Structures
The purpose of a loop is to get VBA to repeat a snippet of code a certain number of times. The
iteration can be specified as a fixed number (e.g. do this 10 times), or variable (e.g. do this for as many
times as there are rows of data).
Loops can be constructed in many different ways to suit different circumstances. Often the same result
can be obtained in different ways to suit your personal preferences. The examples below will
demonstrate various ways to use loops in VBA.
There are two basic kinds of loops, both of which are demonstrated below: Do - Loop and For -
Next loops. The code to be repeated is placed between these keywords. Since looping is very often
used in programming it is suggested that you get quickly familiar with the different looping structures
in VBA.
The Do – Loop structure
In a Do - Loop structure the code between the Do and the Loop statements is executed for as long
as the condition specified in the Do line remains True. This type of loop is the one to use when you
cannot predict when the condition will become false. In other words, you don’t know how many times
the loop will iterate. Here’s a dummy example:
Do While <there is a value in the cell to the left>
valAmount = valAmount + the value to the left
Move one cell down
Loop
When the code enters the loop starting with the Do statement, it checks if the condition on the right of
the Do evaluates to True. If there is indeed a value in the cell to the left of the active cell then the code
in the loop is run. It increments the value of valAmount with the value found in the cell then move
the active cell down one row and repeat the loop again.
If the condition is still True the second time the loop is executed and the value of valAmount is
increased by the value of the next cell found. Now valAmount is equal to the sum of the first two
cells. The process continues until the condition next to the Do statement evaluates to False, there is no
value in the cell to the left. Data Val
The table on the right shows a loop executed five times. The first time val will equal 5. 5 5
The next time it is equal to 5+8=13, then 13+3=16, then 16+12=28 and so on until there 8 13
is not data in column Data. When the code runs the active cell is at the top of the 3 16
second column. 12 28
The actual code for such a procedure is: 9 37
26
Excel VBA Introduction – Part 1
Sub LoopCummul()
Dim valAmount As Integer
' As long as the cell to the left is not empty...
Do While Not IsEmpty(ActiveCell.Offset(0, -1))
' Cummulate values and write total in active cell.
valAmount = valAmount + ActiveCell.Offset(0, -1)
ActiveCell.Value = valAmount
' Move down one cell by selecting it.
ActiveCell.Offset(1, 0).Select
Loop
End Sub
This is a perfectly valid macro and it can be run anywhere in a worksheet. The macro will start
summing all values to the left until there are no more. If the cell to the left the active cell is blank VBA
will exit the loop. As you can easily appreciate, imagine writing a macro that would cumulate 1,000
values without using a loop!
The Do – Loop structure provides a mean to exit the loop if an unpredictable condition occurs. You
might decide that if the value to the right is a word then the loop must stop and the Sub must stop. To
exit a loop use the Exit Do statement and the code will continue after the Loop statement. For
instance:
Do While Everything is Fine
If Something Goes Wrong
Exit Do ' Resume after the Loop statement.
Else
Run the code
End If
Loop
Depending on how you interpret the condition (and personal preferences) there is also another flavour
you can use: The Do Until – Loop.
In a Do Until – Loop iteration will occur as long as the condition is False. The loop stops when it
becomes True. We could illustrate the two variations in plain English using:
Do While <The condition is True> ' Run while it is true
<VBA code to run>
Loop
Or
Do Until <The condition becomes True> ' Run while it is false
<VBA code to run>
Loop
Think of the Do Until flavour like a Do While except that the condition needs to be is False
instead of True for the loop to continue. Here is the same code found at the beginning of this section
but written another way:
Do Until <there is no more value in the cell to the left>
valAmount = valAmount + the value to the left
Move one cell down
27
Excel VBA Introduction – Part 1
Loop
It takes a little while to become familiar with various loops. Practice a bit by typing examples and you
will be fine.
The For – Next structure
If you know (or can get VBA to find out) how many times to repeat a block of code you can use a For
- Next loop. For example it is very easy to find out how many worksheets are in the current
workbook.
The For – Next loop requires a variable that will increment for each iteration until it reaches the
maximum value specified in the For line. When the variable reaches this value the loop automatically
stops and the code continues after the Next statement. Here’s a dummy example:
Dim x As Integer, valAmount As integer
For x = 1 to 10
valAmount = valAmount + x
Debug valAmount ' Print valAmount in the Immediate Window
Next x
The first time the loop is executed x=1 so valAmount = 1. The second time x=2 so valAmount = 3
(1+2), then when x=3, valAmount = 6 (3+3) and so on until the loop is executed ten times. The
variable valAmount will then be equal to 55: The sum of the first ten numbers. Here is an example of
a function using a For – Next loop:
Function CountHyphen(strWord As String) As Integer
Dim i As Integer, intCount As Integer
For i = 1 To Len(strWord)
If Mid(strWord, i, 1) = "-" Then
intCount = intCount + 1
End If
Next i
CountHyphen = intCount
End Function
You could use this function in Excel to count how many hyphens are in a cell entry. For example if A1
contained ‘The co-worker was well-received’ then the formula =CountHyphen(A1) would return 2.
The For – Next structure provides a mean to exit the loop if an unpredictable condition occurs. To
exit a loop use the Exit For statement and the code will continue after the Next statement.
One last note about the For – Next loop. You can change the way the variable increments by
specifying a value for the Step statement in the For line. In the next example the loop will run 10
times:
For i = 0 to 18 Step 2
<VBA code to run>
Next i
The variable i will have the value 0, 2, 4, 6, 8 and so on to 18. In the following example the variable
decrements by 1 every time the loop is executed.
For i = Collection.Count to 1 Step -1
28
Excel VBA Introduction – Part 1
29
Excel VBA Introduction – Part 1
Sub UpperEachCell()
Dim rng As Range
For Each rng In Selection
' Make each cell uppercase.
rng = StrConv(rng, vbUpperCase)
Next rng
End Sub
This sub will change all text entries in the selected cells in uppercase. Use vbLowerCase or
vbProperCase for other use of this Sub.
To loop through each worksheets in a workbook you can use the following:
Sub VisitEachSheet()
Dim wks As Worksheet
For Each wks In Sheets
' Print the name of each worksheet in the Sheets collection.
Debug.Print wks.Name
Next wks
End Sub
You will note that the name of a collection generally is the plural form of a work (Sheets, Names,
Workbooks, etc). You will find more information about collection in the topic: Specifying an Item in a
Collection of page 47 and Looping Through Items in a Collection on page 48.
Passing Parameters
When you create your own procedures you will often (but not always) feed them with a starting value
called a parameter. The parameter is processed by the procedure then it will either do something with
it (if it’s a Sub) or return a value (if it’s a Function)
Parameters are sometimes called arguments and your procedure many require more than one. This
may be easy to understand when you think that most Excel functions require one of more arguments.
The same principle applies here.
The following two sections will show a couple of easy examples:
Supplying a parameter to a function
Let’s start with functions because it is easier to understand why you would do this in the first place.
The following function calculates the area of a rectangle. Knowing the length of both sides of a
rectangle you can easily calculate its area:
Function AreaRect(Length As Integer, Width As Integer) As Integer
AreaRect = Length * Width
End Function
The AreaRect function requires two parameters: Length and Width. Both of them are integers
(whole numbers). There is only one line of code in this function. It simply multiplies the value of the
two parameters and assigns the result to the name of the function. This is how a function knows what
value to return. If A1 contains 3 and B1 the value 5 then entering the formula =AreaRect(A1,B1)
in any cell would return 15.
30
Excel VBA Introduction – Part 1
Your function could also be used in your code instead of in Excel. If you find that you often need to
calculate areas, simply create the function in your workbook and use it anywhere else in the same
workbook.
Examine the next example:
Function PaintCost(Width As Integer, Height As Integer) As Single
' Calculates the cost of the paint.
Dim LitrePaint As Integer, WallSurface As Integer
The PaintCost function needs two parameters: A Width and a Height values. To calculate the
cost of the paint the procedure also needs to know the area of the wall.
Since it doesn’t know how to do this it sends the two measurements to the AreaRect function that
will return that important information. The result of AreaRect is assigned to the variable
WallSurface and the procedure continues.
Depending of the area the procedure calculates the number of litres required. Finally PaintCost
(the function name) is assigned the number of litres times $45.00 (cost of each litre of paint).
To use a custom function in your code (as you would for any standard VBA function) assign the
returned value to a variable this way:
MyVariable = MyFunction(FirstArgument, SecondArgument)
In this case MyVariable will be assigned the value returned by MyFunction.
Supplying a parameter to a Sub
A sub may also require a parameter. Suppose that you often need to add a new worksheet at the end
of the workbook. The name of this worksheet will always be the name of the month specified by a
date parameter.
For example if the date supplied is 5-Nov-2007 then the name of the worksheet should be November.
The following Sub would do just that. Let’s not focus too much on how that procedure works but that a
Sub can accept a parameter.
Sub CreateMonthlySheet(datWhatDate As Date)
Dim strCurrentMonth As String
strCurrentMonth = MonthName(Month(datWhatDate))
' MonthName return the name of the month number.
31
Excel VBA Introduction – Part 1
ActiveWorkbook.Sheets.Add _
After:=Worksheets(Worksheets.Count)
ActiveSheet.Name = strCurrentMonth
End Sub
To call a procedure from within another one type the name of the procedure to run without brackets,
even if it requires an argument. For example:
MyProcedure strStringArgument, intNumericValue
Using the procedure above you could call it from another Sub the following way:
CreateMonthlySheet Date()
This would create a new worksheet with the current month name in the tab. This worksheet would be
the last worksheets in the workbook.
Named Parameters
This section will discuss a common way to specify parameters to methods (or actions) in the Excel’s
object model. This technique is used by many programmers but not by all.
All parameters of a method have a name. If you want, you can give a value to a parameter by
specifying its name prior to the value. Here’s a straightforward example. The MsgBox function can use
up to five parameters. Most programmers only use the first three: A Prompt, the Button configuration
and a Title (in that order).
Suppose that you want to specify only the prompt and the title while accepting the default button
configuration. Here are two ways to write this:
strVal = MsgBox("Do you really need this?", , "Important")
strVal = MsgBox(Title:="Important", _
Prompt:="Do you really need this?")
Although not apparent at first sight there are three important differences between the two
techniques.
Each parameter is preceded with the name of the parameter separated with a colon and an equal
character.
Note the two consecutive commas in the first example. They must be used because MsgBox has
three parameters but we are ignoring the second one (accepting its default value). If you skip a
parameter and want to move on to the next one you still need to use the comma.
The second example does not need extra commas.
Normally the order of the parameters for MsgBox is Prompt, Button and Title. Because the second
example uses named parameters you can specify the parameters in any order you want.
Here is another example. This example uses the Add method of the Sheets collection to add a new
worksheet. Normally the parameters for the Sheets.Add statement are:
Sheets.Add Before, After, Count, Type
If we want to use this code to add 2 worksheets after the Summary worksheets we could specify it in a
couple ways:
Sheets.Add , Sheets("Summary"), 2
Sheets.Add After:=Sheets("Summary"), Count:=2
32
Excel VBA Introduction – Part 1
Just remember that if you are going to use named parameters you must use a colon and an equal sign
to separate the parameter and its value.
33
Excel VBA Introduction – Part 1
34
Excel VBA Introduction – Part 1
Logical errors are the hardest one to locate because there is nothing wrong with the code. The error is
in the reasoning or the logic followed by the procedure. The VBE offers many tools to trap or zero-in
on a logical error and fixing it.
The Debug.Print statement
As we have seen in this course you can use the Debug.Print statement to dump a value in the
Immediate window. This allows you to save a copy of the value a variable has at some point. You can
print any VBA expression in the Immediate window. For example the statement:
Debug.Print "After " & i & " iterations the total is " & intTotal & "."
May print the following result: ‘After 5 iterations the total is 28.’
You will find that the Debug.Print statement is very useful in loops where a variable will take on
multiple values.
Using Breakpoints to stop the code
A breakpoint is a line where the code will stop
executing and enter Break mode. The line having a
breakpoint is not executed. Rather it waits for you
to resume the code in a couple of ways.
To set a breakpoint in your code move to the line where you wish to enter in Break mode and hit F9.
The whole line is highlighted in burgundy and a dot (a margin indicator) appears in the left margin.
Note that you cannot set a breakpoint on a line using the Dim statement or if it is blank.
When the procedure runs it will stop dead on the
line having a breakpoint. You will be in Break mode.
The VBE title bar will display [break] next to the
workbook name.
In Break mode you step into your procedure one line at a time by pressing F8. The yellow bar will move
one line down and wait. If you want you can hit F5 to resume the procedure or click on Reset to exit
Break mode. For more information on this topic see page 20
In Break mode you can see the value of a variable by moving your mouse over a variable or an
expression returning a value. This is very handy when you
are examining how a variable is doing in a loop.
On the right you can see that the current value for the
variable Cummulative is 12.
The Current Line of Execution
You noted the yellow arrow margin indicator in the left
margin. VBE calls this arrow the current line of execution. It
is pretty easy to understand that it points to the line that
will be executed next.
What is interesting about this arrow is that you can drag it
up or down in the margin so that you specify which line will run next. This allows you to re-run a
couple of lines or to skip some.
35
Excel VBA Introduction – Part 1
Some bugs are pretty nasty and need a thorough examination of how the code run before you discover
them.
About the Immediate Window
As you have seen in depth in the Excel objects section on page 17 while you are in Break mode you can
interact with Excel and interrogate variables and properties by typing expressions in the Immediate
window. When your procedures are in Break mode you can type an expression in the Immediate
window using any variable in your code to test for a value.
For example if your code has a variable called strSuburb and it is assigned a value you can retrieve its
value by typing (don't forget that you must be in Break mode to do this):
?strSuburb
You can type more elaborate expression too. For example (this one uses two variables):
?Mid(strSuburb,intPosition,2)
Finally, in a procedure using a selection assigned to the variable rng and two variables intRows and
intCols equal some value, you can type statements like:
?rng.Cells(intRows,intCols)
This expression prints the value of the cell intRows down and intCols across from the top left
corner of the selection assigned to rng. If, for example, intRows = 3 and intCols = 2 then the
above expression returns the value of the cell in the third row and second column or the selection.
The lesson here is: Do not forget the immediate window! It is not for nothing that it used to be called
the Debug window. It is an invaluable element of the VBE.
Adding a Watch
Last but not least is the Watches window. This window allows you to keep an eye on the evolution of
as many variables as you want. You do not need to be in Break mode to add variables. In this case they
will contain no value. The Watches window will display <Out of context> in the Value column.
Add a variable to the Watches window by right-clicking a variable name and choosing Add Watch. The
Add Watch dialog box appears to confirm that you want to ... watch that variable. Click OK to confirm
and the Watches window appears. Below are two variables in the Watches window while in Break
mode. You can see the current value of the two variables.
To watch another variable, double-click the variable name and drag it inside the Watches window. To
remove a variable from that window select it and hit Delete.
What is truly interesting is that you can change the value of a variable in the Watches window to test
what happens if it has this value. Simply click the current value and type a new value. This way you can
examine the behaviour of a procedure if a variable had a particular value.
36
Excel VBA Introduction – Part 1
To remove an entry from the Watch window click the spectacle icon at the far left and hit Del.
Error Handling
The expression Error Handling refers to the programming technique dealing with an error in your code.
From the outset you need to understand that we are not talking about bugs in your code but a
situation that may arise that prevents your code from executing. This type or errors are called run time
errors.
An easy run time error is if the user attempts to rename a worksheet using a name that already exists
in the workbook or code that divides the value of two cells and the second one contains a zero.
The On Error Statement
For a procedure to trap any error you must use the On Error Goto <label> statement at the top of your
procedure. This statement tells the procedure what to do if an unexpected error occurs. These
instructions are specified in the same procedure near the end of the procedure and they are located
using labels.
Here's a typical easy example:
Sub CreateNewSheet(strName As String)
On Error GoTo CreateNewSheetError
ActiveWorkbook.Sheets.Add _
After:=Worksheets(Worksheets.Count)
ActiveSheet.Name = strName
CreateNewSheetExit:
Exit Sub
CreateNewSheetError:
If Err.Number = 1004 Then
MsgBox "Sorry the name already exist."
Else
MsgBox Err.Description
End If
End Sub
The Sub CreateNewSheet creates a new worksheet at the end of the workbook sheets and gives it
the name specified as the argument (strName). The line On Error Goto specifies that, if a run
time error occurs for any reasons, the code after the label CreateNewSheetError is to be
executed.
A label is simply a single word (no space in other words) followed with a colon. Under this label you
will find an If statement that checks the error number and act accordingly. In this example the error
number 1004 is the "Cannot rename a sheet to the same name of another sheet.". After the message
is acknowledge by the user the code resumes after the End If.
What if there is no error in the procedure? If Excel does not return an error executing the
ActiveSheet.Name statement then it goes on with the next statement. In this case it is Exit
Sub (Labels are not VBA statements per see).
What do you think would happen if the following lines did not exist in the sub?
CreateNewSheetExit:
37
Excel VBA Introduction – Part 1
Exit Sub
When a run time error occurs you will see the error number at the top of the dialog box displaying the
error. Note the number and use it in the If Then Else structure to react accordingly.
On the right you see the error message. If you want to know the
error number after you have introduced an error handler (in
which case the dialog box will not appear) you can use the
following statements in your If statement to print the error
number and text respectively:
Debug.Print Err.Number
Debug.Print Err.Description
If you are in Break mode you can also type in the Immediate window:
?Err.Number
?Err.Description
The Resume Next Statement
The Resume Next statement is useful when the error is not critical (even possibly expected) and this
will not stop the execution of your code. Here the term Next refers to the line after the one causing
the error. Look at the following example:
Sub DivideCells()
On Error GoTo DivideCellsError
Dim rng As Range
DivideCellsExit:
Exit Sub
DivideCellsError:
rng.Offset(0, 2) = 0
Resume Next
End Sub
This DivideCells procedure divides each cell in the selection by the cell immediately to its right
and writes the answer in the third column (two cells to the right of the selection).
You will note that the second column contains an occasional zero. Because it is impossible to divide by
0, the procedure would stop when it encounters the first 0 if there was no error handler. But because
there is an error handler the code after the DivideCellsError label is executed.
The DivideCellsError section simply writes a 0 in the third column then resume execution on
the next line where the error occurred. In this case it is the line with the statement Next rng. In
other words in the cell to the right of rng = 0 then write a 0 in the third column and do as if there was
never an error, it was taken care of.
Once the procedure is done with each cell in the selection the procedure ends and runs the line in the
DivideCellsExit label which is Exit Sub.
38
Excel VBA Introduction – Part 1
Understanding Arrays
As you learn more about programming Excel you will eventually encounter the term array. For
example, if you have used the VLookup function you may remember that the name for the second
argument is table_array. In that context, array simply means the database that is being searched and
which will return the value sough.
You may also have heard of array formulas. This special type of formulas uses ranges of cells as
arguments where you would normally use one cell only. Some array formula can also return multiple
values (an array).
Although arrays are not exactly the same in VBA, we can learn something from the term used in
functions or with array formulas: An array is an object that contains multiple values. In VBA you
declare a variable using a special syntax where you specify as many values as necessary for that array
variable.
You assign and access individual element of an array by using its unique index value.
About arrays and index
To be able to differentiate various elements of an array they are assigned an integer number starting
at 0. The first element has the index 0, the second one is indexed 1, and so on. It takes a little while to
get used to having the first element labelled 0.
In a new module type this small procedure:
Sub MyFirstArray()
Dim aryFruits As Variant
aryFruits = Array("Apple", "Kiwi", "Banana")
End Sub
While the insertion point is inside the procedure hit F8 three times. You are now in break mode and
the last line is highlighted. This means that the variable aryFruits was initialized and assigned the
name of three fruits.
In the Immediate window type the following expression and hit Enter:
?aryFruits(0)
The string Apple is returned. The index 0 contains the first of a three element array. Try with the index
1 and 2. Now try using the index 3 and look at the message.
Looping through an array
Modify the above procedure as follow:
Sub MyFirstArray()
Dim aryFruits As Variant, varFruit As Variant
aryFruits = Array("Apple", "Kiwi", "Banana")
For Each varFruit In aryFruits
Debug.Print varFruit
Next
End Sub
While the insertion point is inside the procedure hit F5 to run it. The procedure will print in the
Immediate window all the elements of the array. Try adding another couple of fruits in the Array
39
Excel VBA Introduction – Part 1
function. You will learn more about this type of loop in the section Looping Through Items in a
Collection on page 48.
Declaring Arrays
There are a couple of ways you can declare (or Dim) arrays in your code. In the previous example we
explicitly assigned three pieces of fruits to the array variable. Not very flexible you might say.
If you know how many elements the array will contain you can use this value in its declaration. Look at
the following example:
Sub AnotherArray()
Dim aryNames(3) As Variant
Dim intCounter As Integer
For intCounter = 0 To 3
aryNames(intCounter) = ActiveCell.Value
ActiveCell.Offset(1, 0).Select
Next intCounter
For intCounter = 0 To 3
Worksheets.Add after:=Worksheets(Worksheets.Count)
ActiveSheet.Name = aryNames(intCounter)
Next intCounter
End Sub
In this example we know that the array will contain four values (remember the first element is 0). This
is why they are called fixed-size arrays (or static arrays). It then reads the value of four cells starting
with the active cell and finally creates four new worksheets using the names in the array.
To try this procedure type four names in four cells going down. Move the active cell to the first one.
While the insertion point is in the procedure hit F5 to run it in one go of press F8 to run it in break
mode. Remember to delete the four worksheets if you want to run it more than once.
The next example shows how to use an array to do something with multiple worksheets. In this case
the Sub deletes them but we could move, copy, hide or print the sheets contained in the array.
Sub DeleteTheSheets()
' Delete the first four sheets in the active workbook.
Dim arySheets(3) As Variant, intCounter As Integer
For intCounter = 0 To 3
arySheets(intCounter) = Sheets(intCounter + 1).Name
Next intCounter
Application.DisplayAlerts = False
ActiveWorkbook.Sheets(arySheets).Delete
Application.DisplayAlerts = True
End Sub
Inside the For loop note the expression Sheets(intCounter + 1). The reason for this is that
arrays are zero based but not the Sheets collection (which is not an array). So arySheets(0) is assigned
Sheets(1), arySheets(1) is assigned Sheets(2), and so on.
Here are other examples of statements you could have used in this procedure:
ActiveWorkbook.Sheets(arySheets).Visible = False
40
Excel VBA Introduction – Part 1
ActiveWorkbook.Sheets(arySheets).Move Before:=Sheets(1)
ActiveWorkbook.Sheets(arySheets).Printout Preview:=True
ActiveWorkbook.Sheets(arySheets).FillAcrossSheets _
Sheets(1).Range("A1")
The first example makes all sheets in the array invisible. The next example moves all sheets at the
beginning of the workbook. The third one displays all the sheets in Print Preview. In the last example
the value of cell A1 in the first sheet is copied in cell A1 of all the worksheets in the array. Powerful?
Indeed.
What is the size of an array?
If you want to know how many elements an array contains use the UBound function (Upper Bound).
Note that UBound will return the last index number and recall that arrays are zero based. You will
need to adjust the value returned by UBound to reflect the number of elements in the array.
Suppose an array contains five cities then the last element will have the index 4. To store the number
of elements is the variable intQuantity use the following:
intQuantity = UBound(aryCities)+1
Use the LBound function (Lower Bound) to know the index of the first element of an array. For
example the following For loop will consider each value of an array of unknown size.
For x = LBound(MyArray) To UBound(MyArray)
<VBA code to run>
Next x
41
Excel VBA Introduction – Part 1
Next intCount
For intCol = 0 To 3
For intRow = 0 To 5
aryData(intCol, intRow) = (intRow + 1) * (intCol + 1)
Next intRow
Next intCol
Range("A1:D6") = Application.Transpose(aryData)
End Sub
This procedure will create an array of 4 columns by 6 rows populated by the multiplication of the index
values of each element of the array.
Because arrays are zero based we need to add 1 in the multiplication. For example the element (1, 4)
contains the value 10 (2 x 5) and the element (3, 5) (4 x 6) contains the value 24.
The whole array is then dumped in a range of 24 cells as shown on the right.
In conclusion
If you need to program Excel Userforms containing dropdown lists or list box controls array will
become an essential tool to populate these controls. You can go a long way in Excel VBA without using
arrays but keep in mind that you will eventually need to work with them.
43
Excel VBA Introduction – Part 2
5
In Excel 2007 click the Office button then Prepare then Properties.
44
Excel VBA Introduction – Part 2
45
Excel VBA Introduction – Part 2
6
A quantity that is defined by its magnitude only (ie position, name).
46
Excel VBA Introduction – Part 2
CreateNewSheetExit:
Exit Sub
CreateNewSheetErr:
If Err.Number = 1004 Then
MsgBox "Already a worksheet with that name!"
End If
Resume CreateNewSheetExit
End Sub
47
Excel VBA Introduction – Part 2
48
Excel VBA Introduction – Part 2
The HasFormula property returns True if a cell contains a formula. When the procedure finds a
formula it increments a variable and print the cell’s address in the Immediate Window.
49
Excel VBA Introduction – Part 2
By nature the R1C1 notation is an absolute reference. So R1C1 always refer to cell $A$1 and R5C8 will
refer to $H$5. Fortunately you will rarely use the R1C1 notation this way7.
In general you will need to refer to a cell or a range using a relative reference.
With the R1C1 reference style you use the square bracket to specify the
number of rows and columns to offset from the active cell. For example
R[1]C[1] always mean one cell below and one column to the right from the
active cell wherever it is.
The table to the right shows you how to refer to the eight possible cells
around the active cell. As you can see, omitting the row or column number
will refer to the same row of column as the active cell. You could also use R[0]C[1] or R[1]C[0] to
achieve the same thing.
Type the following two rows of four numbers each anywhere in a worksheet then select the two cells
past the last column as shown here.
7
If you need to always refer to the same cell you might consider using a named cell instead.
50
Excel VBA Introduction – Part 2
If you have a hard time figuring out how to convert a formula from the A1 style to the R1C1 reference
style you can use the ConvertFormula method of the Application object. It allows you to convert
any references from one notation to another. Here’s an example. If the active cell is in C6 the following
expression:
Application.ConvertFormula("=SUM(C1:C5)",xlA1,xlR1C1)
Will return:
=SUM(R[-5]C:R[-1]C)
Another way you can do this is to interrogate the Formula and the FormulaR1C1 property. As you
know all cells have a Value, a Formula and a FormulaR1C1 property. The Value property returns the
value in the cell (maybe the result of a formula). The Formula property will return the formula as
shown in the Formula Bar and the FormulaR1C1 which will return the formula using the R1C1
reference style.
Try ?ActiveCell.Formula or ?ActiveCell.FormulaR1C1 in the Immediate Window to
display the formula in the active cell in the two reference styles.
51
Excel VBA Introduction – Part 2
52
Excel VBA Introduction – Part 2
53
Excel VBA Introduction – Part 2
Once we have found the region and the number of rows and columns, locate the first cell in the next
column at the right of the table. Note the use the Cells property to establish the reference to that cell
in the first row and intCols + 1 columns across. The Cells property is discussed shortly.
Once rngRight point to that cell, it is redefined (resized) to include the number of rows in the table.
The line rngRight.Select selects the cells just to show that the range has been resized. In you
applications you would immediately set the FormulaR1C1 property with whatever calculation you
want to do with the list. For example:
rngRight.FormulaR1C1 = "=SUM(RC[-" & intCols & "]:RC[-1])"
This would sum all the numbers to the left.
The Offset property
The Offset property returns a range that is shifted from the specified range. It has the same size as the
referenced range. This can be useful if you want to create a new range with exactly the same size of
another one, especially if you cannot predict the size of the original range.
The Offset property can use a horizontal (column) and a vertical (row) measurement. You can use both
or only one. Suppose rng is assigned to the range A1:A10 look at the following examples:
rng.Offset(0, 5).Select
rng.Offset(, 5).Select
Set rng2 = rng.Offset(intRows, intCols)
Selection.Offset(0, 10).Select
The first two examples do the same thing; select the cells 5 column to the right of rng with the same
size as rng. As you can see if the offset is 0 you can skip this parameter although it is self documenting
to specify the 0.
The third example assigns to the variable rng2 a new range shifted from rng the specified number of
rows and columns stored in the variables.
The last example selects the cells 10 columns across. The new selection has the same size as the
original one.
Small assignment: Suppose rng is assigned the range A1:D10, can you figure out what the following
example will do.
Set rng2 = rng.Offset(1, 0).Resize(rng.Rows.Count-1)
Answer:
The Cells property
Another very useful property of the Range object is Cells. It returns a one cell range from the specified
(larger) range. You refer to a specific cell by specifying its row and its column number. For example:
rng.Cells(row number, column number)
For example:
Range("D8:G16").Cells(1, 1)=1000
Will writes 1000 in the first cell (the upper left cell) of the selection D8:G16.
54
Excel VBA Introduction – Part 2
Make sure you understand that if you do not specify a range when using the Cells property, you are
referring to an absolute cell reference. Thus simply using:
Cells(1,1)=1000
This will always write 1000 in cell A1 whereas in the previous example it is writing in the upper-left cell
of the selection.
Suppose rng refers to the range D5:F7 on the right then:
rng.Cells(1, 1) Returns A
rng.Cells(3, 2) Returns F
The values used with the Cells property above are relative to the referenced range. If you do not
specify a range then it will use an absolute measurement.
Cells(1, 1) Refers to A1
Cells(3, 2) Refers to B3
You will most likely use variables to refer to a cell in a range instead of numeric values. This makes it
very easy to loop through every cell in a range and do something with each one. Here’s one example:
Sub Looping()
Dim i As Integer, j As Integer
For i = 1 To 5
For j = 1 To 5
Cells(i, j) = "R" & i & "C" & j
Next j
Next i
End Sub
This will fill the range A1:E5 with their respective row and column number. For example A1 will contain
R1C1 and E5 will contain R5C5.
Small assignment: Modify the above procedure so that it works from any selected cell instead of
always start at A1. Hint: You only need to add a single word at
the proper place.
Look at the following example:
Sub FillSelection()
Dim rng As Range
Dim intRows As Integer, intCols As
Integer
Dim r As Integer, c As Integer
Dim intValue As Integer
For c = 1 To intCols
For r = 1 To intRows
intValue = intValue + 1
55
Excel VBA Introduction – Part 2
rng.Cells(r, c) = intValue
Next r
Next c
End Sub
Look at the first For – Next loop. The first time, the variable c will have the value 1. While c is equal
to 1 the variable r will have the values 1, 2, 3, 4 and 5. Can you see how this allows the loop to create
all the combination of cells in the first column of the selection? So the expression Cells(r, c) will
alternately refer to (1, 1), (1, 2) and so on to (1, 5). The same thing will happen when c will be equal to
2 and so on to last column of the selection.
You might come across Cells(1) in some sample code. This technique refers to the 1st cell in the
range at the upper-left corner. So Cells(2) would refer the second one across unless the range is a
single column.
Multiple Ranges Selections
The Excel object model offers a way to work with non-contiguous ranges selections. This is very handy
because you may wish to design your code with that type of selections. For example, you may want to
scan a range of cells for a value and continue in another range. This way, your code continues to run
and go about its business.
When you select two non-contiguous ranges you can access each range through the Areas collection.
The Areas collection contains one range object for each selected range. You normally access Areas
through the Selection property.
Select two ranges in a worksheet then type in the Immediate Window:
?Selection.Areas.Count
Now try:
?Selection.Areas(1).Address
Try also the value 2.
Now try the next one with the value 1 and 2 as well:
?Selection.Areas(1).Count
Since Areas is a collection of objects (Range objects) it is possible to loop through each range using a
For Each – Next loop (See Looping Through Items in a Collection on page 48).
Suppose you need to fill each selected ranges with the month of the year starting with Jan. The second
range will contain Feb and so on.
Sub FillMonths()
Dim rng As Range, i As Integer
For Each rng In Selection.Areas
i = i + 1
rng = MonthName(i, True)
Next
End Sub
Parts of the following procedure is exactly the same as the example on page 55 where we fill each cell
in a range with the cell number. In this example the code continues to fill the other selected ranges.
56
Excel VBA Introduction – Part 2
Sub FillAreas()
Dim rng As Range
Dim r As Integer, c As Integer
Dim intRows As Integer, intCols As Integer
Dim intValue As Integer
In Conclusion
Hopefully this handout did not intimidate you to the point that you think VBA is too difficult to learn. If
you work at it and search Google for more explanations you will find yourself creating small but useful
pieces of code. After a few months, you will look back at some of your ‘creations’ and wonder at how
clever you were to come up with such elegant solutions.
I often recommend that you start by creating useful functions because they are generally short and
can replace calculation you are already familiar with in your worksheets.
After a short while tackle a few simple macro procedures. If you do not know how to code a task in
Excel, create a macro doing that one task only. Look at the recorded macro and see how you can use
that code in your procedure adapting it to your need. You will find that often you can simply copy and
paste the recorded macro into your procedures.
Happy development,
Daniel Lamarche
ComboProjects
57
Excel VBA Introduction – Part 2
Want a reliable source of information with heaps of reviews? Go to Amazon.com and type ‘Excel VBA
books’. See what hundreds of readers have said.
58