Sei sulla pagina 1di 29

A tutorial on Excel programming with Visual Basic for Applications

By Mark F. Dabbs

http://www.mfdabbs.pwp.blueyonder.co.uk/

This file contains a print out of the five lessons from an Excel/VBA tutorial created by Mark Dabbs, a teacher from the United Kingdom. The lessons and Excel files are available at the following URL:

http://www.mfdabbs.pwp.blueyonder.co.uk/Excel_Pages/Programming_Tutorial.html

This document simply puts together the five lessons from Mr. Dabbs into a single PDF file.

All credits in the production of this document and the accompanying Excel spreadsheets go to Mr. Mark F. Dabbs.

1

Programming 1

User Defined Functions (UDF’s) - one glitch and one inconvenience!

Anyone who has experimented with UDF’s in any version of Excel later than Excel 5 will have noticed two annoying features. These will be looked at first before we do any more advanced work.

The Glitch

Open Excel and centre align all Cells. In Cell B6 type ‘x’ and from B8 to B21 fill with a range of integers from –3 to 10. Highlight Cells B6 to B21 and select Insert Name Create, etc, to name the range ‘x’. In Cell A3 type h and in Cell A4 type 0, then highlight Cells A3 to A4 and select Insert Name Create, etc, to name the Cell ‘h’.

Next, select File SaveAs, and type “glitch1”. Save to your floppy disk. In Cells C6 to G6 type in ‘a’ to ‘e’, one to each Cell. In C8 type = x^3 – 4*x^2 + 4/(x + 5) , and press Return. This should give a Cell output of - 61. Next, double click on the fill handle button of Cell C8 to automatically fill the ‘a’ column.

Note that, if you instead have a column of - 61’s then your worksheet will still be in the ‘Manual Calculation’ Mode. If you wish to reset to ‘Automatic Calculation’ Mode then select Tools Options Calculation Tab, and then click in the “Automatic” option followed by OK. If you do not wish to change back then simply press the Special Function Key F9 once – but I suggest that you do change back.

Now, select File SaveAs, and type “glitch1a”. Save to your floppy disk.

Next, press Alt+Special Function Key F11, that is, Alt+F11. This opens up the Visual Basic for Applications (VBA) window into which we are now going to write the previous function. Select Insert Module, this opens up a window into which we type the following code:

(Recall that the editor will fill much of this code in automatically – provided we press either the Return or Tab buttons at the appropriate moment.)

Function f(x As Single) As Single f = x ^ 3 - 4 * x ^ 2 + 4 / (x + 5) End Function

Click on the Excel Icon in the Standard Toolbar to return to the Excel worksheet and now in Cell D8 type in = f(x) , and press Return. What will be shown is the error message “#VALUE”. Regardless of this error, double click on the fill handle of the Cell to fill down the formula. Next, in Cell B4 type = f(h) , and press Return. This time you should have the value 0.8 in the Cell (If you once again have “#VALUE” then it may be because you didn’t alter the argument to the function f( ) from ‘x’ to ‘h’) Repeat this previous operation but instead in Cell C24. It should again give 0.8. Thus, single Named Cells experience no problems with User Defined Functions (UDF’s)

First ‘Fixit’

2

In Cell E8 type in =f(VALUE(x)) , and press Return (Upper case is not necessary) and double click on the fill handle of the Cell to fill down the formula. This works, but it is neither particularly succinct nor mathematically clear.

Second ‘Fixit’

In Cell F8 type in = f(x+0) , and press Return and double click on the fill handle of the Cell to fill down the formula. This works but again it could be mathematical confusing.

Third ‘Fixit’

In Cell G8 type in = f(x + h) , and press Return and double click on the fill handle of the Cell to fill down the formula. This works and gives the correct answer to what we expect of f(x) (because at present h is set equal to zero). Now this may not be exactly what we were after BUT the fact that the combination of a Named Range of values with a Named Cell put into the argument of our UDF will have much use later on, and will then have greater mathematical meaning. Recall setting up the Central Derivative Module from page 11 in the “Named Ranges 3” exercise. In that case the UDF was acting on a single Cell and not a Range of Cells. We now know that such a UDF can also return values from a Range of Cells.

Notice that f(1*x), f(2*x), f(x/5), etc, or f(p*x), f(x/q), etc, would also return full range values for appropriate choices of p and q – useful for transformation graphs.

Therefore, at present I suggest that you actually type in the function in terms of x as you have done in column C and then copy this formula down. Then a click on any Cell in this range will show you the mathematical form of the function in the formula bar, in this case = x^3-4*x^2+4/(x+5). Next, open the VBA editor with Alt+F11 and define the same function in a module, and then this will be what you use in later work in the worksheet (Provided that you will be using an argument to the function other than a sole ‘x’ – as has been discussed in depth above).

Recall again that for a single, Named Cell rather than a Named Range of Cells then the straight forward Cell entry of = f(x) will evaluate the function correctly without either of the above ‘fixes’

The Inconvenience

Open Excel, Centre align all Cells. Select File SaveAs, and type “vba_func”. Save to your floppy disk. In Cell B4 type x, and in B5 type in the value 2. Give this data Cell the Name x. In Cell C5 type = ACosh(x) + x –3, and press Return, the cell should have the value 0.316958.

