22
User Defined Functions Conestoga College © v.1.5 Peter Komisar reference: 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad This note has been generated for private academic use and is not meant to be published - PK // We discuss how to create functions followed by a survey of Mr. Excel's team's functions Excel calls user defined functions UDFs. They are used just like built-in functions. UDFs can only be entered into standard modules and not into Sheet and ThisWorkbook modules. Building a Custom Function Open a new module type the following function code in when finished save the module The function is ready to be used! A Simple Function Function CopyRight( ) As String CopyRight = “©” End Function Simple Sub To Run This Function Sub CopyR() Range(“A1”).Value = CopyRight End Sub The function name is CopyRight, it takes no arguments and returns a String value, the copyright symbol. Another Function Example Function ConCat(N1 As String, N2 String As String) As String Concat = N1 & N2 End Function

User Defined Functions - Sentex Data Communicationspkomisar/VBA/4_UserDefinedFunctions.pdf · Excel calls user defined functions UDFs. ... results of an operation inside the function

Embed Size (px)

Citation preview

User Defined Functions

Conestoga College © v.1.5 Peter Komisar

reference: 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy SyrstadThis note has been generated for private academic use and is not meant to be published - PK

// We discuss how to create functions followed by a survey of Mr. Excel's team's functions

Excel calls user defined functions UDFs. They are used just like built-in functions. UDFs can only be entered into standard modules and not into Sheet and ThisWorkbook modules.

Building a Custom Function

• Open a new module • type the following function code in• when finished save the module

The function is ready to be used!

A Simple Function

Function CopyRight( ) As String CopyRight = “©”End Function

Simple Sub To Run This Function

Sub CopyR()Range(“A1”).Value = CopyRightEnd Sub

The function name is CopyRight, it takes no arguments and returns a String value, the copyright symbol.

Another Function Example

Function ConCat(N1 As String, N2 String As String) As StringConcat = N1 & N2End Function

Summary of Function Structural Details

ConCat → function nameParenthesis → house two arguments'As String' → makes the variable type 'String'

Notice each argument within the braces is set to String type butalso the overall function is set to 'As String' implying the value thatwill be returned by the function is a String type.

Setting the return type of the function seems to be optional, as the function works without this declaration. One assumes the compiler can figure out the return type of the function from what is assigned to the name of the function. It is good to set the function return type though. A reader can easily tell what return value the function generates.

Assigning the Function Return Type By Assigning to the Function Name

Another unique aspect to Excel functions, is the assignment of the results of an operation inside the function to the name of the function.This maneuver establishes what return value the function will have.

Example

Add = N1 + N2 // where Add is the name of the function

To Use UDFs, User Defined Functions // specifically this Add function

• Enter a worksheet • type numbers into cells A1 & A2• select A3 • press Shift + F3 // or hit the fx icon

• select User Defined under category• select target function• select A1 in arg box 1• select A2 in arg box 2• click OK

This function can also be called from a macro as is shown below.

A Procedure Calling a User Defined Function

Sub ToAdd()Range("A1").Value = Add(10001, 20002)End Sub

A Word on Editing, Overwriting and Deleting Functions

Note Functions are not as accessible as Macros to editing which is probably an intentional design consideration.

What if you write a second function with the same name?

Rather than replacing the original you get an error message that the name of the function is ambiguous and Excel then qualifies the name with the name of the module. So the function name becomes Module11.Add or something like that.

So how do I get rid of functions to start fresh?

The functions are stored in modules even though they are not offered up for editing like macros are. Use Project Explorer in the VB Editor to locate the module the function is stored in and edit it there or you may delete it altogether.

Storing UDFs

User defined functions can be stored in different places to suit specificrequirements. Mr. Excel lists the following.

• Personal.xlsb – for private use and not in a workbook opened on another computer

• Workbook – store it in the workbook in which it is being used• useful for distributing to many people

• Add-in – putting the UDF in an Add-in allows group sharing

• Template – A UDF can be stored in a Template • for use in creating several workbooks • distributed to many people

Mr. Excel doesn't tell us yet the details of these sharing techniques so for now we will store by the default method which associates the function with the current opened workbook.

Excel 2010, Chapter 4 vs Excel 2013 Chapter 13

A quick look shows the two chapters have the same content except thefinal method, that uses the Case statement has had the example switched.

Contributor Examples

