81
Chapter 2 Visual Basic for Applications – Excel 2007 2.1 Writing VBA Code When an EXCEL workbook is opened, a project is created which consists of Worksheets, modules of various types and any forms created by the program- mer. Code is written in modules. There is a module for each sheet and a general module, but user-defined code is most often written in separate modules. The code can then be exported and saved to a file, and imported into other workbooks. Modules are written in the Visual Basic Editor (VBE). The VBE can be called up from Excel by Alt-F11. Pressing Alt-F11 again gets one back to Excel. The Menu item in Excel Developer | Codes | Visual Basic can also be used to transfer to the IDE from Excel. A code module consists of two parts, a Declarations section right at the top, followed by a line and a remaining part below the line where code for routines is written. The Declarations section can be blank. It contains options and declarations of global properties of variables. The VBA Project Window in the VBE shows a tree of the various parts of your current project. The Project Window can be loaded into the VBE from the View menu button. To create a module in the project click an item in the project and use the Insert menu. 1

Tutorial excel

  • Upload
    marcial

  • View
    28

  • Download
    6

Embed Size (px)

DESCRIPTION

Tutorial excel

Citation preview

Chapter 2

Visual Basic for Applications –Excel 2007

2.1 Writing VBA Code

• When an EXCEL workbook is opened, a project is created which consists ofWorksheets, modules of various types and any forms created by the program-mer.

• Code is written in modules. There is a module for each sheet and a generalmodule, but user-defined code is most often written in separate modules.The code can then be exported and saved to a file, and imported into otherworkbooks. Modules are written in the Visual Basic Editor (VBE). The VBEcan be called up from Excel by Alt-F11. Pressing Alt-F11 again gets one backto Excel. The Menu item in Excel Developer | Codes | Visual Basic can alsobe used to transfer to the IDE from Excel.

• A code module consists of two parts, a Declarations section right at the top,followed by a line and a remaining part below the line where code for routinesis written. The Declarations section can be blank. It contains options anddeclarations of global properties of variables.

• The VBA Project Window in the VBE shows a tree of the various parts ofyour current project. The Project Window can be loaded into the VBE fromthe View menu button.

• To create a module in the project click an item in the project and use theInsert menu.

1

2 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

• When working with both EXCEL sheets and the VBE, it is sometimes con-venient to press the middle button at the top right of each of these windowsand to tile the two one above the other by moving them and adjusting theborders. Double clicking at the top bar of one of the windows expands (orcontracts) the window.

• Three useful windows which can be included in the VBE display are:Locals Window – shows how all the variables in procedures change duringruntimeImmediate Window – commands entered here are immediately executedWatch Window – allows you to monitor specific variables during execution.These windows can be docked into your VBE window from the View menu.If it becomes undocked, it can be redocked by double clicking the bar at thetop of the window.

Figure 2.1: The VBE Screen

2.2. FUNCTIONS, SUBROUTINES AND VARIABLES 3

2.2 Functions, Subroutines and Variables

Contents: Functions, Subroutines, Variables, Examples of a function and Sub,Built-In Functions, Looping, Conditional Statements, Arguments and returnvalues of functions.

• There are two types of user-definable procedures: functions and subroutines(subs).

• Functions. A function can return a value (if it does not, there is a defaultvalue that it returns). User defined functions are defined (programmed) in amodule. Once defined, a function can be used to enter values in EXCEL cells,in the same way as e.g. =SIN(180), or it can be used in other functions andsubs. In addition, there are system defined functions like LOG(). There aresuch functions in both EXCEL and VBA. Many of the EXCEL functions arealso available in VBA. A function may NOT directly alter the characteristicsof the spreadsheet (colour, value, ...) other than by using it as a formula ina cell (by inserting =fn(x).) The purpose of a function is to calculate a value(and possibly to write it to EXCEL.)

• Subs A subroutine does NOT return a value through its name as is the casewith functions. It MAY alter the characteristics of a spreadsheet, and can becalled from the spreadsheet, for example by going to the Developer | Code |Macro menu. (Subs are also called macros.)

• A ’ at the beginning of a line indicates that the line is a comment.A space followed by an underscore at the end of a line indicates that theline is continued on the next line.

2.2.1 Variables

• Variable names begin with a letter (uppercase or lowercase) and continue withletters or numbers or underscore . Variable names are not case sensitive.

• Each variable has a type. Some of the principal types are Integer, Long, Single,Double, Boolean, String, Variant. (Long is an integer type, Double is areal number type with double precision, Boolean can take values True, False).

• The Variant type is a sort of hold-all, and all the other types can be ac-commodated in it. The type of a variable need not be declared (unless

4 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Option Explicit is set - see below), and if the type is not declared, it isautomatically of type Variant. The Variant type sets aside more memoryspace than other types. At some stage, it is converted to house the actualvariable (of whatever type.) A useful application of Variant types is whendata is requested from a user which could be text or numeric. Putting it intoa Variant typed variable allows either format.

• The Declarations (first section) of a module can contain Option statementsand certain variable declarations. A very useful option is

Option Explicit

This makes it compulsory for a variable to be either an argument of a func-tion or sub, a function name or to be declared in a Dim dimension statement.(Note that a function name is automatically declared (without a Dim state-ment), with type as stated at the end of the function declaration line andthe arguments are also automatically declared but a sub name is NOT.) Thedimension statement is of the form

Dim Str,Int,Rl

where Str,Int,Rl are variable names – the types of the variables are not de-clared in this form so the three variables are of Variant type. Alternatively

Dim Str As String, Int As Integer, Dbl As Double, Var

types all the variables except for Var, which is then of Variant type by default.Dbl is a double precision real number.

Note: You cannot use Dim Str1,Str2,Str3 As String.

• Scope of variables: If a variable is declared in the Declaration section it isglobal to whole module. If it is declared in a function/subroutine it is localto the subroutine. If it is declared as Public in the Declaration section, forexample by

Public Dim Rope As String

then it can be used in other modules/workbooks. If it is declared as Privatein the Declaration section then it can be used only by the routines in themodule. If it is declared as Static, it persists between calls of functions inthe module, and maintains its value.

• Variables have default initial values (0 for numeric variables, the empty string"" for strings, and so on.)

Note: 1. Option Explicit can be made to appear automatically in all modulesby setting the VBE menu Tools|Options|Editor tab, and ticking the checkbox

2.2. FUNCTIONS, SUBROUTINES AND VARIABLES 5

Require Variable Declaration.2. It is often good practice to have one or more capital letters in a variablename – when typing it in the VBE, type it in small letters and the VBEchanges it to the form with capital(s) enabling you to guard against mistakes(there will be no change if you have misspelled the variable name.)

2.2.2 An example of a user-defined function

The procedure QMinus below calculates the solution of the quadratic equation

Ax2 + Bx + C = 0

given by

x =−B −

√B2 − 4AC

2A

for the case A 6= 0, B2 − 4AC ≥ 0. Very little error checking is done. QPlusbelow calculates the other root. A more complete quadratic equation solverwill be the subject of a later exercise.

Function QMinus(A As Double, B As Double, C As Double) As Double

Dim Delta As DoubleDelta = B*B−4*A*C

If Delta >= 0 Then QMinus = (−B−SQR(Delta))/2*AElse QMinus = 999999

End Function

• Variables A,B,C need not be declared in a Dim statement, and have typesdouble here.

• The same holds for the variable QMinus (typed As Double at the end ofline 1). Omission of the typing results in Variant variables.

• This is a ”one-line” If-Then-Else statement - a multiline version will ap-pear later.

• SQR is a VBA function doing the same work as SQRT in Excel.

• SQR is not available in Excel, and SQRT is not available in VBA.

• QMinus, the function name, is assigned a value and this is the return value ofthe function. If you use the function, (for example =QMinus(1,2,3) in anExcel cell), then the final value of the variable QMinus is the value returned.

6 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Function QPlus(A As Double, B As Double, C As Double) As Double

Dim Delta As DoubleDelta = B*B−4*A*C

If Delta >= 0 Then QPlus = −QMinus(A,B,C) + B/AElse QMinus = 999999

End Function

To test the function, tile EXCEL and VBE and enter in the Immediate Win-dow

Range("C1") = QMinus(1,-3,2)Range("D1") = QPlus(1,-3,2)Debug.Print QPlus(1,-3,2)MsgBox QMinus(1,-3,2)

Enter in the EXCEL sheet

=QMinus(1,-3,2) in C2=QPlus(1,-3,2) in D2

• If there are errors, the program will stop. Try to correct them and thenpress the button with a triangle in the VBE to continue or the button with asquare to stop. You can stop before a line by clicking in the left margin nextto the line and running the function. A dot appears in the margin next tothe stoppage line. You can watch the variables at that time by looking in theLocals window or setting a watch in the Watch window. Click the triangleto run the function in which the cursor is sitting, or to continue. You canrun the function step by step by successively pressing F8. See the section onDebugging for further information.

• To exit from a function before the last statement use:

Exit Function

• The words Public or Private before the word Function in the declarationindicates, in the case of Public, that the function is usable outside the codemodule and in the case of Public that it is not. The default is Public.

2.2.3 User-defined sub procedures

To access and change the WorkBook cells, we must use the object-orientedaspects of VBA. This can be done by sub procedures. Function procedureshave limited ability to change the spreadsheet.

2.2. FUNCTIONS, SUBROUTINES AND VARIABLES 7

• For Help on an identifier (e.g. Pattern or ColorIndex), place the cursor onthe identifier in the VBE and press F1.

• A Subroutine has the form

Sub MySub(A As Double, B As String)Dim C As IntegerRange("A1").Value = "Value" ’ "Value" is a string

End Sub

More generally, there can be more than one Dim statement and more thanone line assigning to variables and evaluating functions and subs and usingmethods and setting properties.

• Remember that MySub is not available immediately as a variable, in contrastto the case of functions.

• For examples of manipulating ranges and cells see the forthcoming section onworking with ranges and cells in VBA.

• To exit from a sub before the last statement:

Exit Sub

• to call or run a sub from within another sub use:

MySub 2.34,"fine"

or

MySub A:=2.34,B:="fine"

There are other ways of calling subs. There is a method using Call but thisis undesirable. Sometimes subs (or methods) must be run using a bracketnotation for the arguments. This is discussed further in the section on Objectsbelow.

• The sub can be declared as Public or Private as for functions, with defaultPublic.

2.2.4 Built-In functions

There are built-in functions in both VBA and Excel.

• One can use both, in VBA, except for a few Excel functions that are inboth VBA and Excel, and for which only the VBA version can be used.

8 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

• To find a list of built-in VBA functions. Click Help, the Index taband type Math in the box. Then press Enter and click on Math Functions.There is also an item Derived Math Functions, but these must be enteredby the user as composites of the standard functions - they do not exist ontheir own. Another route:

Help|Contents|VisualBasic Language References|Groups|Maths Func-tions.

• Using EXCEL Functions in VBA. The correct way is to prefix thefunction by

Application.WorksheetFunction

and then use the EXCEL function name. It will also work if WorksheetFunctionis omitted or if Application is replaced by Excel. Such a prefix is lengthy.If you need to use it several times in a module, you can put the followingin the Declarations section:

Dim WSF as WorksheetFunction

In any function which uses EXCEL functions, you can put the statementSet WSF = Application.WorksheetFunction

Then, for example,WSF.cosh(2)

will give you the value of cosh 2. If you get some error, check that thefunction you use is actually allowable for use in VBA.

• To enter a Formula into a Cell from VBAIt is often necessary to do calculations on the worksheet rather than inVBA. An example of this is in the use of Solver routines, which requireits inputs to be calculated by EXCEL formulae evaluated in cells.To enter a formula from VBA which will output to a single cell, use thefollowing format:

Activesheet.Range("A1").Formula = "=NormSInv(Rand())”The formula is evaluated and the result placed in cell A1.To enter a formula from VBA which will output an array, use the followingformat:

Activesheet.Range("A1:A5").FormulaArray = "=MMult(C1:G5,I1:I5)"

The formula is evaluated and the result placed in range A1:A5.

2.2.5 Looping

The following is the most common looping structure:

2.2. FUNCTIONS, SUBROUTINES AND VARIABLES 9

Dim i as Integer, a As DoubleFor i = 1 to 10

a = a + i(other statements)

Next i

The i in Next i may be omitted. Other structures are

Do While (condition) ... LoopDo Until (condition) ... LoopDo ... Loop Until (condition)Do ... Loop While (condition)

where (condition) is an expression which must evaluate to either True orFalse.

For looping through object collections (see later) use

For Each . . . Next

2.2.6 Conditional Statements

The following illustrate the multiline If-Then-Else statement, the single lineversion and the Select Case statement.

Multiline If-Then-Else

Dim Number, Digits, MyStringNumber = 53 ’ Initialize variable.If Number < 10 Then

Digits = 1ElseIf Number < 100 Then

’ Condition evaluates to True so the next statement is executed.Digits = 2

ElseDigits = 3

End If

Single Line If-Then-Else

’ Assign a value using the single-line form of syntax.If Digits = 1 Then MyStr = "One"ORIf Digits = 1 Then MyStr = "One" Else MyStr = "More than one"

