Sei sulla pagina 1di 92

Excel® VBA for Physicists

A Primer
Excel® VBA for Physicists
A Primer

Bernard V Liengme
St Francis Xavier University, Nova Scotia, Canada

Morgan & Claypool Publishers


Copyright ª 2016 Morgan & Claypool Publishers

All rights reserved. No part of this publication may be reproduced, stored in a retrieval system
or transmitted in any form or by any means, electronic, mechanical, photocopying, recording
or otherwise, without the prior permission of the publisher, or as expressly permitted by law or
under terms agreed with the appropriate rights organization. Multiple copying is permitted in
accordance with the terms of licences issued by the Copyright Licensing Agency, the Copyright
Clearance Centre and other reproduction rights organisations.

Rights & Permissions


To obtain permission to re-use copyrighted material from Morgan & Claypool Publishers, please
contact info@morganclaypool.com.

Online supplementary data files are available at http://ej.iop.org/images/books/978-1-6817-4461-2/


live/bk978-1-6817-4461-2suppdata.zip

ISBN 978-1-6817-4461-2 (ebook)


ISBN 978-1-6817-4460-5 (print)
ISBN 978-1-6817-4463-6 (mobi)

DOI 10.1088/978-1-6817-4461-2

Version: 20161101

IOP Concise Physics


ISSN 2053-2571 (online)
ISSN 2054-7307 (print)

A Morgan & Claypool publication as part of IOP Concise Physics


Published by Morgan & Claypool Publishers, 40 Oak Drive, San Rafael, CA, 94903 USA

IOP Publishing, Temple Circus, Temple Way, Bristol BS1 6HG, UK


To Pauline, my wife, my friend,
and my amanuensis, with many, many thanks.
Contents

Preface x
Acknowledgements xi
Author biography xii

1 Introduction 1-1
1.1 Preparation 1-1
1.2 Demonstrating a simple function 1-3
1.3 Saving a macro-enabled workbook 1-5
1.4 Using constants and VB functions 1-6
1.5 User-defined array function 1-7
1.6 Notes on VBA functions 1-8
1.7 A simple subroutine 1-9
1.8 Linking an image to a subroutine 1-11
1.9 Recording a macro 1-11
1.10 Finding a home for macros 1-14
1.11 Typographical matters 1-14

2 Variables, Dim statements, and data types 2-1


2.1 Naming variables 2-1
2.2 The Dim statement 2-1
2.3 The major reason for variable declarations 2-1
2.4 Declarations in function headers and for constants 2-3
2.5 Data types 2-3
2.6 A second reason for variable declarations 2-4
2.7 Dimensioning arrays 2-4
2.8 The Set statement 2-6
2.9 The With…End With structure 2-7

3 Structured programming 3-1


3.1 Branching structures (If and Select Case) 3-1
3.2 Looping structures (For…Next and Do…While/Until) 3-4
3.3 Some further examples 3-7

vii
Excel® VBA for Physicists

4 The Excel object model 4-1


4.1 Examples of properties, methods and events 4-1
4.2 The Range object properties 4-3
4.3 Range object methods 4-5
4.3.1 Select, Copy, and Paste 4-5
4.3.2 Clear methods 4-7
4.3.3 Delete method 4-7
4.4 WorksheetFunction object 4-7
4.5 Workbook and worksheet events 4-12
4.5.1 Workbook event 4-12
4.5.2 Worksheet event 4-13
4.6 Code for sending email 4-14

5 Working with add-ins 5-1


5.1 Creating an add-in 5-1
5.2 Installation 5-2
5.3 Using the add-in 5-2
5.4 Making changes to the add-in 5-3
5.5 Viewing worksheets 5-3
5.6 Protecting the add-in 5-4
5.7 Reversing everything 5-4

6 Numerical integration 6-1


6.1 The trapezoid approximation 6-1
6.2 The Simpson 1/3 approximation 6-4
6.3 An aside 6-6
6.4 Monte Carlo integration 6-7
6.5 Gaussian and Romberg integration 6-8

7 Numerical methods for differential equations 7-1


7.1 Euler’s method 7-1
7.2 The Runge–Kutta fourth-order method 7-4
7.3 Simultaneous OEDs 7-6
7.4 Example of a system of two OEDs 7-6
7.5 Higher order OEDs 7-8
7.6 R–L circuit 7-8

viii
Excel® VBA for Physicists

8 Finding roots 8-1


8.1 The bisection method 8-1
8.2 The successive iteration method 8-3
8.3 Root finding with Solver 8-4
8.4 Using range names 8-7

ix
Preface

This work will introduce the reader to Visual Basic for Applications (VBA) and
demonstrate how it can greatly enhance Microsoft Excel® by giving users the ability
to make their own functions that can be used within a worksheet, and to create
subroutines to perform repetitive actions.
Visual Basic (VB, the parent of VBA) has its roots in the educational
programming language BASIC redeveloped at Dartmouth College in 1964. In
the half-century since then, the language has evolved to become a high-powered
object-orientated language which is no longer denigrated by aficionados of
language such as C++ and C#. The VBA compiler and editor is incorporated
within the Excel application; there is nothing to buy or install.
The author’s primary aim is to show the reader how to write both functions and
subroutines, and to demonstrate that this is not a complex topic. The material is
presented in a manner that will allow the reader to experiment with VBA
programming; this is the best way to learn it. The scenarios used in the examples
center around either fairly simple physics or non-complicated mathematics, such as
root finding and numerical integration. The text, therefore, will be suitable not just
for physicists but for other scientists and engineers, including students.
A tested Excel workbook can be downloaded from here for each chapter.
The brevity of the book prevents total rigour so it was necessary to condense some
material, but Internet links are provided so the reader can explore VBA topics in
greater depth. For the reader who prefers a paper reference source, Excel 2007 VBA
by John Green et al (2007, New York: Wiley) is an excellent book, notwithstanding
its date; furthermore, it can be obtained very cheaply online.
The author is more than happy to reply to email inquiries about topics in the
book or other Excel (with or without VBA) questions. Please use the word Excel in
the subject line of each message.
Have fun learning to extend Excel with VBA!

Bernard V Liengme
bliengme@stfx.ca

x
Acknowledgements

The author thanks Microsoft Excel Most Valuable Professionals (MVPs) Jon
Peltier, Bob Umlas, and Jan Karel Pieterse for their help over the years.

xi
Author biography

Bernard V Liengme
Bernard V Liengme attended Imperial College London for his
undergraduate and postgraduate degrees; he held post-doctoral
fellowships at Carnegie-Mellon University and the University of
British Columbia. He has conducted extensive research in surface
chemistry and the Mossbauer effect. He has been at St Francis
Xavier University in Canada since 1968 as a Professor, Associate
Dean, and Registrar, as well as teaching chemistry and computer science. He
currently lectures part-time on business information systems. Bernard is also the
author of other successful books: COBOL by Command (1996), A Guide to
Microsoft Excel for Scientists and Engineers (now in its fourth edition), A Guide to
Microsoft Excel for Business and Management (now in its second edition), Modelling
Physics with Microsoft Excel® (2014), and SMath for Physics: A Primer (2015).

xii
IOP Concise Physics

Excel® VBA for Physicists


A Primer
Bernard V Liengme

Chapter 1
Introduction

Visual Basic for Applications (VBA) is a programming language that has been built
into Microsoft Office since Office 1997. It has its roots in Visual Basic (VB), so when you
perform an internet search on a VBA topic do not be surprised by references to VB.
In this chapter we will make a few simple changes to our Excel environment to
allow us to code and run macros. Then we will see how to code some examples of
simple macros (procedures), i.e. functions and subroutines. We close with a brief
look at recording a subroutine.

1.1 Preparation
There is little to do in preparation. We start by adding the Developer tab to the
Excel ribbon. Right click on the Home tab and select Customize Ribbon. This opens
the dialog box as shown in figure 1.1, click the box to the left of Developer to add a
check mark (if it is not already there), and then click the OK button in the lower
right-hand corner of the dialog. As can be seen from the title in this dialog, one can
also customize the ribbon by using the command File | Options | Customize Ribbon.
The ribbon now has the Developer tab present, as shown in figure 1.2. We can
now check the macro security setting. Open the Developer tab and click on Macro
Security to open the dialog shown in figure 1.3. Make sure that the setting is Disable
all macros with notification (this is the default setting and should not be changed
without good reason.) Beginning with Office 2007, Microsoft required that
workbooks containing macros be saved with the extension XLSM; we refer to
such workbooks as macro-enabled. This is a security feature since a rogue macro can
harm a computer. When you open a macro-enabled workbook you will see a
warning as shown in figure 1.4; click on Enable Content if you trust the workbook
not to have rogue macros. If you are working with Excel 2003, your workbooks will
have the extension XLS even when they contain macros. To learn more about macro
security, visit https://support.office.com/en-us/article/Enable-or-disable-macros-in-
Office-files-12B036FD-D140-4E74-B45E-16FED1A7E5C6.

doi:10.1088/978-1-6817-4461-2ch1 1-1 ª Morgan & Claypool Publishers 2016


Excel® VBA for Physicists

Figure 1.1. Customizing the Quick Access Toolbar to add the Developer tab.

Figure 1.2. The ribbon with the Developer tab added.

You may not see this warning every time; Excel seems to remember if a specific
macro-enabled file has been opened in the same user session. At other times the
warning comes with a more ominous message (figure 1.5). It seems odd that this
message occurs when the file sits on the author’s hard drive.
In subsequent chapters all the reader needs to do is open one of the workbooks
(Topic2.xlsm to Topic8.xlsm) which are available for download—see the preface. In
this chapter the reader needs to learn how to open the VB Editor (VBE), add a
module, and save a macro-enabled file. It is best that the reader starts with a new file.
However, to cut down on the work, the companion site has the file Topic1BVL.xlsm,
and this chapter gives instructions on copying from that workbook to the reader’s
new workbook.

1-2
Excel® VBA for Physicists

Figure 1.3. Setting the macro security.

Figure 1.4. Example of a macro warning.

Figure 1.5. Another macro warning format.

1.2 Demonstrating a simple function


Within the Excel environment there are three types of function: the worksheet function
(examples being SUM, AVERAGE, ACOS); VB functions (Lcase, Len, Round);

1-3
Excel® VBA for Physicists

and functions that are coded by a user. Functions of the last type are often referred to
as user-defined functions (UDFs).
Later we will see that all VB functions may be used within a UDF, but there is a
restriction on which worksheet function may be used. In general, if there is an
equivalent VB function then the worksheet function may not be used.

Example. A physics student needs to compute the kinetic energy given the mass and
velocity of the object. Figure 1.6 shows a sample worksheet. In column C he uses a
worksheet formula to compute the kinetic energy, while column D shows how a
UDF may be used. The reader should set up a worksheet like this but leave D2:D5
empty for now. In B7 we have the formula = FORMULATEXT(C2), which displays
the referenced cell’s formula.

Open the Developer tab, click on Visual Basic (the left most icon) to open the
VBE. Figure 1.7 shows the VBE window, but since you have just opened it the
working space (the module area, the panel at top right) will be grey. Click on the
Insert command and select Module. Now type this code into the module:
Function KE(mass, Vel)
KE = (1 / 2) * mass * Vel ^ 2
End Function
You may now return to the worksheet by clicking the green Excel icon on the far
left of the VBE toolbars, or by clicking the worksheet if it is visible behind the VBE.
In D2 type =KE(A2, B2), press Enter to complete the formula, and drag the
formula down to row 5.
Suppose you made a mistake in the code and had entered KE = (1/2)
*mass*vel+2. You can return to the VBE (try the shortcut ALT+F11) and
make the correction. How disappointed will you be when on returning to the
worksheet you find the results in columns C and D still do not agree?
MORAL. Whenever a change is made to a UDF it will not affect the worksheet
until the worksheet is recalculated. Do this by pressing F9, or selecting a cell with the
UDF (D2 for example) and double clicking it.

Figure 1.6. Example of using a UDF.

1-4
Excel® VBA for Physicists

If you have a syntax error in a macro, Excel will throw up a warning. Click the
Debug button and the offending line will be highlighted. After making a correction,
click the square blue reset button—it is right under Run in the menu bar of the VBE
as shown in figure 1.7. When there is a VBA error you cannot do anything with the
worksheet until the error is removed.

1.3 Saving a macro-enabled workbook


Now we will save our work. From the Excel workspace either click the Save icon in
the Quick Access Toolbar (will Microsoft think of a new icon when we have all
forgotten about floppy discs?) or use the command File | Save. In the normal way,
give the file a name such as ‘Topic1’ but there is an extra step. Under the name box
you will see a box Excel Workbook (.xlsx) with a drop down arrow at the right.
Click the arrow and select the second option, Excel Macro-Enabled Workbook
(.xlsm), see figure 1.8. If you fail to do this Excel will detect the presence of a macro
and issue a warning. If you do not heed the warning all your modules will disappear!

Figure 1.7. The VBE interface.

Figure 1.8. The macro-enabled option in Save.

1-5
Excel® VBA for Physicists

1.4 Using constants and VB functions


Professor X wants to make a worksheet to compute the most probable, the mean,
and the root-mean-squared velocity of various gases at a specified temperature. Her
worksheet is shown in figure 1.9. Once again we will perform our calculations first
with worksheet formulas and then with UDFs. The author likes to confirm that the
two methods agree when testing a new UDF.
The formulas for the three velocities in C10:E10 are: =SQRT(2*8.3145*Temp/
(B10*10^-3)), =SQRT(8*8.3145*Temp/(PI()*B10*10^-3)), and =SQRT
((3*8.3145*Temp)/(B10*10^-3)). Note that B6 has been given the name
‘Temp’.
Open your Topic1.xlsm workbook, add a new worksheet and make it
similar to the figure. The reader may wish to open Topic1BVL.xlsm, select A1:
F29, and copy and paste to his/her Sheet2. Initially this will give #NAME! errors

Figure 1.9. Another UDF.

1-6
Excel® VBA for Physicists