Next, press Alt+Special Function Key F11, that is, Alt+F11. This opens up the Visual Basic for Applications (VBA) window into which we are now going to write the previous function. Select Insert Module, this opens up a window into which we type the following code:

Function f(x As Single) As Single f = ACosh(x) + x -3 End Function

Click on the Excel Icon in the Standard Toolbar to return to the Excel worksheet and now in Cell D5 type = f(x) , and press Return. What will be shown is the following error message below.

3

The cause of this problem is that the VBA language does not know what the ArcCosh of x means, unlike the actual Excel worksheet. In fact VBA has a surprisingly sparse collection of known mathematical functions ‘pre-programmed’ in to it. To see a listing of available VBA mathematical functions first get into the VBA screen using Alt+F11, then anywhere on an open (module) window type vba.math. , and on typing in the last period (full stop!) you will have the available functions displayed in a ‘pop-up’ list. As you will see things are rather limited, however, where there is a will there is a way!

The listing on the next page gives many useful mathematical functions re-written in terms of some of the available VBA functions. Note that in an expression such as:

Arccosh = Log(x + Sqr(x * x - 1)),

I have deliberately left out the argument of the actual function. This is due to how it must be implemented in the VBA Module code. For example, consider the Module code given below, both

of which output the same value, that of cosh

1

(x) or arccosh (x) :

Function f(x As Single) As Single Arccosh = Log(x + Sqr(x * x - 1)) f = Arccosh + x – 3 End Function

or

Function f(x As Single) As Single f = Log(x + Sqr(x * x - 1)) + x - 3 End Function

I think that the first is preferable since we are reminded exactly which function we are using.

Now rewrite your previous module code to be either of the previous two and before returning back to the Excel worksheet either select Run Reset, or simply click on the small blue square on the toolbar. The purpose of this action is to enter your changes and stop the Editor’s Debug mode. On returning to the worksheet, make sure that your answer is identical to that in C5. Save your file.

4

Construction of functions based on VBA functions

Sec = 1 / Cos(x) Cosec = 1 / Sin(x) Cotan = 1 / Tan(x) Arcsin = Atn(x / Sqr(-x * x + 1)) Arccos = Atn(-x / Sqr(-x * x + 1)) + 2 * Atn(1) Arcsec = Atn(x / Sqr(x * x - 1)) + Sgn((x) - 1) * (2 * Atn(1)) Arccosec = Atn(x / Sqr(x * x - 1)) + (Sgn(x) - 1) * (2 * Atn(1)) Arccotan = Atn(x) + 2 * Atn(1) Sinh = (Exp(x) - Exp(-x)) / 2 Cosh = (Exp(x) + Exp(-x)) / 2 Tanh = (Exp(x) - Exp(-x)) / (Exp(x) + Exp(-x)) Sech = 2 / (Exp(x) + Exp(-x)) Cosech = 2 / (Exp(x) - Exp(-x)) Cotanh = (Exp(x) + Exp(-x)) / (Exp(x) - Exp(-x)) Arcsinh = Log(x + Sqr(x * x + 1)) Arccosh = Log(x + Sqr(x * x - 1)) Arctanh = Log((1 + x) / (1 - x)) / 2 Arcsech = Log((Sqr(-x * x + 1) + 1) / x) Arccosech = Log((Sgn(x) * Sqr(x * x + 1) + 1) / x) Arccotanh = Log((x + 1) / (x - 1)) / 2 LogN = Log(x) / Log(n)

Note that not all of the above functions are available as standard functions in Excel either. To find out which are first change to the Excel workbook and then click on any clear Cell and then select Insert Function. This will display the “Paste Function” Dialogue Box, as shown below. Then choose “Math & Trig” and scroll through the available functions. Those that aren’t in the list, such

as

cosech (x) , etc, can either be inputted as a UDF, as described above, or as the corresponding equivalent form:

-1

Log((Sgn(x) * Sqr(x * x + 1) + 1) / x)

But, notice the following necessary alterations for use within the Excel workbook rather than for VBA, viz:

Log((Sign(x) * Sqrt(x * x + 1) + 1) / x)

since the Excel workbook has different ‘calls’ for the same function – confused yet? Personally I would go for a UDF to clarify the working.

5

The Application.WorksheetFunction

Before you begin to think that having to know all and more of the above formulae constructions is completely beyond you Excel has a very simple, albeit wordy way of ‘grabbing’ any functions found in the Excel Worksheet and putting them into VBA code. The above module code for the ArcCosh function would instead need to be written:

Function f(x As Double) As Double f = Application.WorksheetFunction.Acosh (x) End Function

Notice now that the worksheet function ‘Acosh’ must have its argument set as a double-precision, floating-point number.

The importance of this seemingly innocuous example cannot be overstated; the Application.WorksheetFunction in your code should almost always be used. The reasoning being that your own attempts at designing a suitable function, though admirable, will almost always cause your code to run slower and may also contain mistakes.

Notice that when you are typing the phrase “Application.WorksheetFunction.Acosh(x)” then you will actually only need to type the final ‘(x)’ believe it or not! – see the stages below!

(1)

Right click after the ‘=’ sign. Click on either “List Properties/Methods” or “Complete Word”

(2)

Scroll down to the word ‘Application’ and either select it and press the ‘Tab’ button or double click it.

(3)

(4)

(5)