Select Case

10 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Dim NumberNumber = 8

’Initialize variableSelect Case Number

’ Evaluate NumberCase 1 To 5

’ Number between 1 and 5, inclusiveDebug.Print "Between 1 and 5"

’ The following is the only Case clause that evaluates to True.Case 6, 7, 8

’ Number between 6 and 8Debug.Print "Between 6 and 8"

Case 9Debug.Print "Number is 9"

Case Else’Other values

Debug.Print "Not between 1 and 9"End Select

Note: In the phrase Select Case Number we could replace Number by anyvariable or expression that evaluates to a number or a character string.

2.2.7 Arguments and Return Values of Functions

A function returns a value, and this can be used in a cell to assign a value,e.g. =f(q). You may want to return several values from a function or sub foruse in another function or sub.

• A function declaration is of the formFunction functionname(var1 As Integer, var2, var3() As Single,

Optional var4 As Double) As Boolean

◦ If the type is not declared, then a variable is of type Variant.◦ functionname, var1, var2, var3, var4 are all available for use in the

body of the function, and cannot be dimensioned with Dim or ReDim.◦ Variable var3() is an array argument which takes its dimension from the

input array at runtime - see the section on arrays later.◦ functionname can be assigned a value in a function - in this case a

Boolean value. If we had omitted As Boolean then functionname wouldhave been of type variant. See below for discussion of optional variables.

◦ If we have a sub declaration, then it must be of the form:

2.2. FUNCTIONS, SUBROUTINES AND VARIABLES 11

Sub subname(var1 As Integer, var2, var3() As Single, Optionalvar4 As Double)subname is not automatically a variable which can be used, and needNOT be assigned a value.

◦ When using a function, make sure that the constants or variables assignedto each argument are of the correct type as given in the declaration. Forexample, it cannot be that one is of type Double and the other typeVariant.

• Calling arguments by Reference and by Value

Function or Sub arguments are called by Reference. This means that theaddresses of the arguments are passed to the function. Whatever is in theseaddresses is used. If the values of the variables are changed by the functionor sub, then these new values are stored in the addresses, whose values as aresult are changed. In this way you can return values to another function orsub - set the variable to contain the returned values in the calling sub withDim statements, and make them arguments to the function or sub called.If you do not want the argument in the calling function or sub to changethen call the arguments by value:

Sub gh (ByVal N As Integer) . . . End Sub

This passes only the values (in a temporary copy) to the calling procedure.Since the function does not know the address of the variable that is passed,the value of the variable cannot be changed by the function. Arrays can-not be passed as ByVal arguments to a function or sub. In the followingexample, the values of a,b,c at the end of the sub tt are 3.1, 0 and 7.1respectively. (Note that since call by reference is the default, the inclusionof ByRef in the first line of function tt is unnecessary.)

Function tf(ByRef a As Double, ByVal b As Double) As Doublea=3.1b=4.1tt=7.1End Function

Sub tt()Dim a As Double, b As Double, c As Doublea = 0b = 0c = 0c = tf(a,b)End Sub

12 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

2.2.8 Optional Arguments

In the functions we have been writing, all arguments are compulsory, that is,they must be supplied. It is possible to make some arguments optional byusing declarations of the form:

Function Opt(intNumber As Integer, Optional strWord As String)

Then legal calls are of the form var=Opt(1,"go") and var=Opt(1). If Opt isa sub, then use

Sub Opt(intNumber As Integer, Optional strWord As String)Opt intNumber:= 1, strWord:= "go"Opt intNumber:= 1

All compulsory arguments should go before the optional ones, to enable oneto use the Opt(1) form, since the called arguments must appear in order, andit may not be clear what is omitted.

To test whether an optional argument has been used, the IsMissing booleanfunction can be used in the function or sub provided that the variablehas Variant type:

If IsMissing(strWord) Then GoTo Stop

If the variable does not have type Variant then one can assign a default valueto the variable and then check in the procedure whether the variable still hasthe default, in which case it is missing:

Function Opt2(intN As Integer, Optional strW As String = "Default1")If strW="Default1" Then GoTo Stop

• It is also possible to have as arguments a variable number of parameters byusing the ParamArray argument. See below.

Parameter Arrays as Arguments - Passing a Variable Number ofArguments

This section requires arrays and should be read after the later section onarrays, but the material is relevant to this section. A parameter array canbe used to pass an array of arguments to a procedure. One does not have toknow the number of elements in the array when you define the procedure.

2.2. FUNCTIONS, SUBROUTINES AND VARIABLES 13

One uses the ParamArray keyword to denote a parameter array. The arraymust be declared as an array of type Variant, and it must be the last argumentin the procedure definition.

The following example shows how one might define a procedure with a pa-rameter array.

Sub AnyNumberArgs(strName As String, ParamArray intScores() AsVariant)

Dim i As Integer

Debug.Print strName; " Scores"’ Use UBound function to determine upper limit of array.For i = 0 To UBound(intScores())

Debug.Print " "; intScores(i)Next

End Sub

The following examples show how you can call this procedure.

AnyNumberArgs "Jamie", 10, 26, 32, 15, 22, 24, 16

AnyNumberArgs "Kelly", "High", "Low", "Average", "High"

Note: Another way of passing a variable length argument list is to declare saythe last argument of a function or sub as a Variant. Then feed the argumentsinto the variable by feeding in an array. One can then use the above procedurewith Ubound to find out how many arguments have been passed and accessthem as above. This has many advantages as a range object can be passedto the variant and its values are then available to the function. However, seethe function maxRange below for another method.

Further Examples

The function maximum illustrates the writing of a program with an arbitrarynumber of variables. The function hypotenuse avoids squaring large numbersand then taking their square root, thereby reducing the possible sizes of theinputs. The function maxRange inputs a range of cells and finds the numberof rows and columns in the input. This is useful for inputting data.

Function maximum(ParamArray inputs() As Variant)Dim i As Integer

maximum = inputs(0)

14 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

For i = 1 To UBound(inputs())If inputs(i) > maximum Then maximum = inputs(i)

NextEnd FunctionFunction minimum(ParamArray inputs() As Variant)Dim i As Integer

minimum = inputs(0)For i = 1 To UBound(inputs())

If inputs(i) < minimum Then minimum = inputs(i)NextEnd Function

Function hypotenuse(x As Double, y As Double) As DoubleDim temp As DoubleIf x > y Thentemp = y / xhypotenuse = x * Sqr(1 + temp ^ 2)Elsetemp = x / yhypotenuse = y * Sqr(1 + temp ^ 2)End IfEnd Function

Function maxRange(strRange As String) As DoubleDim ran As Range, i As Integer, j As IntegerSet ran = Range(strRange)maxRange = ran.Cells(1, 1)For i = 1 To ran.Rows.Count

For j = 1 To ran.Columns.CountIf ran.Cells(i, j) > maxRange Then maxRange = ran.Cells(i, j)

Next jNext iEnd Function

Sub tstmax()Dim m As Double, h As Double, r As Doublem = maximum(1, 2, 3, Application.Pi())h = hypotenuse(311111111111, 411111111111)r = maxRange("A1:E2")End Sub

2.2. FUNCTIONS, SUBROUTINES AND VARIABLES 15

2.2.9 Running a function whose identity is passed to anotherfunction

We often have to pass a function (or sub) to another function (or sub). Forexample, in Newton’s method, we need to tell the function implementingthe method which function to use for in order to find the root and what itsderivative is. We would like to pass this as an argument. There is a VBAfunction Run which takes as first argument the string that is the functionname and as subsequent arguments the arguments of the function to be run.The output is the value that would have resulted had we run the function inthe normal way. We give an example.

Function newt(fn As String, fnder As String, N As Integer, guess As Double) _As Double

Dim i As Integer, z As Double, y As Double z = guessFor i = 1 To N

y = Run(fnder, z)If y = 0 Then

Exit FunctionElse

z = z - Run(fn, z) / yEnd If

Next inewt = zEnd Function

Function qd(x As Double) As Doubleqd = x ^ 2 - 3End FunctionFunction qdder(x As Double) As Doubleqdder = 2 * xEnd Function

Sub tst() ’Calculates the square root of 3 by Newton’s MethodDim d As Doubled = newt("qd", "qdder", 100, 3)End Sub

16 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

2.3 Working with Ranges and Cells in VBA

• The following indicate how to refer to Range and Cells objects and theirproperties:

Object DescriptionApplication The entire EXCEL spreadsheet that is currently open

The default value (when omitted) is the current workbookSheets("Sheet2") WorkSheet named Sheet2 of current application

The default value (when omitted) is the current active sheetRange("A1:B3") The cells in this rangeRange("A1").Name e.g. Range("A1").Name = "X"Range("A1").Formula e.g. Range("A1").Formula = "=C1"Range("A1").Value e.g. Range("A1").Value = 1.2

(Value may be omitted after Range, as it is the default)Range("A1").Font.Name = "Times New Roman"Range("A1").Font.Size = 11Range("A1").Font.Fontstyle = "Bold"Range("A1").Font.Superscript = TrueRange("A1").Font.Subscript = FalseRange("A1").Font.ColorIndex = 4

1=black;2=white;3;4;5=R;G;B (Look up ColorIndex in VBE Help)Range("A1").Interior.ColorIndex =5 ColorIndex is a property of InteriorRange("A1").Interior.Pattern See VBE Help under PatternRange("A1").Interior.PatternColorIndexRange("A1").Borders(xlEdgeRight) See HelpRange("A1").Borders.LineStyle = xlContinuousRange("A1").Borders.Weight = xlThickRange("A1").Borders.ColorIndex = 3With Range("A1").Borders Way to avoid repeating prefixes

.LineStyle = xlContinuous

.Weight = xlThick

.ColorIndex = 3var = .ColorIndex Assigns the value of ColorIndex to a variable

End WithRange("B2:C5").BorderAround weight:=xlMediumCells(i,j) The row i, column j cell of the active worksheet

Note that the indices are 1-basedCells(3,2) Cell B3Range("B2").Cells(2,3) D3Range("B3:C10").Cells(i,j) Cell (i,j) relative to B3 as (1,1)

2.3. WORKING WITH RANGES AND CELLS IN VBA 17

So this is the cell in the 2 + i row, 1+j columnRange(Cells(2,3),Cells(4,5)) Another way of writing C2:E4

• Tile EXCEL and the VBE and enter variations of the above property settingsin the Immediate Window.

• The Cells Property and Looping through CellsA way of referring to cells and ranges is with the Cells property. See examplesin the previous list. This may be used, for example, to loop through a rangeof cells:

For i = 1 To 10For j = 1 To 12matrix(i,j) = Range("B2").Cells(i,j).ValueNext

Next

Alternatively:

For i = 1 To 10For j = 1 To 12matrix(i,j) = Range(Chr(Asc("B") - 1 + j) & i).ValueNext

Next

where Chr() converts a positive integer to the character with that number inthe ASCII character set and Asc() converts a character to its number in theASCII character set.

• The property Value of the Range object is the default property. Thus Range("A1").Valueand Range("A1") both return the Value property value.

• To get some idea on how to do spreadsheet tasks in VBA, you can do theprocess in EXCEL while recording the code Excel uses in a module. The codeis almost always cumbersome and NEEDS MUCH EDITING to get it concise.

◦ In EXCEL, use the menu items in Developer | Code.

◦ Enter a name for the Macro (Subroutine), click OK and do your tasks.

◦ Stop Recording.

◦ Go to the VBE and look at the modules. One of them will have the codeof your tasks.

◦ To view all the colours referenced by ColorIndex, run the following sub,after changing ”Sheet3” to the sheet that you would like to use:

18 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Sub colors()Dim i As Integer, j As IntegerWith Sheets("Sheet3")

With Range("G5").Value = "Colorindex".Font.fontstyle = "Bold".Columns.AutoFit.Interior.ColorIndex = 15

End WithFor j = 1 To 20

.Cells(j, 1).Interior.ColorIndex = jNext For j = 1 To 20

.Cells(j, 3).Interior.ColorIndex = j + 20NextOn Error GoTo endprocFor j = 1 To 20

.Cells(j, 5).Interior.ColorIndex = j + 40NextEnd Withendproc:End Sub

• The following sub draws a border around a range selected and colours it withcolour number index.

Sub colourborderrange(index As Integer)With Selection

.BorderAround Weight:=xlMedium, LineStyle:=xlContinuous

.Interior.ColorIndex = indexEnd With

End Sub’With ... End With enables one to avoid repetition of parts of a statement

To run this, select a range in EXCEL and enter in the Immediate Window:

colourborderrange 5

Alternatively, we could replace the first two lines by

Sub colourborderrange(index As Integer, strRng As String)With Range(strRng)

2.4. USING ARRAYS IN VBA 19

which does the same for the range which is the contents of strRng (such as"B2:C5") instead of a selected range.

2.4 Using Arrays in VBA

1. Dimensions and Typing

• Arrays have lowest index 0 unless the declaration

Option base n

is placed in the declarations section (all arrays then have lowest index n)

• Dim StrVect(5) As Stringdeclares a vector of 6 elements (0, 1, 2, 3, 4, 5) of type string.

