2.3 The major reason for variable declarations 2-12.4 Declarations in function headers and for constants 2-32.6 A second reason for variable declarations 2-4... This work will introduce
Trang 4Bernard V Liengme
St Francis Xavier University, Nova Scotia, Canada
Morgan & Claypool Publishers
Trang 5or 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
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
Trang 82.3 The major reason for variable declarations 2-12.4 Declarations in function headers and for constants 2-3
2.6 A second reason for variable declarations 2-4
Trang 94 The Excel object model 4-14.1 Examples of properties, methods and events 4-1
7 Numerical methods for differential equations 7-1
Trang 108 Finding roots 8-1
Trang 11This work will introduce the reader to Visual Basic for Applications (VBA) anddemonstrate 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 createsubroutines to perform repetitive actions
Visual Basic (VB, the parent of VBA) has its roots in the educationalprogramming language BASIC redeveloped at Dartmouth College in 1964 Inthe half-century since then, the language has evolved to become a high-poweredobject-orientated language which is no longer denigrated by aficionados oflanguage such as C++ and C# The VBA compiler and editor is incorporatedwithin 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 andsubroutines, and to demonstrate that this is not a complex topic The material ispresented in a manner that will allow the reader to experiment with VBAprogramming; this is the best way to learn it The scenarios used in the examplescenter around either fairly simple physics or non-complicated mathematics, such asrootfinding and numerical integration The text, therefore, will be suitable not justfor physicists but for other scientists and engineers, including students
A tested Excel workbook can be downloaded fromherefor each chapter.The brevity of the book prevents total rigour so it was necessary to condense somematerial, but Internet links are provided so the reader can explore VBA topics ingreater 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, notwithstandingits date; furthermore, it can be obtained very cheaply online
The author is more than happy to reply to email inquiries about topics in thebook or other Excel (with or without VBA) questions Please use the word Excel inthe subject line of each message
Have fun learning to extend Excel with VBA!
Bernard V Liengmebliengme@stfx.ca
Trang 12The author thanks Microsoft Excel Most Valuable Professionals (MVPs) JonPeltier, Bob Umlas, and Jan Karel Pieterse for their help over the years.
Trang 13Bernard V Liengme
Bernard V Liengme attended Imperial College London for hisundergraduate and postgraduate degrees; he held post-doctoralfellowships at Carnegie-Mellon University and the University ofBritish Columbia He has conducted extensive research in surfacechemistry and the Mossbauer effect He has been at St FrancisXavier University in Canada since 1968 as a Professor, AssociateDean, and Registrar, as well as teaching chemistry and computer science Hecurrently lectures part-time on business information systems Bernard is also theauthor of other successful books: COBOL by Command (1996), A Guide toMicrosoft Excel for Scientists and Engineers (now in its fourth edition), A Guide toMicrosoft Excel for Business and Management (now in its second edition), ModellingPhysics with Microsoft Excel®(2014), and SMath for Physics: A Primer (2015)
Trang 14In this chapter we will make a few simple changes to our Excel environment toallow us to code and run macros Then we will see how to code some examples ofsimple macros (procedures), i.e functions and subroutines We close with a brieflook at recording a subroutine.
1.1 Preparation
There is little to do in preparation We start by adding the Developer tab to theExcel ribbon Right click on the Home tab and select Customize Ribbon This opensthe dialog box as shown infigure1.1, click the box to the left of Developer to add acheck mark (if it is not already there), and then click the OK button in the lowerright-hand corner of the dialog As can be seen from the title in this dialog, one canalso customize the ribbon by using the command File| Options | Customize Ribbon.The ribbon now has the Developer tab present, as shown infigure1.2 We cannow check the macro security setting Open the Developer tab and click on MacroSecurity to open the dialog shown infigure1.3 Make sure that the setting is Disableall macros with notification (this is the default setting and should not be changedwithout good reason.) Beginning with Office 2007, Microsoft required thatworkbooks containing macros be saved with the extension XLSM; we refer tosuch workbooks as macro-enabled This is a security feature since a rogue macro canharm a computer When you open a macro-enabled workbook you will see awarning as shown infigure1.4; click on Enable Content if you trust the workbooknot to have rogue macros If you are working with Excel 2003, your workbooks willhave the extension XLS even when they contain macros To learn more about macrosecurity, visit https://support.office.com/en-us/article/Enable-or-disable-macros-in-Office-files-12B036FD-D140-4E74-B45E-16FED1A7E5C6
Trang 15You may not see this warning every time; Excel seems to remember if a specificmacro-enabled file has been opened in the same user session At other times thewarning comes with a more ominous message (figure 1.5) It seems odd that thismessage occurs when thefile 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 Inthis chapter the reader needs to learn how to open the VB Editor (VBE), add amodule, and save a macro-enabledfile It is best that the reader starts with a new file.However, to cut down on the work, the companion site has thefile Topic1BVL.xlsm,and this chapter gives instructions on copying from that workbook to the reader’snew workbook
Figure 1.1 Customizing the Quick Access Toolbar to add the Developer tab.
Figure 1.2 The ribbon with the Developer tab added.
Trang 161.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);
Figure 1.3 Setting the macro security.
Figure 1.4 Example of a macro warning.
Figure 1.5 Another macro warning format.
Trang 17and 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 arestriction on which worksheet function may be used In general, if there is anequivalent VB function then the worksheet function may not be used
Example A physics student needs to compute the kinetic energy given the mass andvelocity of the object Figure1.6shows a sample worksheet In column C he uses aworksheet formula to compute the kinetic energy, while column D shows how aUDF may be used The reader should set up a worksheet like this but leave D2:D5empty for now In B7 we have the formula = FORMULATEXT(C2), which displaysthe referenced cell’s formula
Open the Developer tab, click on Visual Basic (the left most icon) to open theVBE Figure 1.7 shows the VBE window, but since you have just opened it theworking space (the module area, the panel at top right) will be grey Click on theInsert command and select Module Now type this code into the module:
Function KE(mass, Vel)
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) andmake the correction How disappointed will you be when on returning to theworksheet youfind 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 worksheetuntil the worksheet is recalculated Do this by pressing F9, or selecting a cell with theUDF (D2 for example) and double clicking it
Figure 1.6 Example of using a UDF.
Trang 18If you have a syntax error in a macro, Excel will throw up a warning Click theDebug 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 infigure1.7 When there is a VBA error you cannot do anything with theworksheet 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 inthe Quick Access Toolbar (will Microsoft think of a new icon when we have allforgotten aboutfloppy discs?) or use the command File | Save In the normal way,give thefile a name such as ‘Topic1’ but there is an extra step Under the name boxyou 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), seefigure1.8 If you fail to do this Excel will detect the presence of a macroand issue a warning If you do not heed the warning all your modules will disappear!
Figure 1.8 The macro-enabled option in Save.
Figure 1.7 The VBE interface.
Trang 191.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 Herworksheet is shown infigure1.9 Once again we will perform our calculationsfirstwith worksheet formulas and then with UDFs The author likes to confirm that thetwo 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 itsimilar 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.
Trang 20in C18:E21 and C26:E29 because the Topic1.xlsm workbook lacks the referencedUDFs.
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 thekinetic energy function (as we are working in SI units we need the molar mass to be
in kilograms, hence the 10−3factor):
The code for Vmean is shown below; it is left as an exercise for the reader to codeVrms:
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 simpleformula; (ii) VBA permits a constant to be defined with an expression such as ConstTwoPi=2 * 3.14159265358979, but functions are not permitted in theexpression, making Const Pi = 4 * Atn(1) invalid
While researching these formulas for these velocities, the author found severalsites that computed them All agreed when the root-mean-squared velocity wascalculated, but there was a wide spread for the others To test for correctness, use the
π
vmean ( 2 )vpropandv = 3v
2 rms prop The following website gave consistentresults: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 theworksheet 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
Trang 21workbook, 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 thecurly braces to denote an array function We can now drag C26:E26 down to row 29.Function Velocities(T, M)
1.6 Notes on VBA functions
Because the marriage of Office Excel and VB was made when both were matureapplications, it is not surprising that sometimes there is a clash between them Thereader should be aware that there are some differences between worksheet and VBfunctions 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 Toobtain 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 makethe result even; so Round(3.5,0) and Round(4.5,0) each give 4 as theresult, and Round(−3.5,0) and Round(−4.5,0) each give −4 Contrastthis with the Excel results, which would be 4 and 5 for positive values and−4and −5 for negative values, since Excel rounds up when x > 0 and downwhen x < 0 when the digit to be rounded is 5 The VB behavior is sometimescalled‘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 theModoperator: 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 intable 1.1; the last two columns show alternative ways of performing thecalculations
TRUNCand INT are similar in that both return integers TRUNC removesthe fractional part of the number INT rounds numbers down to the nearestinteger based on the value of the fractional part of the number The resultsfrom INT and TRUNC are different only when using negative numbers:
Trang 22TRUNC(−4.3) returns −4, but INT(−4.3) returns −5, because −5 is thelower number The table above is taken fromhttps://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 theworksheet to look likefigure1.10, leaving rows 4 and 7 empty Using the commandInsert| 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 themenu, 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
Figure 1.10 Example of output from a subroutine.
Table 1.1 Comparing Excel ’s MOD and VBA’s Mod.
Trang 23Range(“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 OnError GoTo … is very common in VB programming, especially in the form OnError 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 anerror is detected The programflow is directed to the very end of the subroutine in thiscircumstance 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 MolMassand mTemp,1causing the various velocity functions to misfire Note how we can accessthese velocity functions even though they reside on a different module within the sameworkbook Should we wish to prevent such access we could add the word‘Private’ atthe start of a function header—Private Function Whatever(….)
Before we proceed we need to return to the worksheet Right click on the shapeand by selecting Assign Macro, indicate that this shape should run the subroutineMolVelwhen clicked
Next we look at various ways of calling up the subroutine
1 Within the VBE we could use the Run command (figure1.11) on the menu(or its shortcut F5), or click the green arrow just below the Debug menucommand 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 doubleclick the sub you wish to run If the mouse cursor is inside a subroutine thisdialog 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 Macrostool, and select View Macros In either case a dialog will open with a list ofmacros—not just those in the current project but all those in the currentlyopened 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 theMolVelsubroutine 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!).
Trang 24When we run MolVel, Excel is told to activate the appropriate sheet, otherwise ouroutput could damage another worksheet Of course, if we always ran the sub byclicking the shape on the MolSpeed worksheet, this statement would be redundant.Next a box pops up (figure1.12) asking the user to name the gas This name is thenplaced in cell B4 In similar ways we obtain the molar mass and temperature in B5 andB6, 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 thatresides 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 figure1.10we have a blue rectangle which, when clicked, causes the subroutineMolVel to run The image can be a shape or picture After placing it on theworksheet right click it to bring up the dialog shown to the left infigure 1.13 Theuser clicks the Assign Macro item bringing up a list of subroutines available in thecurrent 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 thatcan be used over and over This can be useful for formatting and entering textual data
Figure 1.12 The InputBox dialog.
Figure 1.11 Some commands in the VBE menu.
Trang 25It 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 itmust 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 thestatus 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 recordingand perform the following operations:
1 Fill in the dialog box as shown infigure1.14and click the OK button Wewill not bother with a shortcut
Figure 1.14 The Record Macro dialog.
Figure 1.13 Linking an image to a subroutine.
Trang 262 Hold down the CTRL key and drag the tab of Sheet2 to the left betweenSheet2 and MolSpeed Release the CTRL key Now we have a newworksheet 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 afill 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 addedModule3 holding the sub DuplicateSheet2 This reads:
Trang 271.10 Finding a home for macros
We have placed our functions and subroutines in modules stored in the currentworkbook This is generally the safest choice Macros housed in other workbooks areaccessible when those workbooks are open; one generally avoids this complication
If you have macros that you wish to use in many different workbooks, then thebest course is to store them in the Personal.xlsb workbook This workbook can bemade by starting the recorder, specifying Personal as the stage place (the third box infigure1.14), and recoding a one-line sub Then go to the VBE, open the Personalproject, and delete the module with the dummy subroutine
The Personal.xlsb workbook is stored in your Xlstart folder and opens every timeExcel is started, and it is normally hidden in Excel but visible in the VBE Thefollowing links provide further information (do not be concerned if they mentionolder versions of Excel or Windows):
• http://www.rondebruin.nl/win/personal.htm
• Workbook-AA439B90-F836-4381-97F0-6E4C3F5EE566?ui=en-US&rs=en-US&ad=US
https://support.office.com/en-us/article/Copy-your-macros-to-a-Personal-Macro-Another place for macros is an Add-in workbook; we explore this topic inchapter 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 statementsbetween For and Next are indented it is immediately obvious what code isrepeated
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
Trang 28It is important to note that the underscore is placed just after a space in the longcode This cannot be a space within a literal The correct way to split a literal isdemonstrated by
Range(“A10”) = “Now is the time for all good folks to ” _
& “come to the aid of the party”
Trang 29Bernard 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 Themaximum length is 255 characters
ii Avoid spaces and other symbols, although VBA will tolerate the underscoresymbol
iii You cannot use reserved word like Dim, Sub, Next, or the names of VBfunctions 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 themacro you introduce the name‘MyData’ and then later type ‘mydata’, theeditor 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 ensurethat all new modules have this option included, then open the VBA Tools commandand check the box Require Variable Declaration, seefigure2.1
While there are several good reasons for declaring all variables with Dimstatements, most examples in the book do not use them since the procedures areshort and the author wanted neat and clear code examples
2.3 The major reason for variable declarations
Figure2.2shows the worksheet Sheet1 in Topic2.xlsm We have a cylinder of radiuscylRadand height cylHeight partiallyfilled by liqVol litres of liquid A rod ofradius rodRad is immersed in the liquid to a depth of rodLen Our task is tofindthe height of the liquid in the cylinder The formula in F3 is =(E3*1000 + PI()
*C3^2*D3)/(PI()*A3^2)
Trang 30Consider these two functions (the second of which is found in Module1):Function LiqH(cylR, cylH,
rodR, rodL, liqV)
pi = 4 * Atn(1)
cylV = pi * cylR ^ 2 * cylH
rodV = pi * rodR ^ 2 * rodL
LiqH = (liqV * 1000 + redV) /
(pi * cylR ^ 2)
End Function
Option Explicit Function LiqH(cylR, cylH, rodR, rodL, liqV) Dim pi, cylV, rodV
pi = 4 * Atn(1) cylV = pi * cylR ^ 2 * cylH rodV = pi * rodR ^ 2 * rodL LiqH = (liqV * 1000 + rodV) / (pi * cylR ^ 2) End Function
Figure 2.1 The Tools | Options dialog.
Figure 2.2 Worksheet Sheet1 of Topic2.xlsm.
Trang 31The one on the left will always return the same value for LiqH no matter what therod dimensions are Can you see why? We have typed‘redV’ for ‘rodV’ in the laststatement 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 OptionExplicit and Dim statements will help If we add Option Explicit and theDimstatements shown on the right, then when we call the function on the worksheetVBA will throw up an error message should itfind redV in the code The offendingstatement will be highlighted in yellow After correcting it, the user must reset theprocedure using the small blue square on the menu bar or by opening the Run menuitem and selecting Reset, seefigure2.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 whenOption Explicithas been specified; nor do we ever dimension constants definedwith Const We may use Dim statements for functions and arguments if we wish tospecify their data types Should we feel the need to give a constant a data type, theformat is Const Pi As Double = 3.14159265358979
If we plan to use the same variable in several macros in the same module, we canput a Dim statement at the top of the module before thefirst procedure; for example,Dim alpha Alternatively, we could use Private alpha Similarly, if we wish touse constants in several procedures, we can declare the constant at the top of themodule 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: Publicalphaand Public Const Pi As Double = 3.14159265358979 with orwithout As Double
The reader is encouraged to modify the right-hand function in such a way that ifthe rod is immersed so far as to cause spillage, then the height is never reported asbeing greater than cylH
Trang 32write a very complex application, then speed and memory considerations make datatype assigning essential, but this is not the case with our examples.
Data type Bytes used Range of values
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
String 1 per character Varies according to the number of characters
Our function LiqH does not need a great deal of precision so data type Singlewill 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 asSingle, 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 Bydefault, 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 procedurewill run somewhat faster This is not a consideration with our simple procedures
2.7 Dimensioning arrays
We saw in chapter1that the statement Dim Vel(3) generates a one-dimensionalarray with three elements Similarly, a two-dimensional array with four rows andthree 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), andVel(2) Likewise, the element in the third row, second column of myMatrixwould 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 inthe declaration So Dim Vel(1 to 3) would give us the elements Vel(1),
Trang 33Vel(2),and Vel(3) This is moreflexible than the option method since we can use,for example, ZeroStart(4), which would have indices 0, 1, 2, and 3; whileStrange(5 to 8)would have indices 5, 6, 7, and 8 A two-dimensional array offour 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 thiscase we declare it with no size, as in ThisArray() Before we can add values to theelements of ThisArray we must tell VBA what size to use; this is done with aRedimstatement
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 arrayand then a computation is used resulting in an output similar to (but not identical to) theworksheet FREQUENCY function The reader may wish to work out how and why theydiffer The output is on Sheet2, seefigure2.4; click the ball to run the procedure Notethat 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
Trang 342.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 oftyping 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 subfinds values in column A of Sheet2 (see figure2.4) that aregreater than 50 and copies them to Sheet3 The Set command creates a newworksheet object pointing at the sheet of interest The output of the sub is shown infigure2.5
Sub OverFifty()
Worksheets(“Sheet2”).Activate
Set Target = Worksheets(“Sheet3”)
lastrow = Target.Cells(Rows.Count, “A”).End(xlUp).RowKillrange = “A1:A” & lastrow
Target.Range(Killrange).ClearContents
Target.Range(“A1”) = “50 and over”
Figure 2.4 Output from the MyFreq subroutine.
Trang 35j = 1
For k = 2 To WorksheetFunction.Count(Range(“A:A”))
If Cells(k, “A”) >= 50 Then
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) WithWorksheet(“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 (seefigure2.4) that are under 50 to column B of Sheet3 The output of the sub is shown infigure2.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”))
Figure 2.5 Output from subs.
Trang 36If Cells(k, “A”) < 50 Then
j = j + 1
With Worksheets(“Sheet3”)
.Cells(j, “B”) = Cells(k, “A”)
Trang 373.1 Branching structures (If and Select Case)
Branching structures present the program with various paths to follow depending onthe value of one or more variables
VBA has three branching structures: GoTo, If…Else, and Select Case Wehave 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 squarebrackets are optional
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 Figure3.1showsthe 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 threestatements separated by colons Note also the use of Or and And in the conditions
Trang 38The Debug.Print statements are used to help us see how the macro behaves; theresults go to the Immediate window of the VBE, seefigure 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
Figure 3.1 Sheet1 of Topic3.xlsm.
Figure 3.2 Example of the Immediate window.
Trang 39Tritype = “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 determinethe number of real roots of a quadratic equation ax2+bx +c=0; see row 6 offigure 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 thenumber of roots and their values; this uses an array within the VBA and, sincethree values are returned, we must enter the function call on the worksheet usingCTRL+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)
Case 0: RootCount = 1 Select Case Disc
Case Is > 0: RootCount = 2 Case Is < 0
Case Else: RootCount = 0 temp(1) = “No real”
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
Trang 403.2 Looping structures (For …Next and Do…While/Until)
Looping structures cause a group of statements to be executed several times TheFor…Next structure is generally used when the number of iterations needed is aknown 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 twoUDFs
k = 2
Do While k < Sqr(n) + 1
If n Mod k = 0 Then IsPrimeB = “Not a prime” Exit Do
End If
k = k + 1 Loop End Function
The syntax for For…Next is
For counter = first To last [Step step]
Figure 3.3 The quadratic solver on Sheet2.