in C18:E21 and C26:E29 because the Topic1.xlsm workbook lacks the referenced
UDFs.
Open the VBE. Sometimes it is expedient to have more than one module, but that
is not the case here. On Module1 add the following code below the code for the
kinetic energy function (as we are working in SI units we need the molar mass to be
in kilograms, hence the 10−3 factor):
Function Vprob(T, M)
Const R = 8.3145 ‘SI units
Vprob = Sqr(2 * R * T / (M * 10 ^ −3))
End Function
In C18 enter the formula =Vprob(Temp, B18). In figure 1.9 the inset shows
that our UDF appears in the tooltip box when we type =v.
In the function code we have declared R to be a constant and given it a value. This
prevents users from reassigning a value to R later in the code—not very likely in a
two-statement function but a potential error in longer macros. Within the code
Const R = 8.3145 ‘SI units, everything after the single quote is a
comment. Since VB functions take precedence over worksheet functions we use
its Sqr function rather than the worksheet function SQRT.
The code for Vmean is shown below; it is left as an exercise for the reader to code
Vrms:
Function Vmean(T, M)
Const R = 8.3145 ‘SI units
Pi = 4 * Atn(1)
Vmean = Sqr(8 * R * T / (Pi * M * 10 ^ −3))
End Function
We will code the UDF used in C26:E29 shortly.
Two things to note: (i) VB has no built in function for π, we could have coded Pi
= 3.14159265358979, but to guard against typing errors we choose the simple
formula; (ii) VBA permits a constant to be defined with an expression such as Const
TwoPi=2 * 3.14159265358979, but functions are not permitted in the
expression, making Const Pi = 4 * Atn(1) invalid.
While researching these formulas for these velocities, the author found several
sites that computed them. All agreed when the root-mean-squared velocity was
calculated, but there was a wide spread for the others. To test for correctness, use the
fact that vmean = ( 2π )vprop and vrms = 3 vprop . The following website gave consistent
2
results: http://hyperphysics.phy-astr.gsu.edu/hbase/kinetic/kintem.html.

1.5 User-defined array functions


It is possible to write code that returns data to more than one cell—think about the
worksheet functions LINEST and FREQUENCY. The code below computes Vprob,
Vmean, and Vrms all in one function. If you pasted C26:E29 from the author’s

1-7
Excel® VBA for Physicists

workbook, please delete those cells now. Select C26:E26, type =Velocities
(Temp,B26) and commit the formula with CTRL+SHIFT+ENTER. Cells C26:
E26 will each display {=VelocitiesV(Temp,B26)} where Excel has added the
curly braces to denote an array function. We can now drag C26:E26 down to row 29.
Function Velocities(T, M)
Dim Vel(3)
Const R = 8.3145
Pi = 4 * Atn(1)
Vel(0) = Sqr(2 * R * T / (M * 10 ^ −3))
Vel(1) = Sqr(8 * R * T / (Pi * M * 10 ^ −3))
Vel(2) = Sqr(3 * R * T / (M * 10 ^ −3))
End Function
In the first statement we use the Dim feature to define an array called ‘Vel’ having
three components. We compute values for each component and then pass the values
of the Vel array to the function named ‘Velocities’. Unless the reader is familiar with
languages like C++, the use of Vel(0) might be a bit unsettling. By default, VB
uses array indices starting with zero; chapter 2 shows how we can obtain the more
familiar first index of 1.

1.6 Notes on VBA functions


Because the marriage of Office Excel and VB was made when both were mature
applications, it is not surprising that sometimes there is a clash between them. The
reader should be aware that there are some differences between worksheet and VB
functions with the same name.
1. While the worksheet function =LOG(3) returns the logarithm of 3 to base
10, the VB expression x = Log(3) results in the logarithm to base e. To
obtain a base 10 result one codes x = Log(3)/log(10).
2. When the digit to be rounded is 5, the VB Round function rounds to make
the result even; so Round(3.5,0) and Round(4.5,0) each give 4 as the
result, and Round(−3.5,0) and Round(−4.5,0) each give −4. Contrast
this with the Excel results, which would be 4 and 5 for positive values and −4
and −5 for negative values, since Excel rounds up when x > 0 and down
when x < 0 when the digit to be rounded is 5. The VB behavior is sometimes
called ‘bankers’ rounding’, but there is little evidence that bankers use it.
3. Excel has the MOD function: =MOD(11,10) returns the value 1. VBA has the
Mod operator: the expression 11 Mod 10 also returns 1. However, the two
do not agree when one (not both) of the arguments is negative, as is shown in
table 1.1; the last two columns show alternative ways of performing the
calculations.
TRUNC and INT are similar in that both return integers. TRUNC removes
the fractional part of the number. INT rounds numbers down to the nearest
integer based on the value of the fractional part of the number. The results
from INT and TRUNC are different only when using negative numbers:

1-8
Excel® VBA for Physicists

Table 1.1. Comparing Excel’s MOD and VBA’s Mod.

a b MOD Mod a-(b*INT(a/b)) a-(b*TRUNC(a/b))

11 10 1 1 1 1
−11 9 7 −2 7 −2
19 −13 −7 6 −7 6
−11 −10 −1 −1 −1 −1

Figure 1.10. Example of output from a subroutine.

TRUNC(−4.3) returns −4, but INT(−4.3) returns −5, because −5 is the


lower number. The table above is taken from https://support.office.com/en-
us/article/TRUNC-function-8B86A64C-3127-43DB-BA14-AA5CEB292721?
ui=en-US&rs=en-US&ad=US.

1.7 A simple subroutine


In this section we see a simple subroutine that asks for input from the user and,
having made a calculation, places the result on a worksheet. For the demonstration
it is convenient to stay with the molecular velocities theme.
Using the icon of an X within a circle after the last sheet tab, the reader should insert
a new worksheet. Then right click its tab and rename the sheet ‘MolVel’. Set up the
worksheet to look like figure 1.10, leaving rows 4 and 7 empty. Using the command
Insert | Illustrations | Shapes, place any shape on the worksheet and add text to it.
Navigate to the VBE and in the Project panel (top left) select Topic1. From the
menu, use Insert | Module. It is not essential to put our code in a separate module,
but it helps with the demonstration.
Enter the code shown below, this may be copied from Module2 in Topic1BVL.
xlsm:
Sub MolVel()
On Error GoTo Hades
Worksheets(“MolSpeed”).Activate
Range(“B4:D4”).ClearContents

1-9
Excel® VBA for Physicists

Range(“B7:D7”).ClearContents
Gas = InputBox(prompt:=“Give gas name or formula”)
Range(“B4”) = Gas
MolMass = InputBox(prompt:=“Give molar mass (g/mole)”)
Range(“C4”) = MolMass
mTemp = InputBox(prompt:=“Give temperature in K”)
Range(“D4”) = mTemp
Range(“B7”) = Vprob(mTemp, MolMass)
Range(“C7”) = Vmean(mTemp, MolMass)
Range(“D7”) = Vrms(mTemp, MolMass)
Hades:
End Sub
Experienced programmers may be appalled to see a ‘GoTo’, but the construct On
Error GoTo … is very common in VB programming, especially in the form On
Error GoTo … Resume Next to tell the program to ignore any error it encounters.
Here we have made up a name ‘Hades’ for a line to which the program will go when an
error is detected. The program flow is directed to the very end of the subroutine in this
circumstance. Examples of possible errors: (i) there is no worksheet called ‘MolSpeed’ or
(ii) the user fails to enter a meaningful value for one of the numeric variables MolMass
and mTemp,1 causing the various velocity functions to misfire. Note how we can access
these velocity functions even though they reside on a different module within the same
workbook. Should we wish to prevent such access we could add the word ‘Private’ at
the start of a function header—Private Function Whatever(….).
Before we proceed we need to return to the worksheet. Right click on the shape
and by selecting Assign Macro, indicate that this shape should run the subroutine
MolVel when clicked.
Next we look at various ways of calling up the subroutine.
1. Within the VBE we could use the Run command (figure 1.11) on the menu
(or its shortcut F5), or click the green arrow just below the Debug menu
command. In these cases, VBA may present a dialog box listing the macros
(i.e. subroutines) in the current VBA Project—even when there is only one!
Click on the macro of interest and then click the Run button, or just double
click the sub you wish to run. If the mouse cursor is inside a subroutine this
dialog is often skipped.
2. In the Code group (far left) of the Developer tab click on the item Macros, or
on the View tab locate the Macros group (far right), click on the Macros
tool, and select View Macros. In either case a dialog will open with a list of
macros—not just those in the current project but all those in the currently
opened workbook. The shortcut ALT+F8 results in the same dialog.
3. Click on the shape on the MolSpeed sheet. Since we have assigned it to the
MolVel subroutine this is what will run.

1
A variable must not have a name which is also a keyword, so we used mTemp rather than Temp just in case
Temp is a keyword (actually, it is not!).

1-10
Excel® VBA for Physicists

Figure 1.11. Some commands in the VBE menu.

Figure 1.12. The InputBox dialog.

When we run MolVel, Excel is told to activate the appropriate sheet, otherwise our
output could damage another worksheet. Of course, if we always ran the sub by
clicking the shape on the MolSpeed worksheet, this statement would be redundant.
Next a box pops up (figure 1.12) asking the user to name the gas. This name is then
placed in cell B4. In similar ways we obtain the molar mass and temperature in B5 and
B6, respectively. These are used by the velocity functions (Vprob, Vmean, and Vrms)
and the results of the functions are placed in cells B7:D7. Note that this subroutine that
resides in Module2 has access to functions defined in Module1. If we wished otherwise
we would add the word ‘Private’ before Function in the headers.

1.8 Linking an image to a subroutine


In figure 1.10 we have a blue rectangle which, when clicked, causes the subroutine
MolVel to run. The image can be a shape or picture. After placing it on the
worksheet right click it to bring up the dialog shown to the left in figure 1.13. The
user clicks the Assign Macro item bringing up a list of subroutines available in the
current Excel session and clicks the appropriate one.

1.9 Recording a macro


Excel has a tool for recording the user’s keystrokes and generating a subroutine that
can be used over and over. This can be useful for formatting and entering textual data.

1-11
Excel® VBA for Physicists

Figure 1.13. Linking an image to a subroutine.

Figure 1.14. The Record Macro dialog.

It cannot be used to make functions or to have a subroutine place a value in a cell.


Many users have found the Recorder useful for learning simple VBA commands, but it
must be stressed that the resulting subroutine is seldom very efficient.
Let us see an example. Open Sheet2 of the Topic1 workbook. To the left of the
status bar just after the word Ready, there is a small box which switches the recorder
on and off. The Code group of the Developer tab also has this tool. Start recording
and perform the following operations:
1. Fill in the dialog box as shown in figure 1.14 and click the OK button. We
will not bother with a shortcut.

1-12
Excel® VBA for Physicists

2. Hold down the CTRL key and drag the tab of Sheet2 to the left between
Sheet2 and MolSpeed. Release the CTRL key. Now we have a new
worksheet called Sheet2 (2) and it is the active sheet.
3. Using tools in the font group of the Home group:
i. Change the size of the type in A1:E1 and A6:C6.
ii. Select A8:E13 and give the range a fill colour and change its font colour.
iii. Do the same with A16:E21.
iv. Click on F14.
4. Switch off the recorder.
Open the VBE and in the Topic1 project you will find the recorder added
Module3 holding the sub DuplicateSheet2. This reads:
Sub DuplicateSheet2()

‘ DuplicateSheet2 Macro
‘ Make a duplicate of Sheet2 and format some ranges

Sheets(“Sheet2”).Select
Sheets(“Sheet2”).Copy Before:=Sheets(3)
Range(“A1:E1”).Select
Selection.Font.Size = 14
Selection.Font.Size = 16
Range(“A6:C6”).Select
Selection.Font.Size = 14
Selection.Font.Size = 16
Range(“A8:E13”).Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent3
.TintAndShade = 0.799981688894314
.PatternTintAndShade = 0
End With
With Selection.Font
.ThemeColor = xlThemeColorAccent2
.TintAndShade = 0
End With
Range(“A16:E21”).Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.399975585192419
.PatternTintAndShade = 0
End With

1-13
Excel® VBA for Physicists

With Selection.Font
.ThemeColor = xlThemeColorAccent5
.TintAndShade = −0.249977111117893
End With
Range(“F14”).Select
End Sub
The reader is encouraged to spot the pieces of code that correspond to the actions
performed while recording. Of course, some parameters (such as Font.Size,
TintAndShade) will have different values depending on what the user selected.

1.10 Finding a home for macros


We have placed our functions and subroutines in modules stored in the current
workbook. This is generally the safest choice. Macros housed in other workbooks are
accessible when those workbooks are open; one generally avoids this complication.
If you have macros that you wish to use in many different workbooks, then the
best course is to store them in the Personal.xlsb workbook. This workbook can be
made by starting the recorder, specifying Personal as the stage place (the third box in
figure 1.14), and recoding a one-line sub. Then go to the VBE, open the Personal
project, and delete the module with the dummy subroutine.
The Personal.xlsb workbook is stored in your Xlstart folder and opens every time
Excel is started, and it is normally hidden in Excel but visible in the VBE. The
following links provide further information (do not be concerned if they mention
older versions of Excel or Windows):
• http://www.rondebruin.nl/win/personal.htm
• https://support.office.com/en-us/article/Copy-your-macros-to-a-Personal-Macro-
Workbook-AA439B90-F836-4381-97F0-6E4C3F5EE566?ui=en-US&rs=en-
US&ad=US

Another place for macros is an Add-in workbook; we explore this topic in


chapter 5.

1.11 Typographical matters


The indentation shown in our example is not mandatory but is highly recommended
as it makes reading the code a lot easier. For example, when the statements
between For and Next are indented it is immediately obvious what code is
repeated.
A long statement may be split into several rows using the underscore character.
For example:
Range(“A2”) = Range(“F2”).Value + Range(“C2”).Value
may be coded as
Range(“A2”) = Range(“F2”).Value _
+ Range(“C2”).Value

1-14
Excel® VBA for Physicists

It is important to note that the underscore is placed just after a space in the long
code. This cannot be a space within a literal. The correct way to split a literal is
demonstrated by
Range(“A10”) = “Now is the time for all good folks to ” _
& “come to the aid of the party”

1-15
IOP Concise Physics

Excel® VBA for Physicists


A Primer
Bernard V Liengme

Chapter 2
Variables, Dim statements, and data types

2.1 Naming variables


