User-Defined functions Concepts Microsoft Excel includes a powerful programming language called Visual Basic for Application (VBA) which enables you to write modules which may be subroutines of functions. A subroutine performs aprocess such as displaying a dialog box in which the user enters data. A function returns a value to a cell (or a range) in the same way as a built-in worksheet function. We shall explore only function coding. If you have experience with any programming language you will be familiar with many of the topics covered in this chapter. If you are not yet a programmer, VBA is a great way to begin. The emphasis in this chapter is on how to write functions so we will use simple examples. Later chapters make use of this skill to code more useful functions. Visual Basic for Applications is a very broad topic and there are many books devoted to it alone. Why and when do we use user-defined functions? Just as it is more convenient to use =sum(a1:a20) rather than =A1+A2+…+A20, a user-defined function may be more convenient when we repeatedly need to perform a certain type of calculation for which Microsoft Excel has no built-in function. Once a user-defined function has been correctly coded it may be used in the same way as a built-in worksheet function. Before you write a user-defined function, make sure that it is not already provided by Excel. The built-in functions are more efficient than user-defined functions. After you have written a function you must test it thoroughly with a wide range of input values. A simple function The user-defined function is to calculate the area of a triangle given the length of two sides and the included angle: Area = 1/2absin(). The function code is as follows. ' Computes area of a triangle given two sides and the included angle Function Triarea(side1, side2, theta) Alpha =worksheetFunction.Radian(theta) ' degrees to radians Triarea = 0.5 * side1 * side2 * VBA.sin(Alpha) ' computes area End function Remarks for the codes: 1. The complete syntax for referencing a worksheet function is Application.WorksheetFunction.FunctionName but the first word may be omitted as it is in our function. To maintain compatibility with earlier versions you may also use the syntax Application.FunctionName. 2. The trigonometric Sin function is available in Visual Basic. We have used VBA.sin in the example in order to call up the list of VBA functions. 3. If a function is available as a VBA function and as a worksheet function, we must use the one from VBA. You can not use a worksheet function when VBA provides the same function. The worksheet function SQRT cannnot be used since VBA includes the equivalent SQR function. Tips : You can include as many user-defined functions in one module as possible. However, ther is a problem with having more than one function on a single module. If any one of the functions contains an error then all functions on that module return error values on the worksheet. This can be confusing, especially for beginners. Ther are other considerations that help you decide whether to put more than one functions on a single module but these relate to the use of Public and Private in the function header. A user-defined Array function We may require our user-defined function to return more than one value or we may wish to pass a range of cell values to a function. In this exercise we do both. We will code a function to compute the real roots of the quadratic equation ax2 + bx + c = 0. Option base 1 function Quad(a,b,c) dim temp(3) d =(b*b)-(4*a*c) select case d case is < 0 temp(1) = "no real" temp(2) = "roots" temp(3) = "" case 0 temp(1) = "one root" temp(2) = -b/(2*a) temp(3) = "" case else temp(1)="Two roots" temp(2)= (-b + sqr(d)) / (2 * a) temp(3) = (-b - sqr(d))/ (2*a) end select Quad = temp End function This function return an array. When you use it, you need select 3 cells first and enter the function and its arguments, complete the entry with CTRL+SHIFT + ENTER. The call to the function uses the formula =quad(a1,a2,a3). If you wish to call the function using =quad(A1:A3), the function could be re-coded as shown below. function Quad(coeff) dim temp(3) d =(coeff(2)^2)-(4*coeff(1)*coeff(3)) select case d case is < 0 temp(1) = "no real" temp(2) = "roots" temp(3) = "" case 0 temp(1) = "one root" temp(2) = -coeff(2)/(2*coeff(1)) temp(3) = "" case else temp(1)="Two roots" temp(2)= (-coeff(2) + sqr(d)) / (2 * coeff(1)) temp(3) = (-coeff(2) - sqr(d))/ (2 * coeff(1)) end select Quad = temp End function Inputting an Array In the last part of the previous exercise we saw how to pass a one-dimensional array to a function. This could be a group of contiguous cells in a row or in a column. In this exercise, we pass a two-dimensional array to a function. We pass a block of 12 cells arranged in three rows and four columns to the function which sums each of the three rows and returns the value of the three sums. option base 1 'function to return maximum sum of three rows function MaxRow(data as object) dim RowSum(3) for r = 1 to 3 for c = 1 to 4 RowSum(r) = RowSum(r) + Data.cells(r,c) next c next r MaxRow = Application.Max(RowSum) End function The code DATA as OBJECT in the argument list of the function references range A3:D5 in the worksheet formula. In line 4 the array RowSum is created to hold the three values of the sum of each row. Note the use of DATA.CELLS(r,c) to reference the value of each cell in the range. The worksheet MAX function is used to find the largest value in the RowSum array. Improving Paste Function the function you have written will appear on the paste function dialog box in the user-defined category but we need to make a small improvement. We will get it and the Formula Palette to display information about the function. 1 Click the Paste Function tool. Select the User-Defined category and you will see the names of all the user-defined functions. Select a one you want to add information to. The lower part of the dialog box mistakenly states Choose the Help button for help on this function and its arguments. Click on the cancel button. 2 Use the cammand Tools|Macros|Macros to open the Macros dialog box. In the Macro name box enter the function name you want. Click on the Option button. In the Description box enter a short description of the functions. Click OK. The description is displayed at the bottom of the MAcro dialog box. Some debugging tricks 1 Add MSGBOX function msgbox "message string" 2. Add DEBUG.PRINT Debug.Print "message string" In this case, the information will show in immediate Window. If it is not visible, you should use the View menu to bring it up.