• Numeric Arrays are initialised to have the value 0 and string Arrays areinitialized to "".

• Multidimensional Arrays are available e.g.

Dim iArray(3, 4, 5) As Integer

• More flexible indices are possible e.g.Dim iArray2 (2 to 5, 3 to 7, 8 to 13) as Integer

• The statementDim vntArray(3)

creates an array of 4 elements of type Variant.

• Dynamic Assignment

Dim dArray( ) As Double

allows one to dimension the array later. For example if (positive) integervariables are calculated or read as input (M, N say) then a later statement

ReDim dArray(M, N)

results in an array with these dimensions. The Dim statement cannot containvariables (like M,N).

• There are functions

ubound(arrayname, number of index from left)

and

lbound(arrayname, number of index from left)

20 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

The function

ubound(dArray, 2)

above yields the value in N. The function call

lbound(iArray2, 3)

has value 8. For a dynamic array, we can use

Redim dArray(ubound(iArray2,2))

• Passing Arrays to Other Subs

The best way usually is to use an extension of the following code fragment:

Sub CallingSub ()Dim e() as DoubleRedim e(7)CalledSub e

’e() is here the previous array e(7) after processing by CalledSub.’The values have been stored in d() (hence in e) since the variable’d is called by reference in CalledSub.

End Sub

Sub CalledSub (d() as Double)Dim i As IntegerFor i = 1 to Ubound(d,1)

’Do something with array d()Next

End Sub

• Assigning Values to ArraysWe consider two cases:

◦ The object to which values are assigned is NOT a Range in theSpreadsheetIt is then best to assign values component by component, although underspecial circumstances, it is possible to use a block method (see below).

The following is RECOMMENDED:

Sub imprt(A() As Double)

2.4. USING ARRAYS IN VBA 21

’If A is an MxN array, the values assigned to it’are the MxN values of the cells in the block starting’at D1

Dim i As Integer, j As Integer

For i = 1 To UBound(A, 1) ’assuming base 1 is usedFor j = 1 To UBound(A, 2)

A(i, j) = Range("D1").Cells(i, j).ValueNext

NextEnd Sub

The following type of block assignment is legal but NOT RECOM-MENDEDThe reason for not recommending this method is that large variant arrays cantake up a great deal of space. It is feasible for medium sized arrays.

Dim A As VariantA = Range("A1:B2").Value

If you wish to assign an array directly, do not dimension A or use A(1)= 2etc before assigning the array to A. Also, A must be of type Variant if youassign worksheet values in a block of cells directly to A.

Function VarAssgn (q as Variant)’Values of a 3× 1 range of cells will be passed to q

Dim v as Variant, i as Integer, d() as Doublev = q ’v is a variant containing a 3× 1 array!ReDim d(ubound(v,1))

For i = 0 to ubound(v, 1)d(i) = v(i, 1)

Next iVarAssgn = d

End Function

The output of VarAssgn is of type Variant.

22 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

◦ The object to which values are assigned IS a Range in the Spread-sheet

Provided that the shape of the input and output is the same, the assignmentcan be made directly.

However, there are some problems:EXCEL needs to distinguish between a row vector in a sheet, and a columnvector. It does this by regarding

A row vector as a 1× n arrayA column vector as an n× 1 array.

So, even if the spreadsheet range to which we are assigning is part of a singlecolumn, say, the array whose values we assign to it must be an n× 1 array.

In VBA, we can use this principle to make input and output more compact,as in the following example which calculates the path of the asset price in theBlack-Scholes model, and places the vectors calculated in the range ”A1:EN”where N is the number of points on the path (an input) and S, rate, sigmaand dt are inputs representing initial price, risk-free rate, volatility and stepin the path. Try it out, and note carefully how the arrays are handled.

Sub calc(S, rate, sigma, N, dt)

Dim i As Integer, t()As Double, w() As DoubleDim x()As Double, u()As Double, rd() As DoubleReDim t(N, 1 To 1), w(N, 1 To 1), x(N, 1 To 1),

u(N, 1 To 1), rd(N, 1 To 1)

rd(1, 1) = Application.Worksheetfunction.NormsInv(Rnd)t(1, 1) = 0w(1, 1) = 0x(1, 1) = Su(1, 1) = S

For i = 2 To Nrd(i, 1) = Application.Worksheetfunction.NormSInv(Rnd)t(i, 1) = t(i - 1, 1) + dtw(i, 1) = w(i - 1, 1) + rd(i, 1) * Sqr(dt)x(i, 1) = x(i - 1, 1) * (1+ rate * dt + sigma *

(w(i, 1) - w(i - 1,1)))u(i, 1) = u(1, 1) * Exp((rate - 0.5 * sigma ^ 2) * t(i,1)

+ sigma * w(i,1))

2.4. USING ARRAYS IN VBA 23

Next i

Range("A1:" & "A" & N).Value = rdRange("B1:" & "B" & N).Value = tRange("C1:" & "C" & N).Value = wRange("D1:" & "D" & N).Value = xRange("E1:" & "E" & N).Value = u

End Sub

We could equally have done the output using cells(i,j) and a loop.

• We could have just used one-dimensional arrays x(N) and so on and in thefinal statements writing to a range we could have then usedRange("A1:" \& "A" \& N).Value =Application.Transpose(rd)and so on.

• To enter an Array Formula from VBATo enter a formula into a cell from VBA which will output an array, use thefollowing format:

Activesheet.Range("A1:A5").FormulaArray ="=Application.MMult("C1:G5","I1:I5")"

The formula is evaluated and the result placed in range A1:A5.

Using a 1-dimensional array-valued VBA function in EXCEL cells:

◦ When a 1-dimensional array (vector) occurs in a function or sub, it is AL-WAYS regarded as a row vector when written to the spreadsheet.

◦ Even if you transpose (Application.Transpose(v)) the vector v and assignit to the function name and then use the function in a spreadsheet, it willoutput a row vector.

To enter a 3-vector which is the output of function f(q) into your spreadsheet,select a 1× 3 set of cells, enter =f(q) and (simultaneously) press

Ctrl-Shift-Enter

To enter it as a column, select the 3× 1 column and enter

=TRANSPOSE(f(q))

and then

Ctrl-Shift-Enter

24 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Alternatively in a VBA sub enter, for example (if v is dimensioned as v(N))

Worksheets("Sheet1").Range ("C4:C6")=Application.Worksheetfunction.Transpose(v)