The rules for naming variables are simple:
i. You can use letters and digits but the first character must be a letter. The
maximum length is 255 characters.
ii. Avoid spaces and other symbols, although VBA will tolerate the underscore
symbol.
iii. You cannot use reserved word like Dim, Sub, Next, or the names of VB
functions. Any of these will cause the VBE to throw up an error message.
iv. VBA does not distinguish upper and lower case. Indeed, if early in the
macro you introduce the name ‘MyData’ and then later type ‘mydata’, the
editor will replace it with ‘MyData’ to be consistent.

2.2 The Dim statement


Most computer languages require each variable to be declared before being used.
However, VBA allows you to introduce a variable on the fly. This can be over-
written by adding Option Explicit at the top of a module. If you wish to ensure
that all new modules have this option included, then open the VBA Tools command
and check the box Require Variable Declaration, see figure 2.1.
While there are several good reasons for declaring all variables with Dim
statements, most examples in the book do not use them since the procedures are
short and the author wanted neat and clear code examples.

2.3 The major reason for variable declarations


Figure 2.2 shows the worksheet Sheet1 in Topic2.xlsm. We have a cylinder of radius
cylRad and height cylHeight partially filled by liqVol litres of liquid. A rod of
radius rodRad is immersed in the liquid to a depth of rodLen. Our task is to find
the height of the liquid in the cylinder. The formula in F3 is =(E3*1000 + PI()
*C3^2*D3)/(PI()*A3^2).

doi:10.1088/978-1-6817-4461-2ch2 2-1 ª Morgan & Claypool Publishers 2016


Excel® VBA for Physicists

Figure 2.1. The Tools | Options dialog.

Figure 2.2. Worksheet Sheet1 of Topic2.xlsm.

Consider these two functions (the second of which is found in Module1):


Function LiqH(cylR, cylH, Option Explicit
rodR, rodL, liqV) Function LiqH(cylR, cylH, rodR, rodL, liqV)
pi = 4 * Atn(1) Dim pi, cylV, rodV
cylV = pi * cylR ^ 2 * cylH pi = 4 * Atn(1)
rodV = pi * rodR ^ 2 * rodL cylV = pi * cylR ^ 2 * cylH
LiqH = (liqV * 1000 + redV) / rodV = pi * rodR ^ 2 * rodL
(pi * cylR ^ 2) LiqH = (liqV * 1000 + rodV) / (pi * cylR ^ 2)
End Function End Function

2-2
Excel® VBA for Physicists

The one on the left will always return the same value for LiqH no matter what the
rod dimensions are. Can you see why? We have typed ‘redV’ for ‘rodV’ in the last
statement. Since this variable has been given no value it will be treated as zero. This
is easy to spot in such a short macro but with longer macros the use of Option
Explicit and Dim statements will help. If we add Option Explicit and the
Dim statements shown on the right, then when we call the function on the worksheet
VBA will throw up an error message should it find redV in the code. The offending
statement will be highlighted in yellow. After correcting it, the user must reset the
procedure using the small blue square on the menu bar or by opening the Run menu
item and selecting Reset, see figure 2.3. The reader is encouraged to experiment.

2.4 Declarations in function headers and for constants


Note that we are not required to dimension function names or arguments even when
Option Explicit has been specified; nor do we ever dimension constants defined
with Const. We may use Dim statements for functions and arguments if we wish to
specify their data types. Should we feel the need to give a constant a data type, the
format is Const Pi As Double = 3.14159265358979.
If we plan to use the same variable in several macros in the same module, we can
put a Dim statement at the top of the module before the first procedure; for example,
Dim alpha. Alternatively, we could use Private alpha. Similarly, if we wish to
use constants in several procedures, we can declare the constant at the top of the
module. Should we wish to have a variable (or a constant) accessible to all modules
in the current project (i.e. all the modules in the current workbook), we add the word
‘Public’ before their definitions at the top of a module. For examples: Public
alpha and Public Const Pi As Double = 3.14159265358979 with or
without As Double.
The reader is encouraged to modify the right-hand function in such a way that if
the rod is immersed so far as to cause spillage, then the height is never reported as
being greater than cylH.

2.5 Data types


Most computer languages are strictly typed, in that they require every variable to be
dimensioned and assigned a data type. We will look only briefly at data types. If you

Figure 2.3. Part of the VBE menu.

2-3
Excel® VBA for Physicists

write a very complex application, then speed and memory considerations make data
type assigning essential, but this is not the case with our examples.

Data type Bytes used Range of values

Boolean 2 True or False


Integer 2 −32 768 to 32 767
Long 4 −2 147 483 648 to 2 147 483 647
Single 4 −3.402823E38 to 1.401298E45
Double (negative) 8 −1.79769313486232E308 to −4.94065645841247E–324
Double (positive) 8 4.94065645841247E–324 to 1.79769313486232E308
Currency 8 −922 337 203 685 477.5808 to 922 337 203 685 477.5807
Date 8 1/1/100 to 12/31/9999
String 1 per character Varies according to the number of characters
Object 4 Any defined object
Variant Varies Any data type
Used defined Varies Varies

Our function LiqH does not need a great deal of precision so data type Single
will serve our purpose. So we could code:
Function LiqH(cylR as Single, cylH as Single, rodR as Single,
rodL as Single, liqV as Single) as Single Dim pi as Single, cylV as
Single, rodV as Single
Note that even when used on one line, the Dim statement needs each variable to
be assigned a data type.
In the examples we have been using, we worked with un-typed variables. By
default, they are assigned the Variant type and may take on any type of data:
Boolean, integer, decimal number, string, etc.

2.6 A second reason for variable declarations


When variables are declared, in particular when they are also typed, the procedure
will run somewhat faster. This is not a consideration with our simple procedures.

2.7 Dimensioning arrays


We saw in chapter 1 that the statement Dim Vel(3) generates a one-dimensional
array with three elements. Similarly, a two-dimensional array with four rows and
three columns is generated with Dim myMatrix(4,3)—note the RC (row-before-
column) convention.
By default we would refer to the elements in Vel as Vel(0), Vel(1), and
Vel(2). Likewise, the element in the third row, second column of myMatrix
would be located with myMatrix(2,1) and this is very confusing to most.
The simplest way to get all arrays in a procedure to have index values starting at
1, is adding Option Base 1 at the top of the module.
Another way is to included the lower and upper bounds of the array in
the declaration. So Dim Vel(1 to 3) would give us the elements Vel(1),

2-4
Excel® VBA for Physicists

Vel(2), and Vel(3). This is more flexible than the option method since we can use,
for example, ZeroStart(4), which would have indices 0, 1, 2, and 3; while
Strange(5 to 8) would have indices 5, 6, 7, and 8. A two-dimensional array of
four rows and three columns could be declared with MyArray(1 to 4, 1 to 3),
making references to the elements more readily understood.
Sometimes we do not know beforehand what size is needed for the array. In this
case we declare it with no size, as in ThisArray(). Before we can add values to the
elements of ThisArray we must tell VBA what size to use; this is done with a
Redim statement.
The sub myFreq (found in Module2 and shown below) finds how many numbers are
in column A and re-dimensions myArray accordingly. The data are placed in the array
and then a computation is used resulting in an output similar to (but not identical to) the
worksheet FREQUENCY function. The reader may wish to work out how and why they
differ. The output is on Sheet2, see figure 2.4; click the ball to run the procedure. Note
that myArray has index vales 1 to mycount while freq has index values 0 to 19.

Sub MyFreq()
Dim myArray(), freq(20)
Worksheets(“Sheet2”).Activate
‘How many numbers in column A
mycount = WorksheetFunction.Count(Range(“A:A”))
MsgBox (“There are “ & mycount & “ numbers in A2 and down”)
‘Redimension myarray for this number
ReDim myArray(1 To mycount)
‘Debug.Print LBound(myArray), UBound(myArray)
‘Get each number and put into myArray
For k = 1 To mycount
myArray(k) = Cells(k + 1, “A”)
Next k
‘Count of zero, and multiples of 5
For k = 1 To mycount
If myArray(k) = 0 Then
bin = 0
Else
bin = Int(myArray(k) / 5)
End If
freq(bin) = freq(bin) + 1
Next k
‘Display results
For j = 0 To UBound(freq)
Cells(j + 2, “D”) = j * 5
Cells(j + 2, “E”) = freq(j)
Next j
End Sub

2-5
Excel® VBA for Physicists

Figure 2.4. Output from the MyFreq subroutine.

2.8 The Set statement


Suppose we have a need to refer to a certain worksheet several times in a procedure;
let the worksheet be called ‘Sheet3’. It would be a headache (and a possible source of
typing errors) if we had to repeatedly type text such Worksheets(“Sheet3”).
Range(“B6”). To avoid this, we use the Set statement. The Set statement may refer
to a workbook, a worksheet, or a range. Examples: (i) Set mysheet = Workbooks
(“Book2.xlsx”).Worksheet(“Sheet3”) and (ii) Set Data = Range
(“A1:B25”).
The Set statement is used in the subroutine OverFifty (found in Module3)
shown below. The sub finds values in column A of Sheet2 (see figure 2.4) that are
greater than 50 and copies them to Sheet3. The Set command creates a new
worksheet object pointing at the sheet of interest. The output of the sub is shown in
figure 2.5.
Sub OverFifty()
Worksheets(“Sheet2”).Activate
Set Target = Worksheets(“Sheet3”)
lastrow = Target.Cells(Rows.Count, “A”).End(xlUp).Row
Killrange = “A1:A” & lastrow
Target.Range(Killrange).ClearContents
Target.Range(“A1”) = “50 and over”

2-6
Excel® VBA for Physicists

Figure 2.5. Output from subs.

j = 1
For k = 2 To WorksheetFunction.Count(Range(“A:A”))
If Cells(k, “A”) >= 50 Then
j = j + 1
Target.Cells(j, “A”) = Cells(k, “A”)
End If
Next k
MsgBox j & “ values copied from Sheet2 to Sheet3”
End Sub

2.9 The With…End With structure


This is essentially an alternative to the Set command. The syntax for this structure is:
With objectExpression
[ statements ]
End With
The objectExpression can be simple or complex. Examples: (i) With
Worksheet(“HappyDays”), (ii) With Workhsheet(1).Range(“A1”A10”),
(iii) With Selection, and (iv) With Range(“A1”).Font.
Our demonstration sub UnderFifty copies values in column A of Sheet2 (see
figure 2.4) that are under 50 to column B of Sheet3. The output of the sub is shown in
figure 2.5.
Sub UnderFifty()
Worksheets(“Sheet2”).Activate
With Worksheets(“Sheet3”)
lastrow = .Cells(Rows.Count, “B”).End(xlUp).Row
Killrange = “B1:B” & lastrow
.Range(Killrange).ClearContents
.Range(“B1”) = “Under 50”
End With
j = 1
For k = 2 To WorksheetFunction.Count(Range(“A:A”))

2-7
Excel® VBA for Physicists

If Cells(k, “A”) < 50 Then


j = j + 1
With Worksheets(“Sheet3”)
.Cells(j, “B”) = Cells(k, “A”)
End With
End If
Next k
MsgBox j & “ values copied from Sheet2 to Sheet3”
End Sub

2-8
IOP Concise Physics

Excel® VBA for Physicists


A Primer
Bernard V Liengme

Chapter 3
Structured programming

The normal flow in any computer program is from line to line. This is called a
sequential structure. Anything that changes this flow is called a control structure. A
branching structure gives the program two or more alternative paths to follow
depending on the value of a variable. A repetition or looping structure causes code
within a loop to be executed one or more times.

3.1 Branching structures (If and Select Case)


Branching structures present the program with various paths to follow depending on
the value of one or more variables.
VBA has three branching structures: GoTo, If…Else, and Select Case. We
have seen an example of GoTo and will reserve it for error trapping only.
The syntax of the If…Else structure is shown below. Items within square
brackets are optional.
If condition Then
[statements]
[ElseIf condition-n Then
[elseifstatements]] …
[Else
[elsestatements]]
End If
You may run into a one-liner (i.e. ‘immediate’) If in the form: If condition
then statement(s); note the absence of End.
In our example we have three cells with values representing the length of the sides
of a triangle; we want to know what type of a triangle (if any) it is. Figure 3.1 shows
the worksheet Sheet1 of the workbook Topic3.xlsm; the VBA code (which is found
in Module1) is shown below it. Note the three one-liner Ifs; each has three
statements separated by colons. Note also the use of Or and And in the conditions.

doi:10.1088/978-1-6817-4461-2ch3 3-1 ª Morgan & Claypool Publishers 2016


Excel® VBA for Physicists

Figure 3.1. Sheet1 of Topic3.xlsm.

Figure 3.2. Example of the Immediate window.

The Debug.Print statements are used to help us see how the macro behaves; the
results go to the Immediate window of the VBE, see figure 3.2.
Function Tritype(a, b, c)
Debug.Print a, b, c
‘Sort the sides in ascending order
If b > a Then temp = a: a = b: b = temp
If c > a Then temp = a: a = c: c = temp
If c > b Then temp = b: b = c: c = temp
Debug.Print a, b, c
‘Test for triangle type
If a > b + c Then

3-2
Excel® VBA for Physicists

Tritype = “None”
ElseIf a * a = b * b + c * c Then Tritype = “Right”
ElseIf (a = b) And (b = c)
Then Tritype = “Equilateral”
ElseIf (a = b) Or (b = c) Then Tritype = “Isosceles”
Else: Tritype = “Scalene”
End If
Debug.Print Tritype
End Function
The syntax for the Select Case construct is
Select Case testexpression
[Case expressionlist-n
[statements-n]] …
[Case Else
[elsestatements]]
End Select
The next example (Sheet2) uses the Select Case construct to determine
the number of real roots of a quadratic equation ax 2 + bx + c = 0; see row 6 of
figure 3.3. The number of real roots is found by testing the value of the discrim-
inator. Then we expand on the work to code a function that determines both the
number of roots and their values; this uses an array within the VBA and, since
three values are returned, we must enter the function call on the worksheet using
CTRL+SHIFT+ENTER to signify an array function.