Next type a period “.” , this will open another drop-down menu. Now either scroll down or just type ‘w’ – this will automatically scroll you down to the start of the options that begin with the letter ‘w’. Again, either select the required option: ‘WorksheetFunction’ and then press the ‘Tab’ button or double click the required option.

Again type a period “.” , this will open

either select the required option:

‘Acosh’ and then press the ‘Tab’ button or double click the required

option.

Similarly,

6

Now type the opening bracket and notice the information box that appears. It gives you important information regarding how many arguments the function can accept and what type of arguments must be used.

(6)

Finally type in your functions dummy argument – it need not be x – and close the bracket. Thus only (x) needed to be typed!!

Finally, be aware that there will be times when you have to write your own custom function, possibly because it is neither present in the Excel Worksheet or the VBA function lists. A simple mathematical example is the Hyperbolic Secant. Here then, the Table on Page 4 above is of use.

5

Programming 2

Control Buttons on the Worksheet

Open Excel, select File SaveAs, and call the new file “Prog2a” on your floppy disc. Select View Toolbars Visual Basic. This puts the Visual Basic Icons in the Toolbar, namely:

Puts the Excel Sheet into Design Mode – this allows editing of buttons in worksheet

Opens the VBA Editor. (Same as Alt+F11)

Opens the VBA Control Toolbox, where Control Buttons are stored.

Click on the Control Toolbox, this gives a further menu which may be displayed with the other toolbars or may be free-floating on the workbook.

Command Button

Click on the Command Button Icon and move the mouse cursor (which should look like a fine cross) to the middle of the Cell A2. Next hold down the left mouse button and drag diagonally down to the middle of the Cell C5 and let go. This will create for you a command button within the Excel worksheet. It should be called “CommandButton1” Next, in Cell B8 type ‘a’ and in B9 type 3. Highlight Cells B8 and B9 and select Insert Name Create, etc, to give B9 the Name ‘a’. Notice that entering values into these Cells have “greyed out” the VBA and Control Toolbox Toolbars – they will return as soon as no Cell entries are being made and you will still be in design mode. Now, whilst still in Design Mode, double click on CommandButton1. This takes you to the VBA Editor screen, and you should see something along the lines of the “Project” and “Properties” Boxes on one side of your screen as shown on the following page. Our concern is with the Properties that we want the new button to have.

See the picture of the “Properties” Box below for details, but on the top line - the ‘(Name)’ line - change CommandButton1 to ‘cmdTest’. Similarly, on the ‘Accelerator’ line type in ‘T’ and on the ‘Caption’ line type in ‘Test’. To enter this last alteration, press Return – always do this.

6

Change to
‘cmdTest’
Type in ‘T’
Type in
‘Test’

Note that if ever you go into the VBA editor and cannot see on the screen either of the Project or Properties windows shown above, then whilst in the VBA Editor screen select View from the toolbar and the click on both the ‘Project Explorer’ and the ‘Properties Window’ options.

7

In the Editor window of the screen you may have the following subroutine definition displayed.

Click on this list arrow in the
Object Box and select cmdTest

Click on the list arrow in the Object Box and select cmdTest from the drop down list. This will automatically open up the cmdTest Subroutine that is associated with a Click of the Button on the Excel worksheet. Therefore, any code that is typed into this Subroutine will be executed each time we click on the Button now called Test, which has been embedded into the worksheet. Type the following code into the Subroutine

The “Dim Trans1 As Range” tells VBA that we are defining ‘Trans1’ to be a ‘Range’ variable type, that is it can accept values from single or multiple worksheet Cells. “Dim i As Integer” tells VBA

8

that we are defining ‘i’ to be an ‘Integer’ variable, which in this instance, is for use later on in the program. The four lines

Set Trans1 = Range("B9") Set Trans2 = [B9] Set Trans3 = Range("a") Set Trans4 = [a]

are four possible ways in which the program can ‘read’ the value in the Cell B9 (which also has the name ‘a’ associated with it) from the Excel worksheet which can then be used and manipulated within the program. The ‘Range’ function can accept many types of argument, not just single cell ones. For example, other such acceptable arguments could be “B9,B12” or “A3:E19”. In particular see the Subroutine cmdClear on the next page. The lines

and

Cells(13 - i, 4 + i).Value = Trans1 ^ 3 / 4, Cells(13 + i, "B").Value = Trans1,

show two ways in which values from the program (possibly altered) may be passed back to the worksheet. Notice that the first argument in the ‘Cells’ function is the Row coordinate and the second is the Column coordinate, which may be either a number or letter. Return to the Excel sheet and exit Design mode, we will now see how to clear the worksheet of previous results. Click on the Control Toolbox and click on the Command Button Icon and move the mouse cursor to the middle of the Cell C2. Next hold down the left mouse button and drag diagonally down to the middle of the Cell E5 and let go. This will create for you a second command button within the Excel worksheet. It should be called “CommandButton2”, double click on this button to open the VBA Editor. Once again, from the “Properties” Box, on the ‘(Name)’ line - change CommandButton2 to ‘cmdClear’. Similarly, on the ‘Accelerator’ line type in ‘C’ and on the ‘Caption’ line type in ‘Clear’. Click on the list arrow in the Object Box and select cmdClear from the drop down list. This will automatically open up the cmdClear Subroutine. In the cmdClear Subroutine type the following code:

Private Sub cmdClear_Click()

Range("B14:B17,E12,F11,G10,H9").Clear

End Sub

Return to the Excel sheet, exit Design mode and test your work by altering the value of “a” in Cell B9 and then save it. Also SaveAs the file “Prog2b” on your floppy disk.

In this next file, “Prog2b”, we will introduce Random numbers. Initially, resize your “Test” and “Clear” buttons by first entering the Design Mode on the Visual Basic Toolbar – make each button only one Cell wide and two Cells deep so that the pair of the entirely cover Cells B2 to C3. Create another CommandButton and place it over Cells D2 and D3. It should be called “CommandButton3”. Click onto Cell B5 and enter the word “Upper”, click onto Cell B6 and enter the word “Lower”. Enter 15 into Cell C5 and – 7 into C6. Click onto C5 and then click into the Name Box. Type ‘U’ into the Name Box and press Return. Similarly, click onto C6 and then into the Name Box. Type ‘L’ into the Name Box and press Return. Next, if you are still in Design Mode, double click on this button to open the VBA Editor, and from the “Properties” Box, on the ‘(Name)’ line - change CommandButton3 to ‘cmdRandom’. Similarly, on the ‘Accelerator’ line type in ‘R’ and on the ‘Caption’ line type in ‘Random’. Click on the list arrow in the Object Box and select cmdRandom from the drop down list. This will automatically open up the cmdRandom Subroutine. In the cmdRandom Subroutine type the following code:

9

Private Sub cmdRand_Click() Dim RandValue As Integer Dim Upper As Range, Lower As Range

Set Upper = [U] Set Lower = [L]

Randomize

Notice the ‘American’ spelling

RandValue = Int((Upper - Lower + 1) * Rnd + Lower) Cells(9, “B”).Value = RandValue

End Sub

Notice that we must type in the work “Randomize” before any code as this selects a random ‘seed’ for the Random Number Generator Function, Rnd.

The code

RandValue = Int((Upper - Lower + 1) * Rnd + Lower)

Returns an integer value in the range given by the values in Cells C5 and C6. Return to the Excel sheet, exit Design mode and test your work by altering the value of “a” via the ‘Random’ button. Save your work, and then select File SaveAs “Prog2c” on your floppy disk.

In the new file “Prog2c”, modify the code in the loop, as shown below, from the Subroutine cmdTest– what happens?

For i = 1 To 4 If i = 1 Then Cells(12 - i, 4 + i).Value = "a ^ 3 / 4" Cells(13 - i, 4 + i).Value = Trans1 ^ 3 / 4 ElseIf i = 2 Then Cells(12 - i, 4 + i).Value = "a+2" Cells(13 - i, 4 + i).Value = 2 + Trans2 ElseIf i = 3 Then Cells(12 - i, 4 + i).Value = "3*a" Cells(13 - i, 4 + i).Value = 3 * Trans3 Else Cells(12 - i, 4 + i).Value = "a-3" Cells(13 - i, 4 + i).Value = Trans4 - 3 End If

extra lines
into
cmdTest

Test the file and save your work. Also select File SaveAs “Prog2d” on your floppy disk.

For the penultimate exercise in file “Prog2d”, create two more CommandButtons and place them on top of Cells J2 to K3. In Cell J5 type in 6 and press Return, now click back into the Cell J5 and then click into the Name Box. Give this Cell the name “Seed”. Highlight the empty Cells J6 to L8 and click into the Name Box again; give this block of Cells the name “Block”. Double click on the button over the Cells J2 to J3 double click on this button to open the VBA Editor, and from the “Properties” Box, on the ‘(Name)’ line - change to ‘cmdFill’. Similarly, on the ‘Accelerator’ line type in ‘F’ and on the ‘Caption’ line type in ‘Fill Cells’. Type in the following code

10

Private Sub cmdFill_Click() Dim i As Integer, j As Integer, count As Integer Dim StartValue As Range

count = 0 Set StartValue = Range("Seed")

For i = 10 To 12 For j = 6 To 8 Cells(j, i).Value = StartValue StartValue = StartValue + 1 count = count - 1 Next j Next i

Cells(5, "J").Value = StartValue - Abs(count)

End Sub

Return to the Excel worksheet now and in Design Mode double click on the button over the Cells K2 to K3 to open the VBA Editor, and from the “Properties” Box, on the ‘(Name)’ line - change to ‘cmdClearBlock’. Similarly, on the ‘Accelerator’ line type in ‘C’ and on the ‘Caption’ line type in ‘Clear’. Type in the following code

Private Sub cmdClearBlock_Click() Range("Block").Clear End Sub

Test the worksheet and save your work. What happens if the line

Cells(5, "J").Value = StartValue - Abs(count)

is missing from the code in the Subroutine cmdFill ?

Test the file and save your work. Also select File SaveAs “Prog2e” on your floppy disk.

For the final exercise, using file “Prog2e”, create two more CommandButtons and place them ontop of Cells I14 to I15 and I18 to I19. Next highlight the two Cells I16 to I17, and with the mouse pointer somewhere in this selected range click on the right mouse button. Next, choose Format Cells… Alignment Tab from the drop down menu, and check the “Merge cells” box. Also from the Alignment Tab change both Vertical and Horizontal text boxes to “Center”. From the Font Tab change the Size to 20 points. Click OK.