Mr. Excel dives into a survey of a large number of functions that weredesigned by contributors to his book. There is a lot of code offered forviewing that is not explained at all. We take up doing the survey anyway explaining various salient features we encounter along the way.

Because we are taking up this chapter a little later in our course, thereare points made that have already been covered. This sort of materialis left in to serve as a general review.

Text Download Resource // for reference purposes

Note the text's download resource has these functions listed. There isat least one function for which there are two variations, probably to work with earlier Excel versions. Also some functions in the download are a bit different than in the book so check as you go.

The Workbook Name Function

The first contributor function makes a call on the Name property to return the name of the current workbook. Notice again the return type of the function is String and in this case it takes no arguments. Also notice what is returned is assigned to the name of the function.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function MyName() As String MyName = This Workbook.NameEnd Function

OUTPUT

Book1.xlsm

The following form of the above function supplies the complete path to the workbook.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function MyFullName() As String MyFullName = This Workbook.FullNameEnd Function

OUTPUT

C:\Documents and Settings\Peter\My Documents\VBA\TrustedMacros\Book1.xlsm

A Function To Test If a Book Is Open

The next one of Mr.Excel's contributor functions tests if a workbook is open. Notice the function returns the Boolean type and takes a String value.

Boolean Type – limited to the values True or False, or 1 or 0

Inside this function, T is declared as the object type Excel.Workbook. Recall that when we assign a value to an object reference the Set operator is used.

Example

Dim T as Excel.Workbook'. . .Set T = Application.Workbooks(BK)

// a little review

A call is made on Err object. Err is not in the Object browser but ErrObject is and it has the following information is provided.

The ErrObject module contains properties and procedures used to identify and handle run-time errors using the Err object In it therea Clear method which has the following description.

Clear - clears all property settings for the Err object.

All programming languages have error handling code to deal with unexpected problems that arise in code. The ErrObject is part of VBA's error handling code.

Not … Is Nothing

The 'Not … Is Nothing' construct tests for whether an object reference is empty or not. Consider the following code. At first O is declared as type Application but has nothing assigned to it. Later we assign it something.

Example Demonstrating Not … Is Nothing

Sub NullTester()Dim O As Application'at this point O is an empty referenceIf Not O Is Nothing ThenRange("A1").Value = "Something"Else: Range("A1").Value = "Null"End If

'lets load OSet O = ApplicationIf Not O Is Nothing ThenRange("A3").Value = "Something"Else: Range("A1").Value = "Null"End If

End Sub

In the following code, note the use of the Not … Nothing construct asit is used to test that the variable T is not empty of a reference. Noticethe Function takes the name of a book as a String value and returnsa boolean value, true or false, if the book is open or not.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function BookOpen(Bk As String) As Boolean Dim T As Excel.Workbook Err.Clear 'clears any errors On Error Resume Next 'if the code runs into an error, it skips it and continues Set T = Application.Workbooks(Bk) BookOpen = Not T Is Nothing 'If the workbook is open,then T will hold the workbook object and therefore 'will NOT be Nothing Err.Clear On Error GoTo 0End Function

GoTo 0 // error handling directive, part of Excel error handling system

More on Error Handling, 'GoTo 0' disables enabled error handler in the current procedure and resets it to Nothing.

Following is a Mr.Excel macro that calls the above method.

Sub Example Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Sub OpenAWorkbook() Dim IsOpen As Boolean Dim BookName As String BookName = "Chapter 4 samples.xls" IsOpen = BookOpen(BookName) 'calling our function – don ’t forget the parameter If IsOpen Then MsgBox BookName & " is already open!!" Else Workbooks.Open (BookName) End IfEnd Sub

The function in the table below demonstrates the Exit Function statement. This allows a function to exit before it ends if certain conditions exist. It's use is exampled in the table below.

Use of the Exit Function

Function X_It(S1 As String, S2 As String) As StringX_It = "1. First Arg: " & S1'Exits function at this point as subsequent value(s) are not assignedExit FunctionX_It = "2. Second Arg: " & S2End Function

A Function To Test If a Sheet Is Open in an Open Workbook