The codes (see Module2) for the functions are shown below.
Function RootCount(a, b, c) Function Quad(a, b, c)
Disc = (b * b) − (4 * a * c) Dim temp(1 to 3)
Select Case Disc Disc = (b * b)−(4 * a * c)
Case 0: RootCount = 1 Select Case Disc
Case Is > 0: RootCount = 2 Case Is < 0
Case Else: RootCount = 0 temp(1) = “No real”
End Select temp(2) = “roots”
End Function temp(3) = “”
Case 0
temp(1) = “One root”
temp(2) = −b / (2 * a)
temp(3) = “”
Case Else
temp(1) = “Two roots”
temp(2) = (−b + Sqr(Disc)) / (2 * a)
temp(3) = (−b−Sqr(Disc)) / (2 * a)
End Select
Quad = temp
End Function

3-3
Excel® VBA for Physicists

Figure 3.3. The quadratic solver on Sheet2.

3.2 Looping structures (For…Next and Do…While/Until)


Looping structures cause a group of statements to be executed several times. The
For…Next structure is generally used when the number of iterations needed is a
known quantity while a Do loop can be used until a certain condition is encountered.
Here are two sample functions (one using For…Next, the other using Do…
Loop) to test if a number is a prime; both are based on the Sieve of Eratosthenes.
The reader is encouraged to create a worksheet to experiment with their two
UDFs.

Function IsPrimeA(n) Function IsPrimeB(n)


IsPrimeA = “Is a prime” IsPrimeB = “Is a Prime”
For k = 2 To Int(Sqr(n)) + 1 k = 2
If n Mod k = 0 Then Do While k < Sqr(n) + 1
IsPrimeA = “Not a prime” If n Mod k = 0 Then
Exit For IsPrimeB = “Not a prime”
End If Exit Do
Next k End If
End Function k = k + 1
Loop
End Function

The syntax for For…Next is


For counter = first To last [Step step]
[statements]
[Exit For]
[statements]
Next [counter]
When the Step clause is omitted the step value is set to 1. The programmer
should never alter the value of ‘counter’ within the loop as the results can be
unpredictable. Later we will encounter Excel collections. We can cycle through all
members of a collection using the form For Each item in collection.

3-4
Excel® VBA for Physicists

For our example we will compute the wavelengths of the first 15 Balmer spectral
lines of hydrogen. The worksheet Balmer in Topic3.xlsm is shown in figure 3.4,
where the values in A3:B17 were generated by the subroutine below.
Sub Balmer()
‘Computes the first 15 spectral lines
‘in the Balmer series for hydrogen
On Error GoTo Hades
Worksheets(“Balmer”).Activate
Const Rydberg = 10973730 ‘units of m−1
Const n = 2 ‘Balmer series
myRow = 3
For j = 1 To 15
m = n + j
waveNum = Rydberg * (1 / n ^ 2−1 / m ^ 2)
lamda = (1 * 10 ^ 9) / waveNum ‘in nm
Range(“A” & myRow) = m
Range(“B” & myRow) = lamda
myRow = myRow + 1
Next
Hades:
End Sub

Figure 3.4. The Balmer worksheet.

3-5
Excel® VBA for Physicists

There are two syntaxes for the Do…Loop, one a pre- and the other a post-test
construct:

Do {While | Until} condition Do


[statements] [statements]
[Exit Do] [Exit Do]
[statements] [statements]
Loop Loop {While | Until} condition

The Do…Loop can present a problem for the novice programmer: if there is a
logic error in the coding then ‘condition’ may never become ‘True’ and the loop will
execute for ever. If you suspect this to be the case try using CTRL+BREAK to
interrupt the program, it can be restarted with F5. Alternatively, use ESC to
terminate the program.
For our demonstration we note that as m increases, the wavelengths of the
spectral lines converge. Indeed, it is easy to show that they converge upon λ = n 2 /R .
We set ourselves the task of finding what m is such that a successive pair of lines
differ by 0.5 nm. We will do this with a function and apply it to several hydrogen
spectral series.
Figure 3.5 shows the worksheet called ‘Rydberg’; the values in C8:D13 are
computed with the function SmallDiff found in Module4.

Figure 3.5. Showing the output from the SmallDiff UDF.

3-6
Excel® VBA for Physicists

Option Explicit
Function Smalldiff(n)
Dim myData(2)
Dim Diff, oldLamda, newLamda, m
Const Rydberg = 10973730 ‘units of m−1
Diff = 99
m = n + 1
oldLamda = Rydberg * (1 / n ^ 2−1 / m ^ 2)
oldLamda = 1000000000# / oldLamda
Do Until Diff < 0.5
m = m + 1
newLamda = Rydberg * (1 / n ^ 2−1 / m ^ 2)
newLamda = 1000000000# / newLamda
Diff = oldLamda − newLamda
oldLamda = newLamda
Loop
myData(0) = m
myData(1) = newLamda
Smalldiff = myData
End Function
If the user wanted to be extra careful to avoid a non-ending loop, he/she
might add, just below m = m + 1, the statement If m > 1000 then Exit Sub.

3.3 Some further examples


We wish to be able to find the equivalent resistance of a number of resistors in
parallel. We do not know beforehand how many resistors are involved. A For
Each structure provides a very flexible approach.
Figure 3.6 shows the worksheet Resistors in which the equivalent resistance is
computed for a number of resistors in parallel using the VBA code below (Module5).

Figure 3.6. The Resistors worksheet.

3-7
Excel® VBA for Physicists

Figure 3.7. Computing the trace.

The code will cope with a range of any size. The last If statement prevents a
#VALUE! error should all cells be empty.
Function Requiv(myRange)
For Each mycell In myRange
If mycell > 0 Then temp = temp + 1 / mycell
Next
If temp > 0 Then
Requiv = 1 / temp
Else
Requiv = 0
End if
End Function
For another example we set ourselves the task of finding the trace (the sum of the
elements on the diagonal) of a square matrix. Figure 3.7 shows the worksheet
Matrix. It is convenient to break the problem into two UDFs: test if the range is
square and sum elements only if it is square.
Function IsSquare(myRange)
If myRange.Rows.Count = myRange.Columns.Count Then
IsSquare = True
Else
IsSquare = False
End If
End Function

Function SumDiag(myRange)
If Not IsSquare(myRange) Then Exit Function
For j = 1 To myRange.Rows.Count
SumDiag = SumDiag + myRange(j, j)
Next j
End Function

3-8
IOP Concise Physics

Excel® VBA for Physicists


A Primer
Bernard V Liengme

Chapter 4
The Excel object model

It is helpful to have a passing familiarity with the Excel object model when
writing VBA code. An excellent source of information is https://msdn.microsoft.
com/en-us/library/ff194068.aspx. To navigate on this site just click on an item in the
left panel—they do not look like links but they are!
In fact, we have already used the model in a few macros. For example, when we
coded myRange.Rows.Count we have invoked the Count property which belong
the Rows object which in turn is a property of the Range object.
We will be looking into these concepts: object, child object, property, method,
and event. A car is an object; its child objects include engine, body, and wheel. The
child objects of wheel include rim and tire objects. Note how objects form a
hierarchy. A property is something that has a value; the car body has a color
property; the rim has a diameter property. Some properties can be changed (e.g. the
body color) others cannot (e.g. the car’s vehicle identification number). In VBA we
speak of read-only and read/write properties. Actions that can be performed by, or
on, an object are called methods. The car can slow down; a switch can be used to
lower a window.
Our analogy breaks down when it comes to events. Events are actions performed
by users which trigger the Excel VBA to execute code. Perhaps turn key is a user
event that cause the method start engine to happen!

4.1 Examples of properties, methods and events


In the Excel object model at the top of the hierarchy we do not have Excel but rather
Application. This is followed by Workbook, which in turn has the Worksheet object.
The child objects of the worksheet object include Range, Chart, Shape, etc. We also
need to be aware of Collections. In an Excel session we may have several workbooks
open; these constitute the Workbooks collection—note the final ‘s’. Any one of these
workbooks may contain several worksheets; this constitutes the Worksheets
collection for that specific workbook.

doi:10.1088/978-1-6817-4461-2ch4 4-1 ª Morgan & Claypool Publishers 2016


Excel® VBA for Physicists

Table 4.1.

Properties ActiveCell Returns a Range object that represents the active


cell in the active window.
ActivePrinter Returns or sets the name of the active printer.
ActiveWorkbook ActiveWorkbook.Name returns the name of the
active workbook. Read only.
Methods Calculate Application.Calculate or just Calculate
calculates all open workbooks; Worksheets
(“Resistor”).Calculate calculates the
specific worksheet in a workbook and
Worksheets(“ABC”).Rows(5).
Calculate calculates the specified range of
cells on a worksheet.
Undo Application.Undo cancels the last user action.
Events NewWorkbook Occurs when a new workbook is created.
WorkbookBeforePrint Occurs before any open workbook is printed.

Table 4.1 shows some examples of members of the Application object.


The VBE Immediate window is very useful for experimenting with properties
without having to make a function or subroutine. Start a new Excel session (to limit
the number of open workbooks) and open the workbook Topic4.xlsm. Click in C4
of Sheet1 to make it the active cell. Use Alt+F11 to open the VBE; use CTRL+G to
open the Immediate window if necessary. In the Immediate window type
?ActiveCell and tap the Enter key. Next type ?activeprinter followed by
Enter. The results are shown in figure 4.1. Of course, your printer will not be the
same as the author’s. Note that capitalization is not important. The ActiveCell
request returns the active cell object and displays its value, since this is the default
property. The request ?activecell.value would give the same result.
Experiment in the Immediate window with ?ActiveCell.Address.
The Workbooks object is a collection of all currently open workbooks. Table 4.2
shows some methods and properties.
To demonstrate some of these, the author began an Excel session with a blank
workbook, opened the VBE and experimented in the Immediate window:
?workbooks.Count
2
workbooks.Add
?workbooks.Count
3
?workbooks(1).Name
PERSONAL.XLSB
?workbooks(2).Name
Book1

4-2
Excel® VBA for Physicists

Figure 4.1. The Immediate window.

Table 4.2.

Properties Count Returns the number of currently open workbooks.


Item Returns a single workbook object from the collection. Set TestBook
= Workbooks.Item(“TestFile.xlsx”) sets the TestBook
variable to the named workbook.
Methods Save Saves changes to the specified workbook. Example:
Workbooks(“Book1”).Save
Add Creates a new workbook; the same as the Excel shortcut CTRL+N.

?workbooks(3).Name
Book2
workbooks(3).SaveAs (“junk.xlsx”)
Since in the SaveAs parameters only a file name with no path was given, the file
will be saved in whatever folder is named in the Default local file location found in
the File | Options | Save dialog.
Table 4.3 shows some examples of members of the Workbook object and table 4.4
shows some examples of members of the Worksheet object.

4.2 The Range object properties


In the code Worksheets(“Sheet1”).Range(“A1”).Value = 3.14159 we
are using the Range property to return a Range object to which we then assign a value.
When you are learning VBA it can be confusing to see Range referred to as an object
and as a property. The code Range(“A1”).Value = 3.14159 is a shortcut for
ActiveSheet.Range(“A1”).Value = 3.14159, and in each case Value is
optional as it is the default. From the Excel window, make Sheet1 in Topic4.xlsm the

4-3
Excel® VBA for Physicists

Table 4.3.

Properties ActiveSheet Returns an object that represents the active sheet. Returns
Nothing if no sheet is active.
Experiment in the Immediate window with ?
ActiveSheet.Name.
Then try ActiveSheet.Name = “junk”
Note that ActiveSheet is a property of the workbook
while Name is a property of the worksheet.
Fullname Returns the name of the object, including its path on disk, as a
NamePath string.
Read-only String. Experiment with ?activeworkbook.
name, ?activeworkbook.fullname, and ?
activeworkbook.path.
ThisWorkbook Returns the workbook where the VBA code is running.
Methods Save Saves changes to the specified workbook. Example:
Workbooks(“Book1”).Save
Unprotect Removes protection from a workbook. A password can be set
in the code or in the resulting dialog.
Close Workbooks(“Junk.xlsx”).Close SaveChanges
:=False will close the named workbook without saving
changes. Note Workbooks(“Junk.xlsx”) is a
Workbooks method that obtains the named workbook, then
the Close method of the workbook is called upon.
Events BeforeSave Occurs before the workbook is saved
Open Occurs when the workbook is opened.

active sheet, then in the Immediate window experiment with these lines using Enter
between each: ?range(“A1”), x=Range(“A1”)+1, Range(“A1”)=x,
?Range(“A1”). Observe the results in the Immediate window and on the worksheet.
We can specify a range in several ways:
i. Range(“A1”) clear refers to the single cell A1, while Range(“A1:B5”)
refers to the ten cells in A1:B5. These two statements are equivalent: Range
(“G1:H5”).Select and Range(“G1”,“H5”).Select. The code
Range(“G1:H10 D3:J3”).Select will select G3:H3 as this is the
intersection of the two ranges.
ii. If x is a variable we might use Range(“A”&x). If x happened to have the
value 5, the expression would refer to cell A5.
iii. Cells(1,2) refers to the cell in row 1, column 2; that is the cell B1. Note it is
‘Cells’ in the plural. When we process a number of cells using the counter j,
we can have expressions such as Cells(j, 3) or Cells(j, “C”). The
reader should note that Cells is a property not an object or a collection.
iv. A multi-cell range may be specified with Cells as in Range(Cells(a,b),
Cells(c,d)). For example if the expression evaluated to Range(Cells
(1,1), Cells(5,2)) it would refer to A1:B5. You can confirm this with

4-4
Excel® VBA for Physicists

Table 4.4.

Properties Name Returns or sets a string value that represents the object name.
Experiment with ?ActiveSheet.name. This code within a
subroutine (or in the Immediate window) will rename a worksheet:
ActiveSheet.Name = “Widget”.
Columns To format as bold all the cells in column A:
Worksheets(“Sheet1”).Columns(1).Font.Bold =
True
Range Returns a Range object that represents a cell or a range of cells.
See the comment below
Methods Protect Protects a worksheet so that it cannot be modified.
Unprotect Removes protection from a worksheet. A password can be set in the
code or in the resulting dialog.
Events Calculate Occurs after the worksheet is recalculated. This code will auto-fit
some columns whenever the worksheet is recalculated (later we
will see where such event subroutines are placed):
Private Sub Worksheet_Calculate()
Columns(“A:F”).AutoFit
End Sub
Change Occurs when cells on the worksheet are changed by the user or by an
external link. This event does not occur when cells change during a
recalculation—see Calculate above.