Double click on the button over the Cells I14 to I15 double click on this button to open the VBA Editor, and from the “Properties” Box, on the ‘(Name)’ line - change to ‘cmdUp’. Similarly, on the ‘Accelerator’ line type in ‘U’ and on the ‘Caption’ line type in ‘Up’. Type in the following code.

Private Sub cmdUp_Click()

Range("I16").Activate

ActiveCell.Value = ActiveCell.Value + 1 End Sub

11

Similarly, double click on the button over the Cells I16 to I17 double click on this button to open the VBA Editor, and from the “Properties” Box, on the ‘(Name)’ line - change to ‘cmdDown’. Similarly, on the ‘Accelerator’ line type in ‘D’ and on the ‘Caption’ line type in ‘Down’. Type in the following code

Private Sub cmdDown_Click()

Range("I16").Activate

ActiveCell.Value = ActiveCell.Value - 1 End Sub

Return to the Excel worksheet and, once off Design Mode, click on either button (or hold down the “Alt” button and press either ‘U’ or ‘D’) to see what happens.

How would you modify this code to change the incremental step to any other amount that can be altered from within the Excel worksheet?

Your worksheet should resemble the picture shown below:

12

Programming 3

Dynamic Named Ranges and Automatic Graph Updating – The Power of the Macro Recorder.

A Dynamic Named Range is one in which the size has not been set but rather alters accordingly

with the number of Cells put into it. It can be resized in either sense, that is, made larger or smaller, as often as we choose. If a graph is drawn using two such ranges then it will be seen to update dynamically either when a new point (row of data), or sequence of points, is added or subtracted.

Open Excel, centre justify all Cells and save file as “Prog3a” on your floppy disc. Highlight Cells B2 to B3 and select Format Cells Alignment Tag, and then Center align text both Horizontal and Vertical and also check the Merge cells Box. From the Font Tab change the Size to 16, then press OK. Highlight Cells C2 to C3 and repeat the process.

In Cell B2 (B3 has been absorbed into B2 now) type x, and into Cell C2 type y. Highlight these

enlarged Cells and from the Formatting Toolbar Select the Border Icon to place external and internal borders on the Cells.

To set up the dynamic Named Range

Select Insert Name Define… In the “Names in workbook:” text entry box, type in x. In the “Refers to:” text entry box, type in

= OFFSET(Sheet1!\$B\$4,0,0,COUNTA(Sheet1!\$B:\$B)-1)

Similarly for the y’s, select Insert Name Define… In the “Names in workbook:” text entry box, type in y. In the “Refers to:” text entry box, type in

= OFFSET(Sheet1!\$C\$4,0,0,COUNTA(Sheet1!\$C:\$C)-1)

In Cell B4 type – 5 and fill down to 10 in unit increments. In Cell C4 type = x^2 – 4*x, and press

Return. The value in Cell C4 should read 45, next double click the fill handle to copy down the

formula. Click on any empty Cell to remove the selection of the ‘y’ column.

13

Click on the Chart Wizard from the Standard Toolbar and choose XY (Scatter), smooth and without points and click Next. Select the Series Tab in the 2 nd Chart Wizard window and click on the “Add” button.

= sheet1!x
= sheet1!y

On clicking the “Add” button you will see the word “Series1” appear in the text box, proceed to type in the shown X and Y ranges and then click on Finish. You should now have your graph, select the “Series1” Legend Box and press Delete.

Now highlight the bottom row of your x and y data columns, it should be Cells B19 to C19. click on top of the fill handle and with the left mouse button held down, drag the mouse down until the indicator says ‘15’, i.e. x is at 15, and let go. What should happen is that the graph automatically updates itself to the new range of x and y. Highlight Cells B7 to C24 and press Delete. Once again the graph should update itself.

Save your work and also select File SaveAs, and this time save the file as “Prog3b” on your floppy disk.

Automatic Cell Filling

In Cell E4 type Min x, F4 type Max x and G4 type Step. In Cell E5 type – 10, F5 type 15 and G5 type 1. Use the Name Box to name E5, F5 and G5 minx, maxx and inc, respectively (Notice that we do not name G5 “step” in order to prevent names and functions conflicting later in VBA code). Remember to press Return after writing new names in the Name Box or they will not be permanently entered into the worksheet.

Put the worksheet into Design Mode since we now need to create two CommandButtons. Place these on top of Cells E2 to F3 (halfway through it) and F2 (halfway through it) to G3. Next, select the first button with a click the left mouse button, then whilst still on top of the button, click with the right mouse button. Next, from the Drop Down Menu select Properties and in the “Properties” Box change the following:

Name:

Accelerator: C

Caption:

cmdCalc

Calculate

(Changes the name on the button face)

14

In a similar manner but with the second button in its “Properties” Box change the following:

Name:

Accelerator: r

Caption:

cmdClear

Clear

Still in Design Mode, double click on the “Calculate” Button to take you into the cmdCalc Subroutine (associated with the “Calculate” Button) within the VBA Editor. In the Subroutine write the following code:

Private Sub cmdCalc_Click()

Dim i As Single, Count As Single, CellNumber As Single Dim Minx As Range, Maxx As Range, Inc As Range

Set Minx = Range("minx") Set Maxx = Range("maxx") Set Inc = Range("inc")

