VBA Tutorial
VBA Tutorial
VBA Tutorial
02 August 2023
09:04
Sub
When working with VBA, you need to create procedures to store your code.
The most basic type of procedure is called a "Sub".
1. Create a sub procedure titled "HelloWorld"
Sub HelloWorld()
End Sub
All of your code should go in between the start and the end of the procedure.
Comments
You can add comments anywhere in your code by proceeding the
comment with an apostrophe (').
Comments can be placed on their own line or at the end of a line of code,
to make the code easier to follow.
Objects are items like workbooks, worksheets, cells, shapes, textboxes, or comments. Objects have
properties (ex. values, formats, settings) that you can change. Methods are actions that can be
applied to objects (ex. copy, delete, paste, clear).
If no sheet name is specified, VBA will assume you are referring to the worksheet currently "active"
in VBA
First, using a set of quotations that doesn't contain anything will generate
a "blank" value.
range("a3").value = ""
Second, you can use the & operator to combine strings of text:
"string of" & "text"
5. Assign the value of "EZ" to cell A3 by separating "EZ" into 2 strings of text and combining
them.
Sub Macro1()
Range("A3").Value = "E" & "Z"
End Sub
6. Declare the variable "Row" and set it equal to 5. Now, using the variable, set range "A5" = 1.
Sub Macro1()
Dim Row
Row = 5
End Sub
Named Ranges are cells that have been assigned a custom name. To reference a named range,
instead of typing the cell reference (ex. "A1"), type the range name (ex "drate").
7. Assign the value of .05 to the named range "drate".
Sub Macro1()
Range("drate").Value = 0.05
End Sub
Named ranges are very useful when working in Excel, but they are
absolutely essential to use when working with VBA.
Why? If you add (or delete) rows & columns all of your Excel formulas will
update automatically, but your VBA code will remain unchanged.
If you've hard-coded a reference to a specific range in VBA, it may no
longer be correct. The only protection against this is to name your ranges.
Ranges of Cells
Now instead of assigning a value to a single cell, let's assign a value to a
range of cells with one line of code.
8. Assign the value of 5 to cells A2:B3 . Hint: Enter the range exactly how it would appear in an
Excel formula
Sub Macro1()
Range("A2:B3").Value = 5
End Sub
Cell Formulas
VBA can assign formulas to cells by using the "formula" property.
Example: range("c3").formula = "=1 + 2"
Hint: Remember to surround your formula with quotations and start the formula with an equal sign.
Sub Macro1()
Range("A2:B3").Formula= "5*2"
End Sub
The .formula property will assign the same exact formula to each cell in the specified range. If you
are using cell references (ex "A1"), the references will be hard-coded based on what you've entered
in quotations. Often times you will want to assign a formula with relative references instead (ex.
Applying a formula to an entire column, where the formula in each row needs to reference cell(s)
from that row).
To accomplish this you will want to use the .formulaR1C1 property, which is discussed in a future
lesson.
Sub Macro1()
Range("A2").Value= Range("B2").Value
End Sub
Important! You can assign a single cell's value to one or more cells at
once:
Range("a1:a3").value = range("b1").value
But if you want to assign a range of cell values, you must make sure the
range sizes are the same otherwise you will receive an error.
Range("a1:a3").value = range("b1:b3").value
Clear Method
There are also many methods that can be applied to ranges.
Examples of methods include: .clear, .delete, and .copy.
The .clear method. This will clear all of the cell's properties (values,
formulas, formats, comments, etc.)
11. Clear cell A2
Sub Macro1()
Range("A2").Clear
End Sub
The .clearcontents method to only clear the cell's contents, keeping the cell's formatting and all
other properties.
12. Clear only the contents of cell A2.
Sub Macro1()
Range("A2").ClearContents
End Sub
When you refer to a range without explicitly declaring a worksheet or workbook, VBA will work with
whichever worksheet or workbook is currently active in the procedure. Instead you can (and should)
explicitly tell VBA which worksheets and workbooks (if applicable) to use.
No WS or WB, will use whatever is active.
range("a1").value = 1
With WS declared.
Sheets("Inputs").range("a1").value = 1
Sub Macro1()
Sheets("Data").range("A2").Value = "text"
End Sub
Sub Macro1()
Workbooks("wb1.xlsm").Sheets("Data").range("A2").Value = "text"
End Sub
.Activate and .Select are used to activate or select an object (ex. A range),
to shift the focus to the desired object(s):
range("a1").select
Selection.value = 1
The above code is identical to this:
range("a1").value = 1
The second instance is much shorter, easier to follow, and less error
prone. In fact, you should almost never use .activate or .select. You can
almost always accomplish the same task by writing smarter code. If you
are editing code from a recorded macro, you should consider "cleansing"
your code of .activate and .selects.
The only time you should use these commands is when shifting the focus
for the user.
For example, you might want to add a navigation button to jump to a
different worksheet:
Sub nav_Index()
Sheets("index").activate
End Sub
VARIABLES
02 August 2023
09:04
Declaring variables
Declaring a variable tells VBA what kind of information the variable will
store. You can declare different number types, strings (to store text),
objects (worksheets, workbooks), dates...
To declare a string variable:
Dim StringVariable as string
1. Declare variable "myStr" as a string variable type.
Sub Macro1()
Dim myStr as string
End Sub
To declare other variable types use the same syntax except replace
"string" with "long" (for integer numbers), "variant", "date" or whatever
other variable type you want to use.
You don't need to declare variables, but doing so is recommended, as it
helps preventing coding error. Enter Option Explicit at the top of your
module or change your VBA options to require it.
Numerical Integer Accepts only integer values, mainly used for counters;
value needs to be between -32768 and 32767. Note:
You should always use Long instead of Integer. Integer
numbers used to be needed to reduce memory usage.
But it is no longer necessary.
Numerical Long Accepts only integer values, used for larger referencing
like populations; value needs to be between -
2,147,483,648 and 2,147,483,648
Numerical Variables
Declare variables like this
Dim i as long
i=1
Dim j as Double
j=1.1
Sub Macro1()
Dim j as long
j=2
End Sub
Once you assign a value to a variable it's easy to change that value. With number variables you can
even perform operations to recalculate the variable.
3. Add 1 to the variable j.
Sub Macro1()
Dim j as long
j=2
j = j+1
End Sub
Sub Macro1()
Dim j as long
j=2
Range("A1").Value = j
End Sub
5. Declare a variable (i) that will allow you to store a large number (ex. 443,439)
Sub Macro1()
Dim i as long
i = 443
End Sub
6. Declare a variable (i) that will allow you to store a decimal number (ex. 54.33)
Sub Macro1()
Dim i as double
i = 54.33
End Sub
Sub Macro1()
Dim strTest as string
strTest = "this is a string"
End Sub
Sub Macro1()
Dim strTest as string
strTest = Range("A1").Value
End Sub
The cell value will now be stored as text, regardless of whether the cell value is a number or
text.
Sub Macro1()
Dim Flag as Boolean
Flag = FALSE
End Sub
if you want to switch the TRUE / FALSE indicator use the Not command: Flag = Not Flag
Sub Macro1()
Dim Flag as Boolean
Flag = Not Flag
End Sub
Object Variables
Object variables can store objects (workbooks, worksheets, ranges, etc.).
You declare object variables in the same way you would declare any other variable. However, the
process to assign an object to a variable is slightly different; you must add "Set"to the assignment.
Dim myWB as Workbook
Object variables can be useful when you are doing multiple calculations and you need to reference
your workbook/worksheet every time.
Workbooks("Example.xlsm").Sheets("MySheet").Range("A1").Value = 4
Workbooks("Example.xlsm").Sheets("MySheet").Range("A2").Value =51
Workbooks("Example.xlsm").Sheets("MySheet").Range("A3").Value =26
This can easily be simplified to the following:
Dim myWS as Worksheet
Set myWS = Workbooks("Example.xlsm").Sheets("MySheet")
myWS.Range("A1").Value = 4
myWS.Range("A2").Value = 51
myWS.Range("A3").Value = 26
Sub Macro1()
Dim myWB as Workbook
set myWB = Workbooks("Example.xlsm")
End Sub
11. Assign the worksheet "data" to the variable "myWS". Don't define a workbook.
Sub Macro1()
Dim myWS as Worksheet
set myWS = Worksheets("data")
End Sub
12. Assign this workbook (where the code is stored) to variable curWB.
Sub Macro1()
Dim curWB as Workbook
Set curWB = ActiveWorkbook
End Sub
Sub Macro1()
Dim myWS as Worksheet
Set myWS = ActiveWorksheet
End Sub
Sub Macro1()
ActiveCell.Value = 5
End Sub
When you first run a procedure, the active sheet (workbook) is the sheet (workbook) that is
currently visible .
The active workbook will only change if
1. You open a new workbook. Then the new workbook becomes active.
2. You manually change the active workbook
with workbooks("wb2.xlsm").activate Or workbooks("wb2.xlsm").select
You should almost NEVER change the active worksheet or workbook. You should only do so to
change what sheet (or workbook) the user will see once your code has finished running.
Reference Worksheets by Cell Values or
Strings
15. Declare a string variable called "strWS" and give it the value "2017_12".
Sub Macro1()
Dim strWS as string
strWS = "2017_12"
End Sub
Now if one of your sheets is called "2017_12" it you can easily reference that sheet by doing the
following:
Sheets(strWS).Range("A1").Value = 2
This is useful if you want to reference a worksheet name based on some inputs:
strWS = Year(Now) & "_" & Month(Now)
Sheets(strWS).Range("A1").Value = 2
17. Set strWS equal to named range "date". Then set cell "A1" on sheet strWS equal to 1.
Sub Macro1()
Dim strWS as string
strWS = Range("date").Value
Sheets("strWS").Range("A1").Value = 1
End Sub
CONDITIONAL LOGIC
02 August 2023
09:05
Operators
Operator Description
= Equal to
1. Test if 5 is less than or equal to 3 and assign the result to the variable "Test"
Sub Macro1()
Dim Test as Boolean
Test = 5 < = 3
End Sub
2. Compare "String" and "string" and assign the result to the variable "test".
If Statements
Using the "IF" statement, you can use those same logical operators to test whether a statement is
TRUE or FALSE and perform one action if TRUE and another action if FALSE.
If n < 0 then
Data_val = "Warning! Negative Value"
Else
Data_val = "ok"
End if
4. Test if n > 100 with an IF Statement. Set note = "check" if TRUE else note = "immaterial"
You can test multiple conditions with a single "IF" statement by using the
"And" and "Or" operators.
To test whether a number n is between (but not equal) to 3 and 10:
If (n > 3) and (n < 10) then
Range("A1").Value = "in range"
End if
You don't need to add the line "Else" if you don't need to run anything if
the condition is FALSE. In fact you could write the code in one line and you
can omit "End IF":
If (n > 3) and (n < 10) then Range("A1").Value = "in range"
Elseif
"Elseif" to test a second condition if the first is false:
If animal = "Cat" then
MsgBox "Meow"
ElseIf animal = "Dog" then
MsgBox "Woof"
Else
MsgBox "*Crickets*"
End if
5. Add another Elseif to the previous example to test if animal = "Cow". If TRUE then create a
message box that says "Moo".
Sub Macro1()
Dim animal as string
If animal = "cat" then
MsgBox "Meow"
Elif animal = "dog" then
MsgBox = "Woof"
Elif animal = "cow" then
MsgBox = "Moo"
Else
MsgBox = "*crickets*"
End If
End Sub
Nested If Statement
You can embed one if statement inside another. For example, let's say we want to test whether the
number n is greater than 3. If TRUE, we want to test whether the number m is greater than 3.
If n > 3 then
If m > 3 then
Range("A1").Value = "n greater than 3 and m greater than 3"
Else
Range("A1").Value = "n greater than 3 but m less than or equal to 3"
End if
Else
Range("A1").Value = "n less than or equal to 3 and we don't know
about m"
End if
Select Case
Select Case is an efficient way to do multiple logic tests in VBA. First you indicate a variable, object or
a property of an object that you wish to test. Next you define "cases" that test if the variable, etc.
matches and if so, do something.
To test a specific value (that is whether the variable is equal to a value), we can simple type the
value after the word Case. If we want to use an operator to test a value, we have to type the word
"Is" before we enter the operator.
Select Case i
Case Is <= 2: MsgBox "i is less than or equal to 2"
Case 3: MsgBox "i is equal to 3"
Case 4: MsgBox "i is equal to 4"
End Select
6. Use a Select Case statement to test if variable "animal" is equal to "cat" or "dog" and output
"meow" or "woof" to the variable "sound" if there is a match.
Sub Macro1()
Dim animal as string
Dim sound as string
Select Case animal
Case "cat": sound = "meow"
Case "dog": sound = "woof"
End Select
End Sub
FOR LOOPS
02 August 2023
12:15
For loops repeat a block of code a set number of times either by running through a set of numbers,
or through a defined series of objects.
This first example defines a set number of times to repeat a task:
Dim i as long
'Repeat tasks 10 times
For i = 1 to 10
'perform tasks here
Next i
This next example, starts at variable i=1 and cycles through 10 times, each time increasing i by 1 (ex.
i = 1, i =2, etc.).
Dim i as long
'Repeat tasks 10 times
For i = 1 to 10
Range("a" & i).value = 5 * i
Next i
After the loop, the variable stays at its most recent value (i = 10) and can be used as usual.
1. Create a For loop to repeat a task 5 times using the variable i. Your answer should be two
lines.
For i = 1 to 5
'Repeat task 5 times
ADVANCED REFERENCING
04 August 2023
09:53
1. Get the row number of named range "drate" and assign it to a variable "row_num".
Sub Macro1()
Dim row_num as Long
row_num = Range("drate").row
End Sub
2. Get the column number of named range "drate" and assign it to variable "col_num".
Sub Macro1()
Dim col_num as Long
col_num = Range("drate").column
End Sub
Rows and Columns Objects
This code snippet will delete rows 2 & 3
Rows("2:3").delete