the Address property; type into the Immediate window, Range(Cells


(1,1), Cells(5,2)).Address. Generally, one uses Cells(a,b) with
variables.
v. A less common referencing system uses the range addresses with an index.
So Range(“G4:G10”)(4).Select selects G7 as it is the fourth element
in the range, but Range(“G4:H10”)(4).Select selects H4 since the
enumeration goes left-to-right, then down.
vi. The lazy way is to use square brackets. To give cell J10 the value 12 we
could code [J10]=12. But this method is less transparent to other users
and, more importantly, since at execution time it needs interpretation, it has
a detrimental effect on the procedure’s speed.
The Range object has a number of useful properties, as listed in table 4.5

4.3 Range object methods


We will view some sample code to demonstrate various important range methods.

4.3.1 Select, Copy, and Paste


Go to Sheet1 of Topic4.xlsm and turn on the macro recorder (square icon to the
right of Ready on the status bar). Perform these actions:
1. Select A1:C4, right click the mouse and use Copy from the popup menu.
2. Right click on H1 and use the Paste command.

4-5
Excel® VBA for Physicists

Table 4.5.

Columns Returns the number of the first column in the first area in the specified range.
Read-only Long. If the active cell is H5 then ?activecell.column
will return 8.
Columns Returns a Range object that represents the columns in the specified range.
The code Range(“A1:D5”).Columns(1)=1 will make each cell A1:
A5 have the value 1.
Row and Rows Analogous to Column and Columns.
Count Returns a Long value that represents the number of cells in the specified
range. The code Range(“A1:D5”).Count will return the value 20.
Font Returns a Font object that represents the font of the specified object.
Experiment with ?range(“A1”).Font.Name. The Font property
returns the Font object which cannot be displayed so we must use its
Name property.Font is an object with properties such as Bold, Italic,
Underline, Size, ColorIndex, Name, etc.
Formula This read/write property access a cell’s formula. With Sheet1 of Topic4
active, experiment with range(“a10”).Formula =“=Sum(A1:A8)”
and ?range(“a10”).Formula. Then look at the worksheet.
Offset Returns a Range object that represents a range that is offset from the
specified range. So ?range(“A1”).Offset(2,3).Address will
return D3.
NumberFormat Returns or sets a Variant value that represents the format code for the
object. If A1 is displaying 4.4 then ?Range(“A1”).NumberFormat
could return either General or 0.0.
Next Returns a Range object that represents the next cell. This property emulates
the TAB key, although the property returns the next cell without selecting
it. On a protected sheet, this property returns the next unlocked cell. On
an unprotected sheet, this property always returns the cell immediately to
the right of the specified cell. Thus ?range(“a1”).Next.Address
returns B1 provided that it is not a locked cell in a protected sheet.

3. Note that the ‘ant track’ is sill running around A1:C4 so tap the ESC key to
turn it off.
4. Switch off the recorder.

The macro code will be:


Sub Macro1()
Range(“A1:C4”).Select
Selection.Copy
Range(“H1”).Select
ActiveSheet.Paste
Application.CutCopyMode = False
End Sub

4-6
Excel® VBA for Physicists

In the statement ActiveSheet.Paste, ActiveSheet is a worksheet object.


When you run the sub you will notice that H1:J4 remains selected. We can add the
statement Range(“H1”).Select just before End Sub to solve this.
The Copy method has a provision to set the destination of the copy. We can make
a simple sub:
Sub CopyMe()
Range(“A1:C4”).Copy Destination:=Range(“H1”)
End Sub
Note the use of colon equal (:=) rather than just equal (=) to set the value of a
parameter. But since Copy takes only one parameter we can omit Destination
and code: Range(“A1:C4”).Copy Range(“H1”) with a space before the
destination range.
Of course, in both cases we might wish to be careful that we are copying from the
correct worksheet. To do this we add Worksheets(“Sheet1”).Activate as
the first statement in the subs.
We can copy from one sheet to another. The following sub works just fine,
regardless of what worksheet is active:
Sub Copy2Another()
Worksheets(“Sheet1”).Range(“A1:C4”).Copy Worksheets
(“Sheet2”).Range(“A1”)
End Sub

4.3.2 Clear methods


There exist Clear, ClearContent, and ClearFormat. The first clears everything
(content and format), the second leaves the format intact, and the third clears the
format leaving the content. So we might code Worksheets(“Sheet1”).Range
(“A1:G37”).Clear. The reference to the worksheet is optional but well advised.

4.3.3 Delete method


We can delete entire rows or columns. Examples: (i) Range(“3:5”).Delete will
delete rows 3, 4, and 5, and (ii) Range(“D:D”) will delete column D. When we
delete a range, we should tell Excel to shift the remaining material up or to the left:
Range(“F4:G4”).Delete Shift:=xlUp or Range(“F4:G4”).Delete
Shift:=xlLeft.

4.4 WorksheetFunction object


This object is a container for the Microsoft Excel functions that may be called in a VBA
macro. As noted previously, if there is an equivalent VBA function then the
corresponding Excel function is not a member of the WorksheetFunction object.
Here is a partial list of VBA functions; omitted are functions related to text file
manipulation and data type conversion functions. The site https://www.techonthenet.
com/excel/formulas/index_vba.php can be most helpful.

4-7
Excel® VBA for Physicists

Function What is returned

Array functions

LBound The lower bound of an array.


UBound The upper bound of an array.

Date and time functions

Date The current system date.


DateAdd A date with a specific date interval added to it.
DateDiff The difference between two dates as a time interval.
DatePart An integer containing a specific part of a date.
DateSerial A date for a specified year, month, and day.
DateValue A date from a string.
Day The day of the month of a date.
Hour The hour of a time.
Minute The minute of a time.
Month The month of a date.
MonthName A string indicating the specified month.
Now The current system date and time.
Second The second of a time.
Time The current system time.
Timer The number of seconds since midnight.
TimeSerial The time for a specified hour, minute, and second.
TimeValue A time serial number from a string.
Weekday A number representing a day of the week.
WeekdayName A string indicating the specified weekday.
Year The year of a date.

Format functions

Format An expression in a particular format.


FormatCurrency A number as a string, formatted as currency.
FormatDateTime A number as a string, formatted as a date and/or time.
FormatNumber A number as a formatted string.
FormatPercent A number as a string, formatted as a percentage.

Information functions

IsArray True if a variable is an array.


IsDate True if a variable is a date.
IsEmpty True if a variable has not been initialized.
IsError True if an expression is an error value.
IsMissing True if an optional argument was not passed to a procedure.
IsNull True if an expression contains no valid data.
IsNumeric True if an expression can be evaluated as a number.

4-8
Excel® VBA for Physicists

Lookup functions

Choose A value from a list based on a given position.


Switch A value associated with the first expression in the list that is True.

Math functions

Abs The absolute value of a number.


Asc The first character of string to its ASCII value.
Atn The arctangent of a number.
Cos The cosine of a number.
Exp The base of the natural logarithms (e) raised to a power.
Fix The integer portion of a number.
Hex A hexadecimal value from a digital.
Int The integer portion of a number.
Log The natural logarithm of a number.
Oct An octal value from a decimal.
Randomize Used to seed the RND function.
Rnd A random number between 0 and 1.
Round A number to a specific number of decimal places.
Sgn An integer that indicates the sign of a number.
Sin The sine of a number.
Sqr The square root of a number.
Tan The tangent of a number.

String functions

Chr An ANSI value to a character.


InStr The position of a string within another string.
InStrRev The position of a string within another string, beginning at the back
end of the string.
LCase A string converted to lowercase.
Left A specified number of characters from the left of a string.
Len The length of a string, in characters.
LTrim A copy of a string with no leading spaces.
Mid A specified number of characters from a string.
MidB A specified number of bytes from a specified position in a string.
Replace A string in which one substring is replaced with another.
Right A specified number of characters from the right of a string.
RTrim A copy of a string with no trailing spaces.
Space A string with a specified number of spaces.
Split An array consisting of a number of substrings.
Str A string representation of a number.
StrComp A value indicating the result of a string comparison.
StrConv A string variant converted as specified.
String A repeating character or string.

(Continued)

4-9
Excel® VBA for Physicists

(Continued )

Function What is returned

StrReverse The characters of a string in reverse order.


Trim A string without leading and spaces and replaces multiple spaces with a
single space.
UCase A string in uppercase.
Val The numbers contained in a string.

The code Application.WorksheetFunction.Min(Range(“A1:E1”))


will return the result of applying the Excel function Min to the range A1:E1.
With Sheet1 of Topic4.xlsm active, the reader might wish to experiment with this
code (adding a ? before Application).
It is not essential to use both Application and WorksheetFunction; one
will suffice. There are advantages and disadvantages to both. When both or just
WorksheetFunction are used, VBE offers a pop-up IntelliSence list of permitted
functions, see figure 4.2.
However, when both or just Application is used then error checking works.
Here are two functions; clearly when x > 3 the Match fails so an error occurs. The
function TestF1 does not trap the error and the cell calling it displays #VALUE!.
The function TestF2 does trap the error and the cell displays Error after
displaying the message box.
Function TestF1(x)
TestF1 = WorksheetFunction.Match(x, Array(1, 2, 3), 0)
If IsEmpty(TestF1) Then ‘Should be triggered when x > 3
MsgBox “Formula returned an Error value”
TestF1 = “Error”
End If
End Function
Function TestF2(x)
TestF3 = Application.Match(x, Array(1, 2, 3), 0)

Figure 4.2. Demonstration of IntelliSence.

4-10
Excel® VBA for Physicists

If IsError(TestF3) Then ‘Will be triggered when x > 3


MsgBox “Formula returned an Error value”
TestF3 = “Error”
End If
End Function
Here are further examples of error trapping. The user has a table of names and
scores. The subroutine uses the InputBox function to request a name; this is then
used in a Vlookup to find the score. We need to help the user in case: (i) the
InputBox’s OK button is pressed without filling in a name, (ii) the Cancel button is
pressed, or (iii) the name is not located in the table.
Sub GetScoreA()
On Error Resume Next
Name = InputBox(“Enter name”, “Lookup Score”)
Score = Application.VLookup(Name, Range(“A2:B10”), 2, False)
MsgBox Name & “ scored “ & Score
End Sub

Sub GetScoreB()
Name = InputBox(“Enter name”, “Lookup Score”)
Score = Application.VLookup(Name, Range(“A2:B10”), 2, False)
If Len(Name) < 1 Then Exit Sub
On Error GoTo NotFound
MsgBox Name & “ scored “ & Score
Exit Sub
NotFound:
MsgBox “Name “ & Name & “ not found on list”
End Sub
GetScoreA merely ends the sub when any of the above events occur. GetScoreB
is more user friendly. Events (i) or (ii) cause the sub to terminate—this is what the user
might expect. When an invalid name is entered there is a message to that effect. Note
the need to use Exit Sub just before the NotFound label in this case. These subs are
demonstrated on Sheet4 of Topic4.xlsm. If the user types, for example, ‘emma’ with a
lowercase ‘e’, then that is how Name appears in the message box. The reader may like
to think of a way (two readily come to mind) to overcome this.
In addition to the InputBox function, there is also an InputBox method. The
method is called with Application.InputBox(…); it has features not present in
the function. For example, one can specify if a number or a string can be entered.
A note in case the reader finds Internet sites with out-of-date information. Prior to
Office 2007, Excel had a special group of functions which were available only when
the Analysis ToolPak was loaded. This feature has been discontinued and all
worksheet functions in both the Excel window and in VBA code are accessed in
the same way. Gone is the need to load either Analysis ToolPak or Analysis

4-11
Excel® VBA for Physicists

Figure 4.3. Output from a Workbook_BeforeSave subroutine.

ToolPak-VBA for these previous special functions. The code below will make use of
the MyRound function to round a number to the nearest 100.
Function MyRound(numb)
MyRound = WorksheetFunction.MRound(numb, 100)
End Function

4.5 Workbook and worksheet events


4.5.1 Workbook events
For an example of a workbook event subroutine we will look at one that performs
an action before the workbook is saved. Here is our scenario: a lab manager wishes
to know who worked on a workbook and saved it. Figure 4.3 shows the worksheet
LogUser that is used by the subroutine Workbook_BeforeSave to log the data.
The code for this sub is:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean,
Cancel As Boolean)
With Worksheets(“LogUser”)
LastRow = .Cells(Rows.Count, “A”).End(xlUp).Row
.Cells(LastRow + 1, “A”) = Date
.Cells(LastRow + 1, “B”) = Time
.Cells(LastRow + 1, “C”) = Application.UserName
.Cells(LastRow + 1, “D”) = Environ$(“Username”)
End With
End Sub
Important. Any workbook event code must be placed in the correct module. Open
the VBE, in the Project panel find Topic4.xlsm, and double click on ThisWorkbook
in the list of Microsoft Excel Objects. The code above will then be displayed in the
Workbook module. If you are starting from scratch or wish to add another event,
open up the list in the right-hand box (figure 4.4) and click on the event you plan to
capture; this will provide a template with the correct heading.
If we do not want to activate the LogUser worksheet (indeed we might wish to
hide it) we could preface every range reference to that sheet as in LastRow =
Worksheets(“LogUser”).Cells(Rows.Count, “A”).End(xlUp).Row.
To avoid the tedium of doing this (and the risk of making typing errors) we use

4-12
Excel® VBA for Physicists

Figure 4.4. Workbook events.

Figure 4.5. Demonstration of Worksheet_Change.

the With construct. Every dot with nothing before it takes on the reference in the
With statement.
On the LogUser worksheet, column A has been given a date format to display the
month name (this avoids confusion between the US and the international date
formats). It is important to know that Application.UserName returns the name
that is set in File | Options | General | Personalize… | User Name box. The Environ
$(“Username”) is given the system name used when Windows was installed on
the computer. In the author’s case Opening C:\Users\ in the File Manager shows a
user called blien—this was originally bliengme but a Windows 10 update altered it
and the author is working to get back his unabbreviated name. It is somewhat more
difficult to trap a network sign-on name.

4.5.2 Worksheet events