This next Mr. Excel function also returns a Boolean, True or False. Itchecks if a workbook has been added before setting to the WB variable. The code exits if no workbook has been set.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function SheetExists(SName As String, Optional WBName As String) As Boolean Dim WS As Worksheet Dim WB As Workbook On Error Resume Next If Len(WBName) > 0 Then 'check whether a workbook name was entered Set WB = Workbooks(WBName) If WB Is Nothing Then Exit Function 'exit if the workbook isn’t open Else Set WB = ActiveWorkbook End If

Set WS = WB.Sheets(SName) 'if the sheet is found,WS will contain the sheet object 'if the sheet is not found,WS will contain Nothing 'so,if WS is NOT NOTHING,then it must be the sheet object and therefore returns TRUE SheetExists = Not (WS Is Nothing)End Function

Following is the Sub example from the book to run the above method

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Sub CheckForSheet() Dim ShtExists As Boolean ShtExists = SheetExists("Sheet9") 'notice that only one parameter was passed;the workbook name is optional If ShtExists Then MsgBox "The worksheet exists!”" Else MsgBox "The worksheet does NOT exist!”" End IfEnd Sub

// omitted in this survey, the pre-Excel 2007 version of the following method

Recursive File Counter Function Set to Count Workbooks

The following code is rather complicated. It also deals with input andoutput (IO) of files, folders which we haven't covered. The string extension is set to “XLSM” as we are looking at workbook files. It could have been set to other values to search for other file types.

This function is recursive, that is, it is called on itself. When the function finds a directory, it goes into it and recalls itself to iterate the files in the subdirectory. It will recurse until it reaches the bottom of all directories. Where the function is recalled is highlighted in the following code example.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function NumFilesInCurDir(Optional strInclude As String = "", Optional blnSubDirs As Boolean = False)

Dim fso As FileSystemObjectDim fld As FolderDim fil As FileDim subfld As FolderDim intFileCount As IntegerDim strExtension As String strExtension = "XLSM" Set fso = New FileSystemObject Set fld = fso.GetFolder(ThisWorkbook.Path)

For Each fil In fld.Files ' UCase changes a string to uppercase If UCase(fil.Name) Like "*" & UCase(strInclude) & "*." & UCase(strExtension) Then intFileCount = intFileCount + 1 End If Next fil If blnSubDirs Then For Each subfld In fld.Subfolders intFileCount = intFileCount + NumFilesInCurDir(strInclude, True) Next subfld End If NumFilesInCurDir = intFileCount Set fso = NothingEnd Function

The Following macro is supplied to test the method.

Macro Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Sub CountMyWkbks( )im MyFiles As IntegerMyFiles = NumFilesInCurDir(MrE*,true) MsgBox MyFiles & ”files(s) found” End Sub

We skip the User ID function but some points are worth noting.

