7 VBA functions - staff.city.ac.uk

advertisement
Excel VBA - City University Continuing Education
VBA for Microsoft Excel – Part 7
Table of Contents
1
2
3
4
5
6
7
8
Creating User Defined Functions ................................................................ 1
1.1
The Function Declaration .................................................................... 1
1.2
Defining a function ................................................................................ 1
1.3
Testing the function .............................................................................. 2
1.4
Using the function on a worksheet ..................................................... 2
1.5
A function to calculate NetPay ............................................................ 2
1.6
Calling a function from VBA code ...................................................... 3
Do loops .......................................................................................................... 4
2.1
Do While Example ................................................................................ 4
2.2
Do Until Example .................................................................................. 4
2.3
The Conditional statement in a Do loop ............................................ 4
2.4
Avoiding ‘runaway’ loops ..................................................................... 5
WorksheetFunction method ......................................................................... 5
Creating a command button ......................................................................... 6
4.1
Attaching code to a button ................................................................... 6
Calling a procedure from another procedure ............................................ 7
Events .............................................................................................................. 7
VBA functions ................................................................................................ 8
Showing the Developer Tab (Excel 2010 /2013) ...................................... 10
1
Creating User Defined Functions
There are two types of procedure –Subs and there are also Functions. The
characteristic feature of a function is that it returns a value to the location
where the function is called. Secondly, if you create a function you can use it
on the worksheet as a formula.
1.1
The Function Declaration
The opening line is called the function declaration. For example the first line of
a function to find the area of a circle might look like:
Function AreaCircle(rad as Single) As Single
Argument
1.2
data type of argument
data type of return value
Defining a function
The whole function might look like:
Function AreaCircle(rad as Single) As Single
AreaCircle = 3.14159 * rad * rad 'this line returns the value
End Function
The calculation in the body of the function uses the argument that must be
supplied to it, i.e., rad – a variable here is not necessary.
The whole point of a function is to return a value; therefore the function must
include a line somewhere that does this. In the above example that line is
AreaCircle = 3.14159 * rad * rad
It is essential to note that in this expression the return value is the same word
as the function name, i.e., AreaCircle
Page 1 of 10
Excel VBA - City University Continuing Education
1.3
Testing the function
You can test the function in the Immediate window before you attempt to use
it, e.g.,
In the next step click in the textbox and click the cell that contains the radius,
then click OK
?AreaCircle(10)
The example is supplying 10 as the argument, so the function returns the area
of a circle with radius 10
1.4
Using the function on a worksheet
You cannot run a function in the same way you would run a Sub. You must
call it. You can directly use it in a formula:
Type ‘=AreaCircle( ‘ into a cell, click a cell that contains a number , then
click the Enter button (the tick)
1.5
A function to calculate NetPay
Let's say you want to create a function that calculates how much your Net Pay
is after deductions. The function would involve these values:
Or you can click the InsertFunction button,
choose UserDefined
from the dropdown,
select the function
from the list and
click OK

GrossPay: how much you earn before deductions

Income Tax as a percentage

National Insurance as a percentage

Pension Fund as a percentage
NetPay is how much you take home after IncomeTax, National Insurance and
Pension Fund contributions have been deducted.
The arithmetic would look like this in code:
Deductions = (GrossPay * IncomeTax) _
+ (GrossPay * NI) _
+ (GrossPay * Pension)
NetPay = GrossPay - Deductions
Page 2 of 10
Excel VBA - City University Continuing Education
The full function would look like this:
Function NetPay _
(GrossPay As Single, _
IncomeTax As Single, _
NI As Single, _
Pension As Single) As Single
Dim Deductions As Single
Deductions = (GrossPay * IncomeTax) + _
(GrossPay * NI) + _
(GrossPay * Pension)
NetPay = GrossPay - Deductions
End Function
Note that NetPay is the return value for the function and the function name.
Again, select a cell and choose the Insert Function icon
Choose the User Defined category and select NetPay and click OK
Put the cell references into the textboxes and click OK
As another example, you could write a function which named PriceChange
to calculate the percentage change in a share price. The function might look as
follows:
Function PriceChange _
(opening As Single, closing As Single) As Single
PriceChange = (closing - opening) / opening
End Function
It really doesn’t matter what you call the arguments, as long you use them in a
way that is consistent with the logic of the function.
1.6
Calling a function from VBA code
The following sub is designed to work with the worksheet Prices in the week 7
workbook. To simplify the code, cell D2 would need to be preselected
To call a function in code use it on the RHS of an equals sign, e.g.
variable = Function(argument list) or
RangeObject=Function(argument list)
Sub CalcReturns()
Do
ActiveCell = PriceChange _
(ActiveCell.Offset(0, -2), ActiveCell.Offset(0, -1))
ActiveCell.NumberFormat = "0.00%;[Red]-0.00%"
ActiveCell.Offset(1, 0).Select
Loop Until ActiveCell.Offset(0, -3).Value = ""
End Sub
Above, we have ActiveCell = PriceChange(Arg1, Arg2)
The function is designed to accept two arguments.
The repetition is controlled by Do .. Loop Until. The call to the function is on
line 3, and the two required arguments are supplied. Crucially, the two
arguments are the cell that is two to the left and the cell that is one to the left of
the active cell.
Page 3 of 10
Excel VBA - City University Continuing Education
2
Do loops
We have previously encountered two types of For loop:
For Each iterates through a range of selected cells, or a collection
For loops enable actions to be repeated a specified amount of times
Do Loops can be used when the programmer cannot be sure how many times
the repetition needs to take place. The syntax of a Do loop requires a condition,
which evaluates to True or False and the condition determines how many
times to repeat code. There are two variants of a Do loop:

Do While - the loop can run while some condition is true – when it
becomes false, the loop stops. An example would be to carry out some
arithmetic while there is data
2.2
Do Until Example
Sub CalcSquares_until()
Do Until IsEmpty(ActiveCell)
ActiveCell.Offset(0, 1) = ActiveCell ^ 2
ActiveCell.Offset(1, 0).Select
Loop
End Sub
Note that both these loops use ActiveCell, and require that you select the next
cell down, otherwise the loop will never terminate.
Here is an example that uses a variable in the conditional statement.
Do loops use a conditional expression, like an If statement e.g.,
Sub DWL()
Dim x As Integer
x = 0
Do While x < 5
Debug.Print x
x = x + 1
Loop
End Sub


2.3

Do Until – the initial condition is false and the loop runs until it becomes
true - when it becomes true, the loop stops. An example would be to sum
values in cells until a certain figure is reached.
In truth, however, a programmer can usually arrive at a solution using either.
Do While Total <= 100
Do Until Total >= 100
Do loops are often set up to repeat code until an empty cell is encountered.
Do Until IsEmpty(ActiveCell)
The following two programs do the same thing, they iterate through a range of
cells (take care they contain numbers) in a column, and write the square of the
number to the adjacent cell on the right.
2.1
Do While Example
Sub CalcSquares_while()
Do While Not IsEmpty(ActiveCell)
ActiveCell.Offset(0, 1) = ActiveCell ^ 2
ActiveCell.Offset(1, 0).Select
Loop
End Sub
x < 5 is the condition which initially evaluates
to True
The key word Loop returns control to the Do
While statement which re-evaluates the
condition;
The Conditional statement in a Do loop
Actually, there are two further variations on Do While and Do Until 
The programs above have the condition at the beginning of the loop.
It is also possible to have the condition at the end of the loop. In the majority
of cases it doesn’t make any difference!
Change the above code by assigning the value 6 to the variable x, and run the
code again – nothing prints, because the condition is never True.
So, a characteristic of the Do . . While loop is that, depending on
circumstances, it may never execute the statements at all.
The next code has the conditional statement at the end of the loop
Page 4 of 10
Excel VBA - City University Continuing Education
Sub DLW()
Dim x As Integer
x = 0
Do
Debug.Print x
x = x + 1
Loop While x < 5
End Sub
ActiveCell = WorksheetFunction.Average(Range(“B2:B9”)) or
there is no condition at this stage so the
statements to be executed happen at least
once.
If you write the code so that the condition is evaluated at the end, the loop is
guaranteed to execute the statements at least once. To illustrate, assign 6 to the
variable x immediately before the Do statement.
Avoiding ‘runaway’ loops
2.4
Note the statement x = x + 1 which eventually changes the outcome of the
condition - otherwise the loop would run ‘forever’. Similarly, it the loop is
coded to terminate when a blank cell is encountered, forgetting to select the
next cell down would mean the loop can never terminate.
If there is a mistake in the programmer’s logic it is possible to write a loop that
never terminates. If you have a runaway loop press Escape. Otherwise you
may need to use Windows Task Manager and terminate Excel and lose unsaved
work.



Loops can contain control statements such as If Then or other loops
If statements can contain loops
You can break out of a Do loop if necessary by using the Exit Do
keywords
3
WorksheetFunction method
If you want to use Excel’s worksheet functions in your code, the
Application has a WorksheetFunction method. The syntax is:
Application.WorksheetFunction.FunctionName(arg1,arg2)
where FunctionName is the name of an Excel function. (You can drop
Application from the reference) For example,
ActiveCell = WorksheetFunction.Max(Worksheets(“Exams”).Range(“C6:C22”))
Range(“B10”) = WorksheetFunction.Average(Selection)
You can make use of the Union operator (,) with the arguments to the function
ActiveCell = WorksheetFunction.Average(Range(“B2:B9”), Range(“D2:D9”))
The limitation with WorksheetFunction is that the functions don’t recalculate
unless you re-run the macro - for dynamic data, it is better to use Excel’s
formulas. On the other hand these statements are quicker to run than a
solution that uses loops
You might put the return value into a variable e.g.,
variable = WorksheetFunction.Sum(Selection)
Sub SumNumbersInSelection()
Dim Total As Single
Total = WorksheetFunction.Sum(Selection)
Range(“D12”) = Total
MsgBox "The sum of numbers in the selection is " _
& Total
End Sub
You can combine WorksheetFunction with a loop, e.g., the following calculates
the average of numbers in the two columns to the left of the active cell.
Sub LoopAverage()
Do While Not IsEmpty (ActiveCell.Offset(0, -1))
ActiveCell = WorksheetFunction.Average _
(ActiveCell.Offset(0, -1).Value, _
ActiveCell.Offset(0, -2).Value)
ActiveCell.Offset(1, 0).Select
Loop
End Sub
WorksheetFunction.Pi
Excel’s Pi( ) function can be used to provide  in calculations. For example,
Circumference = 2 * WorksheetFunction.Pi * Radius
Page 5 of 10
Excel VBA - City University Continuing Education
4
Creating a command button
Use the Insert button on the Developer tab (see section 8).
If you use the Insert button you will display the available controls, divided
into two categories: Form controls and Active X controls. While they look
identical, they work in a different way. Form controls have been superseded
by the Active X controls; the main difference is that you can write code
directly for an Active X control, whereas with a Form control you can only
assign an existing macro.
The most immediate properties are:
• Name – the name of the button which is how you refer to it in VBA code
• Caption – the text as displayed on the button itself
By changing the caption, you can see that the button display changes - spaces
are not allowed in names, but are allowed in captions. Close the Properties
window when you have finished with it.
4.1
To place a command button on your worksheet, click the command button
tool then draw a rectangle on your worksheet to the size that you want.
Attaching code to a button
At the moment there is no code is attached to the button. To create code, in
Design mode double-click the button. You will see the beginning and end of
a procedure. The programmer’s job is to write the code, or call an existing
macro.
Private Sub CommandButton1_Click()
End Sub
This code is known as an event procedure, specifically the Click event of the
button. The first line has the optional keyword Private - this means the code
can only run when the button is clicked, it is not otherwise available.
When you create the Command button, the Design mode button is
automatically turned on. In Design mode you can resize the button, move it,
and customise its properties.
Click the Properties button to display the Properties window.
The name of the sub consists of: the name of the button, an underscore, the
event, i.e. Click and the brackets. All event handling code follows this
pattern. Also notice the location of the code – it is on the module for the sheet
that contains the button.
Page 6 of 10
Excel VBA - City University Continuing Education
5
Calling a procedure from another procedure
One sub can call another Sub, merely by typing the sub’s name on a line – you
can optionally use the keyword Call. For example,
Private Sub cmdCalcPrices_Click()
Range("D2").Select
Call CalcReturns
End Sub
You will note the above code is attached to the click of a button. It selects the
appropriate cell, and calls the program CalcReturns. In this way you can
reuse the program CalcReturns elsewhere in the workbook, because it is
free of references that tie it to a specific location.
Calling a Sub from another sub is not restricted to button code, you can use
the technique in any module. In fact, it is good programming practice. Don’t
try to make one procedure do too much – divide a complex task into ‘chunks’,
write a separate Sub for each chunk, and call the other subs from a main
program as necessary.
6
Double click here to
opent the workbook
module
The module is initially empty; click the dropdown control at the top left of the
window, and click Workbook.
Events
As well as properties and methods, objects have Events. An Event is a change
of state which can be interrupted by some user defined code.
Strictly speaking a command button is not an Excel object, it as an Ms Office
object. However you can use events of Excel objects, usually Application,
Workbook and Worksheet. An intuitive example is the Workbook’s Open
event.To create some code for the Workbook’s Open event, double click the
ThisWorkbook icon in the Project Explorer window and this will open the
module that belongs to the workbook.
This creates an empty procedure for the Open event, merely type in any code
that you wish to be executed every time the workbook is opened.
Private Sub Workbook_Open()
MsgBox "Welcome " & Application.UserName & vbCr & _
"The workbook was opened " & Now()
End Sub
Tip! To open the workbook and bypass the event code, hold down Shift
when you double-click the file icon to launch the file. This can be a lifesaver if
the code you create has unintended effects.
Page 7 of 10
Excel VBA - City University Continuing Education
7
VBA functions
VBA provides many inbuilt functions, some of which are the same as in Excel. They are divided into categories, here is a selection.
VBA Date and Time functions
Function
Date() or Now()
Day()
Month()
Year()
Weekday()
Description
returns the current system date
returns an Integer representing the day from a Date
value
returns an Integer that represents the month of a Date
value
returns an Integer that represents the year of a Date
value
returns day of the week (Sunday = 1)
Example (You can use # instead of “ in examples)
Date()
Day(“31-Jan-2004”)
returns 31
Month(“31-Jan-2004”)
returns 1
Year(“31-Jan-2004”)
returns 2004
Weekday(“31/01/2004”)
returns 7
DateAdd()
returns a data to which a specified time interval has
been added; all three arguments are required
DateAdd("yyyy", 1, date())
returns the date 1 year from today
DateAdd("ww", -3, ”4 Mar 2004”)
returns the date 3 weeks earlier than 4th March 2004
DateDiff()
DateSerial()
returns an Integer representing the difference between
two dates
returns a date given three integers
that specify year, month, day in that order
VBA Text manipulation functions
LCase()
UCase()
Trim()
LTrim()
RTrim()
Len()
returns lower case version of a string
returns upper case version of a string
removes leading and trailing spaces from a string
removes leading spaces from a string
removes trailing spaces from a string
returns number of characters in a string
Left()
returns leftmost characters of a string
DateDiff(“d”, Date(), ”31-Jan-2004”)
returns the number of days between 31-Jan-2004 and the current date
DateSerial(2004, 1,31)
returns 31/01/2004
Example
LCase(“ABCD”)
UCase(“abcd”)
Trim(“ ABC “)
LTrim(“ ABC”)
RTrim(“ABC “)
Len(“Manchester”)
returns 10
Left(“Manchester”,4)
returns Manc
Page 8 of 10
Excel VBA - City University Continuing Education
Right()
returns rightmost characters of a string
Mid()
returns characters within a string
StrComp()
compares two strings for equivalence and returns the
integer result of comparison: 0 if strings are equal, -1or
1 if strings are different
StrConv
converts the case of a string
Val()
returns numeric value of a string
Right(“ABCDEF,3”)
returns DEF
Mid("Lindsey Davenport",9,4)
returns Dave i.e. start at the 9th character and return a string 4
characters long
Mathematical functions
Abs()
returns absolute value of numeric field
Int()
returns numeric value with the decimal fraction
discarded
returns a number rounded to a specified number of
decimal places. syntax is:
Round()
Round(expression, numdecimalplaces)
where the numdecimalplaces argument
Rnd()
is optional; the
function returns an integer if it is omitted.
creates random number (single) between 0 and 1
StrComp(“ABC,”abc”)
returns 1 (strings are not considered to be the same)
StrComp(“ABC,”abc”,vbTextCompare)
returns 0 (strings are are considered to be the same; vbTextCompare
performs case insensitive comparison)
StrConv(“london”, vbProperCase) returns “London”
you could also use vbUpperCase and vbLowerCase for the
conversion argument
Val(“123.45”)
Example
Abs(-1234.5)
returns 1234.5
Int(13.9)
returns 13
round(12.459, 2)
returns 12.46
round(12.9)
returns 13
to generate a random whole number between 0 and 9 you can use:
Int(Rnd()*10)
Other maths functions are: Atn , Cos , Exp, Log, Sgn, Sin, Sqr, Tan
Page 9 of 10
Excel VBA - City University Continuing Education
Array function
You can use the Array() function to write a value to a range of cells instead of
coding each cell separately. For example, to generate headings you could have
Range(“A1:D1”) = Array (“First Name”,”Last Name”,”Dept”,”Pay Rate”)
You can also use Array() to group worksheets
Worksheets(Array("Prices", "Exams", "net_pay")).Select
or
Worksheets(Array(1, 3, 5)).Select
The next code example shows how to create a loop that processes grouped
worksheets.
Sub GroupSheets()
Dim w As Worksheet
Worksheets(Array("Prices", "Exams", "net_pay")).Select
For Each w In ActiveWindow.SelectedSheets
w.Cells(1).Interior.Color = vbGreen
Next w
End Sub
The reference you need to remember is
For Each variable In ActiveWindow.SelectedSheets
8
Showing the Developer Tab (Excel 2010 /2013)
To display the Developer tab in the Ribbon, follow these steps:
1.
2.
3.
4.
click the File menu in Excel
choose Options
in the list on the left click Customize Ribbon
in the List on the right check the entry for Developer
The Developer tab gives you additional buttons to record and stop recording
macros, and access to the Visual Basic Editor. There is also an Insert button
which you can use to place controls on worksheets like Command buttons,
Combo boxes and more.
The Developer Tab (Excel 2007)
To show the Developer tab for Excel 2007, follow these steps:
1.
2.
3.
4.
click the icon to display the Office toolbar
choose Excel options at the bottom of the display
in the window that appears ensure that Popular is highlighted
tick the checkbox that says Put the Developer Tag in the Ribbon
Page 10 of 10
Download