Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
A Primer
Excel® VBA for Physicists
A Primer
Bernard V Liengme
St Francis Xavier University, Nova Scotia, Canada
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.
DOI 10.1088/978-1-6817-4461-2
Version: 20161101
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
vii
Excel® VBA for Physicists
viii
Excel® VBA for Physicists
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
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.
Figure 1.1. Customizing the Quick Access Toolbar to add the Developer tab.
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
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.
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-5
Excel® VBA for Physicists
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-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-8
Excel® VBA for Physicists
11 10 1 1 1 1
−11 9 7 −2 7 −2
19 −13 −7 6 −7 6
−11 −10 −1 −1 −1 −1
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
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-11
Excel® VBA for Physicists
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-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
Chapter 2
Variables, Dim statements, and data types
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-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.
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-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
2-6
Excel® VBA for Physicists
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-7
Excel® VBA for Physicists
2-8
IOP Concise Physics
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.
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
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
3-5
Excel® VBA for Physicists
There are two syntaxes for the Do…Loop, one a pre- and the other a post-test
construct:
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.
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-7
Excel® VBA for Physicists
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
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!
Table 4.1.
4-2
Excel® VBA for Physicists
Table 4.2.
?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-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.
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.
4-6
Excel® VBA for Physicists
4-7
Excel® VBA for Physicists
Array functions
Format functions
Information functions
4-8
Excel® VBA for Physicists
Lookup functions
Math functions
String functions
(Continued)
4-9
Excel® VBA for Physicists
(Continued )
4-10
Excel® VBA for Physicists
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
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-12
Excel® VBA for Physicists
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-13
Excel® VBA for Physicists
4-14
Excel® VBA for Physicists
Sub SendTab()
Workbooks(“SendEmail.xlsm”).Activate
Worksheets(“EmailData”).Activate
WhoTo = Range(“WhoTo”).Value
Subject = Range(“Subject”).Value
Application.ScreenUpdating = False
‘Do not save the new workbook; turn screen updating back on.
ActiveWorkbook.Close savechanges:=False
Application.ScreenUpdating = True
End Sub
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
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.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-2
Excel® VBA for Physicists
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-3
Excel® VBA for Physicists
5-4
Excel® VBA for Physicists
5-5
IOP Concise Physics
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.
Function MyFunction(x)
MyFunction = Exp(-x)* Sin(x)
End Function
6-2
Excel® VBA for Physicists
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
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
6-4
Excel® VBA for Physicists
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
6-5
Excel® VBA for Physicists
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
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-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-8
IOP Concise Physics
Chapter 7
Numerical methods for differential equations
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.
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
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
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.
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.
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
Range(“A13:B13”).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents: Range(“A13”).Select
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
( 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
dy
= −0.5y y(0) = 4
dx
dz
= 4 − 0.3z − 0.1y z(0) = 6.
dx
7-6
Excel® VBA for Physicists
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)
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.
Figure 7.4. Demonstration of the Runge–Kutta fourth-order method with a system of equations.
7-8
Excel® VBA for Physicists
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
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)
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
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.
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-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-4
Excel® VBA for Physicists
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
8-6
Excel® VBA for Physicists
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.
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-7
Excel® VBA for Physicists
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