• Obtaining arguments from a Range (see also previous section onParamArrays: This example illustrates the techniques, but Sub Square isclearly not a good way to square a matrix. For abbreviation, it has beenwritten to square 2× 2 matrices.

Sub squared()Dim B(1 To 2, 1 To 2) As Double

B(1, 1) = 1B(1, 2) = 2B(2, 1) = 3B(2, 2) = 4square BRange("G1:H2") = B

End Sub

Sub square(A() As Double)Dim i As Integer, j As Integer

Range("A1:B2").Value = ARange("D1:E2").Value=Application.WorksheetFunction.MMult _

(Range("A1:B2"), Range("A1:B2"))

For i = 1 To UBound(A, 1)For j = 1 To UBound(A, 2)

A(i, j) = Range("D1").Cells(i, j).ValueNext

NextEnd Sub

2.5 Further VBA

Contents: Using Help, Communication with the user, Input from the user,Constants, User-defined Data Types, Timing Code, Running Subs from buttons,

2.5. FURTHER VBA 25

Setting passwords, Creating Add-Ins.

Read and experiment with the following VBA structures and func-tions.

• Use the VBE Help by entering a keyword in a module, putting the cursorover it and pressing F1.

• Communication with the user can be made with

MsgbBox prompt:= . . . , title:= . . .

where prompt is required, but title is optional. There are more optionalarguments, but these are not dealt with here.

Call msgbox (prompt:= "Hi", title:= "Hello")

is another calling method which should, however, not be used.

• To get input from the user, one way is to use a pop-up box Inputbox.Find out how to use it and experiment. There are several other ways to getinput from the user:

◦ From the EXCEL sheets.

◦ Through a UserForm (see later).

◦ All these methods can be activated from a button on the sheet. See laterin this section.

• How to specify an unchanging constant like π:

Const pi As Double = 3.14159

The text As Double is optional. Constants declared in a Sub, Function,or Property procedure (see the section on Class Modules) are local to thatprocedure. A constant declared outside a procedure is defined throughout themodule in which it is declared. You can use constants anywhere you can usean expression.

• User-Defined Data Types

This example uses the Type statement to define a user-defined data type.The Type statement is used at the module level only and cannot be definedwithin a procedure. If it appears in a class module (see later section), a Typestatement must be preceded by the keyword Private.

26 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Type EmployeeRecord ’Create user-defined type.ID As Integer ’Define elements of data type.Name As String * 20Address As String * 30Phone As LongHireDate As Date

End Type

Sub CreateRecord()Dim MyRecord As EmployeeRecord ’Declare variable.

’Assignment to EmployeeRecord variable’must occur in a procedure.

MyRecord.ID = 12003 ’Assign a value to an element.MyRecord.Name = "Bob"

End Sub

• Timing Code

Use the following to time the execution of a block of code:

StartTime = timer(code)

EndTime = timerTotalTime = StartTime - EndTimeRange("A1").value = TotalTime

This places into cell A1 the time taken in seconds to execute the code.

• Running subroutines from a Button

◦ This method uses a button on the Forms toolbox.

◦ Activate a worksheet

◦ Go to Developer | Controls | Insert, click the Button on the Forms sectionand them click a cell in the Worksheet. The button appears there, and abox appears asking you to assign a macro. Give the name of one of thesubroutines you have written in your code modules.

◦ Click on another cell. Then click your button. The macro will run.

◦ To change the button caption, right click on the button, highlight the cap-tion with left button and change it.

2.5. FURTHER VBA 27

◦ Right click on the border of the button. Choosing Assign Macro will allowyou to change the macro. Choosing Format Control will allow you to formatsome aspects of the button. Resizing can be accomplished by using the sizehandles.

Subroutine with Arguments

◦ You must insert the button from the Control Toolbox. Do so. Go intoDesign Mode by making sure the toolbar button with the blue triangle isclicked. Double click the button. A code window appears with a subroutinewhich runs whenever the button is left - clicked. In the subroutine enter

YourSub arg1:= . . . , arg2:= . . .

◦ Click the Properties button of the Control Toolbox. Change the Captionproperty to your desired caption. Click the blue triangle button on the tool-bar if necessary to turn design mode off. Click your button - the subroutinewill run.

Setting a PasswordYou can prevent others from expanding your workbook’s name by settinga password.

◦ Go to the VBE. Go to menu item Tools | VBAProject Properties, and thento the Protection tab. Set the password and confirm it. Press OK andsave the project (say, from the File menu). To load it in a new instance ofEXCEL and to be able to expand the project in the VBE you will need toenter the password.

◦ Having entered the password, you can remove the protection by using thesame protection tab and deleting the password and repetition.

◦ Creating an Add-InOne can change any workbook into an Add-In. Any code will not be avail-able for alteration and the worksheets of the Add-In can never becomeactive. The Code of the Add-In can, however, write to its own worksheets,and these changes can be saved. The subs and functions of the Add-Indo not appear on the available list of subs and functions. These can berun from other open workbooks also from forms and menus in these otherworkbooks. We will not go into all this, but merely give a way of saving aworkbook as an Add-In. When it is loaded in the usual way via the Tools| Add-Ins menu, the functions and subs can be used. We will only discussbriefly a method for saving changes. Further information can be found onthe Microsoft website.

◦ To change your workbook into an Add-In while it is open, go to the File |Save As menu, go to the drop-down menu at the bottom marked Save as typeand go down to find Microsoft Excel Add-In (*.xla). Choose this and

28 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

save. The file is saved as an .xla file. This can be loaded as an Add-Infrom the Tools menu in the usual way. You can then use the functions andsubs, so document these beforehand.

◦ To delete the Add-In, go to the directory in which it is housed and changethe name or delete it. When you go into Excel, try to load the Add-In fromthe menu. It will give you the opportunity of deleting it from the Add-Inlist.

◦ To delete the Add-In from your project without deleting it totally as above,use the Intermediate window with code like

Workbooks("AddInName.xla").Close

◦ If you wish to use the sheets of the Add-In you should use code like

ThisWorkbook.Sheets("Sheet2").Range("A1:B5").Clear

◦ You can save changes by entering in the BeforeClose event code:ThisWorkbook.Save

You can also use a dialog box in this code to leave it to the user to decidewhether to save or not.

2.6 Debugging

• To run a function or sub with no argumentsIn the VBE, place the cursor somewhere in the code for the routine and clickthe button with a triangle. It will run or give an error message.

• One can set a breakpoint in the function or sub at a line, and the procedurewill pause before executing the line. To do so, click in the left margin at thecode line (a disc appears in the margin). You can look at the values of thevariables at the time of the pause by viewing the Locals window. To removethe breakpoint, click on it. One useful spot to set a breakpoint is on theEnd Sub or End Function statement, to see what has happened at the end.If the Locals window is not visible, it can be made visible from the Viewmenu.

• To continue running after a breakpoint pause, click the triangular buttonagain. To stop the run, click the button with the square. You can watch thevariables as they are when the run stopped at a breakpoint by looking in the

2.6. DEBUGGING 29

Locals window or setting a watch (see below). Click the triangle to run thefunction in which the cursor is sitting, or to continue.

• You can run the function step by step by first placing the cursor in thefunction code and then successively pressing F8.

• To look only at a few variables (not all) you can use the Watch windowand set the variables you want to see. To set them, go to Debug|Add watch(while the cursor is in the desired routine.) You can then set breakpoints andlook at only the watched variables at these points.

• To run a sub that has an argument do so from the Immediate window(which can be made visible from the View menu). You would enter in theImmediate window something like

sbr arg1:=2,arg2:=3

• A useful command to add to a routine when debugging it is

Debug.Print variablename

which prints the value of variablename (when this statement is reached) inthe Immediate window.

• To run a function named fun with, for example, a numerical argument v,either call it from a specially written sub, or set breakpoints and enter in theImmediate window something like :

a=fun(1.5)Debug.Print a

or

Debug.Print fun(1.5)

2.6.1 Excel Link for Matlab

A facility distributed by Matlab allows EXCEL to export data from the spread-sheet or VBA to Matlab, to execute Matlab programs and to import data fromMatrlab into EXCEL. The linking functions can be called either from the spread-sheet or from VBA.

• Matlab must be installed. ExcelLink must first be available from Matlab andinstalled. We will assume that this has been done.

• Ensure that the link is loaded as an Add-In. Exclink.xla is an Add-In filewhich is usually in the ToolBox subdirectory of the main Matlab directory.

30 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

In the Tools | Add-Ins menu make sure that there is an Excel Link option, andcheck the check box. If it is not there, use the browse button to find it in theabove directory and load it and check the box. There will be some additionalbuttons on the upper toolbar such as GetMatrix. Press one to make sure thatMatlab is running and if not click the buttons to ensure that it is. If youare running link routines in VBA, you need also to switch to the VBE andin Tools | References check the Excel Link box. The latter can only be donewhen Matlab is running.

• We will deal only with writing the routines in VBA. We will list a program inVBA which illustrates most of the features and then comment on the code.

• Only one- and two-dimensional numeric arrays, and one-dimensional charac-ter arrays (which are just the same as character strings can be transferredto EXCEL. In addition, two-dimensional cell arrays whose elements are allcharacter strings may be transferred.

• Sub ExLinkTrial()Dim i As Integer, j As Integer, NewSheet As ObjectDim C1(2, 2) As Double, D(2, 2) As Double

Set NewSheet = Sheets.Add(Type:=xlWorksheet)NewSheet.Name = "Scratch"

For i = 1 To 5For j = 1 To 4

Sheets("Scratch").Range("A1").Cells(i, j) = i * jNext

NextFor i = 1 To 4

Sheets("Scratch").Range("F1:F4").Cells(i, 1) = iNextSheets("Scratch").Range("F1:F4").Name = "y"For i = 1 To 2

For j = 1 To 2C1(i, j) = i * j

NextNext

MLOpenMLPutMatrix "AMat", Sheets("Scratch").Range("A1:D5")MLPutMatrix "y", Sheets("Scratch").Range("F1:F4")

2.6. DEBUGGING 31

MLEvalString "SDE2"MLEvalString "y=AMat*y;z=1"MLGetMatrix "AMat", "Scratch!H1:K5"MatlabRequestMLGetMatrix "y", "Scratch!M1:M4"MatlabRequestMLPutVar "C1", C’MLGetVar "C1", D

Sheets("Scratch").Range("A7:B8").Value = D

MLClose

Application.DisplayAlerts = FalseSheets("Scratch").DeleteApplication.DisplayAlerts = TrueEnd Sub

• The program first creates a new sheet in the workbook to do input-outputfrom a worksheet. Input-output from Matlab can also be done directly to VBAvariables by using MLPutVar and MLGetVar as illustrated in the program.

• The program then writes some data to the new sheet, sends it to Matlab, runsa Matlab script file, executes Matlab commands to manipulate the data andthen imports it back to the spreadsheet and to VBA. It then deletes the newsheet.

• MLOpen opens Matlab. Later MLClose closes it. Matlab need not be openedif it is already open and need not be closed.

• MLPutMatrix "AMat", Sheets("Scratch").Range("A1:D5") loads the con-tents of A1:D5 in sheet Scratch into Matlab variable AMat. Note that thesecond argument has no quotes around it. The routines are inconsistent inthis respect.

• MLEvalString "SDE2" executes the Matlab statement SDE2. This happens tobe the name of a Matlab m-File in this version and this script file is executed.

• MLEvalString "yAMat*y;z=1”= executes the two statements yAMat*y=and z1= in Matlab (the second one is pointless but is included for illustrativepurposes).

• MLGetMatrix "AMat", "Scratch!H1:K5" puts the contents of Matlab vari-able AMat into the spreadsheet range H1:K5. It must have the command

32 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

MatlabRequest immediately following it. Note the quotes in this case.

• MLPutVar "C", C puts the contents of VBA variable C into Matlab variableC1. MLGetVar "C1", D gets the content of Matlab variable C1 into Matlabvariable D. Once again, note the position of the quotes.

• Running form the Spreadsheet These statements can also be run fromthe spreadsheet. For example enter =MOpen() in a blank cell outside the dataarea, press F2 and Enter. Enter =MLPutMatrix("AMat",A1:D5) to put thecontents of the given range into the Matlab variable AMat. Note the positionof the quotes.

• MLPutVar, MLGetVar are only for use in VBA.

• Recommendation It is recommended that you use VBA programming torun your Matlab programs.

• It is easiest to write all your routines in Matlab m-Files and to execute themas in the above program.

• After executing a Matlab m-File , the variables local to the m-File disappear.In order to pass a variable to the base Matlab layer so that one can thentransfer it to EXCEL use statements like the following in your m-File:

assignin(’base’,’PassVarName’,mFileVarName)

This assigns to a variable named PassVarName in the base layer the contentsof mFileVar in the m-File. PassVarName will persist after the m-File has beenrun and can be transferred to EXCEL using, for example, MLGetMatrix.

2.7. OBJECTS 33

2.7 Objects

Contents: Objects, Properties, Methods, Classes, Collections, Executing Func-tions and Subs from VBA.

Object Notation

• VBA deals with the objects of EXCEL such as cells, sheets, workbooks, charts,etc. Given an object, there are usually subobjects included in the object,properties of the object that can be accessed and changed and methods forthe object that perform calculations on the object or create something. Thereare also objects which are collections of other objects of the same type. Anobject has a type - when using a variable to store an object, it is declared in aDim statement (compulsory under Option Explicit) e.g. Dim Rng As Range.The hierarchy of objects in an application is a tree, but there are too manynodes to view diagrammatically.

• To view the tree, select Object Browser from the View menu in the VBE. Inthe top combobox, select EXCEL from the drop down list. In the column atthe left there appears a list of all the built in classes available in EXCEL.

◦ Click on Application. Application is the root of the Excel tree. On theright there appears the properties, methods, events and possibly certainconstants that are part of the class. The icon on the right indicates whichit is.

◦ Some of these properties return objects which are themselves classes witha similar name to the property. For example, Workbook and Workbooks arealso classes, the latter being the Collection of all the instances of the classWorkbook that have been created to date.

◦ Click on Workbooks in the Classes window of the Object Browser. You canfind out the values of the properties listed in the right hand window or theoutput of a method which returns a number by entering one of the followingtwo types of statement in the Immediate Window (which can be insertedfrom the View menu):

Debug.Print Application.Workbooks(1).Sheets(1).Range("A1").WidthMsgBox Application.Workbooks.CountDebug.Print Application.Workbooks.Count

The first pops up a messagebox with the property value, and the secondprints the value in the Immediate Window. At this stage, the value is 1.

34 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Figure 2.2: The Object Browser

◦ Collections Objects are defined by means of Classes written in Class Mod-ules. The defining code of the system classes is not visible to the user, butthe user can write her own class modules. The Class defines the abstractproperties of an object. To create objects requires a creator and a placeto store the new object once created. Collections are sets of objects ofthe same type that have already been created, and are also Classes. Theywill usually have methods Add, Delete (or Remove), Count. The Addmethod creates a new object of a class and stores it in the collection. Ifa class is called Sheet then the collection is conventionally called Sheetsand similarly for other classes. One way of referring to the instances ina collection is to use an index. Thus Sheets(2) is one of the sheets of aWorkbook. (But BEWARE, it may not be the second sheet created or thesheet "Sheet2". If some of the sheets have been deleted, then the indicesare rearranged to give them consecutive numbers starting from 1.) Add

2.7. OBJECTS 35

and other methods may have different arguments in different classes. Onemust check which arguments are non-optional for each class and use at leastthose.

◦ To use a method, use a statement, for example in the Immediate Window,of the form

Application.Workbooks.Add

If you wish to assign the new Workbook to a variable, then you can useDim wkbk As WorkbookSet wkbk = Application.Workbooks.Add

Note: The word Set must appear in an assignment statement involving anobject. This has the effect of adding a new workbook, which will appearas a new project in the Project Window. There is an optional argumentwhich allows you to add an existing project which has been saved previously.If Myproject.xls already exists in the current directory (press the Openbutton to find out the current directory), the following will add it as aproject to your running version of EXCEL:

Application.Workbooks.Add "MyProject"

◦ Try the following in the Immediate Window:Application.Workbooks(1).Sheets(1).Chartobjects.Add 100,100,100,100

This creates a Chartobject in the first worksheet in the Sheets collection ofthe first workbook (or project) in the current instance of your application(look at your Worksheets to find a blank square in one of them.) Notethat the collection of Worksheet objects is Sheets. Find out what the 4arguments 100,100,100,100 signify by clicking the Chartobjects class andthen its Add method (look at the bar below the Classes Window.) Tryleaving them out - you get an error message, since they are compulsory.

◦ Try this with other properties and methods and explore the tree of yourinstance of an EXCEL application. Some of the properties may yield errormessages (they may be required to have been set previously.)

• Every created object has a parent in the tree, uniquely defined For example,in the collection Chartobjects the Parent of an instance of Chartobjectwill be the particular worksheet to which it belongs. A Chart has parenta Chartobject if it is an embedded chart, or the sheet itself if the chart islocated in its own sheet. When a Chartobject is created in some sheet, aChart is automatically created as its child.

• Objects have Properties and Methods. Properties can be changed and meth-ods executed to give a result. Count is a method of all collections. In theImmediate Window type

36 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

MsgBox Activesheet.Chartobjects.Count

A box will appear, with the number of objects in this collection.

• Executing Functions and Subroutines from VBAThere are two possible ways of writing the arguments of functions and sub-routines when executing them. HOWEVER in some situations only one ofthese is permissible.

Subroutines: We illustrate with the MsgBox subroutine which displays a(modal) messagebox with a message. To find out all the possible argumentsof this sub, type MsgBox on a new line in the Immediate window and press thespacebar. A list of arguments appears. Alternatively, put the cursor in themiddle of the word and press F1. VBA help appears for this sub, listing thearguments (in the Syntax portion of the window.) Arguments with squarebrackets are optional. So there is only one required argument for MsgBox,namely prompt. We will also use title.

Msgbox Activesheet.Name

recognises that Activesheet.Name is the required prompt argument, it eval-uates the expression and puts the result in a box with an “OK” button (thedefault). The box is “modal” in that it must be closed before you can con-tinue.

Msgbox Activesheet.Name, title:= "trial1"

puts a caption in the coloured bar at the top of the box. Or

Msgbox prompt:= Activesheet.Name, title:= "trial1"

uses the argument name prompt in the function call. Optional arguments liketitle must use the argument name in the call.

Note: Putting brackets around the arguments instead of writng them with-out brackets as above will sometimes work but should NOT be done asit can lead to unpredictable results. On the other hand if we use CallMsgBox(Activesheet.Name) the brackets are ESSENTIAL. Call should beAVOIDED if possible, as it is obsolete, and adds confusion. Also CallMsgBox(prompt:="hello") will work.

To directly assign a (possibly function) value to another variable at initializa-tion, one can use the following (BRACKETS COMPULSORY):

Dim Var1 = Fun(arg1, arg2)Dim Var2 = 3

• When assigning to a variable whose type is some object type, one must useSet. For example:

Set rng = Range ("A1")

2.8. CHARTS 37

• As an example of placing the arguments of a method associated with anobject, we use the Location method of Chartobject, which is a subroutine(invisible to the user). Both the following statements are legal:

Chartobjects(1).Location where:= xlChartobjectasobject, Name:="Sheet1"ORDim chtobj As ChartobjectSet chtobj = Chartobjects(1).Location(where:= x1Chartobjectasobject,

Name:="Sheet1")

Note: Brackets around the arguments of Location are used in both lines forthe Set command. NO brackets are used in the first use of Location. Bracketsare used in the second use of Location. This will not work otherwise! Line 2calls the Location method of an existing object, while Line 3 sets the variablechtobj in addition to calling the Location method.

2.8 Charts

• You can either have a chart as an embedded object in a worksheet or in itsown separate sheet.

• In the case of “embedded object” the chart has Parent a Chartobject in theChartobjects collection of the worksheet. In the case of a “separate sheet”,the parent is the worksheet itself.

• To create an instance of the Chartobject class and add it to the Chartobjectscollection of worksheet sheetname use:

Sheets("sheetname").Chartobjects.Add(1, 1, 1, 1)

(the arguments 1,1,1,1 are compulsory, and give top, left, height, widthin pixels - they can be altered later.) This creates an embedded chart on thesheet whose name is given by the contents of the string variable sheetname.To assign the new object to a variable, use the Set command as explainedabove.

• Another alternative:

Dim Cht As Chart, strActiveSheetName As StringstrActiveSheetName = ActiveSheet.NameActiveSheet.ChartObjects.Delete

Set Cht = Charts.Add

38 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Set Cht = Cht.Location(where:=xlLocationAsObject, Name:= strActiveSheetName)

This adds a chart to the global Charts collection, and then makes it anembedded chart in a sheet.

• Once created the characteristics can be altered by VBA. See the example thatfollows this discussion.

• Use Macro Recording to get an example and select the features you need.(But try to use one of the methods if the macro is different.)

• Use Help, and F1 (when the cursor is on a term) to get assistance and tofind further examples. Also use the Drop down menus that appear when youinsert a period after an identifier.

• The following example illustrates the procedure. You may have to click onthe area that the graph should occupy to display it.

Sub MyChart()’ Before use, place numberical data in D2:E10

Dim chtobj As ChartObject, cht As Chartdatarng As Range, obj As Object

Application.Screenupdating = FalseSet datarng = Range("D2:E10")On Error Resume NextSheet1.ChartObjects.DeleteSet chtobj = Sheets("Sheet1").ChartObjects.Add(1, 1, 1, 1)Set cht = chtobj.ChartWith chtobj

.Top = Range("A1").top

.Left = Range("A1").Left

.Height = 150

.Width = 450

.RoundedCorners = TrueEnd WithWith cht

.Type = xlXYScatter

.SetSourceData Source:=Range("D2:E10"), PlotBy:=Columns

.ChartArea.Interior.ColorIndex = 30

.HasLegend = TrueWith .PlotArea.Fill

2.8. CHARTS 39

.ForeColor.SchemeColor = 50

.BackColor.SchemeColor = 43

.TwoColorGradient Style:=msoGradientHorizontal, Variant:=1End With

End WithApplication.Screenupdating = True

End Sub

• A number of things need still need to be done to make the output moreacceptable. The series may be plotted with markers. To eliminate them, use:

cht.SeriesCollection(i).Markers = xlNone

where i is an index to loop through (or use For Each obj In Series.Collection..... Next).

Also, the fonts may need to be resized, to avoid a default size that is toolarge. This applies to the title, axis title and legend. These can be changedby setting the following to values:

cht.ChartTitle.Font.Sizecht.Axes(xlCategory).Ticklabels.Font.Sizecht.Axes(xlValue).Ticklabels.Font.Sizecht.Legend.Font.Size

40 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

2.9 Using Solver in VBA

• To use the subroutines in the Solver package in VBA, it is firstly necessaryto go to the VBE and the menu item Tools|References and tick the Solverbutton - in the VBE open a module first, click on a word in it and then dothe above. The help menu in the VBE lists the Solver routines and argu-ments. Look them up and look at them. If you do not find SOLVER listedin Tools|References then make sure that the solver add-in has been loaded(in EXCEL), and if you still do not find it, run solver from EXCEL on sometrivial problem and then check for the reference.

• The package contains functions and subroutines and these do not return auseful value - they return values to a worksheet range. Their arguments arealso, in some cases, cell names so it is necessary to enter arguments and resultsin the spreadsheet (possibly using VBA), and then call the Solver routines inVBA, after which the results can be retrieved from the spreadsheet and furtherprocessed in VBA.

Example 1: To solve ax2 + 3x + 2 = 0 for various a.The following will be done in the ActiveSheet. To use a specific sheet, usefor example

Sheets("Sheet1").Range("A1").Name = "a"

Sub Quad()Dim v As DoubleRange("A1").Name = "a" ’Parameter of function fRange("B1").Name = "x" ’Variable of function fRange("C1").Formula = "=f(x,a)"Range("x").Value = 0 ’Estimate for solutionRange("a").Value = 1 ’set parameter valueSolverResetSolverOK SetCell:= "C1", MaxminVal:=3, ValueOf:= "0", _

ByChange:= "x"’set cell C1 to the value of 0 by changing x;’Maxminval 3 is "match specific value"SolverSolve UserFinish:= TRUE’Executes routine, "TRUE" value suppresses dialogue boxv = Range("x").ValueEnd Sub

Function f(x As Double, a As Double) As Doublef = a * x ^ 2 + 3 * x + 2

2.9. USING SOLVER IN VBA 41

End Function

Example 2 – Optimisation of Functions with many Arguments

If a function has many arguments the arguments are best combined into anarray which is entered in a spreadsheet range. Suppose for example that thearguments are entered into cells B1:B40 and that these are the cells that mustbe varied to obtain the optimum. A fragment of a suitable function is thefollowing:

Function g(vec As Variant)) As DoubleDim i As Integer, M As Integer, params() as Double

M=Application.Count(vec)Redim params(M)

For i = 1 To Mparams(i)=vec(i)

Next i

.....

End Function

We would then use

Range("C1").Formula = "=g(B1:B40)"

The appropriate argument of SolverOK would be

SolverOK SetCell:= "C1", MaxminVal:=3, ValueOf:= "0", _ByChange:= "B1:B40"

Note: If vec were a string variable this would not work. Example 3 – Tosolve the simultaneous equations y + t = 3, 3y + t = 5.

Sub LinEq()Dim a As Double, b As DoubleRange("G1").Name = "y"Range("I1").Name = "t"Range("G2").Formula = "=y+t-3"Range("I2").Formula = "=3*y+t-5"Range("I3").Formula = "=G2 ^ 2 + I2 ^ 2"

42 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

SolverOK SetCell:="I3", MaxMinVal:=3, _ValueOf:="0", ByChange:="G1, I1"

SolverSolve UserFinish:=Truea = Range("y").Valueb = Range("t").ValueEnd Sub

Note: Constraints can be added. For example

3x + 2y ≤ 4

can be added by entering

"=3*x+2*y-4"

in a cell (say C6) and then calling

SolverAdd CellRef:="C6", Relation:="1", FormulaText:="0"

This can be changed at a later date by e.g.

SolverChange CellRef:= "C6", Relation:="2", FormulaText = "0"

and can be deleted by using

SolverDelete CellRef:= "C6", Relation:="1", FormulaText = "0"

Note: FormulaText can, according to the Help, take any constant as well asa text cell name. However it does not seem to work with any constant otherthan 0.

Example 4 – To solve the linear programming problem x + y = max!, 3x +2y ≤ 4, 5x + y ≤ 4, x, y ≥ 0.

Sub LinProg()Dim a As Double, b As DoubleRange("B6").Name = "x"Range("B7").Name = "y"Range("C6").Formula = "=3*x+2*y-4"Range("C7").Formula = "=5*x+y-4"Range("D6").Formula = "=x+y"

SolverAdd CellRef:="C6", Relation:="1", FormulaText:="0"SolverAdd CellRef:="C7", Relation:="1", FormulaText:="0"SolverAdd CellRef:="B6", Relation:="3", FormulaText:="0"SolverAdd CellRef:="B7", Relation:="3", FormulaText:="0"SolverOK SetCell:="D6", MaxMinVal:=1, ByChange:="B6, B7"

2.9. USING SOLVER IN VBA 43

SolverSolve UserFinish:=Truea = Range("x").Valueb = Range("y").ValueEnd Sub

• The possible values for the argument Relation are:

1 is <=2 is =3 is >=

• The possible values for MaxMinVal are:

1 is maximize2 is minimize3 is match a specific value (set by argument ValueOf)4 cells referenced by CellRef must be integers5 cells referenced by CellRef must be 0 or 1

44 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

2.10 Errors

• Worksheet Errors - Common causes

##### Number, date or time is wider than current cell#DIV/0! Division by cell containing blank or zero, or formula containing /0#REF! Cell reference not valid (perhaps it was deleted)#NULL! Incorrect range operator or cell reference#NAME? Using a name that does not exist#N/A (not available) - something cannot be found#VALUE! Wrong variable type#NUM! Number required and other type used

• Note that these are CELL WORKSHEET FUNCTION errors, not runtimeerrors in VBA.

• Runtime Errors in VBA In VBA, an error (at RUNTIME) that occurs isdescribed by an intrinsic object Err (that need not be created). Refer to theHELP in VBA (F1 in the VBE). Look at the entries for Err Object and ErrObject Example. Properties are:

Err.Number (default property) the number of the errorErr.DescriptionA string description of the errorErr.Clear Clears the error - can now proceed

and some other possibilities.

Two useful error numbers are9 Subscript out of range11 Division by zero

• Trapping ErrorsWhen errors occur, control can be transferred to another section which hascode to deal with them, and then control can be transferred back if necessary.Such error trapping can be done by a variant of the following code:

On Error GoTo Label1 ’Turns on error handling statements.

(program statements)

Exit Sub ’or "Exit Function" as appropriateLabel 1:

2.10. ERRORS 45

(error handling statements)

Resume ’Optional - if error is fixed you can retry your statementEnd Sub

• An alternatives for the ”On Error” statement and the ”Resume” statementin the above example:

On Error Resume Next’skips statement with error and starts at next statement

The statement

On Error GoTo 0

turns normal VBA error handling on again (after the last error stoppedthings). It DOES NOT instruct return to line 0 - heaven knows what itdoes exactly.

Note: The most common runtime errors are division by zero (9) and subscriptout of range (11) in numerical work, and a variety of system errors associatedwith files when using them in VBA (File referred to does not exist etc.)

• Example The following example first uses the On Error GoTo statement tospecify the location of an error-handling routine within a procedure. In theexample, an attempt to delete an open file generates error number 55. Theerror is handled in the error-handling routine, and control is then returnedto the statement that caused the error. The On Error GoTo 0 statementresumes error trapping After return from the handling routine. A differentprocedure is used for the next error. The On Error Resume Next statementis used to defer error trapping to the following line so that the context forthe error generated by the next statement can be known for certain. Notethat Err.Clear is used to clear the Err object’s properties after the error ishandled.

Sub OnErrorStatementDemo()Dim Msg As String, ObjectRef As Object, num As Integer

On Error GoTo ErrorHandler ’ Enable error-handling routine.Open "TESTFILE" For Output As #1 ’ Open file for output.Kill "TESTFILE" ’ Attempt to delete open file.On Error GoTo 0 ’ Resumes normal error trapping.On Error Resume Next ’ Defer error trapping.

46 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Open "TESTFILE" For Output As #1 ’ Open file for output.Kill "TESTFILE"If (Err.Number = 55) Then

’ Tell user what happened.’ Then clear the Err object.

Msg = "There was an error attempting to delete an open file!"MsgBox Msg, , "Deferred Error Test"Close #1Err.Clear ’ Clear Err object fields

End IfExit Sub ’ Exit to avoid handler

ErrorHandler: ’ Handling routine.’ Deals with "Open File" error

Select Case Err.Number ’ Evaluate error number.Case 55 ’ "File already open" error.

Close #1 ’ Close open file.Case Else

’(statements) ’ Handle other situations here...End SelectResume ’ Resume execution at same line

’ that caused the error. (The file’ is now closed).

End Sub ’ is now closed).