This is a somewhat contrived scenario: on Sheet5 of Topic4.xlsm (see figure 4.5) the
text in A4:A9 represents different types of measurements performed in a lab. The
numbers in B4:B9 represent the recorded measurement values. This range (shown in
yellow) has been given the name ‘Measured’. Our objective is to keep a record of
how many times each measured value is updated; this is done in the ‘Changes’ range
(shown in blue). We do this with a Worksheet_Change subroutine.

4-13
Excel® VBA for Physicists

Just as a workbook event code must be on the ThisWorkbook module, so a


worksheet event code must be on the module specific to that sheet. This time we have
two methods of accessing the module: from the Project window by double clicking
the sheet name, or by right clicking the sheet’s tab and selecting View Code. The two
methods are equivalent.
Our code is:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range(“Measured”)) Is Nothing Then
Exit Sub

If If Target.Cells.Count > 1 Then


Application.EnableEvents = False
MsgBox “Please change one cell at a time”
Application.Undo
Application.EnableEvents = True
Exit Sub
End If
Cells(Target.Row, “D”) = Cells(Target.Row, “D”) + 1
End Sub
We will accept the header and its ByVal phrase without comment.
The first statement checks that the cell that has been changed lies within the range of
interest; if not the sub is exited. The next If…End If block ensures that the user has
not changed more than one cell (for example, he/she could have selected and deleted
several cells). We cannot handle multiple changes so a message is thrown up and the
action is undone. Now this undoing will itself trigger the Worksheet_Change sub
and we could have recursion. This is avoided by encapsulating the Undo within an
Application.EnableEvent False/True pair of statements.
The final statement adds 1 to the data in the blue region using the target’s row
property to select the correct item to update.

4.6 Code for sending email


The workbook SendEmail.xlsm demonstrates how to send a worksheet to a number
of recipients by email. The author has tested this only on a PC with Microsoft
Outlook as its default email client.
Figure 4.6 shows the EmailData worksheet in this file. It is here that we list the
intended recipients, the subject text for the message and the name of the worksheet
to be sent. Note that the cells in A1:C1 have been used to name ranges below each as
indicated by a yellow fill. Hopefully, when testing the sub, the reader will substitute
his/her own email address for the author’s! Note how we can have up to ten
addresses here, and the entries do not need to be hyperlinks.
The second worksheet EmailSheet contains the material that we wish to send. The
author decided to include a chart on this sheet.
The code to send the email is:

4-14
Excel® VBA for Physicists

Figure 4.6. The EmailData worksheet (with inset).

Sub SendTab()
Workbooks(“SendEmail.xlsm”).Activate
Worksheets(“EmailData”).Activate
WhoTo = Range(“WhoTo”).Value
Subject = Range(“Subject”).Value
Application.ScreenUpdating = False

‘Copy the target worksheet, specified in cell “WhatSheet”,


‘to generate a new workbook.
Worksheets(Range(“WhatSheet”).Value).Copy

‘The new workbook is now the ActiveWorkbook, which gets


emailed
ActiveWorkbook.SendMail WhoTo, Subject

‘Do not save the new workbook; turn screen updating back on.
ActiveWorkbook.Close savechanges:=False
Application.ScreenUpdating = True
End Sub

We activate the SendEmail sheet in the SendEmail.xlsm workbook; we obtain the


list of recipients and the message’s subject. The ScreenUpdating statement
prevents distracting screen changes as the procedure runs.
At first glance the statement Worksheets(Range(“WhatSheet”).Value).
Copy would seem to just copy a worksheet, but it actually does this and pastes it to a
new workbook. The new workbook is given the name Book1.xlsx (the 1 in the name
can be any number depending on what workbooks are currently open) with a sheet
called ‘EmailSheet’, but we never see this because of the ScreenUpdating action.
The workbook method SendMail then sends the messages; the parameters for
this method specify the recipients and the subject. There is no need to specify the
workbook explicitly; it is specified by ActiveWorkbook.
At this point Office throws up a warning as shown in the inset of figure 4.6. The
user must click on the Allow button when the green band is complete.

4-15
Excel® VBA for Physicists

The newly created workbook is closed without saving and screen updating is restored.
If you wish to see Book1.xlsx, just comment out the ActiveWorkbookClose..
statement.
The SendMail method does not allow for text in the message area of the email.
For this one needs to create an Outlook object within the Excel VBA code. Ron de
Bruin’s website http://www.rondebruin.nl/win/s1/div/mail.htm has some excellent
information on emailing from within Excel.

4-16
IOP Concise Physics

Excel® VBA for Physicists


A Primer
Bernard V Liengme

Chapter 5
Working with add-ins

In this section we see how to create an add-in, how to install it, and how to use it.
Our scenario is that a user wishes to share some UDFs with co-workers. So we
will not make a fuss about security and passwords. Everything we will do is
reversible, and we show how at the end of the section, so have no fear!

5.1 Creating an add-in


Normally the user would start with a new workbook and code all the required
macros using the VBE, and then save the file first as a macro-enabled workbook and
then as an add-in. We will skip the first step and use the file PhysFun.xlsm, which
contains some simple functions. Open the File tab and click on Info in the right
panel; note that this file has been given a Title (figure 5.1).
The reader may wish to look in the VBA to see the functions it contains. Now the
reader should perform a SaveAs and specify the file type as Excel Add-In (*.xlam).
Excel 2016 automatically attempts to place add-in files in the user’s AddIns
folder. To see where this is, open the VBE and in the Immediate window of the
VBE type ?application.UserLibraryPath; the response will be something

Figure 5.1. File ∣ Info used to give a Title to a workbook.

doi:10.1088/978-1-6817-4461-2ch5 5-1 ª Morgan & Claypool Publishers 2016


Excel® VBA for Physicists

like C:\Users\blien\AppData\Roaming\Microsoft\AddIns\. You can elect to save the


add-in elsewhere.

5.2 Installation
The installation is a one-time action. In Excel, open the File tab and select Options.
From the Options dialog select Add-ins. This opens a dialog similar to that shown
in figure 5.2. Since we are installing an xlam file, leave the Manage box as it is and
click Go.
Now we have another dialog (figure 5.3). If the reader has saved the add-in in the
AddIns folder, the add-in’s name will automatically appear. Otherwise, one must use
the Browse button to navigate to the folder where the add-in resides. In either case,
click the box to add a check mark before the add-in name. Note how the workbook’s
Title is used here; had we not given it a Title we would see a very uninformative
‘physfun’ (the file name).

5.3 Using the add-in


The workbook Topic5.xlsx contains no macros but is setup to use UDF in the
PhysFun.xlam add-in workbook. Before we install the add-in, the Topic5 workbook

Figure 5.2. The File ∣ Options ∣ Add-ins dialog.

5-2
Excel® VBA for Physicists

Figure 5.3. Loading add-ins.

will display #NAME! errors since it references functions that it cannot find. After the
add-in has been installed these function calls will work as if the UDF were part of
Topic5.xlsx. For example, if a user types =Eff then the IntelliSense popup will show
the EffectR UDF.

5.4 Making changes to the add-in


Perhaps you wish to modify a function or create a new one. Since we have not
locked and given a password to the add-in, we can just go to VBE to make the
modification. Then you need to click the Save icon on the VBE menu bar. Of
course, it will be necessary to redistribute the file if it was previously sent to
others.

5.5 Viewing worksheets


Some users keep data on worksheets of add-in workbooks. Normally, the work-
sheets of a XLAM file are hidden so some steps are required to view them. In the
VBE Project window expand Microsoft Excel Objects and click on ThisWorkbook,
see figure 5.4. Now in the properties window below locate the IsAddin item and set it
to False. Return to the Excel window and the worksheets will be visible. Reset the
IsAddin property to True when done. You will need to re-save the file if you made
any changes on a worksheet.

5-3
Excel® VBA for Physicists

Figure 5.4. Setting the IsAddin property.

5.6 Protecting the add-in


You may wish to hide the code for your add-in procedures to prevent others from
making incorrect alterations, or to protect intellectual property. In the VBE window
right click on the VBA project name and open the VBA Properties dialog. On the
Protection tab (figure 5.5) you can lock the project from viewing and add a
password. If you then need to make changes as discussed above, you will need to
un-lock it and provide the password.

5.7 Reversing everything


The demo functions are not really exciting, so the reader will not wish to keep the
add-in. First go to the dialog shown in figure 5.3 and uncheck the Physics Function
box. Now go to the AddIn folder and delete the workbook.

5-4
Excel® VBA for Physicists

Figure 5.5. Adding a password and locking an add-in.

5-5
IOP Concise Physics

Excel® VBA for Physicists


A Primer
Bernard V Liengme

Chapter 6
Numerical integration

The purpose of this chapter is primarily to introduce the reader to VBA program-
ming techniques. We will see various methods for finding approximations for
definite integrals. We will accept without formal proof that the value of a definite
integral equates to the area under the curve between the two limits. Our examples
are for definite integrals with known values since the objective is to demonstrate how
to code the numerical methods, not to actually solve problems.

6.1 The trapezoid approximation


While it is doubtful that any reader would use the trapezoid method to evaluate a
definite integral, this method provides us with a fairly simple procedure to construct
a VBA demonstration.
In figure 6.1 the blue curve represents the function which we wish to integrate
between the limits of zero and one. We have divided the area under the curve into a
series of trapezoids denoted in red. This approach is sometimes given the fancy title
of discretizing the integral. Using the simple formula area of trapezoid = average
height × base, we can readily obtain an approximation for the area under the curve.
It is traditional to refer to the base of each trapezoid by the letter h. It should be clear
from the figure that the smaller the value of h the better the approximation. We will
investigate these two features.
Figure 6.2 shows worksheet Trap1 in workbook Trap.xlsm. We wish to obtain an
approximation of the integral shown in the insert on that sheet. The limits of the
integration are in B3 and B4, cells which have been named ‘low’ and ‘high’,
respectively. In cell B7 we have a call to the UDF Trap; this computes the area of
one trapezoid and does so by calling the function MyFunction. This makes it easy
to modify the VBA should we wish to integrate another function. The comment-out
Debug.Print statement was used while testing the code. The code is contained in
Module1 of the workbook.

doi:10.1088/978-1-6817-4461-2ch6 6-1 ª Morgan & Claypool Publishers 2016


Excel® VBA for Physicists

Figure 6.1. Discretizing the integral.

Function MyFunction(x)
MyFunction = Exp(-x)* Sin(x)
End Function

Function Trap(low, high, h)


n = (high - low) / h
x = low
For j = 1 To n
Trap = Trap + (1 / 2) * (MyFunction(x) + MyFunction(x + h)) * h
‘Debug.Print x; Trap
x = x + h
Next j
End Function
The formula in B7 was copied down to B18 to calculate the approximations using
ever decreasing values for h. The graph shows the convergence of the approxima-
tions. The reader may wish to confirm that the final value in B18 agrees well with the
implicit solution.
In the worksheet Trap2 (see figure 6.3), our objective is to compute the definite
integral using successively smaller h values. We will assume we have converged on
an acceptable solution when two successive approximations differ by less than
0.001%. Here we use the subroutine WhatH, the code for which is:

6-2
Excel® VBA for Physicists

Figure 6.2. Example of the trapezoid rule.

Figure 6.3. Result from the WhatH subroutine.

Sub WhatH()
Worksheets(“Trap2”).Activate
Range(“A7:B7”).Delete
low = Range(“low”) : high = Range(“high”)
h = (high - low) / 10
n = 1
Do
Ione = Trap(low, high, h)
Itwo = Trap(low, high, h / 2)
Percent = Abs(Itwo - Ione) * 100 / Ione

6-3
Excel® VBA for Physicists

‘Debug.Print n; h; Percent; Ione; Itwo


h = h / 2
n = n + 1 ‘to trap never ending loop
If n > 100 Then Exit Sub
Loop Until Percent < 0.001
Range(“A7”) = h: Range(“B7”) = Itwo
End Sub
The sub uses the Do…Loop Until structure; to save us from the embarrassment
of a never ending loop while developing the code, we have a variable n that is
increased with each iteration of the loop and causes the incomplete sub to finish
should n exceed 100.

6.2 The Simpson 1/3 approximation


In this method, rather than a linear function through two points, we use a quadratic
between three equally spaced points as shown in figure 6.4, where once again the
blue curve is the function to be fitted, and the red curve is the approximation for just
one pair of segments. This necessarily requires that we have an even number of
points in our analysis.
It can be shown (for example http://www.intmath.com/integration/6-simpsons-rule.
php) that the area under one pair of segments is given by:
b
h⎡ ⎛a + b⎞ ⎤
∫ f (x )dx ≈ ⎢f (a ) + 4f ⎜ ⎟ + f (b )⎥ .
3⎣ ⎝ 2 ⎠ ⎦
a

For this demonstration we find the definite integral shown in figure 6.5. There is no
implicit method to evaluate this integral but WolframAlpha gives the value
16.452627765507230224736…; see https://www.wolframalpha.com/input/?i=integrate
+exp(x%5E2)+from+0+to+2&wal=header.
Figure 6.5 shows the worksheet Simp1, which has been set up to find an
approximation of the integral using a UDF coded to run Simpson’s 1/3 rule.
Again we name two cells for the limits of the integral. In A11 we have the first value

Figure 6.4. The Simpson’s 1/3 rule.

6-4
Excel® VBA for Physicists

Figure 6.5. Output from Simpson’s 1/3 subroutine.

for h while subsequent values are one quarter of the previous; of course we cannot
choose an arbitrary h value: the quantity (high – low)/h must evaluate to an even
integer. In B11 we compute the approximation for the corresponding h value. Both
from the Diff data and the second graph we note that our approximations converge
very quickly.
The code for the UDF (found in Module2) is:
Function MyFunction(x)
MyFunction = Exp(x ^ 2)
End Function

Function SimpThird(h, low, high)


n = (high – low) / h
x = low
For j = 1 To n Step 2
Term= MyFunction(x) +4 *MyFunction(x +h) + MyFunction(x +2 *h)
Integral = Integral + Term
‘Debug.Print Term
x = x + 2 * h
Next j
SimpThird = Integral * h / 3
End Function

6-5
Excel® VBA for Physicists

Previously, textbooks on numerical methods would express concern over round-