Count = Minx CellNumber = Int(CSng((Maxx - Minx) / Inc))

For i = 1 To CellNumber + 1 Cells(i + 3, "B").Value = Count Cells(i + 3, "C").Value = f(Count) Count = Count + CSng(Inc) Next i

Range("A1").Select

f(Count) is actually the function f, defined as f(x) = x^2 – 4*x evaluated at x = Count. This will be written into a VBA Module later.

End Sub

In a similar manner write the code for the “Clear” Button as below:

Private Sub cmdClear_Click() Range("x", "y").Clear End Sub

Initially we shall keep the equation the same as before,

Editor Mode we select Insert Module, and in the new Module window type in the code:

f

(

)

xx=

2 4x . So staying in the VBA

Function f(x As Single) As Single f = x ^ 2 - 4 * x End Function

Now return to the Excel workbook and save your file. Then once you are out of the Design Mode you may change some or all of the values of Min x, Max x or Step, and then click on either of the buttons – though without further modifications to the code I suggest always clicking on the “Clear” Button before the “Calculate” Button.

15

Because the code herein has been written quite sparsely to aid speed and hopefully its clarity, attempting to run VBA enhanced Excel files will sometimes yield error messages. One such message is

In this instance, in this file, simply click on OK and no problem will arise. To attempt to prevent similar messages a much more thorough method of declaring Names, Functions, Subroutines, Function calls, Subroutine calls, Range Declarations, Cell References, Sheet References and so on … is needed. This need for thoroughness is required, in particular, when working across more than one Sheet at a time in the same file, or even in a different file, which may or may not be open!

However, for our purposes here, in the ‘early learning’ stages, brevity will hopefully aid learning until we are more competent with VBA constructs, references to which may be found in the Bibliography.

Save your work again, then select File SaveAs, and this time save the file as “Prog3c” on your floppy disc.

Using the Macro Recorder

In file “Prog3c” choose whichever Min x and Max x you wish but change Step to 0.4 before Clearing and Calculating the new graph. What you will probably notice is that the x and y columns look somewhat messy! that is to say that different Cells appear to be evaluated to a different number of decimal places and they are not centre justified. Recall that the first thing that was done with the original file was to do exactly that, centre justify all the worksheet. Well what has happened is that your VBA code is does not obey the formatting done to your Excel worksheet, so it needs its own formatting to be done within the code.

To find out exactly how to accomplish the above formatting feats may take some time looking through books or through the help screen. However, help is at hand with the Macro Recorder.

The Macro Recorder can be activated by selecting from the Standard Toolbar, Tools Macro Record New Macro. Could you do this now and then you will see the Record Macro Dialogue Box

In general it is useful to choose meaningful names for Macros but leave this as Macro1 and click

OK. You will then see the Floating Menu drag, whatever! will be recorded until the

and from this point on every mouse click, small blue square on the Menu is clicked.

16

After getting to this stage, whilst being recorded, click on an empty Cell, then select from the Standard Toolbar, Format Cells Number Tab, and then in the “Category” list box choose “Number”. Even if we are already set on 2 decimal places adjust it so that we are not, then adjust it back to 2 decimal places (So that an action has taken place), then click on the Alignment Tab. Even if we are already set on Center Alignment in the “Horizontal Text alignment” box adjust it so that we are not, then adjust it back it so that we are horizontally center aligned. Click on OK. Then click on the small blue square on the Floating Menu to stop the recording.

Now select Tools Macro Macros, or click Alt+F8, to get the following Dialogue Box:

With “Macro1” highlighted click on “Edit” to view the code, which should look something like this below:

However, all that we need from this entire Macro are just the two lines

Herein lie the Pros and Cons of recorded Macros:-

They are an excellent learning tool and can do many useful tasks but … … they contain too much irrelevant information and they cannot compete with good VBA programming nor can they do all the tasks that are possible by programming.

To return to our original VBA code in the cmdCalc Subroutine in order so that we may modify the column formatting we can either double click on the ‘Sheet1’ icon in the VBA Project window or

17

else return to the Excel worksheet, select Design Mode and then double click on the embedded “Calculate” Button.

Thus transferring these, previously identified, relevant two lines - only slightly modified - to our original cmdCalc Subroutine gives us the new code:

Private Sub cmdCalc_Click() Dim i As Single, Count As Single, CellNumber As Single Dim Minx As Range, Maxx As Range, Inc As Range

Set Minx = Range("minx") Set Maxx = Range("maxx") Set Inc = Range("inc")

Count = Minx CellNumber = Int(CSng((Maxx - Minx) / Inc))

For i = 1 To CellNumber + 1 Cells(i + 3, "B").Value = Count Cells(i + 3, "C").Value = f(Count) Count = Count + CSng(Inc) Next i

Range("x", "y").Select With Selection .NumberFormat = "0.00" .HorizontalAlignment = xlCenter End With

Notice again the ‘American’ spelling

Range("A1").Select

End Sub

Now return to the Excel worksheet, click off the Design Mode, press the “Clear” Button and once again with “Step” set to 0.4, press the “Calculate” Button. Both x and y columns should now be centre aligned and set to 2 decimal places. Notice also that the axes formatting on the graph has also changed accordingly.

As an extension, how would you rewrite the VBA code in the cmdCalc Subroutine to automatically place an outer border around both the “x” and “y” columns of values?