• Generating Your Own Error StatesYou can also define your own error and give it a number that is not on VBA’slist but which now corresponds to the error that you have detected - e.g. amatrix is not symmetric. You can use

Err.Raise

For example, the following uses raise to announce a system overflow error anda user-defined error.

Sub errTest()Dim Msg As String’ If an error occurs, construct an error messageOn Error Resume Next ’ Defer error handling.Err.ClearErr.Raise 6 ’ Generate an "Overflow" error.’ Check for error, then show message.

2.10. ERRORS 47

If Err.Number <> 0 ThenMsg = "Error # " & CStr(Err.Number) & " was generated by " _

& Err.Source & " " & Err.DescriptionMsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext

End IfErr.ClearErr.Raise 1001, "Sub ErrTest", "Nonsensical Error"If Err.Number <> 0 Then

Msg = "Error # " & CStr(Err.Number) & " was generated by " _& Err.Source & " " & Err.Description

MsgBox MsgEnd If

48 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

2.11 Userforms

Example 1: A simple data entry form

1. Open a Workbook in Excel and switch to the VBE (Alt F11).

2. Access menu Insert|Userform. A dotted form (in design mode) appears inthe window, and a Toolbox pop-up menu titled Controls appears.

3. Click on the form, change its name (say to frmTrial) and set its Captionproperty (in the properties window) to Test Form.

4. ◦ In the Toolbox, click on the label control A.

◦ Near the top left of the Userform, move the cursor so that the cross hairis at the top left point of the position you would like the label to have, andclick. The label appears on the form.

◦ Change the Name of the label (say, to lblHead).

◦ Change the Caption property to Enter Data.

