VBAPrimer
VBAPrimer
Introduction
In the past, even mildly complicated engineering calculations have not mixed well with
spreadsheets because of the very strong tendency to wind up with nearly-impossible-to-debug
"spaghetti" code. While most students seem to enjoy using spreadsheets, instructors recognize
that other than by finding the “correct” answer printed somewhere, it is next to impossible to
grade assignments or to help the occasional student debug them. However, by using Visual Basic
for Applications (VBA) in conjunction with the Excel spreadsheet, the user has the convenience
of a spreadsheet for input/output and graphics, i.e., to function as a graphical user interface
(GUI), while using well-structured, readable, line-oriented code for the more complicated
calculations. This appendix will review a few general aspects of spreadsheets, while providing a
brief introduction to the use of functions and subroutines written in VBA. Many books about
Excel do not address VBA at all, and if they do, the coverage is limited to a few pages [1-3].
However, several recent books, including Walkenbach [4], Orvis [5] and Halberg, et al. [6],
Chapra [7], Albright [8] and Bullen, et al. [9] do cover VBA extensively. References 7 - 9 books
are almost entirely devoted to VBA, with the Chapra book aimed at beginning engineering
students, including those learning to program for the first time.
In early spreadsheets, a macro was just a recording of a series of keystrokes; that can still
be done. (In fact, as will be noted later, recording a series of keystrokes and mouse clicks and
then viewing the resulting VBA code generated is a good way to learn the language.) But VBA,
which has been available since Excel 5.0 and is a subset of Visual Basictm, is a full-featured,
structured programming language and thus far more powerful. Indeed, because VBA allows the
programmer to program and thus control Excel’s rich collection of drawing and chart objects, it
might be considered more potent than VB itself. (Plus you don’t have to buy another package!)
Those who have taken a course using a modern structured language like Java, C++, Fortran 90,
Pascal, etc. can pick up VBA syntax with very little coaching. Indeed, those students who
ordinarily will do anything to avoid writing a traditional computer program find VBA an
attractive and enjoyable addition to their skill set.
Several examples given in this document were implemented originally in Excel Version
7.0; however, all are compatible with later versions. Several workbooks discussed here and
available on the Heat Transfer Today CD and website may not be backwardly compatible. In
addition, provided they are saved properly, workbooks generated on Wintel platforms may be
used on Macintosh computers and vice versa – that capability a major advantage for today’s
mobile students.
General
As with any structured programming language, VBA has certain rules for the naming of
variables. Variable names must start with a letter and may consist of letters, numbers and some
characters. They are case insensitive and must not include spaces or periods. Certain symbols
including #, $, %, & and ! are forbidden as are a number of “reserved” words. Many data types,
including Boolean (T or F), integer, long (integer), single (floating point), double (floating point),
currency, date, string, object, variant and user - defined, are permitted.
The practice of "naming" cells on the spreadsheet is highly recommended. Giving names
to cells allows one to reference them in subsequent cell formulae (and in VBA code) by name
1
An Excel/Visual Basic for Applications (VBA) Programming Primer
rather than cell address, thus making the spreadsheet far more readable than it would be
otherwise. For instance, to someone even mildly familiar with fluid mechanics, the cell formula:
having four of the five variables referenced by name rather than address, looks a lot more like a
ρ Vd
Reynolds number ( Re d = ) than does:
μ
There are two ways to “name” a cell. The first is to use Insert – Name - Define on the
toolbar. This technique allows the programmer to see all cells previously defined, thus avoiding
conflicts, and to delete names already assigned should that be needed. If the cell to the left of the
one you want to name has what appears to be a valid name in it (e.g., Diameter =), then Excel will
suggest that as a possibility and all you have to do is confirm it.
The other way is to highlight the cell and then simply type the name in the box just above
cell A1 and to the left of where the cell formulae appear and hit “enter.” Figure 1 shows a small
section of a spreadsheet:
As will be seen later, VBA coding lends itself well to traditional in-line documentation.
Cell Notes are an effective way to provide documentation on the spreadsheet itself. In Figure 2 a
yellow cell note in Cell B2 warns the user that the formula shown is erroneous.
VBA Functions
Instead of using a formula typed into a cell on the main spreadsheet, one can create a
VBA function to do it. Creating a function is particularly wise if the underlying formula is
complicated or includes more than simply an assignment statement. That function will be
invoked on the main sheet exactly as would any of the hundreds of intrinsic (supplied) functions
(sine, cosine, sum, etc.) provided in Excel by typing the cell formula, e.g.,
= Area_Circle(Diameter)
Now by clicking Tools, Macro, Visual Basic Editor and insert a Module (the later from
the VB Insert menu), a blank page will open where the VBA coding will go. One can also click
on the VBE icon on the toolbar to get directly into VBA. Users of older versions of Excel may
need to use: Insert, Macro, Module.
Figure 3. Project Explorer Window. This project (demosub.xls) has four objects: the
Workbook, three worksheets plus a single module.
When you are in the Visual Basic Editor (VBE) you can check the Project Explorer
Window in the upper left of the screen and you will see a treeview picture of your project. An
annotated example is seen in Figure 3. (You may only see the project name if someone else has
created the workbook and does not want you to see their coding.) You may also find the names
of various Excel “Add-ins” that you or some application you previously used has installed on
your computer. An Add-in consists of VBA code that the supplier, perhaps a commercial entity,
wants you to be able to use, but not have access to the source code. An Add-in does not preclude
you adding your own VBA coding, whereas simply password protecting modules does.
Most of the coding you do should be put in a module. Coding you put there will be
accessible from any of your worksheets and can be exported easily from there to any other
projects where it may be reused. If you place a control, e.g., a command button that activates a
subroutine on a particular worksheet, then coding for the event you want (calling the subroutine)
should appear in the coding for that form. So if you place a command button (from the controls
toolbox) on a worksheet and double click it while in design mode (where the eight “handles” you
use to resize, reshape and reposition it are visible), you will open the editor and the coding you
write to accompany that control will automatically be placed with that sheet instead of in a
module. You can put all the code you want executed with the button (or other control) with the
worksheet, but putting it in a module is probably a neater alternative.
Now here’s what VBA code for finding the area of a circle might look like:
Note that the type of the function itself and the argument passed into it (Diameter) have both
been declared as Double precision floating point numbers. (Numbers in cells on the worksheets
are automatically double precision, so declaring them single precision within the function would
require a type switch both on entering and leaving the function and would cost you about seven
significant figures in precision.) But the function as written above doesn’t work at all! The
message: #NAME? (indicating an error) appears in the cell where the function has been invoked on
the main sheet. If one deletes the Pi() completely, then this function does work (but gives the
wrong answer). The reason is that VBA has some of the intrinsic functions that Excel has, but
not all. To tell it to use the Pi function from Excel instead, one uses: Application.Pi().
With just a single statement assigning a value to the function, this example shows about
the simplest VBA programming one can do. Everything needed is passed into the function as an
argument and a value is returned to the cell where the function has been invoked. Here with
thorough documentation is the finished product:
This next example uses a control structure within a function, but here again, all necessary
data are passed in as arguments and a single value is returned to the cell where the function is
invoked. This example (HTTplnkslaw.xls) is on the HTT CD and website where it also uses
Excel’s Chart function to display values computed over a range of wavelengths and
temperatures. The actual equation being evaluated is:
C1
E λ ,b ( λ , T ) =
⎛ λCT2 ⎞
λ ⎜⎜ e − 1⎟⎟
5
⎝ ⎠
Option Explicit
Function Planck(Lambda As Double, Temperature As Double) As Double
A log-lot plot of the results obtained by invoking the Planck function at an array of
temperatures and wavelengths is shown in Figure 4.
The syntax used in the preceding function for selection has just two options. One can
also allow for multiple selection options:
If (…) Then
(…)
Elseif (…) Then
(…)
Else
(…)
End if
The next example is a little more complicated, but still is a function with parameters
passed in as arguments. In addition to an If - Then, Else, End If for Selection, it uses a For - Next
construct for Repetition. This example is also on the CD (HTTtwodss.xls) and website and uses
both flat and raised contour plots (see below) to show the computed results for a range of inputs.
The function evaluates the following analytical solution for steady-state conduction in a
rectangular region:
nπ y
2( −1) n+1 + 1
∞
nπ x sinh( L)
θ ( x, y ) = ∑ sin
π n=1 n L sinh( nπ W )
L
Option Explicit
Function AnalyticSoln(Nterms As Integer, X As Double, Y As Double) As Double
' This Visual Basic for Applications function evaluates the solution
' to the two-dimensional, steady-conduction problem for a square
' region, fixed value of 1.0 on one boundary, 0.0 on other three.
' The analytical solution from separation of variables is displayed
' on the main sheet and evaluated here. Here W = L = 1.0
' Inputs to this function are the number of terms to be included in
' the series and the x and y coordinates of the point where the
' evaluation is to be made.
' VBA doesn't have Pi or hyperbolic sine, so the "application...." tells it to use
' the Excel function instead. The hyperbolic sine gets very large for large
‘ arguments, so the reduced form of the solution in terms of exponentials is
‘ used then.
Dim K As Integer
Dim Coef As Double, Arg1 As Double, Arg2 As Double, Eee As Double
Dim Pie As Double, Xterm As Double, Yterm As Double
AnalyticSoln = 0#
Eee = 2.7182818
Pie = Application.Pi
For K = 1 To Nterms Step 2 ' Note coefficient = 0 for K even.
Coef = 2# * ((-1) ^ (K + 1) + 1) / (K * Pie)
Xterm = Sin(K * Pie * X)
If (K * Pie < 5#) Then
Arg1 = K * Pie * Y
Arg2 = K * Pie
Yterm = Application.Sinh(Arg1) / Application.Sinh(Arg2)
Else
End Function
A raised contour plot created from a field of data generated by evaluating this function on
a 21x21grid (i.e., at 441 points) using nine terms in the series and created using the Excel Chart
function is seen in Figure 5. On the spreadsheet itself, values of the X coordinate were contained
in one row; Y values were computed and stored in one column and passed as arguments into the
function. A second worksheet in that same workbook implements the same solution using a VBA
subroutine that takes advantage of the fact that one factor in the above equation is only a function
of the horizontal coordinate (x) and another is only a function of the vertical coordinate (y).
1.1-1.2
1-1.1
1.2
1.1 0.9-1
1 0.8-0.9
0.9
0.8 0.7-0.8
0.7 0.6-0.7
0.6
0.5 1 0.5-0.6
0.4 0.8 0.4-0.5
0.3
0.2 0.6 0.3-0.4
0.1 0.4 Y 0.2-0.3
0
-0.1 0.2 0.1-0.2
0
0.15
0-0.1
0.3
0.45
0
0.6
0.75
0.9
-0.1-0
X
Figure 5. Raised Contour Plot of Analytical Solution (9 terms) Evaluated on a 21x21 Grid
Typing Shift F3 with a particular cell selected can access another feature that helps in
debugging functions and subroutines. Figure 6 below shows the display for one particular cell
where the above function (AnalyticSoln) has been invoked. It shows the variables passed into the
function (the number of terms selected and the X and Y coordinates for that cell) as well as their
numerical values for that cell. In the upper right is the value returned for this cell.
In addition to the For … Next construct, there are several other constructs for Repetition:
the Do … While and Do … Until, and two ways to invoke each of them:
Do While ( ) Do
. .
. .
Loop Loop While ( )
The next example uses the Case construct for Selection within a function. In addition, it
shows how to create a Message Box (which will appear on the main worksheet) and also how to
put two statements on one line (which is generally not a good practice, but not that detrimental
here). In creating the message it also concatenates a string and a number.
Option Explicit
Function Discount(Quantity)
The next and last example, a function for finding the area of a circle, has nothing passed
in explicitly as an argument, but the needed input value (radius) is gained by reference to a
particular cell named that on the main sheet. But one must read the note at the top of it very
carefully! Note also that the worksheet was named “Mainsheet.”
Option Explcit
End Function
With the exception of the last one, all the example functions presented so far have gotten
data from the spreadsheet into VBA as arguments, and the output has come back to the
spreadsheet as the function value returned. Since, unlike functions, subroutines can change more
than one value (as is true in any programming language), it is appropriate at this point to point out
several other ways to get data into and out of VBA routines. (See the Walkenbach book for a
much more thorough discussion.)
The Cells property allows one to get data to and from worksheets using the row and
column indices. So to get data from Cell B7 on the main sheet (See how to declare a worksheet
in the previous example), one could use the statement:
Diameter = Shmain.Cells(7, 2)
where “7”refers to the row, “2” to the column. Similarly to return data to cell C9 on the main
sheet, one could write the VBA statement:
Shmain.Cells(9,3) = Area
Obviously the Cells property works well if one wants to get a whole array or vector to or from a
particular area on the spreadsheet.
The Range property allows the programmer to address cells by the address, e.g., B7.
Using the Range property the equivalent of the previous two statements would be:
Diameter = Shmain.Range(“B7”)
Shmain.Range(“C9”) = Area
A true range of cells may also be addressed, so that if one wanted to fill several columns using
VBA coding, the following statement would fill 18 cells with the number 5.0:
Shmain.Range(“A5:C10”) = 5.0
Finally the Range property may be used to address a cell by its name. So assuming the
programmer has named a particular cell on the main sheet as “Circumference” and another as
“Diameter,” the following statement will retrieve the latter and return the former.
You can also use Range and Cells addressing to control cell properties like fonts, background
colors, etc.
VBA Subroutines
In high level programming languages functions return only a single value. In a similar
fashion a VBA function can only affect the one cell where it is invoked. Just as subroutines in
Fortran or any other high level language can return more than one value, a subroutine in VBA can
change more than one cell. The following module is a subroutine that returns values to four
different cells. It also illustrates both the range and cells methods to pass values to and from
cells: by name, by address, and by row and column index. Note the use of space-underline that
has been used in several places to indicate a continued line.
Option Explicit
Sub CompAreaVol()
' Computes area and volume of cylinder and sphere and returns the values
' to appropriate place on main sheet, i.e., it is changing values in
' more than one cell with just one invocation. Note there are no arguments
' passed. Three different ways of obtaining data from the mainsheet (which has been
‘ named "MainSheet") are demonstrated: (1) By name of the cell ‘"Radius"), (2) by cell
‘ address ("B2"), and (3) using the cells method (Row index, ‘Column index).
‘ Obviously the assignment statements below could be made a lot shorter by
' introducing local variables for the radius, length, pi, etc.
' This subroutine has to be invoked in some way, hitting F5 key from this
' window is one; you can also create a RUN button for the user on the main sheet.
' This one accesses the radius by the cell name and returns values by cell name also.
ShMain.Range("Vol_Cyl").Value = Application.Pi() * _
ShMain.Range("Radius").Value ^ 2 * ShMain.Range("Length").Value
' Next calculation includes area of two ends, plus the sides. It accesses the
' radius using the cells method (rowIndex, columnIndex)
ShMain.Range("Area_Cyl").Value = 2.0*Application.Pi() * _
( ShMain.Cells(2, 2).Value ^ 2 + _
ShMain.Cells(2, 2).Value * ShMain.Range("Length").Value)
ShMain.Range("Area_Sph").Value = 4# * Application.Pi() * _
ShMain.Range("Radius").Value ^ 2
End Sub
Note that before running this subroutine (as well as the previous Area_Circle function)
the first worksheet (Sheet1) had been named "MainSheet" – by double-clicking on its tab and
typing in the name. One of the cells (B2) on that sheet had been named "radius" and another
"length". Figure 7 shows the upper left corner of the MainSheet after the subroutine has been
run.
Two of the workbooks on the CD and website, the one for air and water properties [7]
(Airwater.xls) and the projectile motion project (Projmotn.xls,
www.faculty.virginia.edu/ribando/modules/xls), especially the latter, make use of these
concepts. In addition, the projectile workbook includes a command button control to activate
the subroutine.
Especially if you want your VBA coding to interact with Excel’s drawing and charting
tools, you must learn to record and edit a macro. By running the macro recorder while you draw
objects or spruce up graphs and then viewing the VBA code that Excel generates itself, you can
incorporate similar coding into your own VBA. Then you can change the size of an object,
rescale axes, change line weights or nearly anything else you might want to accomplish by
writing your own code. No book can possibly cover all the coding tricks you can pick up this
way! The following section shows an excellent student-written example.
Any of the drawing and charting capabilities of Excel may be implemented through VBA
coding. ActiveX controls may be incorporated similarly. (Use Tools – Customize – Toolbars –
Control Toolbox to bring up the controls toolbox. The toolbox includes an icon that will switch
you between Design and Run mode.) In the example seen in Figure 8 below the user enters the
radius of the two coaxial parallel disks and their separation distance. A VBA function computes
the viewfactor (a geometric quantity representing the fraction of radiation emitted by one disk
that is intercepted by the other assuming the first surface is a diffuse emitter) based on the
analytical solution, and then invokes a subroutine that draws the two disks to scale within the
gray window. As an additional feature, the user can change the viewing angle using the vertical
slider bar control.
In order to see how various geometric shapes are incorporated, one may draw that shape
manually on the worksheet, while recording the macro. So for instance, if one wanted to learn the
VBA coding to draw a red rectangle on the screen, one turns on “Record macro,” draws the
rectangle manually (using AutoShapes) and then selects the fill color. Stop recording, and then if
you edit the macro you have just recorded, you will find something like:
Sub Drawbox()
'
' Drawbox Macro
' Macro recorded 7/19/99 by Robert J. Ribando
'
ActiveSheet.Shapes.AddShape(msoShapeRectangle, 96#, 66#, 144.6, 118.8). _
Select
Selection.ShapeRange.Fill.ForeColor.SchemeColor = 10
Selection.ShapeRange.Fill.Visible = msoTrue
Selection.ShapeRange.Fill.Solid
End Sub
Now one can include similar coding into a custom VBA application program, changing
for instance, the size, colors and location to suit your needs. In Figure 8, several “special effects”
have been used, including horizontal shading of both disks to give the illusion of depth.
Two especially useful controls are the command button and the scrollbar. While a function value
is updated automatically at the cell where that function is invoked whenever one of its input
parameters is changed, one must provide a means to call a subroutine. The command button
provides an easy route. One simply draws the button, double clicks on it and writes the coding to
call the subroutine. Thus to call the subroutine used in the section above, one writes:
Call CompAreaVol()
under the button. This single line accompanying the button calls the subroutine that you have
already saved in a module.
Certain controls, e.g., the scrollbar, have the property of a “linked cell.” In Figure 8, the
cell that in this static picture has a value of 32 is linked to the scrollbar and holds its current
value. VBA code can be made to access this particular cell, thus allowing the scrollbar to be used
for data input.
VBA can be used for some fairly extensive calculations including the “number-
crunching” applications one encounters, for instance, in computational fluid dynamics (CFD)
instruction. Because formatting numbers for output to Excel cells is computationally intensive,
one is strongly encouraged to pass all the inputs from the Excel sheet into VBA and store them
there as local variables. Only when the calculation is complete should the final numbers be
returned to the Excel sheet, where the user will probably want to plot them. If an occasional
piece of data is desired during a transient calculation, one can pass just that data back to the
spreadsheet and use the VBA “DoEvents” function to force the calculation to stop while the
plotting is done.
One may also want to provide coding so that any large data sets generated by the
program is automatically cleared when the workbook is saved. Using ClearContents as part of
the BeforeSave event can dramatically reduce the size of the resulting workbook.
Conclusion
Student response to use of VBA within other courses, both undergraduate and graduate,
has been excellent. Since all have had a structured programming course earlier (some in Fortran
90, some in C++, others in Java), the migration to VBA is very straightforward. Most welcome
the opportunity to add another package to their inventory of proficiencies. Several graduate
students in a recent programming-intensive computational fluid dynamics (CFD) elected to do all
assignments using Excel/VBA.
The topics covered in this note are the subjects of only a couple chapters in the
Walkenbach book, but are certainly sufficient to address nearly all the sorts of calculations that an
undergraduate in engineering (and probably most graduate students) might find him or herself
wanting to do. There are a myriad of other operations and features that one can implement in
VBA; the Walkenbach book is clearly an excellent source of help. About a dozen samples of
Excel/VBA coding mostly applied to heat transfer and fluid mechanics problems may be
downloaded at: http://www.faculty.virginia.edu/ribando/modules/xls .
References
2. Gottfried, B.S., Spreadsheet Tools for Engineers - Excel 2000 Version, McGraw-Hill,
New York (2000).
3. Monson, L., Using Microsoft Excel 97, Que Corporation, Indianapolis (1997).
4. Walkenbach, J., Microsoft Excel 2000 Power Programming with VBA, IDG Books
Worldwide, Inc., Foster City, CA (1999).
6. Halberg, B., Kinkopf, S., Ray, B. et al., Special Edition - Using Microsoft Excel 97, Que
Corporation, Indianapolis (1997).
7. Chapra, S.C., Power Programming with VBA/Excel, Prentice Hall, Upper Saddle River,
NJ, 2003.
8. Albright, S.C., VBA for Modelers – Developing Decision Support Systems with Microsoft
Excel, Duxbury – Thomson Learning, Pacific Grove, CA 2001.
9. Bullen, S., Bovey, R. and Glenn, J., Professional Excel Development: The Definitive
Guide to Developing Applications Using Microsoft(R) Excel and VBA(R), The Addison-
Wesley Microsoft TechnologySeries) , 2005
10. Ribando, R.J. and Galbis-Reig, V., "Convective Heat and Mass Transfer from a Runner
Using Some Advanced Spreadsheet Features," Computers in Education Journal, Vol.
VIII, No. 4, Oct-Dec. 1998, pp. 22-28.