A worksheet picture is shown below of the final stage.

** WHEN USING THIS FILE ALWAYS MAKE SURE THAT THE WORKSHEET CALCULATION MODE IS SET TO AUTOMATIC AND NOT MANUAL – OTHERWISE THE GRAPH WILL NOT AUTOMATICALLY UPDATE FOR A NEW INPUT RANGE **

18

19

Programming 4

In this section we introduce User Forms. A User Form is a Dialogue Box that we design ourselves to be displayed when and where on the Excel worksheet. It may tell us information or ask us for information that can then be used to alter values thereafter within the worksheet. Recall how animating the tangent from the “Named Ranges 3” exercise in the first talk was achieved by manually and repeatedly pressing the F9 Special Function Key. Here we design a User Form that will enable us to automatically recalculate the entire worksheet any number of times, effectively automating the motion of the moving tangent.

Calculate User Form

Start Excel, select File Open, and open file “Name3” from your floppy disk. Select File SaveAs, and save this as “Prog4a” on your floppy disk.

Select View Toolbars Visual Basic, and then click on the Control Toolbox Icon. Place a Command Button over the Cells E14 and F15 on the worksheet. Double click on this button to open the VBA Editor. In the “Properties” Box change the following:

Name:

Accelerator: A

Caption:

cmdAnimateGraph

Animate Graph

(Changes the name on the button face)

Now, still in the VBA Editor, select Insert UserForm and this will open up a new Form

window and a floating Toolbox Menu. Click once on the form and then from the “Properties” window change the following properties relating to the form.

TextBox window

Label

CommandButton

 Name: frmCycle Caption: Animate Graph (Changes the Title on the form)

Next, from the floating Toolbox Menu put one Label Box, one TextBox and two CommandButtons onto your Animate Graph form in a manner similar to below (after resizing the form with the handles)

Clicking on each of the these form objects in turn modify them in the “Properties” Box thus:

 Label Name: lblAnimateGraph Caption: Enter Number of Cycles Font: Alter to size 14 TextAlign: 2 - fmTextAlignCenter TextBox Name: txtCycle Text: (i.e. leave it blank!) Font: Alter to size 20 TextAlign: 2 - fmTextAlignCenter

CommandButton1

CommandButton2

20

Name:

Accelerator: B

Caption:

Font:

cmdBegin

Begin Alter to size 10

Name:

Accelerator: x

Caption:

Font:

cmdExit

Exit Alter to size 10

Your form should now look something like this above. Next double click on the cmdBegin button; this will open the Editor within this procedure. Type in the following code:

Now get back to the frmCycle form window and double click on the cmdExit button. This will put you in Editor mode ready to type in the following code:

Private Sub cmdExit_Click() Unload frmCycle End Sub

If you have trouble finding the frmCycle form window then locate frmCycle in the “Project” window and double click on frmCycle, see the picture below.

Return to the Excel worksheet now and highlight Cells G14 and G15. With these Cells still highlighted select from the Standard Toolbar Format Cells Alignment Tab,

then check the box “Merge Cells”. Also, make sure that both Horizontal and Vertical text alignements are set to “Center”.

Remaining in this Format Cells Menu, click on the Font Tab and change the size to 20.

21

Double click

Lastly, click on the Border Tab and select a double line as an Outline. Then click on OK to exit and save cell format changes.

Next, double click on the cmdAnimateGraph button embedded in the Excel worksheet. This should open up VBA ready to type in the following in the cmdAnimateGraph subroutine:

Private Sub cmdAnimateGraph_Click() frmCycle.Show End Sub

Return back to the Excel worksheet and save your work to the floppy disc.

Make sure that you are no longer in Design Mode (by clicking on the icon again) and click once on the Animate Graph Button – what happens!

 If all works well you may notice that you need to alter both the size and alignment of the text that is manually entered into the Animate Graph Dialogue Box. You may also notice that your

tangent will ‘cycle’ about its starting point on the graph – wherever that may be. Recall that you

can adjust this by simply pressing the Special Function Key F9 before pressing the Animate Graph Button. You may wish to align the point of tangency over the y-axis for example.

Finally, if you are unhappy where the ‘Cycle’ Dialogue Box is displayed on your worksheet then