◦ Change the Font property (by clicking on the button with 3 dots) to Bold.The label now has the caption inside it in boldface.

◦ You may want to resize it manually (by clicking and moving the borders)or to shift it by clicking and holding down on a border and then dragging.

5. ◦ Similarly, put a Frame control under the label.

◦ Change the name, and set the caption to blank (this will remove the textat the top of the frame).

◦ In the frame insert a label control with caption CellB3Content in boldface.

◦ Alongside the label insert a TextBox (ab).

◦ Change the Control source property of the TextBox (remember to click onit first) to Sheet1!B3.

◦ Enter something in the TextBox.

◦ Switch to the EXCEL Sheet1. B3 will have the text you entered.

◦ Switch back to the VBE.

6. ◦ Below the frame in the centre, insert a Command Button.

◦ Change its caption to Close and give it a Name.

◦ Double Click on the button. A code window opens with a sub headingCommandButton Click( ) (your name for the button will appear in placeof Command Button.)

2.11. USERFORMS 49

◦ Insert the codeUnload Me

7. Double click on the Userform (possibly renamed) tag in the Project Windowto go back to the Userform.

8. Press the Run button (small square), enter something in the TextBox, clickClose and look at Sheet1. Cell B3 will have the content of the TextBox. (Youcan also exit the form by clicking the "×” box on the bar at the top of theform.

9. ◦ Now return to the spreadsheet Sheet1 (use AltF11).

◦ Go to menu View|Toolbars|Control Toolbox.

◦ Click the CommandButton and place it somewhere on Sheet1.

◦ Click the Properties icon on the top row of the toolbar Control Toolbox.Change the name of the button to btnEnter, and the Caption to EnterData (in boldface).

◦ Make sure the Design Mode icon (blue triangle) on the top row of theControl Toolbox is clicked.

◦ Double click the button. The code window appears with Sub btnEnter click().Add the code line

FrmTrial.Show

10. ◦ Return to the spreadsheet (Alt F11).

◦ Make sure the Design Mode button is off (click it if necessary.)

◦ Click the Command Button. The form appears on the spreadsheet.

◦ Enter something in the TextBox and click Close. The entered item appearsin cell B3.

11. Add a few more TextBox’s and labels to enter data to your form and test it.

Some Properties and Methods:

1. A Userform is modal by default, in that it retains focus until it is unloadedor hidden - nothing else can be done to the computer until the modal objectis made to disappear. To create a modeless form and shows it:

frmFormname.Show vbModeless

This allows other tasks to be performed while the form is open.

50 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

2. frmFormname.Load loads the form into memory, initially.Show loads and makes visible.Hide makes invisible.Unload deletes from memory

For any object in the Userform, "Me" refers to the parent, namely theUserform e.g.

Unload Me

3. Userforms can contain the following objects. It is best to name them asindicated below:

Frame frmFrameNameTextbox txtBoxNameCommandButton btnButtonNameOptionbButton optButtonNameCheckBox chkBoxNameListbox lstBoxNameLabel lblLabelNameSpinBox spnBoxName

To give these a name, click on the object and change the Name field in theProperties Window. There are several other controls objects - see the Con-trols Toolbox.

4. The Control Source property links a cell in a worksheet to the Value prop-erty of the object e.g. one can set the ControlSource property to Sheet1!A1.

5. The Caption property can be used to give the object a descriptive title (whichis written somewhere on the object).

6. HINT: When changing a property in the property window, first click on thetext to be changed in the box on the right of the property name to highlightproperty value, then double click. This highlights the text, and you can typein the new text without erasing the old text. ALTERNATIVELY doubleclick the property name on the left.

7. Multiple Controls

• If you have several different possibilities for the user, you can add a MultipageControl, with tabs to change pages. You can insert material on each pageas if it were a single form.

2.11. USERFORMS 51

• Enlarge your form and add a Multipage control. It will by default have2 tabs. To add more pages, right click on a tab. You will have 4 options:New page, Delete Page, Rename, Move.

• Some properties on the property list of a Multipage: (to get this list,click on the Multipage border or use the dropdown list in the PropertiesWindow (in Design mode)).

Value the number of the page displayedStyle tabs can appear as tabs, buttons or not appear at allTab Orientation tabs may appear on the top, bottom, left or rightMultirow if there are many tabs, more than one row can be used

• Click on a Page to set its properties. Try adding other controls and get-ting them to work (e.g. SpinButton, ControlBox, TextBox, ListBox,CheckBox, OptionButton.)

52 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

2.12 Working with files in VBA - Method 1

• Creating and Opening a File To work with the data in a file (read or write)the file must be created if it does not exist, or opened if it does exist. For Helpwith the following, enter Open Statement in the VBE Help Index. The follow-ing statement creates or opens a file with name pathname - it only creates thefile if mode is Output. (For example, pathname = "c:\direc\myfile.txt".)filenumber is a unique integer.

Open (pathname) For (mode) As #(filenumber) ’Omit thebrackets

Possible values:

Mode: Input ’allows one to read but not writeOutput ’allows one to read and writeAppend ’writes to end of file

Filenumber: ’A filenumber different from other flenumbers in’use must appear here. The function Freefile’returns the smallest filenumber not in use

There are other arguments and other possibilities for mode (see HELP inVBE). The above options for mode allows sequential access - other forms ofaccess are possible.

• Working with Directories (You can find further details by consulting theHelp in VBE (NOT IN EXCEL) and entering the command name in theINDEX). The most important function is

Dir(PathName)

where pathname is a string which may contain wildcards * (any number ofletters) and ? (1 letter) in your pathname, for example, "c:\windows\*.e??"

There is also the possibility of using a second argument

Dir(pathname, attribute)

Dir returns files without regard to attributes. Possible attributes:vbReadOnly, vbHidden, vbSystem, vbDirectory.

◦ Dir("c:\windows\*.e??") returns the first filename in the current direc-tory matching the pathname.

◦ To get the next matching file use Dir without any arguments.

◦ If no files are left to return, Dir returns the empty string "".

2.12. WORKING WITH FILES IN VBA - METHOD 1 53

◦ dir is a method of the FileSystem object. See the Object Browser andthe next item for information on other methods.

◦ Other useful methods of FileSystem:ChDir, ChDrive, FileCopy, FileDateTime, FileLen, GetAttr, Kill (Deletesfile), MkDir, Name (renames the file), RunDir, SetAttr

◦ It is best to use an error trapping procedure when working with files, asthere are frequent user and system errors.

◦ Enter the following in a module and run it with a breakpoint at the finalttbKill. Check the directory and the file in it, reading the contents. Runto the end and check again.

Sub sb()On Error Resume Next ’Disregards error in following statementMkDir "c:\temp1\" ’Creates new directoryOn Error Resume NextKill "c:\temp1\aaatr.txt"Open "c:\temp1\aaatr.txt" For Output As #1Write #1, "all"; ’Writes string "all", leaving line activeWrite #1, " done" ’Writes "done" on same line,starts new lineClose #1 ’Closes file #1Debug.Print Dir("c:\windows\*.e??") ’Finds first .exe fileDebug.Print Dir ’Finds next .exe fileDebug.Print Dir("c:\temp1\a*")On Error Resume NextKill "c:\temp1\aaatr.txt" ’Deletes a fileOn Error Resume NextRmDir "c:\temp1\" ’Deletes a directoryEnd Sub

The following is a program fragment:

Directory = "c:\*.do?"File = Dir(Directory)Cells(1,1) = FileCells(1,2) = FileLen(Directory & File)Cells(1,3) = FileDateTime(Directory & File)File = Dir ’Next file in "c:\*.do?" matching pathname

• Working with Text Files The best way of handling text from files is toread either individual characters or entire lines (“Sequential Access”).

54 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

◦ Opening To work with the data in a file (read or write) the file must beopened. As before, use:

Open (pathname) For (mode) As #(filenumber)

◦ CSV Files (Comma Separated Variable). These have data organised incolumns separated by a comma ”,” and in rows or records terminated bycarriage return/linefeed i.e. chr(13) & chr(10). We will only use suchfiles here. The Open statement with mode Input or Output creates CSVfiles.

◦ Reading FilesInput #(filenumber), Data

’inputs the text up to next comma into variable DataLineInput #(filenumber), Data

’inputs a line of data (up to chr(13)) into variable Data

◦ Input inputs text as a string without the inverted commas created previ-ously by writing using Write # . . . (see below). LineInput includes allpunctuation.

◦ Input #1,(variable list) ’Reads into the successive variables listede.g.Input #1, var1, var2

Example:

Sub sb2()Dim Data As String, r As IntegerData = "dat"r = 0Open "c:\myfile.txt" For Output As #1Write #1, Data;Write #1, Data;Close #1Open "c:\myfile.txt" For Input As #1Do Until EOF(1)

Input #1, Data ’or LineInput #1 ... to input a lineActiveCell.Offset(r, 0) = Datar = r + 1

LoopClose #1Kill "c:\myfile.txt"End Sub

◦ Writing to Files

2.12. WORKING WITH FILES IN VBA - METHOD 1 55

Write #(filenumber), (outputlist)

writes outputlist. For example:Write #1,Data,"This is some data"

will write on one record the content of Data, a string variable, in invertedcommas followed by a comma, followed by "This is some data" followedby chr(13) & chr(10) to start a new line. To avoid ending the line use:

Write #1, Data;

(the ”;” does NOT put chr(13) to end the line and allows further writingto this record.)

◦ Write #1, var1, var2, "a", 3, "b"’Write takes a list of variables and constants.

• Writing to and Reading from EXCELWriting a Range of Cells to a CSV FileThis must be done cell by cell using Write # :

Sub ReadWriteMatrixExcelToFile()Dim rng As Range, row As Integer, col As IntegerDim numrows As Integer, numcols As Integer, data As IntegerSet rng = Selectionnumrows = rng.Rows.Countnumcols = rng.Columns.CountOpen "c:\myfile.txt" For Output As #2Write #2, numrowsWrite #2, numcolsFor row = 1 To numrows

For col = 1 To numcolsdata = rng.Cells(row, col).ValueWrite #2, data;

Next colNext rowClose #2End Sub

A blank cell gives value 0 - you may need to handle this case◦ If you wish to end the record at the end of the line, you must add code:If c <> Numcols ThenWrite #1, Data;Else

Write #1, DataEndIf

56 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

to replace the Write statement.

◦ Reading from a CSV File to a Range of Cells If you want to write eachline in a single row of cells, you need to know how many entries (separatedby commas) are on each line, and use a looped Input #n,word statementto read them into a variable word). They can then be written to EXCEL.If all records are the same length, this is easy if you know what that lengthis. If not, you may have to read the record into a variable using LineInput#n, and then parse the string, removing commas and " " as you go along.Study and try out the following:

Sub ReadWriteMatrixFileToExcel()Dim numrows As String, numcols As String, word As StringDim i As Integer, j As IntegerOpen "c:\myfile.txt" For Input As #1Input #1, numrowsInput #1, numcolsFor i = 1 To Val(numrows) ’Convert string numrows to number

For j = 1 To Val(numcols)Input #1, wordRange("A5").Cells(i, j).Value = Val(word)

NextNextClose #1Kill "c:\myfile.txt"End Sub

◦ The following is useful for reading the whole file:Do Until EOF(1) ’Reading File #1(statements)Loop

orWhile Not EOF(2) . . . Loop

◦ REMEMBER CLOSURE. Always close your file when finished:Close #1

◦ One sometimes forgets to put a Close #n statement and then exits from asub, making the file temporarily unusable. You then need a procedure ofthe following form to close it and make it usable again:Sub cls()Close #nEnd Sub

2.12. WORKING WITH FILES IN VBA - METHOD 1 57

Some comments

• Use Open in mode Output to write to a file. Then close it and use Open inmode Input to read from the file. Use Open in mode Append to write to theend of the file.

• Do NOT open .xls, .doc etc files with Open. Use it for text files (.txt perhaps).

• If you read a “character” number, e.g. "12" from a file and write to thespreadsheet, it will be usable as a number. EXCEL converts strings to nu-merical types. Also Integer variables are usable as Strings in VBA, forexample:

Dim i as Integer, str As Stringi=3str = "A" & iRange(str) = "4"

places the number 4 in cell A3.

58 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

2.13 Working with Files in VBA - Method2

File Management with the Scripting Object

A defect with the method of the previous section is that the object paradigm isnot clear. Visual Basic does not allow the creation of new classes and objectsat runtime, only instances of already defined classes. A form, for example, isa class. It also does not allow the user to evaluate expressions at runtime.Since VBA also connects with an application, one can use the application todo the calculation of expressions and functions, since the application must beable to do this at runtime. We have frequently used this facility. To get aroundthis, one can use a scripting language in a similar way that, say, VBScriptallows runtime calculation on the web. The Scripting Object in VB providesadditional facilities for file management, among other facilities. However, it isnot referenced in VB Help, except for file handling. We outline its use for filemanipulation. It operates within the Object Oriented paradigm.

1. FileSystemObject is the object whose properties are the Drives of the sys-tem. To create such an object use

Dim filesystemSet filesystem = CreateObject("Scripting.FileSystemObject")

Note: The type of statement Set filesystem = New Scripting.FilesystemObjector its variants does not seem to work in some versions of VBA. CreateObjectis used for special types, such as ActiveX objects.

2. Having created a filesystem, we can Create a File:

Dim FileName As String, f , Str As String’Assign your filename to the variable FileName, and then:Set f = GetFile(FileName)Str = f.path ’the path to file f (without the actual filename)

f will have such properties as path, name, DateCreated, DateLastAccessed,DateLastModified.

To delete the file use

Filesystem.GetFile(filename).Delete

3. To read or write to the file, we need to Open it and feed it into a streamobject:

2.13. WORKING WITH FILES IN VBA - METHOD2 59

Dim datastreamSet datastream = filesystem.GetFile(filename).OpenTextStream(1,-2)

datastream has properties such as the position we are at in the file, columnnumber, row number, AtEndOf(line), AtEndOf(File).

The arguments (1, -2) have other possibilities:First Argument : 1 for read only, 2 for write only, 3 for appending (to theend)Second Argument: -2 is the system default for code type (usually ASCII), -1Unicode, 0 ASCII

4. To check whether a file exists: there is a Boolean property

FileExist(filename)

5. Reading:

Dim Str As StringStr = datastream.ReadLine

’must now parse Str to get data - alternativelyStr = datastream.Read(n) ’n an integer - reads n characters

6. Writing:

datastream.Writeline ’writes a whole line Ordatastream.Write 5.47 ’appends to the current line

7. When one has finished with the current type of operation, one must closethe file:

datastream.Close

8. Further information: In VBE go to Help|Contents|Visual Basic LanguageReference|Objects and look at FileSystemObject, File Object, Files Collection- also look at the links on these pages. The read and write methods will bein Contents|Visual Basic Language Reference|Methods.

9. To store and retrieve numerical data from files:

It is simplest to store one number per line - one does not then have to parsethe input string. (The file will be only slightly larger than one having multipledata values per line.)

10. The following is an example of the use of Method 2 of file processing for inputand output of matrices.

60 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Sub SaveMatrixToFile(filename As String, matrix() As Double)’filename is just the name and qualifier e.g. "fnoo.qul", which must’be in the same directory as the workbook running the program

Dim filesystem, datastreamDim i As Integer, j As Integer

Set filesystem = CreateObject("Scripting.FileSystemObject")filename = Application.ActiveWorkbook.Path & Application.PathSeparator & filenameIf filesystem.FileExists(filename) Then filesystem.DeleteFile filename, TrueSet datastream = filesystem.CreateTextFile(filename, True)

’write numrows and numcols each on a linedatastream.Writeline UBound(matrix, 1) - LBound(matrix, 1) + 1datastream.Writeline UBound(matrix, 2) - LBound(matrix, 2) + 1

’write 1st row, 2nd row, ... one element to a lineFor i = LBound(matrix, 1) To UBound(matrix, 1)

For j = LBound(matrix, 2) To UBound(matrix, 2)datastream.Writeline matrix(i, j)

Next jNext idatastream.CloseEnd Sub

Sub ReadMatrixFromFile(filename As String, matrix() As Double)Dim filesystem, datastreamDim numrows As Integer, numcols As IntegerDim i As Integer, j As Integer

On Error GoTo ErrorHandler

Set filesystem = CreateObject("Scripting.FileSystemObject")filename = Application.ActiveWorkbook.Path & Application.PathSeparator & filenameSet datastream = filesystem.GetFile(filename).OpenAsTextStream(1, -2)

numrows = datastream.Readline()numcols = datastream.Readline()

ReDim matrix(numrows, numcols)

2.13. WORKING WITH FILES IN VBA - METHOD2 61

For i = 1 To numrowsFor j = 1 To numcols

matrix(i, j) = datastream.Readline()Next j

Next i

datastream.CloseExit Sub

ErrorHandler:MsgBox Err.Description, vbOKOnly, "Unhandled Error"datastream.CloseEnd Sub

Sub ReadSaveMatrix_Excel_to_File(wsht As Worksheet, strRngName As String, _strFile As String)

’For example, wsht could be Sheets("Sheet1")Dim i As Integer, j As IntegerDim numrows As Integer, numcols As IntegerDim matrix() As Double

numrows = wsht.Range(strRngName).Rows.Countnumcols = wsht.Range(strRngName).Columns.Count

ReDim matrix(1 To numrows, 1 To numcols)

For i = 1 To numrowsFor j = 1 To numcols

matrix(i, j) = wsht.Range(strRngName).Cells(i, j).ValueNext j

Next i

SaveMatrixToFile filename:=strFile, matrix:=matrixEnd Sub

Sub SaveToFile()Dim fName As String, mat(1 To 3, 1 To 3) As Double, i As Integer, j As IntegerFor i = 1 To 3

For j = 1 To 3mat(i, j) = i * j

62 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

NextNextSaveMatrixToFile "fnoo.txt", mat()End Sub

Sub ReadFromFile()Dim mat() As DoubleReadMatrixFromFile "fnoo.txt", mat()End Sub

Sub RangeMatrixToFile()ReadSaveMatrix_Excel_to_File Sheets("Sheet2"), "A1:C3", "fnoo.txt"End Sub

2.14. EVENTS 63

2.14 Events

We will briefly introduce events and their use. Associated with each objectis a set of events. VBA allows one to transfer control from executing some-thing in EXCEL to a program which will do something that you want todo, and after completion return control to EXCEL. For example, there areevents of the type Click CommandButton1 (occurs when this button has beenclicked), the Calculate event (occurs before recalculation takes place), theBeforeRightClick event, the BeforeDoubleClick event, the SelectionChangeand Change events, opening and closing of a workbook events and many more.

For example, to use events associated with a WorkSheet that is active, saySheet1, switch to the VBE and click on Sheet1 in the Project Window, thenlook at the two combo boxes near the top on the right. Click on the left handbox and choose WorkSheet. Then click on the right hand box. All the eventsassocited with WorkSheet are displayed. If you click on one, a sub skeletonappears in the text portion of the window with the name of your event. Youcan then fill in the actions you want taken when the event occurs in VBA.

All the embedded objects in the sheet will appear in the left hand box, and theirevents in the right hand box. If you want to know the events associated witha non-embedded object, find the object in the Object Browser - the events arelisted among the properties and methods.

An example of the use of an event is to display or hide a chart. Suppose youhave a chart in the worksheet. You can place a piece of text in one of the cells,like ”Hide/Show”, and use the SelectionChange event. In the code, check if thenew selection, given by Selection.Cells(1,1).Value, is equal to ”Hide/Show”and if it is, you can use

ActiveSheet.ChartObjects(i).Visible = False

(or set it to True) to perform the hiding or showing.

64 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

2.15 Class Modules

Contents: Classes, Collections.

Creating an object can be conceptually useful for numerical work. We will usean example of a Black Scholes class, which houses some of the information in aBlack Scholes Market Model and allows one to find call and put prices. Otheraspects of the model (for example the Greeks) can be added, but these will beleft as exercises.

The idea is to create a “class”, which we will call BS, which houses in an abstractway all the aspects we will consider. There will be Properties of BS (such asthe initial asset price So), and Methods of BS (such as routines to calculate theoption prices.) Having defined the class BS, we will be able to create an instanceof the class (a particular BS model) and allow the user to assign the relevantproperties (such as Strike and Risk-free interest rate.) For example, the strikeprice will be assigned by

BS.X = 100

Having assigned the properties, the user may determine the Call price by usingthe method Cll in the statement:

dblCallValue = BS.Cll

where the LHS is a variable already declared. (Note that “Call” is a VBAkeyword, and cannot be used as a procedure name, so we use Cll.)

This is similar to what one does when using ordinary programming, but encap-sulates all the routines in one concept. We should be able to extend classes byadding other classes to it (for example,we may want a charting class) but unfor-tunately VBA does not support these hereditary aspects of the object orientedparadigm.

• The inputs to the model are of two types: those which are basic properties ofthe model and those that are incidental, such as for example, user instructionson what is to be displayed. The basic properties are usually given their ownvariables and declared Private to the class. They are usually locally availableto all the routines in the class, and are therefore placed in the declarationssection. We put a prefix m in front of the name to indicate their special nature.In our case, they are

Private mX As DoublePrivate mSo As Double

2.15. CLASS MODULES 65

Private mr As DoublePrivate msigma As DoublePrivate mT As DoublePrivate mq As Double

In our case all the variables are Double variables, so we do not indicate thisas a prefix. Other types are given a prefix.

• Some of the basic properties could be made available to the user, so that theycan be checked or altered. Such a property requires two functions if it is to bea read/write property, a Property Get routine and a Property Let routine,and only one of these if it is to be read-only or write-only. They are of aspecial type, and one of these properties in our case is

Public Property Get X() As DoubleX = mX

End Property

Public Property Let X(ByVal NewX As Double)mX = NewX

End Property

Note that the property is given a new name, X in our case. It is convenientto give the property the same name as the variable to which it corresponds,namely mX, but without the prefix m. The user will access the property by oneof the two types of statement:

VariableName = BS.XBS.X = 100

The first calls Property Get, and the second calls Property Let with NewXas 100. A similar pair of routines must be set up for each property - see theprogram below.

• We also use subs and functions in the class module which are Methods in ob-ject oriented terminology. There are four Methods, d1, d2, Cll, Pt. Thesecalculate the values of the parameters d1 and d2, and the values of the Calland the Put respectively, in terms of the values of the basic properties. Theyare accessed by the user by such statements as

VariableName = BS.Cll

66 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Although none of these methods have arguments, they could have had. Theywould then be used as follows:

VariableName = BS.function1(arg1,arg2)BS.sub1 arg1:= val1, arg2:= val2

• In order to create various BS models, we need a way of creating instances ofthis class, and then we need a way of defining the properties of the specificinstance through the user. To do the latter, we could:

(i) Write a sub or function which sets the properties.

(ii) Write a sub or function which reads values we have entered in a spread-sheet and uses these to set the properties.

(iii) Design an input form.

(iv) Use the InputBox facility, which in our case might look like

mX = val(InputBox("Enter the Strike Price"))

• To create a new instance of the class, it is often desirable to place it in avariable which is private to the set of routines in the module being used,but available to all the routines in the module. One would then put in theDeclarations Section of the module:

Private mBS As BS

and in the sub that needs to create the instance:

Set mBS = New BS

Alternatively, if one is using only one sub, we could use the following in thesub:

Dim mBS as New BS

• A listing of the class BS will be given later. BS must be written in a ClassModule under the VBE, or imported via the File Menu (use Import) intoyour project. It is then usable in all modules in the project. The followingis an example of initialization and use of BS, assuming that the values of theproperties have been entered in cells A1:A6 and the outputs of the Call, Put,d1, d2 are to go in cells C1:C4.

2.15. CLASS MODULES 67

Sub bsc()Dim mBS As New BS

mBS.x = Sheet1.Range("A1")mBS.So = Sheet1.Range("A2")mBS.rate = Sheet1.Range("A3")mBS.sigma = Sheet1.Range("A4")mBS.t = Sheet1.Range("A5")mBS.q = Sheet1.Range("A6")

Sheet1.Range("C1").Value = mBS.CllSheet1.Range("C2").Value =mBS.PtSheet1.Range("C3").Value = mBS.d1Sheet1.Range("C4").Value =mBS.d2

End Sub

• Later on we will set up a new class called mBSs which organizes a collectionof instances of the BS class. We could also discuss the possibility of creatingnew events for the class, and creating error handling routines. However thebasics discussed thus far will suffice for most of our purposes.

• A Class definition must be entered in a Class Module which can be inserted ina project through the Insert menu. Classes can be exported to .cls files andimported to any project. Both Import and Export is accomplished throughthe appropriate menu item in the File menu.

• The name of the Class si the same as the name displayed under Class Modulesin the Project window (initially, it is Class1 or similar). To change the name,press F4 to bring up the Properties menu and alter the name field.

• There follows now a listing of the BS Class.

68 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

’Listing of the BS ClassOption Explicit

Private mX As Double ’R/W X is the Strike pricePrivate mSo As Double ’R/W So is the initial asset pricePrivate mr As Double ’R/W r is the Risk-free rate percentagePrivate msigma As Double’R/W sigma is the Volatility percentagePrivate mT As Double ’R/W T is the time in yearsPrivate mq As Double ’R/W q is the continuous dividend rate

’In variablenames of this class, the default prefix is dbl (Double variables)

Public Property Get X() As DoubleX = mX

End Property

Public Property Let X(ByVal NewX As Double)mX = NewX

End Property

Public Property Get So() As DoubleSo = mSo

End Property

Public Property Let So(ByVal NewSo As Double)mSo = NewSo

End Property

Public Property Get rate() As Doublerate = mr

End Property

Public Property Let rate(ByVal Newr As Double)mr = Newr

End Property

Public Property Get sigma() As Doublesigma = msigma

End Property

Public Property Let sigma(ByVal Newsigma As Double)msigma = Newsigma

2.15. CLASS MODULES 69

End Property

Public Property Get T() As DoubleT = mT

End Property

Public Property Let T(ByVal NewT As Double)mT = NewT

End Property

Public Property Get q() As Doubleq = mq

End Property

Public Property Let q(ByVal Newq As Double)mq = Newq

End Property

Public Function d1() As Doubled1 = (Log(mSo / mX) + (mr - mq

+ 0.5 * msigma ^ 2 * mT)) / (msigma * Sqr(mT))End Function

Public Function d2() As Doubled2 = d1 - msigma * Sqr(mT)

End Function

Public Function Cll() As DoubleCll = mSo * Application.NormSDist(d1) - mX * Exp(-mr * mT)

* Application.NormSDist(d2)End Function

Public Function Pt() As DoublePt = Cll() - mSo + mX * Exp(-mr * mT)

End Function

70 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

• CollectionsGiven a class, it is possible to construct a collection class which will keeptrack of instances of the original class as they are created. In EXCEL, forexample, the WorkSheet class has a collection class Sheets, which houses allthe sheets in a Workbook that have been created. In general, if the classnameis Xyz then the collection of instances of such classes is named Xyzs.

◦ The collection is created by dimensioning a variable As Collection andsetting it to a new instance of the class that has been created. We illustratethis procedure by creating the collection BSs of Black-Scholes objects - seebelow.

◦ The holding variable mBSs is declared Private (which must be done in theDeclarations section.) A collection is a class which has built in methodsAdd, Remove and built in Read-Only properties Item, Count. The meth-ods add and delete an instance, the property Item finds the instance witha given name or index and the property Count returns the number of in-stances in the collection. However, since the variable mBSs is Private, thesemethods and properties are not available to the user. The variable couldbe declared Public, but this would not allow the collection to control theiruse. For example, it may be necessary to define the values of properties ofthe original class, and the user cannot be trusted to do it correctly on hisown. So it is necessary to write Public versions of these properties andmethods, which use the private versions.

◦ the public Add method here creates the BS class instance, fills in all itsproperties and calls the private Add method to add the instance to thecollection. The instance can be created optionally with a name given bythe input string variable sKey. This can be used to refer to the instance(see comments in the function definition below.) If the optional argumentis not included, the instance can be referred to by a positive integral Index.

◦ The Remove and Count property routines are self explanatory.◦ There are two events, Class Initialize and Class Terminate which oc-

cur on initialization and termination of the collection. The first is used toset the variable mBSs to an new instance of a collection. The second is usedto remove the content of this variable.

◦ The routine NewEnum is difficult to explain properly, and may be omitted.If it is omitted, then there is only one way to run through all instances inthe collection, namely

Dim i As IntegerFor i=1 To (variable).Count

(Statements involving Item(i))Next

2.15. CLASS MODULES 71

If the routine is included, one can, in addition, useDim v as ObjectFor Each v In (collectionvariable)

(Statements)Next

The symbols [ NewEnum] indicates a hidden routine. There should be a wayof setting the attributes of this routine by using a statement, but I do notknow what it is. The only way I know is by importing the new collectionclass into the VB6 VBE, placing the cursor on the NewEnum word in thefirst line of that procedure, going to Tools|Procedure Attributes|Advanced,filling in -4 as Procedure ID and checking the Hide this member button.The collection class can be saved and imported back. I am not sure whatall this means.

◦ There is a sub below which illustrates the use of the BSs collection. If youhave not included NewEnum then comment out the For Each ... Nextlines. Run the sub with the Immediate Window open.

◦ The VB6 VBE is a better environment for creating classes. They shouldbe created without the EXCEL features, saved, imported and completed.Some versions have an add-in Class Builder Utility which, among otherthings, allows rapid creation of collections once the class is defined.

◦ Classes can also raise errors and do error handling, and define events, but wewill not go into this here as they are of more limited usefulness in numericalwork.

72 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

’local variable to hold collectionPrivate mBSs As Collection

Public Function Add(q As Double, T As Double, sigma As Double, _rate As Double, So As Double, X As Double, Optional sKey As String) _As BS’create a new objectDim objNewMember As BSSet objNewMember = New BS

’set the properties passed into the methodobjNewMember.q = qobjNewMember.T = TobjNewMember.sigma = sigmaobjNewMember.rate = rateobjNewMember.So = SoobjNewMember.X = XIf Len(sKey) = 0 Then

mBSs.Add objNewMemberElse

mBSs.Add objNewMember, sKeyEnd If

’return the object createdSet Add = objNewMemberSet objNewMember = Nothing

End Function

Public Property Get Item(vntIndexKey As Variant) As BS’used when referencing an element in the collection’vntIndexKey contains either the Index or Key to the collection,’this is why it is declared as a Variant’Syntax: Set foo = x.Item("xyz") or Set foo = x.Item(5)

Set Item = mBSs(vntIndexKey)End Property

Public Property Get Count() As Long’used when retrieving the number of elements in the’collection. Syntax: Debug.Print x.Count

2.15. CLASS MODULES 73

Count = mBSs.CountEnd Property

Public Sub Remove(vntIndexKey As Variant)’used when removing an element from the collection’vntIndexKey contains either the Index or Key, which is why’it is declared as a Variant’Syntax: x.Remove(xyz)

mBSs.Remove vntIndexKeyEnd Sub

Public Property Get NewEnum() As IUnknown’this property allows you to enumerate’this collection with the For...Each syntaxSet NewEnum = mBSs.[_NewEnum]

End Property

Private Sub Class_Initialize()’creates the collection when this class is createdSet mBSs = New Collection

End Sub

Private Sub Class_Terminate()’destroys collection when this class is terminatedSet mBSs = Nothing

End Sub

Testing Routine

Sub BStest()’This is a routine testing various aspects of the BS class, BSs Collection

Dim objBS As BS, v As BS, i As IntegerDim objBSs As BSs

74 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Set objBSs = New BSsSet objBS = objBSs.Add .05, 1, .2, .05, 100, 105, "first")objBSs.Add q:=.025, T:=1, sigma:=.25, rate:=.075, _