Look at the method (at the top of page 86, 2010 book, page 311, 2013 book. Note many of the variables are marked private. This restricts access of these variables to the module. This is an Excel VBA Access modifier.

Excel VBA offers two levels of access which can be applied to procedures, functions, variables etc.

Access Modifiers in Excel

• private• public

In the general case, a private modifier restricts access to element that it is applied to code within the containing module.

Public access makes the code it is applied to accessible from modules other than the containing module.

Constants in Excel VB

Note also that the keyword Const is declared in the code to make a value fixed or constant. This is a user defined constant. By convention constants have all upper-case variable names.

Example

Private Const NO_ERROR = 0

Excel's own built-in constants are preceded with the prefix, 'xl'

Example // http://www.quepublishing.com/articles/article.aspx?p=712186&seqNum=5

ActiveWindow.WindowState = xlMaximized

A Function That Returns Date and Time of Last Save

This one works fine and is nice and short. You do have to formatthe cell for Date. To do this follow the Format button down to Cellsand pick Date. The file specified must be fully specified by path.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function LastSaved(FullPath As String) As Date LastSaved = FileDateTime(FullPath)End Function

A Function That Returns the Date and Time

Another simple function is the date time function. It uses the Nowmethod to return the current date and time. This one like the LastSaved function requires that the cell it is used in has been formattedfor Date.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function DateTime( ) DateTime = NowEnd Function

E-Mail Validation Function // complicated but useful

The next function in the Mr. Excel series is a method that validates whether an e-mail address is formed correctly. First it checks if there is just one @ symbol. Anything else is invalid in an e-address so the function exits if this is the case. This process is repeated for various conditions that would not be allowed in a correct e-mail. The final line assigns the boolean return value to the function name.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function IsEmailValid(strEmail As String) As Boolean

Dim strArray As Variant Dim strItem As Variant Dim i As Long Dim c As String Dim blnIsItValid As Boolean blnIsItValid = True

'count the @ symbols in the string i = Len(strEmail) - Len(Application.Substitute(strEmail, "@", "")) 'if there is anything but one @, then it is an invalid email If i <> 1 Then IsEmailValid = False: Exit Function ReDim strArray(1 To 2) 'the following two lines place the text to the left and right 'of the @ in their own variables strArray(1) = Left(strEmail, InStr(1, strEmail, "@", 1) - 1) strArray(2) = Application.Substitute(Right(strEmail, Len(strEmail) - _ Len(strArray(1))), "@", "") For Each strItem In strArray 'verify there is a string stored in the cell of the array. 'If there isn’t,then part of the email is missing If Len(strItem) <= 0 Then blnIsItValid = False IsEmailValid = blnIsItValid Exit Function End If 'verify only valid characters in the email For i = 1 To Len(strItem) 'lowercases all letters for easier checking c = LCase(Mid(strItem, i, 1)) If InStr("abcdefghijklmnopqrstuvwxyz_-.", c) <= 0 _ And Not IsNumeric(c) Then blnIsItValid = False IsEmailValid = blnIsItValid Exit Function End If Next i 'verify that the first character of the left and right aren’t periods If Left(strItem, 1) = "." Or Right(strItem, 1) = "." Then blnIsItValid = False IsEmailValid = blnIsItValid Exit Function End If Next strItem 'verify there is a period in the right half of the address If InStr(strArray(2), ".") <= 0 Then blnIsItValid = False IsEmailValid = blnIsItValid Exit Function End If i = Len(strArray(2)) - InStrRev(strArray(2), ".") 'locate the period 'verify that the number of letters corresponds to a valid domain extension If i <> 2 And i <> 3 And i <> 4 Then blnIsItValid = False IsEmailValid = blnIsItValid Exit Function

End If 'verify that there aren't two periods together in the email If InStr(strEmail, "..") > 0 Then blnIsItValid = False IsEmailValid = blnIsItValid Exit Function End If IsEmailValid = blnIsItValidEnd Function

A Function That Sums Cells Based on Color Value

Color or Color Index

In Excel VBA you can assign colors by index as in the following.

Example

ActiveCell.Interior.ColorIndex = 17

You can also use the Red, Green Blue model to assign a color directly using integer values between 0 and 255 for each color.

Example

Range("A1:A6").Interior.Color = RGB( 0,150,255 )

A common coding practice is to create a sum in a loop. This sum is created by adding a number to itself together with an increment value.

Example

i = i + 1

(The Function SumByColor in the book and in the resource download didn't work for me. You can try it and may have better luck.)

Here is an equivalent along with a macro to run it. The following code is limited to doing row counts of cells with a particular color index. It could be expanded to do two dimensional contiguous ranges by making the loop two dimensional.

Example of a Function that Counts Color Indexed Cells in Rows

Function Rows_ColorIndexed_Cell_Sum(cellcolor As Range, rowrange As Range)

Dim IC, Total As Integer 'two variables declared as type Integer IC and TotalIC = cellcolor.Interior.ColorIndexFor I = 1 To rowrange.Count If Cells(1, I).Interior.ColorIndex = IC Then Total = Total + 1 End If Next IRows_ColorIndexed_Cell_Sum = TotalEnd Function

Here is a macro to run the above function

A Macro that Runs the Above Function

Sub SixOfOne()'set up variablesDim IC, Count, cell_sum, iColor As Integer

'set an interior color index for six cellsRange("A1:F1").Interior.ColorIndex = 40

cellsum = Rows_ColorIndexed_Cell_Sum(Range("A1"), Range("A1:J1"))

'return the total for viewingRange("D4").Value = "Total in Range"Range("F4").Value = Range("A1:J1").CountRange("D5").Value = "Cells with Index Color"Range("F5").Value = cellsum

End Sub

The Number of Unique Values Function // NumUniqueValues( )

Mr. Excel's Unique values counting function is cleverly devised as it takes advantage of the fact that “a collection, with a key parameter can contain only unique values”. If an attempt is made to load a collection with a repeat value, an error is thrown. When an error is thrown, the function refrains from adding the repeat value, dismisses the error message and continues.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function NumUniqueValues(Rng As Range) As Long Dim myCell As Range, UniqueVals As New Collection Application.Volatile 'forces the function to recalculate when the range changes On Error Resume Next 'the following places each value from the range into a collection 'because a collection can contain only unique values,there will be no duplicates 'the error statements force the program to continue when the error messages 'appear for duplicate items in the collection For Each myCell In Rng UniqueVals.Add myCell.Value, CStr(myCell.Value) Next myCell ' Reset error checking to normal On Error GoTo 0 'returns the number of items in the collection NumUniqueValues = UniqueVals.CountEnd Function

Skipped Functions

The 'Remove Duplicates in a Range' Function is not in the download so we skip it. You can look at it in the text, on page 91 of the old book & page 316 of the new

The FindNonZeroLength function is skipped. (It didn't work for me?)

String Substition Method is Omitted for Brevity. Similar stock methods are easyto understand and use

Also omitted is the Function that subtracts numbers from letters. It is overly complicated and could be simplified. It uses a number of built-in function which deserve attention in their own right.

A Date Format Conversion Function

Next on our list is a Date conversion function. This string convertsa string like 'Week 50 2011' into the corresponding month, day yearform.

Notice how the variable 'FirstMon' is used to capture a return value and then the variable itself is used in an equation that returns again to the same variable.

To use it, remember the cell that the output will be sent to must be formatted for Date.

The function makes use of Excel built-in functions. The DateSerial method creates a date. The Right function picks off the year from the string, the four right characters.

• DateSerial(Year, Month, Day)• Returns a Variant (Date) for a specified year, month, and day.

• Right(String, Length) • returns a String with specified number of chars from right side

• Mod operator • math modulo function returns the remainder of a division

• number_1 mod number_2 → remainder ◦ example → 8 mod 3 returns 2

• :Left(String, Length) • opposite effect of Right function

Convert Date

Function ConvertWeekDay(str As String) As Date 'Str —The Week information to be converted. Dim Week As Long Dim FirstMon As Date Dim TStr As String FirstMon = DateSerial(Right(str, 4), 1, 1) FirstMon = FirstMon - FirstMon Mod 7 + 2 TStr = Right(str, Len(str) - 5) Week = Left(TStr, InStr(1, TStr, " ", 1)) + 0 ConvertWeekDay = FirstMon + (Week - 1) * 7End Function

// Right Function returns a Variant (String) containing a specified // number of characters from the right side of a string.

A Function That Isolates Strings Encased in Delimiters

In the following function the XL Split function is used to isolate strings separated by a delimiter. The resource download says the Split method is not compatible with Excel 97 so that is something to check.

Enter something like A.B.C.D into the field when the function is called,select a period as the delimiter and enter 3 for index and the letter Cis filtered from the entry.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function StringElement(str As String, chr As String, ind As Integer) 'str —The string to be delimited. 'chr —The delimiter. 'ind —The position of the element to be returned. Dim arr_str As Variant arr_str = Split(str, chr) StringElement = arr_str(ind - 1)End Function

A Function That Sorts & Concatenates // calls another function locally defined

This next example is a long one. The first function defined makes a call on a second function which we can list in the same source code. This introduces the Call statement. In our case, functional control is transferred to the BubbleSort function.

Fill a row or column with 6 or seven values. Call the function from theactive cell that you wish the results to display in. Call the function fromthe drop down list.

Call Statement

The Call statement transfers control to a Sub, Function or dynamic-link library (DLL) procedure.

Syntax[Call] name [argumentlist] – a comma separated list of variables, arrays or expressions.

It is described as optional, though if it is used the arguments to the sub it is using must be enclosed in brackets.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function SortConcat(Rng As Range) As Variant 'Rng —The range of data to be sorted and concatenated. Dim MySum As String, arr1() As String Dim j As Integer, i As Integer Dim cl As Range Dim concat As Variant On Error GoTo FuncFail: 'initialize output SortConcat = 0# 'avoid user issues If Rng.Count = 0 Then Exit Function 'get range into variant variable holding array ReDim arr1(1 To Rng.Count) 'fill array i = 1 For Each cl In Rng arr1(i) = cl.Value i = i + 1 Next 'sort array elements Call BubbleSort(arr1) 'create string from array elements For j = UBound(arr1) To 1 Step -1 If Not IsEmpty(arr1(j)) Then MySum = arr1(j) & "," & MySum

End If Next j 'assign value to function SortConcat = Left(MySum, Len(MySum) - 2) 'exit pointconcat_exit: Exit Function 'display error in cellFuncFail: SortConcat = Err.Number & "-" & Err.Description Resume concat_exitEnd Function

Sub BubbleSort(List() As String)' Sorts the List array in ascending order Dim First As Integer, Last As Integer Dim i As Integer, j As Integer Dim Temp First = LBound(List) Last = UBound(List) For i = First To Last - 1 For j = i + 1 To Last If UCase(List(i)) > UCase(List(j)) Then Temp = List(j) List(j) = List(i) List(i) = Temp End If Next j Next iEnd Sub

A Function To Sort Alpha From Numeric Values

One thing of note, in the next example, there are two subs written to support this method. Notice because the second macros use is exclusively designed to be used with the first macro it makes sense to make the dependent sub private.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function sorter(Rng As Range) As Variant ' Rng —The range to be sorted. 'returns an array Dim arr1() As Variant If Rng.Columns.Count > 1 Then Exit Function arr1 = Application.Transpose(Rng) QuickSort arr1 sorter = Application.Transpose(arr1)End Function

// Variants used as parameters can be declared Optional. // If they then are not used, they are assigned the value 'Missing'

Macro Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Public Sub QuickSort(ByRef vntArr As Variant, _Optional ByVal lngLeft As Long = -2, _Optional ByVal lngRight As Long = -2) Dim i, j, lngMid As Long Dim vntTestVal As Variant If lngLeft = -2 Then lngLeft = LBound(vntArr) If lngRight = -2 Then lngRight = UBound(vntArr) If lngLeft < lngRight Then lngMid = (lngLeft + lngRight) \ 2 vntTestVal = vntArr(lngMid) i = lngLeft j = lngRight Do Do While vntArr(i) < vntTestVal i = i + 1 Loop Do While vntArr(j) > vntTestVal j = j - 1 Loop If i <= j Then Call SwapElements(vntArr, i, j) i = i + 1 j = j - 1 End If Loop Until i > j If j <= lngMid Then Call QuickSort(vntArr, lngLeft, j) Call QuickSort(vntArr, i, lngRight) Else Call QuickSort(vntArr, i, lngRight) Call QuickSort(vntArr, lngLeft, j) End If End IfEnd Sub

Private Sub SwapElements(ByRef vntItems As Variant, _ ByVal lngItem1 As Long, _ ByVal lngItem2 As Long) Dim vntTemp As Variant vntTemp = vntItems(lngItem2) vntItems(lngItem2) = vntItems(lngItem1) vntItems(lngItem1) = vntTempEnd Sub

A Function That Finds a String Within Strings in a Range

The following function is effective for collecting which cells in a Range set contain a specific string value. Notice the method makes a case sensitive string selection. The effects of the Boolean values associated with the different Address property is exampled in the table below.

Example // Microsoft Library http://msdn.microsoft.com/en-us/library/aa174749%28v=office.11%29.aspx

“The following example displays four different representations of the same cell address on Sheet1. The comments in the example are the addresses that will be displayed in the message boxes.

Set mc = Worksheets("Sheet1").Cells(1, 1)MsgBox mc.Address() ' $A$1MsgBox mc.Address(RowAbsolute:=False) ' $A1MsgBox mc.Address(ReferenceStyle:=xlR1C1) ' R1C1MsgBox mc.Address(ReferenceStyle:=xlR1C1, _ RowAbsolute:=False, _ ColumnAbsolute:=False, _ RelativeTo:=Worksheets(1).Cells(3, 3)) ' R[-2]C[-2]“

// The Excel INSTR function returns the position of the first occurrence of a substring in a string. InStr( [start], string, substring, [compare] )

// The Address function takes rows columns and two opt. values set to false in following example

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function ContainsText(Rng As Range, Text As String) As String 'Rng —The range in which to search. 'Text —The text for which to search. Dim T As String Dim myCell As Range For Each myCell In Rng 'look in each cell If InStr(myCell.Text, Text) > 0 Then 'look in the string for the text If Len(T) = 0 Then 'if the text is found,add the address to my result T = myCell.Address(False, False) Else T = T & "," & myCell.Address(False, False) End If End If Next myCell ContainsText = TEnd Function

// omit function to reverse contents of a string omitted as likely having few applications

Function Returning the Maximum Value in a Range

The function reports the cell address or addresses of the maximum number found inside the range of cells. If more than one cells has the same maximum value, the cells are reported in a comma-separatedlist.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function ReturnMaxs(Rng As Range) As String ' Rng —The range to search for the maximum value(s). Dim Mx As Double Dim myCell As Range 'if there is only one cell in the range,then exit If Rng.Count = 1 Then ReturnMaxs = Rng.Address(False, False): Exit Function Mx = Application.Max(Rng) 'uses Excel’s Max to find the max in the range 'Because you now know what the max value is, 'search the ranging finding matches and return the address For Each myCell In Rng If myCell = Mx Then If Len(ReturnMaxs) = 0 Then ReturnMaxs = myCell.Address(False, False) Else ReturnMaxs = ReturnMaxs & "," & myCell.Address(False, False) End If End If Next myCellEnd Function

Function That Gets an Web Address From a Link

The following function shows up on the net almost as a formula. Itreturns the web address associated with a link in an Excel page. Create a link to test the function on by using the Insert button → Hyperlink icon.

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function GetAddress(HyperlinkCell As Range) 'Hyperlink —The hyperlinked cell from which you want the address extracted. GetAddress = Replace(HyperlinkCell.Hyperlinks(1).Address, "mailto:", "")End Function

A Function To Return the Column Letter of a Column

This function returns the letter associated with a Range cell.

Function ColName(Rng As Range) As String ' Rng —The cell for which you want the column letter. ColName = Left(Rng.Range("A1").Address(True, False), _ InStr(1, Rng.Range("A1").Address(True, False), "$", 1) - 1)End Function

A Function that Returns a Random Number

The RAND function is a built in function that is useful to create a random number. If reused the seed will be the time of day. This function uses thethe Randomize statement to provide a new seed.

“The Randomize statement uses number to initialize the Rnd function's random-number generator, giving it a new seed value. If you omit number, the value returned by the system timer is used as the new seed value.” - Excel Documentation

Example // from 'VBA & Macros' Microsoft Excel 2010, Bill Jelen & Tracy Syrstad

Function StaticRAND( ) As Double Randomize StaticRAND = RndEnd Function

Final Function Demonstrating the Case Statement

The Case statement is an alternate way to making logical selections over a range of values. It can replace a lot of nested if statements. The following example is much shorter than the one in the text and makes the key aspects of the Case clearer.

The key parts of the case is the 'Select Case' keyword and each case that is suffixed with a value that is compared to that value that follows'Select Case'. A default for when there is no match is supplied by a Case Else statement. The Case statement is terminated by an End Select.

Example

Function DressTheme(Day As Integer) As String Select Case Day Case 1 DressTheme = "Monday - Ordinary" Case 2 DressTheme = "Tuesday - Ordinary" Case 3 DressTheme = "Wednesday - Bright" Case 4 DressTheme = "Thursday - Formal" Case 5 DressTheme = "Friday - Dress down" Case Else DressTheme = " Themeless " End SelectEnd Function

Calling Built in Functions

Here is a sub that shows an example of a built in function being called.

Count will count the number of cells in a range, here A1 to I5 that havenon-zero values. You will need to enter some values in this range to seethis one work.

Sub UsingTheCountFunctionInAMacro( ) Range("C7").Value = "=COUNT(A1:I5)"End Sub

Assignment

1 ) To practice building custom functions ( or UDFs) create the following.

Before you begin, try to build these 'clean sheet' keeping in mind the features of a function noted at the top of the note. Then if you needsome help, refer to the similar sorts of simple functions that are suppliedin the note.

a ) a function that returns your name. b ) a function that returns the date c ) a function that puts a copyright symbol followed by the year in a cell.

2 ) Create a macro that puts some text into a spreadsheet and then callsthe above three functions to enter the associated information into thisspreadsheet.

You may also wish to use the style where the functions are listed below in the same module that contains the macro.

3 ) Add two functions from the Mr. Excel function collection that supplysubs to demonstrate them. Incorporate macro code to incorporatecalls on these two functions into your macro.

Note, as a good practice, when using Mr. Excel or any function from other sources, include a comment that states where the method comes from. A title and a link or just the link I think is adequate

4 ) Screenshot the spreadsheet and submit along with copies of all the code.