off errors and computational time. With Excel’s 15-digit precision the first concern
more or less disappears. To examine the second, the reader may wish to double click
B16 and then click the check mark symbol in the formula bar; the resulting
recalculation takes place in milliseconds.

6.3 An aside
When one looks to WolframAlpha.com to obtain the approximation for the integral
above, we see the result comes from the expression
2
1
∫0 exp(x 2 ) =
2
π erfi(2) ≈ 16.452627765507230224736 …

While Excel has a built in efr error function it has no imaginary error function erfi.
However, the site http://functions.wolfram.com/GammaBetaErf/Erfi/introductions/
ProbabilityIntegrals/ShowAll.html gives a useful definition of erfi:

2 z 2k + 1
erfi(z ) =
π
∑ k! (2k + 1) .
k=0

Clearly we cannot perform a summation to infinity. Furthermore, experimentation


reveals that FACT(170) is the largest possible for k!, returning a value of 7.2574E
+306. Figure 6.6 shows the worksheet Simp2, which calls on the UDF Erfi whose
code is:
Function Erfi(z)
n = 30
Pi = 4 * Atn(1)
For k = 0 To n
Term = z ^ (2 * k + 1) / (Application.Fact(k) * (2 * k + 1))
Debug.Print Term
Erfi = Erfi + Term
Next k
Erfi = (2 / Sqr(Pi)) * Erfi
End Function

Figure 6.6. The Erfi function computed.

6-6
Excel® VBA for Physicists

Note that we have summed from 0 to 30. Entering n = 170 results in a #VALUE!
error, and experimentation shows that with n larger than 30 we obtain the same
18.56… value. Our final value for the integral agrees with WolframAlpha’s value to
13 decimal places; since we are not in the business of gravity waves this is a totally
acceptable precision.

6.4 Monte Carlo integration


This method is shown for completeness, but it is seldom a satisfactory method.
Figure 6.7 shows an integral that would be a challenge for many to perform
implicitly. The inserted equation shows the result from WolframAlpha.
The premise for this method is: a coordinate (x, y) is generated using two random
numbers; the likelihood of this point lying within a certain zone (i.e. under the curve)
is proportional to the area of this zone.
Cell B9 shows the result from a Simpson 1/3 calculation; the code for
SimpThirdB is identical to that for SimpThird shown above (it is found in
Module4) but calls a new MyFunctionB (see below). The result is in satisfactory
agreement with the known value.
Function MyFunctionB(x)
MyFunctionB = 1 + WorksheetFunction.Sinh(2 * x) * Log(x) ^ 2
MyFunctionB = 1 / MyFunctionB
End Function
In the graph we have a rectangle in red that encompasses the curve to be
integrated. In the Monte Carlo function, we generate n random points within the
rectangle; each is tested to see if the point lies below the curve; a count (called hits) is

Figure 6.7. Example of the Monte Carlo method.

6-7
Excel® VBA for Physicists

maintained of how many events satisfy this criterion. Then we use the obvious ratio
hits/n = area-under-curve/area of rectangle. The Monte Carlo function is called ten
times in B13:B22 with the results averaged in B23. Notwithstanding that each call
uses n = 100,000 (so in total we make 1 million throws), the final result is not that
close to the known value for the integral.
The code for the Monte function is shown below. The opening statement
(Application.Volatile) causes each call to the function to recalculate
when F9 is pressed—the recalculation takes less than five seconds on a modest
computer. The statement Randomize provides a new seed for the Rnd function
each time—however, it appears to have little effect on the results.
Function Monte(low, high, maxy)
Application.Volatile
Randomize
n = 100000
For k = 1 To n
x = (high - low) * Rnd + low
y = maxy * Rnd
If y <= MyFunctionB(x) Then hits = hits + 1
Next k
Rect = (high - low) * maxy
Monte = hits * Rect / n
End Function
The Monte Carlo result generally agrees with the Simpson result to a mere three
decimal places. So, in the absence of a known value for the integral, all the Monte
Carlo method does is inform the user that there appears to be no serious error in the
coding of the SimpThird function!

6.5 Gaussian and Romberg integration


For information on these topics the reader may wish to consult the author’s book A
Guide to Microsoft Excel 2013 for Scientists and Engineers (2016, New York:
Academic).

6-8
IOP Concise Physics

Excel® VBA for Physicists


A Primer
Bernard V Liengme

Chapter 7
Numerical methods for differential equations

We are given an ordinary differential equation (ODE) in the form y′(x ) = f (x , y )


together with an initial value y(x0 ) = y0 . We are tasked with finding y(xf ) for some
value of xf . This type of problem is often called an initial value problem (IVP).

7.1 Euler’s method


A formal explanation of Euler’s method for solving the IVP starts with the Taylor
series, but we shall adopt a more pragmatic graphical approach. In figure 7.1 we
have the final solution curve (which we will only approximate) shown in blue with
the initial and final x, y values as markers. We know the value of the differential at
x0; so we know the slope of the tangent at this point—the tangent is shown in red.
Knowing the equation of the tangent we can compute some point not far from the
initial point—this is shown as a red marker.
We are given y′ ∣x = x0 = f (x , y ), so the tangent line is given by
y = y0 + f (x0, y0 )(x − x0 ). Thus our first approximation can be found with:
y1 = y0 + f (x0, y0 )(x1 − x0 ).
Assuming that y1 is close to the true solution curve, we may use f (x1, y1) as the
slope for the next approximation. So we write y2 = y1 + f (x1, y1)(x2 − x1).
Assuming we are working with a constant Δx which we will represent as h, we can
generalize the approach to:
yn+1 = yn + f (xn, yn)h .

For our example, we are asked to find y(2) given y′ = −2y and y(0) = 3. Figure 7.2
shows the worksheet Euler1 in the workbook Topic7.xlsm. The results for a run with
n = 5 (delta = 0.4) are shown in the lower chart (this is an image made using Excel’s
Copy As Picture feature). So that we can compare our approximations with the
exact solution we plot y = 3 exp( −2x ) as the blue curve.

doi:10.1088/978-1-6817-4461-2ch7 7-1 ª Morgan & Claypool Publishers 2016


Excel® VBA for Physicists

Figure 7.1. The Euler approximation.

Figure 7.2. Demonstration of the Euler approximation.

7-2
Excel® VBA for Physicists

The code for the Euler sub used to generate the (x, y) data is found in Module1:
Sub Euler()
‘Clear any previous results
Range(“A13:B13”).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents: Range(“A13”).Select

‘Get data from worksheet


X0 = Range(“X0”)
Y0 = Range(“Y0”)
n = Range(“n”)
h = Range(“delta”)

‘Output initial point


myrow = 13
Cells(myrow, “A”) = X0: Cells(myrow, “B”) = Y0: myrow = myrow + 1

For j = 1 To n
Y1 = Y0 + h * MyFun(X0, Y0)
X1 = X0 + h
‘Output new point
Cells(myrow, “A”) = X1: Cells(myrow, “B”) = Y1: myrow = myrow + 1

‘Setup for next iteration


X0 = X1: Y0 = Y1
Next j
End Sub

Function MyFun(x, y)
MyFun = −2 * y
End Function
Looking first at MyFun, the reader may wonder why we have an argument called
x which is not used. This was done for flexibility. We may later be asked to find
y(0.5) given y′ + 2y = 2 − exp ( − 4x ) with y(0) = 1; then the statement in MyFun
would read MyFun = 2 − exp(−4*x) − 2y, which requires the x value.
In sub Euler we first perform some housekeeping: (i) clear any data from a
previous run; (ii) input data from named cells on the worksheet and output the X0
and Y0 values to the table in the worksheet; (iii) use a For…Next loop to find the
first approximations (X1 and Y1) and output their values to the worksheet; and (iv)
the new values are then treated as initial values in preparation for the next iteration.
Cell B10 of the worksheets displays the final y value using the formula =LOOKUP
(9.99999999999999E+307,B:B) to save the user scrolling when n is large.
How well does the method perform? Remember that in a ‘real’ case we would not
have access to the exact solution (the blue curve). It turns out that if we wanted a

7-3
Excel® VBA for Physicists

Table 7.1.

n 5 10 20 200 1000 exact

y(2) 0.00096 0.01814 0.03458 0.05276 0.054508 0.054947


abs error 98% 67% 37% 4% 1%

good approximation for y(2) this method would be a disappointment. Table 7.1
shows the results of a series of runs.
Our conclusion is that Euler’s method is good only for a ‘quick and dirty’ result.
While a 1% error is generally acceptable, the three or so seconds taken to evolve the
result when n = 1000 would not be acceptable in an interactive environment.

7.2 The Runge–Kutta fourth-order method


Like the Euler method, the Runge–Kutta methods find successive approximations
for y based on the previous value. These mathematicians developed a number of
algorithms to solve differential equations. We shall use the fourth-order Runge–
Kutta method, the derivation of which is beyond the scope of this book.
The iterative formula shown below may look somewhat formidable, so let us see
how we can put it into a worksheet. Each parameter increments y by a multiple of
the parameter preceding it:
1
yn+1 = yn + 6 (k1 + 2k2 + 2k3 + k4)

where
k1 = hf (xn, yn)

( 1
k2 = hf xn + 2 h , yn + 2 k1
1
)
k = hf (x )
1 1
3 n + 2
h , yn + k
2 2

k4 = hf (xn + h , yn + k3) .

It might be easier for some readers to follow the application of these formulas when
solving an IVP by looking at a simple worksheet that uses just Excel formulas without
VBA. The worksheet RK1 solves the same IVP as we had in the Euler method.
The VBA solution is shown in figure 7.3, the design being very similar to that for
the Euler method. What is immediately apparent is the greater precision of the
Runge–Kutta method. Even the n = 5 result would do at a pinch, while the n = 20
result is within 0.01% of the exact value and takes no appreciable time to compute.
The code for this method (see Module2 in the workbook) is
Sub RungeKutta()
Worksheets(“RK2”).Activate
‘Clear any previous results

7-4
Excel® VBA for Physicists

Figure 7.3. Demonstration of the fourth-order Runge–Kutta method.

Range(“A13:B13”).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents: Range(“A13”).Select

‘Get data from worksheet


X0 = Range(“X0”)
Y0 = Range(“Y0”)
n = Range(“n”)
h = Range(“delta”)

‘Output initial point


myrow = 13
Cells(myrow, “A”) = X0: Cells(myrow, “B”) = Y0: myrow = myrow + 1

For j = 1 To n
K1 = h * MyFun(X0, Y0)
K2 = h * MyFun(X0 + h / 2, Y0 + K1 / 2)
K3 = h * MyFun(X0 + h / 2, Y0 + K2 / 2)

7-5
Excel® VBA for Physicists

K4 = h * MyFun(X0 + h, Y0 + K3)
Y1 = Y0 + (1 / 6) * (K1 + 2 * K2 + 2 * K3 + K4)
X1 = X0 + h

‘Output new point


Cells(myrow,“A”)=X1:Cells(myrow,“B”)=Y1:myrow=myrow+1

‘Setup for next iteration


X0 = X1: Y0 = Y1
Next j
End Sub

7.3 Simultaneous OEDs


Consider a pair of simultaneous equations having the form:
y′ = g (x , y , z )
.
u′ = f (x , y , z )
The Runge–Kutta formulas for these equations are:
1
yn−1 = yn + 6 (k1 + 2k2 + 2k3 + k4)
1
u n−1 = u n + 6 (w1 + 2w2 + 2w3 + w4)
k1 = hg(xn, yn , u n)
w1 = hf (xn, yn , u n)

( 1 1
k2 = hg xn + 2 h , yn + 2 k1, u n + 2 w1
1
)
w = hf (x w)
1 1 1
2 n + 2 h , yn + 2 k1, u n + 2 1

k = hg(x w)
1 1 1
3 n + 2 h , yn + 2 k2, u n + 2 2

w = hf (x w)
1 1 1
3 n + 2 h , yn + 2 k2, u n + 2 2

k4 = hg (xn + h , yn + k3, u n + w3)


w4 = hf (xn + h , yn + k3, u n + w3) .

7.4 Example of a system of two OEDs


Here are a pair of coupled OEDs which we wish to solve over the range 0 ⩽ x ⩽ 2:

dy
= −0.5y y(0) = 4
dx
dz
= 4 − 0.3z − 0.1y z(0) = 6.
dx

7-6
Excel® VBA for Physicists

The VBA for this (see Module3) is:


Sub SysOED()
Worksheets(“RK3”).Activate
‘Clear any previous results
Range(“A11:D11”).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents: Range(“A13”).Select
x = Range(“x0”)
y = Range(“y0”)
z = Range(“z0”)
xfinal = Range(“xn”)
n = Range(“n”)
h = (xfinal − x0) / n
t = 0
myrow = 11
Cells(myrow, “A”) = 0: Cells(myrow, “B”) = x
Cells(myrow, “C”) = y: Cells(myrow, “D”) = z
myrow = myrow + 1

For j = 1 To n
k1 = h * g(x, y, z): w1 = h * f(x, y, z)
k2 = h * g(x + h / 2, y + k1 / 2, z + w1 / 2): w2 = h * f(t + h / 2,
y + k1 / 2, z + w1 / 2)
k3 = h * g(x + h / 2, y + k2 / 2, z + w2 / 2): w3 = h * f(t + h / 2,
y + k2 / 2, z + w2 / 2)
k4 = h * g(x + h, y + k3, z + w3): w4 = h * f(t + h, y + k3, z + w3)

t = t + h
y = y + (1 / 6) * (k1 + 2 * k2 + 2 * k3 + k4)
z = z + (1 / 6) * (w1 + 2 * w2 + 2 * w3 + w4)

Cells(myrow, “A”) = j: Cells(myrow, “B”) = t


Cells(myrow, “C”) = y: Cells(myrow, “D”) = z
myrow = myrow + 1
Next j
End Sub
Function g(x, y, z)
g = −0.5 * y
End Function

Function f(x, y, z)
f = 4 − 0.3 * z − 0.1 * y
End Function

7-7
Excel® VBA for Physicists

Figure 7.4 shows the RK3 worksheet for n = 20. The reader can experiment with
other values; the graph can handle values up to n = 100. The exact solution may be
found on the WolframAlpha.com site by entering: solve differential
equation y’ = −0.5y, z’ = 3−0.3z−0.1y, y(0) = 4, z(0) = 6.

