Lecture 19 - Visual Basic
Lecture 19 - Visual Basic
Introduction
We’ve seen some brief examples of Visual Basic in our previous lectures.
Visual Basic is the programming language used for writing macros. If you record a macro
like we learned in Lecture 17, the code behind the macro is Visual Basic.
In the Visual Basic lectures, we will cover some of the commonly-used features of the
language.
Because it is learning a whole new language, don’t be surprised if you find that you need to
go through the Lecture multiple times, or re-read sections to understand.
We’re going to use the Developer tab in the Ribbon to access our macros.
There is a Macros button on the View tab, but it's easier to use the set of commands from the
Developer tab ribbon.
Please note that Worksheets(1) is not necessarily the same sheet as Worksheets("Sheet1")! If
the first tab in the Workbook was called Stuff and the second tab was called Sheet1, then
Worksheets(1) would be referencing Stuff, not Sheet1.
What if the sheet you want to reference is not a Worksheet? Then you’d use Sheets instead of
Worksheets.
Sheets is a collection of worksheets, chart sheets and macro sheets. Sheets can be indexed the
same way we used worksheets:
You can also use ActiveSheet to refer to a sheet that you are actively in at that point in the
code (you can also use ActiveSheet.Next for the sheet one to the right of the current sheet, and
ActiveSheet.Previous for one sheet to the left of the current sheet).
To refer to sheets (or other objects) with the same name (like when you have more than one
Workbook open), you have to name it precisely.
For example:
Workbooks("Book1").Worksheets("Sheet1")
Workbooks(2).Worksheets("Sheet1")
If the object is not named specifically, whatever object (such as the workbook or worksheet) is
currently active is used.
Worksheets.Count – tells you how many worksheets are currently open (this can also
be used for Workbooks)
Range("A1").Value = 30 – puts a value of 30 in cell A1
Range("A1") = 10 – the default property for a Range is Value, so you don’t have to
use .Value like in the previous example.
Selection.Value = "Profit" – puts the Word Profit in the active cell (Just like the
previous example, the .Value is optional and this can also be written as
Selection = “Profit”)
ActiveSheet.Name = "Results" – renames the active sheet as Results
ActiveCell.Offset(0, 1) = "x" – this puts an x in the cell to the right of the active cell
(0 rows, 1 column)
ActiveCell.Offset(1, 0).Select – this selects the cell below the current active cell
(1 row, 0 columns)
ActiveCell.Offset(0,1) = ActiveCell * 2 – puts twice the active cell in the cell to right
(So if you are in cell A1 and the value in the cell is 5, this code would put a value of 10
in cell B1, which is zero rows and one column from A1).
4. Maximize the inner code window, if necessary, and Close the two panes on the left
5. Using the mouse, point to the far left of the Visual Basic Editor (VBE) window and drag it
to the right so that it occupies only half the screen (if the window is maximized, you'll
need to click on Restore Down first)
6. Now run the macro by pressing [F8] - this steps through the lines one at a time (the
arrow and yellow highlight indicates where the macro has reached)
7. Repeat step 6 until the last statement (End Sub) is no longer highlighted
Make sure you understand the statements as they are performed. You will notice that there is
text displayed in green that is preceded by an apostrophe. In Visual Basic, text typed after an
apostrophe is held as a comment and is not run as part of the code – this is a helpful way to
add description to the code so anyone else looking at it knows what the code is for!
You can repeat the macro a second time by pressing [F8] again, if you need.
To see a demonstration of walking through code, watch the first part of the Lecture
19 video.
Range("A2").Select –
Range is a cell or group of cells, and Select says “go there” or “choose this” - so in this case,
cell A2 would be selected.
Selection = "values:"
This tells the code to add text (it’s contained in quotes) to the selection (cell A2), so now cell A2
will contain “values:” (without the quotes)
ActiveCell.Next = 10
This says to take the active cell (cell A2) and put a 10 in the next cell, which is one cell to the
right (cell B2).
ActiveCell.Offset(0, 2) = 20
This says to take the active cell (Note that we did not have the code move to the Next cell, just
put 10 in it, so the active cell is still A2!) and put 20 in the cell zero rows and 2 columns away
(cell C2 – and, since we did not select that cell, cell A2 is still the active cell!)
Cells(3, 1) = "here"
This puts the word here in a cell. The cell is in the third row and first column, so it is cell A3.
Range("B2:C2").Select
This selects cells B2 and C2.
Selection = 100
This puts 100 in both cells – B2 and C2.
Selection.Delete
This deletes cells B2 and C2, moving up the cells below it. You will now have a #REF error
message to appear in D2. It would have been better to use Selection.Clear.
Range("A2:D2,A3").Clear
This clears the data from cells A2, B2, C2, D2 and A3.
ActiveCell.Previous.Select
This moves active cell back a column (since B and C were selected, it moves to A, so A2 is now
the ActiveCell.
ActiveCell.Offset(-1, 0).Select
This moves the active cell minus one row (from 2 to 1) and zero columns – so the active cell
now becomes A1.
End Sub
This ends the code!
However, it is not recommended to do this – instead, the type of variable should be declared
explicitly. Declaring a variable is defining in Visual Basic what type of data a variable will be
used to hold. A variable or array can be restricted to hold certain kinds of data, much the same
way as formatting can be applied to a cell.
An array is a simple way to define a whole series of variables using just one name. When you
define the array, you declare the number of items that make up the array. This designates the
array bounds. Arrays can be one-dimensional, like a row or column of cells would be, or two-
dimensional, like a block of cells would be. Technically, arrays can also have more than two
dimensions, though we won’t go that far in our class lectures.
Dim x(10) as String ' defines 10 variables called x(1), x(2), x(3) ... x(10) for storing
text
Dim m(2,2) as Single ' defines 4 variables called m(1,1), m(1,2), m(2,1) and m(2,2) for
numbers (like a cube)
Dim z(5 to 9) as Date ' defines 5 variables z(5), z(6) ... z(9) for storing dates
Note** By default, array bounds start at zero. So in the first example above, there is also an
x(0). In the second example, there are 5 extra elements – m(0,0), m(0,1), m(0,2), m(1,0) and
m(2,0). The explicit declaration in the third example, however, means that only these
elements exist.
You don't have to use extra (0) elements if you don't want - and you can define a lower bound
of 1 using an Option Base 1 statement at the very top of your VBA code (using the statement
sets the default for all the macros in the file so none of the arrays will use (0) elements).
Variant Arrays
Sometimes, the data held in rows, columns or blocks of cells are of differing types (text,
numbers, dates, etc.) or even some unknown types. If this is the case, you can define an array
as a variant array.
Note** the underscore at the end of the second line in this example is used to indicate that the
statement continues onto another line.
8. The VBA window should still be displayed – if not, click on the Macros button and Edit
MacroB
9. Click on MacroB then use [F8] to step through the macro
This macro picks up the values from an array (x) which is declared as variant so that it can hold
any types of data. Meanwhile, the variable (w) can only hold whole numbers because it is
declared as an integer.
Note** If a variable is used or declared within a macro, the value stored in it is only held while
the macro is running. Try running MacroB again:
10. Run the macro again, using [F5] to run it, rather than step through it – you should find
nothing has changed in your spreadsheet – this is because w has no value when the
macro is started.
You CAN retain the value so that it can be used in other macros. To do this, you have to declare
it outside the macros. Just like earlier when we talked about the Option Base 1, you can declare
globally at the top of your Visual Basic module.
11. Add an apostrophe before the DIM w as Integer statement in the macro (to turn it
into a comment)
12. Using the scroll bar, move to the very top of the VBA display and delete the apostrophe
from the DIM statement here, to activate it and declare w as a Variant.
I demonstrate steps 11 and 12 for you in the second part of the Lecture 19 video.
13. Click anywhere within MacroB and run it again (using [F5]) – the cell is left empty as
w has now been declared variant (it was set to 0 when declared an integer)
14. Repeat step 13 to run it a second time - this time B1 is set to 10 (to see this, you’ll
need to comment out the following lines by adding an apostrophe before each:
a. Range("A1:B1").Clear
b. Range("A1:D2").Clear
The value is held because w is declared globally in the DIM statement as a variant for all
macros in the file.
Finally, try adding a statement which gets rid of the *zero* element of the array:
15. Uncomment the statement Option Base 1 at the very top of the VBA pane – above the
DIM you uncommented earlier.
16. Click on MacroB then press [F5] to run it
You should find the word data appears in cell A2, and an error message also appears. This
happens because originally data was the value held in array element (0) so when using base 1,
“data” is now held in array element (1) – and we didn’t change the reference when it is used
later.
17. Press [Enter] to enter [Debug] mode, then correct the statement to read
ActiveSheet.Name = x(1)
18. Press [F5] to complete the macro.
Output
The code used to get information from a macro contains the Msgbox statement. This can be
used either to relay a fixed message (such as that the macro has reached a particular point in
the code) or to give the current value of a variable used in the program or data held in a cell.
When a Msgbox statement is run, a dialog box appears on the screen, which must be OK'd by
the user.
Note** Msgbox requires a string argument – non-strings need to be converted using the Cstr
function.
Msgbox examples:
Msgbox("Here") or Msgbox "Here" ' the macro has reached this point
Msgbox("x = " & Cstr(x)) ' as above but adds x = (so if x was 10, it would say x=10)
This example displays the dialog box and acts on the result:
Input
To supply information to a macro, an Inputbox statement is used. This could take the form of a
reply to a question or a request to supply a data value. The information will then be passed to
the macro by a variable, which can then be used to determine what happens next. Again, a
dialogue box is displayed to which the user must respond.
Note** When wanting a yes or no answer from a user, it is always valuable to give the user
selection buttons rather than an area for a written prompt, as errors can occur due to case
sensitivity, misspellings, etc. So rather than an InputBox, use a MsgBox for ease of use in
yes/no situations!
19. Click inside MacroC then use [F8] to run through it.
20. Press [F5] to run it a second time.
21. Scroll up to MacroA and move to the end of the first line that says ‘MacroA Macro
22. Hit Enter to add a line, and add your name into the VBA as a comment.
Loops
By using loops, macros can process large amounts of data in Excel.
Loops are set up around other instructions to carry them out a specific number of times or until
a described condition is reached.
There are three main statement pairs which are used to create loops; each has one statement
marking the start of the loop and the other its end.
For … Next
While … Wend
Do … Loop
For … Next
Perhaps the simplest pair of statements is For … Next.
The For statement sets up a variable which increases in value by 1 each time the loop is
completed.
The Next statement marks the end of the loop, which sends the macro back to the For
statement. This statement also checks whether the loop has exceeded its final value and, if it
has, passes control to the statement following the Next statement.
Normally, the loop variable starts with a value of 1 but it does not have to (for example, you
might want the macro to work from a particular row on a worksheet).
The increase value (step value) is also usually 1; but negative or fractional steps can also be
used.
For…Next examples:
For i = 1 to 10
Cells(i,1) = i
Next i
This example sets the values in cells A1 to A10 equal to 1,2, … 9, 10. The first time, it
sets i = 1, and the cell in row 1, column 1 (A1) to 1. Then Next i sends it back to the
For statement. This time, i = 2 and Cells(2,1) = 2 so A2 = 2, then Next i sends it
looping back to the For statement, etc.
For j = 5 to 8
Range("A"&CStr(j)) = j*j
Next j
This example sets the values in cells A5 to A8 equal to 25, 36, 49 and 64
How? When j = 5, Range("A"&CStr(j)) = j*j would be Range("A"&CStr(5)) = 5*5, so
Range(“A5”) = 25. Remember that CStr converts non-strings to strings – 5 is not a
string but A5 is.
For k = 0 to 9 step 2
Range("A"&CStr(k+1)) = k
Next k
This example sets cell A1 to 0, A3 to 2, A5 to 4, A7 to 6 and A9 to 8.
For m = 10 to 1 step -1
Cells(11-m,1) = Cells(m,2)
Next m
This picks up data from column B, starting in B10 so A1 = B10, A2 = B9, etc.
For i = 1 To 100
x = InputBox("Enter data")
If x = "#" Then Exit For Else Cells(i, 1) = x
Next i
Msgbox CStr(i-1) & " rows of data"
This shows an input box that says ‘Enter data’. If a # is entered, it exits the loop. (Exit
For). If a # is not entered (Else), it stores the input entry in variable x and then assigns
the variable x value to Cells(i,1). It repeats this 100 times. At the end of 100 or when a
# is entered, causing the loop exit, it shows a message box that indicates how many
rows were entered.
A slightly more complicated form of For… Next is the For Each … Next statement.
This can be used to pick up loop values from a cell range; repeat a loop for each member of an
array; or repeat the loop for each object in a collection (like each cell in a range).
Visual Basic can automatically set up a counter for the loop if none is specified.
Dim x as Range
For Each x in Range("A1:A10")
x.ClearFormats
x=0
Next x
This declares range variable (x). Then for each cell in the Range (from A1 to A10), it
clears any formatting from the cell and then sets the cell value to 0.
While… Wend
An alternative form of looping is provided by the While statement.
While…Wend example:
While i < 10
X = Selection
If X = "#" then i = i + 1
ActiveCell.Offset(1, 0).Range("a1").Select
Wend
This loops until it finds 10 # signs in a column.
How? The first time i = 1, which is less than 10. If there is a # in the cell, then i = i + 1
so i = 2. If not then it moves one row and zero columns relative (or “A1” away) from
the current. Wend sends it back to the While statement. If there was no # then i still
equals one because it does not equal 2 until it finds a #.
Do … Loop
Yet another way of looping is provided by the Do statement.
Do…Loop examples:
Do Until j = 999
ActiveCell.Offset(1, 0).Range("a1").Select
j = Selection
Loop
This moves cell to cell in a column until it finds a value of 999.
An alternative form uses a While or Until statement to mark the end of the loop:
Do
ActiveCell.Offset(1, 0).Range("a1").Select
j = Selection
While j < 999
In this case, while marks the end of the loop (you could also use Until j = 999).
Click on the File tab, then choose Save As. Save the file to your computer as “Assignment
19.[Your Last Name].xlsm”. In Canvas, upload your assignment document as the response to
Question 1 in the Lecture 19 assessment, then answer the rest of the assessment based on
your file and/or comprehension of the lecture.