you could try altering the following three items in the frmCycle properties (Click on the outside

of the form to display it in the “Properties” window – or click on the properties window list

frmCycle
0 - Manual
130
300

FrmCycle:

Name:

StartUpPosition:

Left:

Top:

These two values work OK for me

A screen shot of the final stage of work is shown overleaf.

22

This merged Cell will display the number of cycles that the animation has remaining. It will count down from the Cycle Number entered into the ‘Animate Graph’ Dialogue Box until it reaches zero – at which time the animation will cease.

This Custom Dialogue Box is opened on screen once the ‘Animate Graph’ button embedded in the worksheet is pressed and will disappear once its own ‘Begin’ command button is pressed

23

Programming 5

In this section we learn about altering axes ranges on any graph. Any of you that have tried to alter the maximum and minimum axes values on both axes will know that it can be somewhat long winded and the results cannot be seen until the Axes Dialogue Box has been fully closed. The following method uses “Spin Buttons” embedded in the worksheet to interactively alter axes ranges.

Start Excel, centre justify all Cells and save the new file on your floppy disc as “Prog5a” In Cell B10 type x and type – 40 in Cell B11. Use Edit Fill Series…, etc, to fill down to + 40 in unit increments. Name this range x. In Cell C10 type y and type = (x^2/4 – x + 3)*(SIN(x/4))^2 – 13 , into C11 and press return. Cell C11 should now show 118 to 3 s.f. Double click the fill handle to copy down this formula. Highlight the corresponding y values and give this range the name y.

Make sure that no Cells are highlighted before clicking on the Chart Wizard Icon in the Standard Toolbar. Choose an XY (Scatter) chart type, smooth and without points visible, before clicking the Next button. In the Data range textbox type x,y and press the Finish button.

Resize the graph as follows: Hold down the “Alt” Key and with the left mouse button held down drag the top left anchor point on the graph border to the top left of Cell H4. The purpose of holding down the “Alt” button is to make the resized graph (or any object) “Snap to Grids”. In a similar manner drag the bottom right anchor point of the graph border to give the largest graph for your screen. Click once on the Chart Legend to highlight it and press the Delete Key on the keyboard. With the mouse in the Plot Area click on the right mouse button and select “Clear” from the drop down menu. In a similar manner repeat the above with any gridline. Thus the graph should have no background colour or gridlines. (The reason being that it refreshes or redraws quicker and without flicker). Save your work.

In Cell F4 type “Axes”, in F5 type 11, E6 type –14, F7 type –15 and G6 type

16. Now highlight the numbers 5, 6 and 7 from the left hand row indicator

column as shown. Whilst these are highlighted click the right mouse button and select “Row Height”. Type in 20 and click OK.

Now press and hold down the Ctrl button on the keyboard, then at the same time click the four Cells F5, E6, F7 and G6. Whilst the mouse pointer remains over one of these Cells press the right mouse button and choose “Format Cells”. Select the “Alignment” Tab and alter the options as shown below. Click OK.

24

If not already on display, open up the Visual Basic Toolbar (View Toolbars Visual Basic). Cilck open the Control Toolbox and select the “Spin Button” Control

Whilst holding down the “Alt” key drag the Spin Button over the Cell F6, it should “Snap” to the Cell size automatically. Repeat with three further Spin Buttons put into the Cells E7, F8 and G7. It will look a little messy now, something like this:

spnyMax

spnxMin

spnyMin

spnxMax

Get into Design Mode if not already activated and right mouse click on top of a Spin Button, choose “Properties” and modify each of the four in the same manner bar their individual names as shown in the picture above. The modifications are given below:

 Name: Either of the above Spin Button names, respectively Height: 6.75 Linked Cell: F5 for spnyMax, G6 for spnxMax, F7 for spnyMin or E6 for spnxMin Max: 500 Min: -500 Orientation: 1 – fmOrientationHorizonal

One of the effects of this is to make the spin buttons like quite thin rectangles. Earlier we ‘top aligned’ the four cells F5, G6, F7 and E6, the reason for this was so that we could squeeze in underneath each number the associated Spin Button. By far the most accurate way to now move each spin button is to highlight it then hold down the “Ctrl” key as you press either of the keyboard cursor (arrow) keys. You should end up with the following picture – I have included a simple border too.

We now give the Cells F5, G6, F7 and E6 the names “ymax”, “xmax”, “ymin” and “xmin” respectively using the Name Box for speed (but don’t forget to press Return each time or the name will not be entered)

Next, in Design Mode, right mouse click on the spnyMax Spin Button and choose “View Code”. Type in the following code:

Private Sub spnyMax_Change() Range("ymax").Activate ActiveCell.Value = spnyMax.Value Call axes1 End Sub

Alter this accordingly with each of the other Spin Buttons respectively.

Now, either stay in the VBA Editor or if in Excel press Alt+F11. Then select Insert Procedure, and fill out the Add Procedure Dialogue Box as shown below giving it the name “axes1”. After pressing OK next type in the code for “axes1” as shown below.

25

Notice that this Procedure is expecting your graph to be called “Chart 1” – if it is not then it will not work. After checking to see what your graph is actually called (Hold down the “Ctrl” key whilst clicking on the graph and look in the Name Box) you can remedy this by either:

1. Changing the name of the graph in the Name Box, or

2. changing the name in the code of the “axes1” Procedure to match that of your graph on the worksheet.

Now go back to the Excel worksheet and click on the Spin Button arrows, what happens? Notice also that you can directly alter axes sizes by clicking in either of the Cells F5, F7, E6 or G6 respectively, typing in any particular value and then pressing Return. Save your work!

Notice also that, unlike in the previous exercise (Programming 4), this range of x and y values are static. Hence, there is little point in altering the maximum and minimum values of x beyond the values 40 and – 40, respectively.

26

We finish with a general statement that should be read as applicable to many of our previous exercises, namely:

To make this particular exercise more transferable to other work delete all of your x and y range and your graph but leave your Spin Buttons and their numbers. Save this file as Axes and then use this as a template or starting point for any other work that will need a graph to be drawn as part of it.

Therefore, once you have a Subroutine or Module that works – SAVE IT somewhere either to be imported or ‘cut and pasted’ at a later time into other projects.

A screen shot is shown below, wherein the worksheet’s Gridlines have been removed for clarity by selecting Tools Options View Tab, and unchecking the Gridlines Box in the ‘Windows options’ section.