7.5 Higher order OEDs


A second-order OED can be converted to a pair of simultaneous OEDs by simple
substitution. For example, to solve y″ = ay′ + by + c, we make the substitution y′ =
u. The introduction of the auxiliary variable u allows us to write the second-order
equations as two simultaneous equations:
y′ = u
u′ = au + by + c.

7.6 R–L circuit


For our example of solving a second-order ODE we consider the circuit shown in
figure 7.5 with R = 15Ω, L = 3 H, and V = 120cos(2t) V. We wish to find the
instantaneous charge q and the current i for the first five seconds after closing the
switch. The task is performed on the Circuit worksheet of the Topic7 workbook.
Our starting assumptions are:
dq dq d2q
By defintion i= and = 2
dt dt dt
2
dq dq
Kirchhoff’s second law L +R = V (t ) .
dt 2 dt
In terms of the Runge–Kutta equations we shall use

Figure 7.4. Demonstration of the Runge–Kutta fourth-order method with a system of equations.

7-8
Excel® VBA for Physicists

Figure 7.5. Sample R–L circuit.

dq
= i = f (t , q , i )
dt
.
di V (t ) − Ri V cos(ωt ) − Ri
= = = g (t , q , i )
dt L L
It so happens that we need not code the f function since it is simply i = i.
The following is the code for the subroutine that generated the data in A13:D63
(see figure 7.6, which shows only down to row 34):
Dim R, L, V, omega

Sub Circuit()
Worksheets(“Circuit”).Activate
‘Clear any previous results
Range(“A13:B13”).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents: Range(“A13”).Select
R = Range(“resist”)
L = Range(“Induct”)
i = Range(“I0”)
q = Range(“Q0”)
V = Range(“V0”)
omega = Range(“omega”)
h = Range(“h”)
t = 0
tfinal = 5
myrow = 13
Cells(myrow, “A”) = 0: Cells(myrow, “B”) = t
Cells(myrow, “C”) = q: Cells(myrow, “D”) = i
myrow = myrow + 1

n = tfinal / h
For j = 1 To n
k1 = h * i: w1 = h * g(t, i)
k2 = h * (i + w1 / 2): w2 = h * g(t + h / 2, i + w1 / 2)

7-9
Excel® VBA for Physicists

Figure 7.6. Output from the Circuit subroutine.

k3 = h * (i + w2 / 2): w3 = h * g(t + h / 2, i + w2 / 2)
k4 = h * (i + w3): w4 = h * g(t + h, i + w3)
t = t + h
q = q + (1 / 6) * (k1 + 2 * k2 + 2 * k3 + k4)
i = i + (1 / 6) * (w1 + 2 * w2 + 2 * w3 + w4)

Cells(myrow, “A”) = j: Cells(myrow, “B”) = t


Cells(myrow, “C”) = q: Cells(myrow, “D”) = i
myrow = myrow + 1
Next j
End Sub

Function g(t, i)
g = (V * Cos(omega * t) − R * i) / L
End Function
One item in the code needs an explanation. The values for R, L, V, and omega are
obtained from the worksheet in the subroutine but are not passed to the function g.
By dimensioning these variables external to the subroutine, they are made globally
available within the current module.

7-10
Excel® VBA for Physicists

Also shown in figure 7.6 is a plot of both V(t) and i(t) to demonstrate the concept
of phase shift. The worksheet (but not the figure) has a plot comparing the
approximate i(t) values to the exact i(t) values. The exact solution for i(t) is
V0 ⎛ ⎛ R ⎞⎞
i (t ) = ⎜R cos(ωt ) + ωL sin(ωt ) − R exp ⎜ t⎟⎟ .
2
R +ωL2 2⎝ ⎝ L ⎠⎠

See http://info.ee.surrey.ac.uk/Teaching/Courses/ee1.cct/circuit-theory/section6/
sinresponse.html.

7-11
IOP Concise Physics

Excel® VBA for Physicists


A Primer
Bernard V Liengme

Chapter 8
Finding roots

There are several numerical methods for finding roots, including the Newton–
Raphson, Secant, and bisection methods. There is also the method called ‘successive
iterations’, which is not often included in textbooks but which, in appropriates cases,
can be the quickest one to implement. In this section we see how to implement the
bisection and the successive approximations methods.
We shall also see how to implement the Excel Solver function in VBA code to find
the roots of functions.

8.1 The bisection method


In figure 8.1 the upper graph shows a plot of x 4 + 0.9x 3 − 2.3x 2 + 3.6x − 25.2 from
−4 ⩽ x ⩽ 3.5. Clearly there is a root between −4 ⩽ x ⩽ 3.5 and another between 1 ⩽ x
⩽ 3. In general, let f(a) and f(b) have different signs (so f(a) × f(a) < 0); if we locate
the midpoint x = (a + b)/2 then one of three cases applies:
⎧< 0 there is a root in[a , x ]

f (a )f (x )⎨< 0 there is a root in[x , b ]

⎩= 0 then x is the root
If one of the first two cases is true, we let b = x or a = x, respectively, and repeat the
process of locating the midpoint x = (a + b)/2 until f(x) is zero or approximately so.
The bisection method will never fail provided we start with a and b values such
that f(a) × f(b) < 0. These can be found programmatically, but a graphical method is
easier to implement. In the worksheet Bisect of Topic8.xlsm (figure 8.1): (i) B3 and
B4 have the names show in A3:A4; (ii) the formula in A8 is =xstart; (iii) in A9 we
use =A8+h and this is copied down to A107; and (iv) in B8 the formula =f(A8)
evaluates the required function for the first x value, this is copied down to B107. So
we have 100 points to plot. The lower chart shows the author’s starting point of
xstart = −10 with h = 0.5. Subsequent experiments quickly generated the top
chart, giving us a pair of a and b values to use with the Bisection function.

doi:10.1088/978-1-6817-4461-2ch8 8-1 ª Morgan & Claypool Publishers 2016


Excel® VBA for Physicists

Figure 8.1. The bisection method.

From the graph we read off −4 and −2 and enter these values into J8:K8, cell L8
calls the Bisection function with =Bisection(J8,K8) to find an x that gives
f(x) = 0. M8 uses =f(L8) to test this x value. Similarly, in J9:M9 we find the root
that lies between 1.5 and 2.5. Below that we show how slightly different starting a
and b values can subtly effect the root that is found by bisection.
The code for the two functions (Module1) is:
Function f(x)
f = x ^ 4 + 0.9 * x ^ 3 − 2.3 * x ^ 2 + 3.6 * x − 25.2
End Function

Function Bisection(a, b)
n = 0
If f(a) * f(b) > 0 Then ‘Inappropriate starting values
Bisection = “N/A”
Exit Function
End If
Do
x = (a + b)/2
Select Case f(a) * f(x)
Case 0
Exit Do
Case Is < 0
b = x

8-2
Excel® VBA for Physicists

Case Is > 0
a = x
End Select
n = n + 1
If n > 10000 Then Exit Function
Loop While Abs(f(x)) > 0.00000000001
Bisection = x
‘Debug.Print “n= “ & n
End Function
The purpose of the n variable is to cause the function Bisection to end after
10,000 iterations. The author hates having the problem of a never ending loop (this
would happen, for example, if Loop While Abs(f(x)) > 0.00000000001
had been mistyped as Loop While Abs(g(x)) > 0.00000000001)
because there have been times when ESC or CTRL+BREAK failed to arrest an
errant loop.
If the reader wishes to see how many iterations are required, just remove the
apostrophe from the start of the Debug.Print statement and recalculate all of the
L8:L11 cells. The Immediate window shows that generally less than 100 iterations
are needed.

8.2 The successive iteration method


If we can write our problem in the form x = g (x ) and we have some information
about x, then we may use an initial approximation (a guess), substitute it into g (x ),
and find a better approximation. Figure 8.2 show an example; since the left-hand
side of the original equation has a small value, we may assume that x is small so we
make the initial value zero. The first approximation is 0.01296, this leads to the third
approximation of 0.1253, and so on. Eventually we have successive approximations
that are the same or differ by very little.

Figure 8.2. The successive iteration method.

8-3
Excel® VBA for Physicists

For a more interesting example we set ourselves the task of finding the molar
volume of CO2 at 1 atm and 500 K using the van der Waals equation; given for CO2,
a = 3.592 L2 · atm·mole−1 and b = 0.04267 L·atm.
a
The van der Waals equation (p + 2 )(V − b ) = RT may be rewritten as
V
a
V = RT (p + 2 )−1 + b so we have the expression x = g(x) needed for the method.
V
For our initial V value, we turn to the ideal gas law. Figure 8.3 shows the worksheet
SuccIter; the code for the function is:
Function SuccIter(p, T, a, b, R)
Flag = True
V = R * T * p
Do Until Flag = False
Vold = V
V = R * T/(p + a/Vold ^ 2) + b
If Abs(Vold - V) < 0.0000001 Then Flag = False
n = n + 1
If n > 100 Then Exit Do
Loop
SuccIter = V
End Function

8.3 Root finding with Solver


The built-in Solver feature of Excel can be used to find roots. Here we will see how to
incorporate calls to Solver within a VBA subroutine. It will be assumed that the
reader’s Excel has Solver available (check in the Data tab to see that the last group is
named Analyze and contains a Solver command); if not, this website will guide you
through the process: https://msdn.microsoft.com/en-us/library/office/ff196600.aspx.
We have been asked to find all the real roots of cos(2x ) − 0.4x = 0 on [−4, +6.5].
Figure 8.4 shows part of the worksheet Solver in Topic8.xlsm. Using a value of −4
for xstart and 0.105 for h, we find that the function crosses the x-axis three times
between −4 and 1 and is moving away from the axis as x increases. This gives us
three pairs of starting values for a and b as shown in D22:E24. We select D21:G24

Figure 8.3. van der Waals calculation.

8-4
Excel® VBA for Physicists

Figure 8.4. Solver called from a VBA function.

and use Formula | Defined Names | Create from Selection to name four sets of three
cells. Note that G22:24 has the name g_x not g(x).
We need some good starting values for the three x values so we code a subroutine
(ResetProb) to give them each the values (a + b )/2. The code for this and for the
subroutine (SolverSub) are found in Module2 and are:
Function g(x)
g = Cos(2 * x) − 0.4 * x
End Function

Sub ResetProb()
For n = 1 To Range(“x”).Count
Range(“x”)(n) = (Range(“a”)(n) + Range(“b”)(n))/2
Next n
End Sub

Sub SolverSub()
SolverReset
SolverOk MaxMinVal:=0, ValueOf:=0, ByChange:=“x”,
Engine:=1,_
EngineDesc:=“GRG Nonlinear”

8-5
Excel® VBA for Physicists

SolverOptions MaxTime:=0, Iterations:=0, Precision:


=0.000000000001, Convergence:= _
0.000000000001, StepThru:=False, Scaling:=True,
AssumeNonNeg:=False, Derivatives:=1
SolverAdd CellRef:=“g_x”, Relation:=2, FormulaText:=“0”
SolverAdd CellRef:=“x”, Relation:=3, FormulaText:=“a”
SolverAdd CellRef:=“x”, Relation:=1, FormulaText:=“b”
SolverSolve Userfinish:=True
End Sub
The RestProb code has the statement Range(“x”)(n) = …; this uses a range
method which was only briefly mentioned in chapter 4. The (n) part tells VBA to
use the nth cell in the range named x.
The code for SolverSub looks formidable but most of it was generated by
manually setting up the Solver model while running the VBA recorder. The resulting
code had a few unnecessary duplicate statements but with experimentation one
is able to obtain a working subroutine. It will be helpful to see the Solver model
(figure 8.5) generated by the code so we can give some explanations.
In the SolverOptions statement the phrase Precision:=0.000000000001
refers to the constraint precision; one of our constraints is setting the g_x-values to
zero, and we wish to get as close to zero as possible.
In the SolverAdd statements we have Relation: = 2, etc. A visit to https://
msdn.microsoft.com/en-us/library/office/ff196600.aspx and opening the SolverAdd
Function link gives us the meanings of these values as shown in table 8.1 below.
The final statement SolverSolve causes Solver to execute and solve the model.
Without the parameter Userfinish:=True would result in the final Solver dialog

Figure 8.5. The Solver model generated by the VBA code.

8-6
Excel® VBA for Physicists

Table 8.1. The Relation parameter for SolverAdd.

Relation Meaning

1 ⩽
2 =
3 ⩾
4 CellRef must have final values of integers.
5 CellRef must have finals value of 0 or 1.
6 CellRef must have final values that are all different and integers.

Figure 8.6. Referencing Solver.

being displayed ready for the user to click the OK button. But the parameter results
in this being automatic.
There is one important step to make after writing or recoding the SolverSub
procedure. In the VBE window with Module2 open, click the Tools icon and select
References to obtain the dialog shown in figure 8.6. Ensure that the Solver box is
checked. This step needs be done just once—when initially working on the code.

8.4 Using range names


Some notes on using range names rather than cell references in VBA procedures:
i. Suppose we have a subroutine with a statement such as Pi = Range
(“B12”).Value. But someone later decides the worksheets need some
tidying up and moves a few things around resulting in the formula =Pi()
now being in D10 not B12. The VBA sub will be unaware of this move and
will work with whatever is in B12. Had B12 been named as ‘PiValue’ and

8-7
Excel® VBA for Physicists

the sub used Pi = Range(PiValue”).Value, then no matter what is


added/deleted in the worksheet (other than deleting that cell!), all will be
well since the location of the named cell must be resolved at run time.
ii. It is easier to understand both the Solver model dialog and the statements in
the sub.
iii. If we wished to modify the worksheet to solve another problem with a
different number of roots, all we need do is select D21:G21 and the
appropriate number of rows, and use Formula | Defined Names | Create
from Selection to redefine a, b, x, and g_x.

In the graph, the three red squares are a plot of F22:G24 and after running
SolverSub these markers will be on the x-axis.
The data in I22:J24 show the results from the Bisection2 function (also in
Module2); the code for this is the same as in the first bisection example but it calls
upon the g(x) not the f(x) function. The values in K22:K24 show that the roots
found by the Solver and the bisection methods differ by insignificant amounts.

8-8

Potrebbero piacerti anche