So:=90, X:=95, sKey:="second"

Debug.Print "Call", objBS.CllDebug.Print "Put", objBS.PtDebug.Print "X", objBS.XDebug.Print "rate", objBS.rateDebug.Print "Count", objBSs.Count

For Each v In objBSsDebug.Print "Call" & " " & i, v.Cll

Next

For i = 1 To objBSs.CountDebug.Print "Put" & " " & i, objBSs.Item(i).Pt

Next

objBSs.Remove "first"objBSs.Remove "second"

End Sub

2.16. APPENDIX 1 - VBA KEYWORDS 75

2.16 Appendix 1 - VBA Keywords

• Visual Basic Naming Rules

Use the following rules when you name procedures, constants, variables, andarguments in a Visual Basic module:

• One must use a letter as the first character.

• One cannot use a space, period (.), exclamation mark (!), or the characters, &, $, # in the name.

• Name cannot exceed 255 characters in length.

• Do not use names that are the same as the functions, statements, andmethods in Visual Basic. You end up shadowing the same keywords in thelanguage.

• Do not repeat names within the same level of scope. For example, onecannot declare two variables named Age within the same procedure.

• Visual Basic is not case-sensitive, but if a name is dimensioned or other-wise declared then VBA repeats the capitalization of the variable in thedeclaration in all occurrences of the same variable.

76 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Data Type Summary

The following table shows the supported data types, including storage sizes andranges.

Data type Storagesize

Range

Byte 1 byte 0 to 255Boolean 2 bytes True or FalseInteger 2 bytes -32,768 to 32,767Long(long integer)

4 bytes -2,147,483,648 to 2,147,483,647 Single (single-precision floating-point) 4 bytes -3.402823E38 to-1.401298E-45 for negative values; 1.401298E-45to 3.402823E38 for positive values

Double(double-precisionfloating-point)

8 bytes -1.79769313486231E308 to -4.94065645841247E-324 for negative values; 4.94065645841247E-324to 1.79769313486232E308 for positive values

Currency(scaled integer)

8 bytes -922,337,203,685,477.5808 to922,337,203,685,477.5807

Decimal 14 bytes +/-79,228,162,514,264,337,593,543,950,335with no decimal point; +/-7.9228162514264337593543950335 with28 places to the right of the deci-mal; smallest non-zero number is +/-0.0000000000000000000000000001

Date 8 bytes January 1, 100 to December 31, 9999Object 4 bytes Any Object referenceString(variable-length)

10 bytes + string length 0 to approximately 2 billion

String(fixed-length)

Lengthof string

1 to approximately 65,400

Variant(with numbers)

16 bytes Any numeric value up to the range of a Double

Variant(with characters)

22 bytes + string length Same range as for variable-length String

User-defined(using Type)

Numberrequired byelements

The range of each element is the same as therange of its data type.

Note: Arrays of any data type require 20 bytes of memory plus 4 bytes foreach array dimension plus the number of bytes occupied by the data itself.

2.16. APPENDIX 1 - VBA KEYWORDS 77

For example, the data in a single-dimension array consisting of 4 Integer dataelements of 2 bytes each occupies 8 bytes. The 8 bytes required for the data plusthe 24 bytes of overhead brings the total memory requirement for the array to32 bytes. A Variant containing an array requires 12 bytes more than the arrayalone.

Note: Use the StrConv function to convert one type of string data to another.

78 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Conversion Keyword Summary

Action KeywordsANSI value to string. ChrString to lowercase or uppercase. Format, LCase, UcaseDate to serial number. DateSerial, DateValueDecimal number to other bases. Hex, OctNumber to string. Format, StrOne data type to another. CBool, CByte, CCur, CDate,

CDbl, CDec, CInt, CLng, CSng,CStr, CVar, CVErr, Fix, Int

Date to day, month, weekday, or year. Day, Month, Weekday,YearTime to hour, minute, or second. Hour, Minute,Second String to ASCII value. AscString to number. ValTime to serial number. TimeSerial, TimeValue

Data Types Keyword Summary

Action KeywordsConvert between data types. CBool, CByte, CCur, CDate, CDbl, CDec,

CInt, CLng, CSng, CStr, CVar, CVErr, Fix, IntSet

Intrinsic data types. Boolean, Byte, Currency, Date, Double, Integer,Long, Object, Single, String, Variant (default)

Verify data types. IsArray, IsDate, IsEmpty, IsError, IsMissing, Is-Null, IsNumeric, IsObject

Math Keyword Summary

Action KeywordsArithmetic. ˆ , −, ∗, /, Mod e.g. 10 Mod 3: result

1,+, & (string op.), =

Trigonometric functions. Atn, Cos, Sin, TanGeneral calculations. Exp, Log, SqrGenerate random numbers. Randomize, RndGet absolute value. AbsGet the sign of an expression. SgnPerform numeric conversions. Fix, IntRounnding. Round(x[,No. Decimal Places])

2.16. APPENDIX 1 - VBA KEYWORDS 79

String Manipulation Keyword Summary

Action KeywordsCompare two strings. StrCompConvert strings. StrConvConvert to lowercase or uppercase. Format, Lcase, UcaseCreate string of repeating character. Space, StringFind length of a string. LenFormat a string. FormatJustify a string. LSet, RsetManipulate strings. InStr, Left, LTrim, Mid, Right, RTrim,

TrimSet string comparison rules. Option CompareWork with ASCII and ANSI values. Asc, Chr

Prefix ConventionsDataType

Prefix

Boolean blnCurrency curDouble dblDate/Time dtmInteger intLong lngSingle sngString strVariant vnt

Relational and Logical Operators

Relational Operators Logical Operators> (greater than) And

< (less than) Or

= (equal to) Not

>= (greater than or equal to)<= (less than or equal to)<> (not equal to)

80 CHAPTER 2. VISUAL BASIC FOR APPLICATIONS – EXCEL 2007

Dates and Times Keyword Summary

Action KeywordsGet the current date or time. Date, Now, TimePerform date calculations. DateAdd, DateDiff, DatePartReturn a date. DateSerial, DateValueReturn a time. TimeSerial, TimeValueSet the date or time. Date, TimeTime a process. Timer

Directories and Files Keyword Summary

Action KeywordsChange directory or folder. ChDirChange the drive. ChDriveMake directory or folder. MkDirRemove directory or folder. RmDirName Return current path. CurDirReturn file date/time stamp. FileDateTimeReturn file, directory, label attributes. GetAttrReturn file length. FileLenReturn file name or volume label. DirSet attribute information for a file. SetAttr

2.17. EXERCISES 81

2.17 Exercises

1. Write a subroutine which takes as input a range in the form A1:C50 andclears the range of all content, all borders and also of colour. Allow the userinstead to clear these from the currently selected range. [If necessary, getideas from running a macro].

2. Write a subroutine for estimating the cumulative normal distribution bymeans of a polynomial. Look up an appropriate algorithm in Press etalor Hull or somewhere similar.

3. Write a subroutine which multiplies two variables representing matrices. In-put also the matrix sizes. Do similarly for a subroutine for taking the trans-pose of a matrix.

4. Write three functions which return values drawn from a Uniform, Poissonand Binomial distribution.

5. Write a function for solving an single equation of the form f(x) = 0 byNewton’s method and by the Newton-Bailey method. [Look them up if nec-essary].

6. Extend the previous question to the case of more than one equation.