You are on page 1of 61

VBA Handbook

VBA
Message &
Input Boxes
A Comprehensive Guide to Using VBA
Message Boxes and Input Boxes

By Martin Green
VBA Message Boxes

Contents
About This Book .......................................................................................................... 4
About the Exercises ..................................................................................................... 4
Message Boxes ........................................................................................................... 5
The Anatomy of the Message Box.................................................................................. 5
Message Box Title ................................................................................................... 5
Message Box Icons.................................................................................................. 6
Message Box Buttons .............................................................................................. 6
Programming Message Boxes........................................................................................ 8
The MsgBox Method for Simple Messages .................................................................. 9
Step-by-Step: A Simple Information Message ........................................................ 9
Multi-line Messages ............................................................................................... 10
Step-by-Step: A Multi-Line Message ................................................................... 11
The MsgBox Function for Multi-Button Messages ....................................................... 14
Step-by-Step: Evaluating a Yes/No Response with an If Statement......................... 14
Evaluating a Yes/No/Cancel Response with a Case Statement ................................ 17
Setting the Default Button ................................................................................. 18
Using the Help Button ........................................................................................... 18
Modal Message Boxes............................................................................................ 19
Writing Long Messages .......................................................................................... 20
Including Data in Messages .................................................................................... 21
Coping with Quote Marks ....................................................................................... 22
Being Creative with Titles ...................................................................................... 23
Using Constants for Consistency ............................................................................. 23
Using Numbered Items and Bullet Points ................................................................. 24
Things You Can't Do with a Message Box ................................................................. 26
Input Boxes.............................................................................................................. 27
The Anatomy of the Input Box................................................................................ 27
Programming Input Boxes .......................................................................................... 29
The VBA InputBox Function .................................................................................... 29
Accepting Input from the User ........................................................................... 29
Checking the User's Response ............................................................................ 30
Let the User Try Again ...................................................................................... 33
What If the User Cancels? ................................................................................. 34
Supplying a Default Value.................................................................................. 35
Excel's InputBox Method........................................................................................ 36
Declaring a Data Type for the Input Box Value ..................................................... 37
If the User Enters the Wrong Data Type .............................................................. 38
If the User Cancels the Input Box ....................................................................... 39
Working with Input Formulas (Type 0) ................................................................ 39
Working with Input Numbers (Type 1) ................................................................ 40
Working with Input Text (Type 2) ....................................................................... 41
Working with Logical Values (Type 4).................................................................. 41
Working with Cell References (Type 8) ................................................................ 42
Working with Error Values (Type 16)................................................................... 44
Working with Arrays of Values (Type 64) ............................................................. 45
Step-by-Step: Exploring Message Boxes ...................................................................... 49
Part 1: Prepare the Workbook ................................................................................ 49
Part 2: Write the Basic Macro ................................................................................. 49
Part 3: Add a Confirmation Message........................................................................ 50
Part 4: Test the Macro ........................................................................................... 51
Part 5: Add a Timer............................................................................................... 51
Part 6: Add Statistics to the Confirmation Message ................................................... 52
Part 7: Let the User Choose the Minimum Number .................................................... 53
Part 8: Add an Error Handler .................................................................................. 55
Final Code Listing for the MessageDemo Macro ......................................................... 57
Flow Diagram for the MessageDemo Macro .............................................................. 59
Appendix: VBA Message Box Constants........................................................................ 60
Notes and Further Information.................................................................................... 61
About the Author .................................................................................................. 61
© Martin Green www.fontstuff.com 2
VBA Message Boxes

Copyright............................................................................................................. 61
Limitation of Liability ............................................................................................. 61

First Published in 2005 by Martin Green


Web Site: http://www.fontstuff.com
e-mail: martin@fontstuff.com
© 2005 Martin Green – All rights reserved.

© Martin Green www.fontstuff.com 3


VBA Message Boxes

About This Book


This book is a guide to using Message Boxes and Input Boxes in VBA (Visual Basic for
Applications) programming in Microsoft Office. It contains a comprehensive summary of the
VBA language associated with these objects and provides examples of their use illustrated
with Step-by-Step exercises which are suitable for all levels of user but which are particularly
aimed at the novice VBA programmer.

This document describes the various different types of message box that can be created with
VBA and explains how to program them. It also describes the VBA input box which, in
addition to displaying a message, can receive typed input via its built-in textbox, and a
special variation of the input box which is available in Excel.

Much of the information here applies equally to all the Microsoft Office applications that can
be programmed with VBA.

It concludes with an exercise in Excel in which several different kinds of message box are
used, illustrating how message boxes and input boxes can be used to inform and interact
with the user.

About the Exercises


My experience of training IT in a classroom has taught me that even the most intelligent of
people can get confused when following instructions in a subject new to them. When doing
an exercise from a book such as this it can be even more confusing since individual authors
have their own way of saying things. So here is an explanation of the conventions I have
used for the Step-by-Step exercises in this document. Please take a moment to read it
before embarking on the exercises to make sure you understand exactly what I'm asking you
to do.

Follow the instructions exactly. Read the instructions carefully and do exactly what they
say. Take care when typing. Remember that the computer takes all your instructions
literally.

Things you have to do are highlighted grey. I explain and illustrate the process as the
exercise proceeds so to distinguish my text from your practical instructions everything you
need to do has a grey background like this.

Instructions are sequentially numbered. So that you can keep track of where you are in
an exercise each step is numbered e.g. Step 1, Step 2 and so on.

"Click" means on the screen. If you have to "click" something it means with your mouse
on the screen, such as a button on a dialog box e.g. Click OK or Click the OK button. Unless
otherwise stated, mouse clicks are made with the primary (usually the left) mouse button. If
it is required to use the secondary (usually the right) mouse button you will be asked to
right-click.

"Press" means on the keyboard. If you have to "press" something it means a key on the
keyboard e.g. Press [Enter] or Press the Enter key.

When Key presses or keyboard shortcuts are required special key names are enclosed
in square brackets e.g. [Enter]. When combinations of key presses are required they are
written thus [Control]+[Enter]. This means hold down the Control key whilst pressing the
Enter key. Function keys are indicated thus: [F8] , [F11] etc.

Choosing menu items is usually indicated by Open the Tools menu and choose Macro then
Macros. Sometimes this is shortened to Go to... or Choose Tools > Macro > Macros.

If you don't understand an instruction don't panic! None of these exercises can harm your
Office programs or your computer. I recommend that, at least to begin with, you always
carry out the practice exercises in a new document or workbook. If things go wrong you can
simply stop the exercise, throw away the document or workbook, and start again.

These exercises have been thoroughly checked and tested. If you find an error in one of
them please let the author know about it. For contact details see: About the Author on
page 61.

© Martin Green www.fontstuff.com 4


VBA Message Boxes

Message Boxes
Every Windows user is familiar with the message box. It is used universally to communicate
with the user in many different circumstances. Message boxes can be used to provide
information to the user, or to obtain a response when a decision has to be made. They can
display a choice of different icons and various combinations of buttons.

The Anatomy of the Message Box


A message box consists of a number of different parts, many of which can be customized by
the VBA programmer. The illustration below (Fig. 1) shows a typical VBA message box.

Fig. 1 The arrangement of a typical message box.

It is made up of a number of component parts most of which can be modified with VBA:

Title: The title bar at the top of the box displays the Title text which can be specified by the
programmer. If no title is defined the message box displays the name of the program here.

Close Button: In the upper right corner is a Close Button which is enabled only if the
message box displays just an OK button, when clicking it is equivalent to clicking the OK
button; or if the combination of buttons includes a Cancel button, when clicking it is
equivalent to clicking the Cancel button. If any other combination of buttons is chosen the
close button is disabled.

Icon: A selection of different icons is available (see: Message Box Icons on page 6). The
message can be displayed without an accompanying icon if required.

Prompt: The message itself is called the Prompt in VBA. It can contain several lines and the
VBA programmer can determine where line breaks occur if they wish.

Buttons: Various combinations of buttons can be displayed on a message box (see:


Message Box Buttons on page 6) varying from a simple OK button allowing the user to
dismiss the message, to a group containing, for example Yes, No and Cancel buttons
requiring the user to make a choice. A Help button can also be added.

Message Box Title


You can choose to ignore the title if you wish. If you do this the message box displays the
name of the host program (Fig. 2 left) but consider the effect of this on the user. If they see
a message bearing the name of the program they are likely to think that the message came
from the host program itself rather than from your program or macro (Fig. 2 right). An
alternative often favoured my me (and liked by the client!) is to use the company or project
name on all message boxes and UserForms and create a uniform "corporate image" for your
program (Fig. 2 middle).

There is a limit to the length of the text in the title. This varies depending upon the mix of
characters (in a proportional font the characters are of different widths) and the Windows
display settings where fonts and point size can be specified. But since you are unlikely to
know the users' display settings it is advisable to keep the title text brief. The width of the
message box will increase to accommodate the title up to its maximum of approximately 50
characters. If the title text contains more than can be displayed it is truncated and an ellipsis
(...) placed at the end of the displayed text.

© Martin Green www.fontstuff.com 5


VBA Message Boxes

Fig. 2 Making use of the message box title.

Message Box Icons


Icons are a valuable addition to a message box, providing a visual cue to the user and
emphasising the purpose of the message. Adding an icon can often mean that a simpler
message will suffice. Four different icons are available (Fig. 3).

Fig. 3 Message box icons. From left to right:


Information, Question, Exclamation, Critical.

Icons convey an important message to the user and help reinforce your own message text.
There is no restriction on which icon is used with which button combination but it pays to use
them logically. Here are some suggested guidelines...

The Information icon (VBA constant: vbInformation) lets the user know that
the message is only providing information and requires no action on their part
other than an acknowledgement. You are most likely to use this in conjunction
with just an OK button.

The Question icon (VBA constant: vbQuestion) tells the user that they have to
make a decision. This would normally be used where there is an message in the
form of a question and a combination of buttons such as Yes and No.

The Exclamation icon (VBA constant: vbExclamation) indicates a moderate


level of alarm. You might use it to warn the user when they have done
something wrong but the problem can be fixed. It is likely to accompany a
message along the lines: "You can't do that!"

As its name suggests the Critical icon (VBA constant: vbCritical) indicates a
high level of alarm. This one is usually reserved for when there is a serious
problem, such as a macro error, when the situation can not be recovered. It
suggests a message like: "We have a problem!"

Note that a message box can display only one icon at a time. If you want to display more
than one icon, or one different to those normally available, you should consider mimicking a
message box with a VBA UserForm (the use of VBA UserForms is covered in detail in another
title in this series: VBA UserForms).

Message Box Buttons


Six different combinations of buttons are available. In each case, clicking a button causes the
message box to close. Although each button has a specific caption this is not associated with
a particular function or action. When more than one button is displayed the message box
returns the value of the button to the procedure so that appropriate action can be taken. The
programmer must write an appropriate procedure to handle the user's response (see: The
MsgBox Function for Multi-Button Messages on page 14).

© Martin Green www.fontstuff.com 6


VBA Message Boxes

When a message box is displayed one of the buttons is the default button. That button is
highlighted with a heavy external border and a dotted internal border. If the user presses the
Enter key on their keyboard the message box will behave as if the default button had been
clicked. If there is a Cancel button on the message box and the user presses the Escape
key on their keyboard the message box will behave as if the Cancel button had been clicked.

The available button combinations are illustrate below:

vbOKOnly

vbOKCancel

vbYesNo

vbYesNoCancel

vbRetryCancel

vbAbortRetryIgnore

In addition, a "Help" button can be added to any of these button combinations:

vbYesNo + vbMsgBoxHelpButton

If a Help button is displayed it has no function unless the programmer specifies the name of
a Help file and a context number within the Help file so that appropriate help is displayed
(see: Using the Help Button on page 18).

© Martin Green www.fontstuff.com 7


VBA Message Boxes

Programming Message Boxes


The message box in VBA is represented by the keyword MsgBox. Message boxes are
unusual in that they can be programmed as a Method or as a Function.

When the requirement is simply to convey information to the user the MsgBox method is
used and it is necessary only to display the OK button. Its programming consists of a
specification of its design and its message.

When a message box is designed to take some input from the user the MsgBox function is
used. The message box will have more than one button, and its programming will also
include the interpreting and processing of the user's response (i.e. which button they
clicked).

When programming a message box, if the Visual Basic Editor's AutoQuickInfo feature is
enabled, help is displayed indicating what information is required (Fig. 4). The Message box
can accept up to 5 parameters. All except the Prompt are optional.

Fig. 4 The Visual Basic Editor displays AutoQuickInfo for a message box.

Here is a summary of the message box parameters:

Parameter Description

Prompt The Prompt is the text of the message itself. It is supplied as a string
and should be enclosed in quotes ("). The message can be up to 1024
characters long. Although the text will automatically wrap within the
message box, you can control the flow of text by inserting commands
that force a new line (see: Multi-line Messages below).

Buttons The Buttons parameter (optional) is used to specify the chosen


combination of buttons to appear on the message box, as well as a
choice of icons, and which button is to be the default. This information is
supplied using VBA constants (see: Appendix: VBA Message Box
Constants on page 60) a list of which appears when you enter the
buttons parameter. Choose more than one option by entering a plus
sign (+) between constants, e.g.: vbYesNo + vbQuestion. If no
buttons are specified the default vbOKOnly is displayed.

Title The Title parameter (optional) is the text that appears in the title bar at
the top of the message box. It is supplied as a string and should be
enclosed in quotes ("). The amount of text possible is limited by the
width of the message box and depends upon your display settings. With
normal Windows settings about 50 characters can be displayed.

HelpFile If a Help button is displayed, this parameter can be used to specify the
path to the relevant Help file. The user can also access this help by
pressing the F1 function key whilst the message box is open (even if no
Help button is used). This parameter is used in combination with the
Context parameter.

Context The Context parameter gives the location of the help within the help file
specified in the HelpFile parameter. Both HelpFile and Context
parameters are optional but if used, both parameters must be supplied.

© Martin Green www.fontstuff.com 8


VBA Message Boxes

The MsgBox Method for Simple Messages


The message box method is used when all that is required is to convey some information to
the user. Depending on the nature of the message you might want to add an icon, but
anything more than a single OK button would be superfluous as there will be no code to
interpret the user's response.

Step-by-Step: A Simple Information Message


This exercise demonstrates a simple message box. Normally it would be included as part of a
larger macro, but in this exercise you will create a macro that does nothing other than
display a message.

You can try this exercise in any Microsoft Office program that supports VBA programming.

Step 1: In a new module create a new procedure by typing:

Sub ShowMessage

and press [Enter].

Step 2: Place your cursor in the empty line between the Sub and End Sub lines and press
[Tab] to indent your code line then type:

MsgBox

followed by a [Space].
This prompts the Visual Basic Editor to display the AutoQuick Info help showing the various
parameters required:

The word Prompt is highlighted in bold indicating that the Visual Basic Editor is expecting
you to supply the message next so...

Step 3: Type the text of the message enclosed in quotes as follows:

"The macro is complete"

Then type a comma to display the list of choices, and scroll down to the item
vbInformation.

Your code window should look like this:

Step 4: Double-click the item vbInformation, then type a comma and enter the text of
the title in quotes as follows:

"Job Done"
Your code window should now look like this:

© Martin Green www.fontstuff.com 9


VBA Message Boxes

As with all VBA code you should not finish a line of code with a comma. Typing a comma
after the closing quote mark of the title would imply that you were going to supply another
parameter, and the Visual Basic Editor would display an error message if you then failed to
do so.

Step 5: Finally, with your cursor located anywhere within the macro code, press the [F5]
key to run the macro.

Step 6: Click the OK button on the message box to dismiss it.


This completes this exercise.

The macro displays the following message box (Fig. 5):

Fig. 5 A simple message box.

The completed code for the simple message box is as follows:

Sub ShowMessage()
MsgBox "The macro is complete", vbInformation, "Job Done"
End Sub

If you want to skip one or more parameters, accepting the defaults, just type another
comma to move to the next parameter. For example, if you did not want to show an icon
your code would look like this:

Sub ShowMessage()
MsgBox "The macro is complete", , "Job Done"
End Sub

The following message box would result (Fig. 6):

Fig. 6 This message box does not display an icon.

Note that even though no button combination was specified, the default "OK" button was
displayed. This was indicated in the AutoQuickInfo help where the second parameter was
shown as: [Buttons As vbMsgBoxStyle = vbOKOnly]

Multi-line Messages
Unless it is instructed otherwise, a message box will display its message text as a single line.
The message box increases in width to accommodate the message text until its maximum
width is reached when the text wraps automatically on to a new line. The exact maximum
width of a message box depends on the current Windows Appearance settings, but the
following examples will give you some idea.

In the example below (Fig. 7) a very long piece of text was inserted into a message box. The
text was truncated when the limit was reached (1024 characters including spaces). The text
is displayed as a single block without any forced line breaks and (quite apart from the fact
that it is written in nonsense Latin!) would be quite difficult to read if this were a genuine
message.

© Martin Green www.fontstuff.com 10


VBA Message Boxes

When constructing a message it is important to think carefully about the user and to present
the message in a way that is easily read and understood. Most computer users will at some
time have been faced with a message that just didn't make sense!

Fig. 7 A message box displaying the maximum permitted amount of text.

Even a fairly short and simple message can often be made clearer by being broken into
separate lines. Placing several different pieces of information on one line makes them
difficult to separate visually (Fig. 8).

Fig. 8 A message presented as a single line.

The same message rephrased and broken into several lines is much easier to read and
understand (Fig. 9).

Fig. 9 A message presented on several lines.

The flow of message text can be controlled using special commands. This can be done in
several ways, my preference being to use the vbCrLf constant. The message is split into
sections, each enclosed in quotes, and the command inserted between the sections using the
ampersand (&) character. The following exercise demonstrates how this is done.

Step-by-Step: A Multi-Line Message


This exercise demonstrates the technique of breaking a message on to several lines. You can
try the exercise in any Microsoft Office program that supports VBA programming.

© Martin Green www.fontstuff.com 11


VBA Message Boxes

Step 1: Create a new procedure by typing:

Sub MultiLineMessage

then press [Enter].

Step 2: Place your cursor in the empty line between the Sub and End Sub lines. Press
[Tab] to indent your code line and type:

MsgBox "The macro is complete."

... followed by a [Space] and an underscore.

A space followed by an underscore at the end of a line of VBA code is referred to as the
line continuation or line break character. It tells the code engine that the current code
statement continues on the next line. At this point your code should look like this:

Step 3: Press [Enter] to create a new line then press [Tab] to further indent the code
and type:

& vbCrLf & "Please remember to save the file."

... followed by a [Space] and an underscore.

The ampersand character (&) concatenates (joins together) the various parts of the message
code, including the VBA constant vbCrLf which represents a combination of "carriage return"
and "line feed". Your code statement is instructing the message box to display: a piece of
text and a new line and another piece of text... and so on.

Your code should now look like this:

Step 4: Press [Enter] to create a new line and type:

& vbCrLf & "Have a nice day!"

... followed by a [Space] and an underscore.

Your code should now look like this:

Step 5: Press [Enter] to create a new line and type a comma to move to the next
parameter. The AutoListMembers help will display a list of items. Scroll down the
list and double-click the item vbInformation.

Step 6: Type a comma to move to the Title parameter and type:

"Job Done"
Your code should now look like this:

© Martin Green www.fontstuff.com 12


VBA Message Boxes

Step 7: Finally, with your cursor located anywhere within the macro code, press the [F5]
key to run the macro.

Step 8: Click the OK button on the message box to dismiss it

This completes this exercise.

The macro created a multi-line message box with just an OK button (Fig. 10):

Fig. 10 A multi-line message box.

Here is the final code listing for the exercise:

Sub MultiLineMessage()
MsgBox "The macro is complete" _
& vbCrLf & "Please remember to save the file." _
& vbCrLf & "Have a nice day!" _
, vbInformation, "Job Done"
End Sub
If you imagine typing your message directly on to the message box, using the "new line"
command is just like pressing [Return] or [Enter]. It can be repeated to create empty lines
in the message, as in this example:

Sub MultiLineMessage()
MsgBox "The macro is complete" _
& vbCrLf & "Please remember to save the file." _
& vbCrLf & vbCrLf & "Have a nice day!" _
, vbInformation, "Job Done"
End Sub
The resulting message box looks like this (Fig. 11):

Fig. 11 Adding blank lines to a message

As an alternative to the vbCrLf (carriage return+line feed) command you can use vbCr
(carriage return), vbLf (line feed), Chr(13) (carriage return), Chr(10) (line feed) or
Chr(13) & Chr(10) (carriage return+line feed) commands. All essentially do the same thing

© Martin Green www.fontstuff.com 13


VBA Message Boxes

although they may not work in the same way in all circumstances. Choose whichever you
prefer.

NOTE: Don't confuse the line breaks in the code with instructions to break lines in the
message. In these exercises I have used the line break character (a Space followed by an
Underscore) to break the code statement itself into separate lines to make it easy to read
in the Visual Basic Editor and on these pages. This has no bearing on the appearance of the
finished message box. The entire MsgBox code statement could be written in a single line
(omitting the line-break characters) and the result would have been just the same.

The MsgBox Function for Multi-Button Messages


Multi-button message boxes are used to obtain a response from the user. But simply adding
buttons to the message box isn't enough. It is necessary to read and then act on the user's
response.

When MsgBox is used in this way in VBA it behaves as a function returning a value to the
procedure when the user clicks one of the buttons. There are seven different button
constants, each one having a numerical equivalent:

VbOK = 1
vbCancel = 2
vbAbort = 3
vbRetry = 4
vbIgnore = 5
vbYes = 6
vbNo = 7

It is this value that is returned to the procedure when the user makes their choice. In
context, each one can be referred to by their name or their integer value. I prefer to use the
name because I find it easier to understand when reading code.

The usual procedure is to declare a variable to hold the value. This variable can have an
Integer data type (since the numerical values of the constants are integers) or, from
Microsoft Office 2000 onwards, the special data type vbMsgBoxResult.

Having placed a value into the variable by displaying the message box, it can be evaluated
with an If Statement or a Case Statement.

Step-by-Step: Evaluating a Yes/No Response with an If Statement


This example is written for Microsoft Excel and is suitable for all versions from Excel 97
onwards. It uses an If Statement to evaluate the user's response to determine whether or
not to continue with the procedure of deleting the current worksheet. You can place the code
in a new module or an existing one...

Step 1: Create a new procedure by typing:

Sub DeleteSheet

and pressing [Enter]

The next step is to declare a variable to receive the value of the button chosen by the user.

Step 2: Press [Tab] to indent your code line then type:

Dim intResponse As Integer

Then press [Enter] to move to a new line.

Now a value is assigned to the variable by displaying a message box. Note how, because
MsgBox is working here as a function its parameters are enclosed in brackets (strictly
speaking they should be called arguments now that they supply information to a function).

© Martin Green www.fontstuff.com 14


VBA Message Boxes

Step 3: Type the following message:

intResponse = MsgBox ("Deleting the current sheet."

followed by a [Space] and an underscore. Then press [Tab] to further indent


the code and type:

& vbCrLf & "Do you wish to continue?"

followed by a [Space] and an underscore. Then press [Enter] to move to a new


line.

At this point your code should now look like this:

Step 4: Type a comma to move to the next parameter and prompt the list of options to
appear. Scroll down the list and double click the item vbQuestion.

Step 5: Type a plus sign (+) to prompt the list to appear again then find and double-click
the item vbYesNo.

A plus sign is used to "add together" the constants when you want to specify a button type
and an icon. If you try to specify two button types or two icons, something a message box
can not display, it reverts to the default setting and displays just an OK button and no icon.

Step 6: Type a comma to move to the Title parameter and type:

"Are you sure?"

Then type a closing bracket ()).

Step 7: Press [Enter] to move into a new line and press [Backspace] to remove the
indent.

Your code should now look like this:

The code now has to evaluate the user's response which, in this case is very easy so a simple
If Statement will suffice. If the user clicked the No button then there is no more to do and
the macro can terminate...

Step 8: Type:

If intResponse = vbNo Then Exit Sub

Then press [Enter] to move to a new line.

Any code which now follows will be executed only if the user clicked the Yes button.

© Martin Green www.fontstuff.com 15


VBA Message Boxes

Step 9: Type the following three lines of code to complete the procedure:

Application.DisplayAlerts = False
ActiveSheet.Delete
Application.DisplayAlerts = True
The finished code should look like this:

The code lines either side of the one that actually deletes the current sheet serve to suppress
then restore the warning message that Excel normally displays when a worksheet is deleted.
If you use this command to turn off alerts you must remember to include the command to
turn them on again, otherwise no more warnings will be displayed until you restart Excel!

Step 10: Check your code by opening the Visual Basic Editor's Debug menu and choosing
Compile VBAProject. If there are any errors in your code the compiler will point
them out now. Correct any errors it finds.

Step 11: Switch to Excel and, having made sure you are on a worksheet that it is safe to
delete, use the keyboard shortcut Alt+F8 to open the Macro dialog. Choose the
DeleteSheet macro and click the Run button to display the message box.

First of all click the No button and note that the message box disappears and the
sheet is not deleted. Then repeat the procedure and choose the Yes button and
note that the active worksheet is deleted.

This concludes this exercise.

The macro created a two-button Yes/No message box (Fig. 12) and a simple If Statement
handled the user's response.

Fig. 12 A Yes/No message box.

Here is the final code listing for the exercise:

Sub DeleteSheet()
Dim intResponse As Integer
intResponse = MsgBox("You are about to delete the current sheet." _
& vbCrLf & "Do you wish to continue?" _
, vbQuestion + vbYesNo, "Are you sure?")
If intResponse = vbNo Then Exit Sub
Application.DisplayAlerts = False
ActiveSheet.Delete
Application.DisplayAlerts = True
End Sub

© Martin Green www.fontstuff.com 16


VBA Message Boxes

The method used to evaluate the user's response depends upon the number of buttons. If
there are two buttons (such as Yes/No or OK/Cancel) it is safe to assume that if they
didn't click one they must have clicked the other. But if there are three buttons it a bit more
complicated. If the user didn't click the first button you still need to know whether they
clicked the second or the third.

Evaluating a Yes/No/Cancel Response with a Case Statement


You can use either an If Statement or a Case Statement to evaluate the response. The
following example uses a Case Statement to evaluate the response from a three-button
Yes/No/Cancel message box.

The macro is intended for use in Microsoft Word and writes the current date into the active
document at the insertion point...

Sub EnterDate()
Dim strDate As String
Dim Response As VbMsgBoxResult
Response = MsgBox("Would you like the Long Date format?" _
, vbQuestion + vbYesNoCancel, "Writing Date")
Select Case Response
Case vbYes
strDate = FormatDateTime(Date, vbLongDate)
Case vbNo
strDate = FormatDateTime(Date, vbShortDate)
Case vbCancel
Exit Sub
End Select
Selection.TypeText strDate
End Sub
The macro starts with the declaration of two variables. The first one (strDate) is a string
variable which will hold the text to be inserted into the document. The second one
(Response) is declared here as a VbMsgBoxResult which identifies it specifically as one of
the message box button constants (NOTE: since this type was new in Office 2000, Office 97
users should declare this variable as an Integer instead).

Then a value is placed into the Response variable by displaying a Yes/No/Cancel message
box (Fig. 13).

Fig. 13 A Yes/No/Cancel message box.

The message box asks the user if they would like to use the Long Date format. They can
choose Yes (the macro will write a date like 27 September 2005), No (the macro will write a
date like 27/09/05 or 09/27/05 depending on your regional settings) or Cancel (the macro
will do nothing.

When the user clicks one of the buttons, the message box closes and passes a value to the
variable. The value is the numerical equivalent of the button constant: vbYes = 6, vbNo =
7, vbCancel = 2. As long as they are used in the correct context, you can write either the
constant name or its value into your code. It will understand what you mean. I prefer to use
constant names as they are easy to remember when writing and reading code (people who
use the numbers are just showing off!). You can find a complete list of VBA message box
constants in Appendix: VBA Message Box Constants on page 60.

Next comes a Case Statement which looks at the value of the Response variable and acts
accordingly. If the value is 6 (vbYes) it writes a long date into the strDate variable with the
help of the VBA FormatDateTime and Date functions. If the value is 7 (vbNo) it writes a

© Martin Green www.fontstuff.com 17


VBA Message Boxes

short date into the strDate variable. If the value is 2 (vbCancel) then the macro
terminates.

Finally (if the macro did not terminate because the user clicked Cancel) the date is written
into the document.

I normally prefer to use a Case Statement when there are more than two choices to evaluate
because I think Case Statements are easier to read, but an If Statement would work just as
well. To do the same job using an If Statement replace the lines from Select Case to End
Select in the previous code listing with the following:

If Response = vbYes Then


strDate = FormatDateTime(Date, vbLongDate)
ElseIf Response = vbNo Then
strDate = FormatDateTime(Date, vbShortDate)
Else
Exit Sub
End If
To make the macro suitable for use in Microsoft Excel change the last line to:

ActiveCell.Value = strDate

Setting the Default Button


The Buttons parameter of a message box can be used to specify which button is the default
(i.e. already highlighted). This is useful where users are prone to hit the Enter key to quickly
dismiss a message box without reading it, or where you want to prompt a user to make a
particular choice. Most people quickly learn that, if they are not sure what to do next,
pressing the default button is probably best.

If the code of the last example was modified as follows:

Response = MsgBox("Would you like the long date format?" _


, vbQuestion + vbYesNoCancel + vbDefaultButton3, "Writing Date")
... the third button (vbDefaultButton3) would be the default and already highlighted when
the message box appeared (Fig. 14):

Fig. 14 The third button has been made the default.

A message box can display up to four buttons, and any one can be designated the default.

Using the Help Button


The creation of custom help is an advanced topic involving the use of special help compiling
software. If you want to create your own help you can use the tools supplied with Microsoft
Office Developer Edition, download the tools from Microsoft's web site, or use one of the
many third-party applications available (some of which are shareware or freeware).

You can, however, offer a link to the built-in help. When programming the "Help" button you
need to supply two pieces of information: HelpFile (the name and location of the file that
contains the help), and Context (an ID number – like a bookmark – to identify the individual
help topic).

This information differs between versions of Microsoft Office. In Excel, for example, Excel 97
uses the old-style Windows help files (the main help file is named Xlmain8.hlp); Excel 2000,
2002 and 2003 use the newer HTML help files (named Xlmain9.chm, Xlmain10.chm and

© Martin Green www.fontstuff.com 18


VBA Message Boxes

Xlmain11.chm respectively). You should check the location of these files on your particular
installation.

To ascertain the Context ID of the appropriate bit of help is not so easy. Various authors have
compiled helpful lists (for example see: http://www.j-walk.com/ss/excel/tips/tip89.htm). In
Excel 2000/2002/2003 you can navigate to the desired help then right-click on the help page
and choose View Source. Look for a reference to "Tnum" followed by a 6-digit number
somewhere near the top of the source code (Fig. 15).

Fig. 15 The source code behind a help page includes the Tnum Help context number.

The message box code in the last example, modified to include a help button linked to
relevant help would look something like this:

Response = MsgBox("Would you like the long date format?" _


, vbQuestion + vbYesNoCancel + vbMsgBoxHelpButton _
, "Inserting the date..." _
, "C:\Program Files\Microsoft Office\Office10\1033\XLMAIN10.CHM" _
, 5198679)
NOTE: The path to the help file might be different on your computer. Use the Windows
Search tool to locate the file. When programming for third-parties, developers can use VBA
to ascertain the location of help files from information in the Windows Registry (this topic is
not within the scope of this document).

NOTE: When the "Help" button is clicked the message box remains open. All other buttons
cause the message box to close when clicked.

Modal Message Boxes


Message boxes are Modal, meaning they are always "on top" of their application's active
window. An message box can be Application Modal or System Modal.

If a message box is Application Modal it will appear on top of the host application window
but, if the user is working in a different application (i.e. if a different program window
currently has the focus) the message box will not interrupt them. Windows XP alerts the user
to the fact that another application needs their attention by highlighting its taskbar button
(Fig. 16).

Fig. 16 Windows XP alerts the user that another application needs their attention.

The user is also prevented from working in the host application until the message box has
been dismissed. All message boxes are Application Modal by default but you can specify it in
the code if you wish...

MsgBox "This message is modal", vbInformation + vbApplicationModal


If System Modal is specified the message box remains on top even when switching to other
programs, although it does not prevent the user from working in another program.

MsgBox "This message is system modal", vbInformation + vbSystemModal


Neither kind of message box prevents you from switching to other programs or working in
them, but if you switch to another program whilst a System Modal message box is displayed

© Martin Green www.fontstuff.com 19


VBA Message Boxes

it will remain visible, on top of all open windows. Both kinds of message box prevent you
from working in the host program. (NOTE: I have described how System Modal is supposed
to work but in practice it does not always function as expected.)

It is important to remember that, even when the display of a message box is the last action
of a macro, the procedure is still running as long as the message box is open. When you are
testing your code, you will find that an open message box will prevent you from working in
the Visual Basic Editor.

Writing Long Messages


As mentioned earlier, a message box has the capacity to display a very long message. Whilst
messages should be kept brief for the benefit of the user, it is sometimes necessary to write
long lines of text. Most programmers like to keep their code lines short enough to fit on the
screen so that they are easy to read but when it comes to text strings, it is not sufficient to
simply break the string with the line continuation command.

The following code line has been broken using a "space & underscore" line continuation
command to fit conveniently into the code window:

MsgBox "This is a very long sentence so I have split it into two _


lines to fit on the screen."

But as it stands the code will be rejected by the Visual Basic Editor and an error message will
be displayed (Fig. 17).

Fig. 17 The Visual Basic Editor rejects a broken string.

The code has been rejected because the line continuation has occurred in the middle of a
string (a piece of text). When splitting a string you must provide each part with both opening
and closing quote marks and the various parts of the string must be concatenated (joined
together) using the ampersand character (&). The code should have been written like this:

MsgBox "This is a very long sentence so I have split " _


& "it into two lines to fit on the screen."

Splitting strings like this has no effect on the arrangement of text in the message box (see:
Multi-line Messages on page 10). Note that I have left a space at the end of the first string,
before the closing quote mark. If I had not done that there would have been no space
between the last word of the first string and the first word of the next string when the
message box was displayed (Fig. 18).

Fig. 18 The effect of omitting a space when concatenating strings.

© Martin Green www.fontstuff.com 20


VBA Message Boxes

Including Data in Messages


A message doesn't just have to be a piece of text. It can include calculated data or
information, either on it's own or as part of a text message. The following code statement
makes use of the VBA Date function to display just the current date...

MsgBox Date, vbInformation


The result displays only the calculated data and the specified icon (Fig. 19):

Fig. 19 A message consisting only of calculated data.

To add text to data simply concatenate the items using the ampersand character (&),
remembering to include spaces where text and data join. This code statement uses the VBA
Format function to modify the displayed date and adds some text...

MsgBox "Today is " & Format(Date, "dddd"), vbInformation


The result appears as a continuous message (Fig. 20):

Fig. 20 A message including text and data.

In the last two examples the included data was created within the message box statement
itself. It is just as easy to add information that is stored in a variable. The next example uses
a Case Statement to generate an appropriate greeting depending on the time of day...

Dim strGreeting As String


Select Case Hour(Now)
Case Is <= 11
strGreeting = "Good morning."
Case Is <= 18
strGreeting = "Good afternoon."
Case Is < 24
strGreeting = "Good evening."
End Select
MsgBox strGreeting & " Today is " & Format(Date, "dddd"), vbInformation
Again, the information held in the variable is concatenated with the text string to produce a
seamless message (Fig. 21):

Fig. 21 This message displays data stored in a variable.

© Martin Green www.fontstuff.com 21


VBA Message Boxes

If, like me, the last example bothers you because the first part of the message ("Good
afternoon.") is followed by a full-stop (a period) but the second part ("Today is Thursday")
lacks one, some people might say that you need to get out more but I say that you are good
programmer material! Little things like that show the attention to detail that makes the
difference between a professionally produced application and one that lacks care. Nobody
notices when things are OK but they will quickly spot things that don't look right, regardless
of how insignificant and unimportant they might seem to you. Here's the improved version...

MsgBox strGreeting & " Today is " & Format(Date, "dddd") & ".", _
vbInformation
Here's a better looking message (Fig. 22):

Fig. 22 Attention to detail – the full-stop has been added.

Coping with Quote Marks


The message and title of a message box are supplied as strings and as such (unless they are
represented by variables or functions which return values that can be interpreted as strings)
they must be enclosed by pairs of quote marks. The Visual Basic Editor does not mind
whether you use double quotes (") or single quotes (') as long as they are paired up
correctly.

You have to pay particular attention to this when creating messages which contain items
which are themselves in quotes. For example, the following code statement will be rejected
by the Visual Basic Editor...

MsgBox "The name "ACME" is not recognised."

When the Visual Basic Editor comes across a quote mark it looks for the next matching quote
mark and assumes that whatever falls between them is a complete string. Here it can see
the string "The name " and the string " is not recognised." and does not know what to
make of the letters ACME between them (Fig. 23):

Fig. 23 Too many quote marks cause problems.

There are two solutions to the problem. One is to alternate double and single quotes, for
example:

MsgBox "The name 'ACME' is not recognised."


But many VBA programmers prefer to use the appropriate VBA character code to insert the
quote marks in the required place in the string. This involves a little more typing but is a
more foolproof way of tackling the problem. The character code for the double quote mark is
34 and this is applied using the VBA Chr() function:

MsgBox "The name " & Chr(34) & "ACME" & Chr(34) & " is not recognised."
This produces a message containing the required arrangement of quotes (Fig. 24):

© Martin Green www.fontstuff.com 22


VBA Message Boxes

Fig. 24 Quotes produced by the Chr() function.

Being Creative with Titles


As with message box messages, you are not restricted to text when creating a title for your
message box. If no title is specified the message box displays the name of the host
application. You can replace that with some relevant text or be more creative by including
other information. Here are some examples...

When this code statement is run in Microsoft Excel the resulting message box displays the
square root of the number in the active cell in the message, and the text "Cell: " followed by
the selected cell's address in the message box title. (NOTE: I have used the VBA Replace
function to remove the dollar signs from the address by replacing them with nothing. The
Address property always returns the address in the format $A$1 whereas A1 is easier for
the user to read.)

MsgBox Sqr(ActiveCell.Value), , "Cell: " & _


Replace(ActiveCell.Address, "$", "")
The resulting message box looks like this (Fig. 25):

Fig. 25 The active cell address is displayed in the title.

The following code statement displays a message box in Microsoft Word in which the
message shows the word count and the title shows the document's name.

MsgBox ActiveDocument.Words.Count & " words", , ActiveDocument.Name


The resulting message looks like this (Fig. 26):

Fig. 26 The document name is displayed in the title.

Using Constants for Consistency


In the same way that data held in variables can be displayed in a message box, the values of
constants can be used too. If you are creating an application that has many message boxes,
you might like them all to show the same title, displaying the company name or perhaps the
name of your custom application.

Similarly, should you decide to change the name of your application, or sell it to a different
company, all that you need to do is change the value of the constant. You won't have to find
and change each message box.

To save you having to remember to enter that bit of information in exactly the same way you
can store it in a VBA constant. A constant has its value "hard-coded" (i.e. written in by the

© Martin Green www.fontstuff.com 23


VBA Message Boxes

programmer) when it is declared. If it is declared as a public constant all the macros in the
same project will be able to refer to it and read its value.

You can declare a constant in any regular code module (not an object module such as that
attached to a worksheet or workbook in Excel or the document module in Word). Place the
code in the declaration area at the top of the module outside of and before any macros.

A typical example might look like this:

Public Const conCompanyName As String = "Acme Tyre Company"

You can now call on the value of the constant in any of your procedures. Just substitute the
name of the constant for the text you would otherwise have written. Here's an example of a
message box that makes use of the constant to display the company name in the title bar of
the message box:

MsgBox "The data has been exported.", , conCompanyName


Here is the resulting message box (Fig. 27):

Fig. 27 The message box title is stored in a constant.

Using Numbered Items and Bullet Points


If you have several things to say in your message, creating a numbered list or adding bullet
points would be a good way to highlight the different items. Unfortunately there isn't a way
to do this automatically as you would in a Word document or on a PowerPoint slide. You will
have to be satisfied with entering the information manually. This is straightforward with a
numbered list. Just type the numbers into the prompt section of your code (Fig. 28 left):

MsgBox "This macro will carry out the following tasks:" & _
vbCrLf & "1. Archive the old file" & _
vbCrLf & "2. Create a new file" & _
vbCrLf & "3. Name and save the new file" & _
vbCrLf & "4. Print a copy of the new file" & _
vbCrLf & "Click OK to continue." _
, vbInformation, "Acme Logisitics Corporation"
Similarly there is no automatic indent facility so to indent the list add some spaces to the
start of each line of the message text (Fig. 28 right):

MsgBox "This macro will carry out the following tasks:" & _
vbCrLf & " 1. Archive the old file" & _
vbCrLf & " 2. Create a new file" & _
vbCrLf & " 3. Name and save the new file" & _
vbCrLf & " 4. Print a copy of the new file" & _
vbCrLf & "Click OK to continue." _
, vbInformation, "Acme Logisitics Corporation"

© Martin Green www.fontstuff.com 24


VBA Message Boxes

Here are the results...

Fig. 28 A manually numbered list without (left) and with (right) indents.

When it comes to adding bullets to a list you will have to make your choice from the various
characters available to you in the standard message box font (normally Tahoma in Windows
XP as shown in these screenshots).

Several different characters are suitable for use as bullets. In this example the right single
angled bracket is used and, since it is one of the characters represented on the standard
keyboard, it can be typed directly into the code (Fig. 29):

MsgBox "This macro will carry out the following tasks:" & _
vbCrLf & "> Archive the old file" & _
vbCrLf & "> Create a new file" & _
vbCrLf & "> Name and save the new file" & _
vbCrLf & "> Print a copy of the new file" & _
vbCrLf & "Click OK to continue." _
, vbInformation, "Acme Logisitics Corporation"

Fig. 29 Angled brackets used as bullet points.

You could also use the hash mark (#) or a simple dash (-). But the standard character set
includes more characters than shown on the standard keyboard including some that make
suitable bullets. These additional characters can be added by specifying their ASCII character
codes with the help of the VBA Chr() function. Suitable characters include the center dot
(character 149: •), the currency symbol (character 164: ¤) and the double right angled
bracket (character 187: ») (Fig. 30).

MsgBox "This macro will carry out the following tasks:" & _
vbCrLf & Chr(187) & " Archive the old file" & _
vbCrLf & Chr(187) & " Create a new file" & _
vbCrLf & Chr(187) & " Name and save the new file" & _
vbCrLf & Chr(187) & " Print a copy of the new file" & _
vbCrLf & "Click OK to continue." _
, vbInformation, "Acme Logisitics Corporation"

© Martin Green www.fontstuff.com 25


VBA Message Boxes

Fig. 30 Using ASCII character codes to add bullets to a list.

Things You Can't Do with a Message Box


Message boxes are very useful, but there are things you can't do with them. For example,
you can't add a custom icon (Fig. 31)...

Fig. 31 You can't add a custom icon to a message box.

You can't add custom captions to message box buttons (Fig. 32)...

Fig. 32 You can’t customize message box buttons.

You can't add interactive controls such as combo boxes (Fig. 33)...

Fig. 33 You can't add a combo box.

These are just a few of the things you can't do with message boxes. But don't despair! All
the examples shown here are fully functioning "real" objects that I created using the Visual
Basic Editor but they were not made using the VBA MsgBox. They were created as VBA
UserForms, custom forms designed and coded within the Visual Basic Editor.

You can read about how to create and use them in the companion to this volume:
VBA UserForms available from the author's web site at http://www.fontstuff.com.

© Martin Green www.fontstuff.com 26


VBA Message Boxes

Input Boxes
The VBA input box is similar to the message box in that it displays a message to the user,
but it has the added facility of a text box into which the user can make an entry which is
returned to the program when the input box closes.

There are two types of input box. The VBA InputBox function is available to all applications
which use VBA and returns the user's input as a string (text) whatever it is. It is entirely up
to the programmer to handle the input. Microsoft Excel has its own InputBox method which
has an additional feature allowing the programmer to specify the kind of input the input box
will accept. Both types look and function in a similar way so I will describe the VBA input box
function first then explain how to use the additional features of the Excel input box method.

The Anatomy of the Input Box


The VBA input box has some similarities to a VBA message box (Fig. 34). At the top it has a
title which can be customized, and a close button. The main part of the input box is reserved
for the prompt (the message to the user) below which is a text box to receive the user's
input. There are two buttons, OK and Cancel on the right side of the box.

Fig. 34 The layout of a typical input box.

Title: The title bar at the top of the box displays the Title text which can be specified by the
programmer. If no title is defined the message box displays the name of the program here.

Unlike the VBA message box, which will increase in width up to its maximum to fit the title
text, the width of the VBA input box is fixed. It will accommodate up to approximately 50
characters. If the specified title exceed the limit it is truncated and the missing text replaced
with an ellipsis (...).

Close Button: In the upper right corner is a Close Button which is always enabled. Clicking
the Close Button has the same effect as clicking the Cancel button or pressing the [Escape]
key on the keyboard – the input box closes and returns a zero length string ("").

Prompt: The message itself is called the Prompt in VBA. It can contain several lines and the
VBA programmer can determine where line breaks occur if required. The maximum length of
the prompt is approximately 1024 characters. As the amount of text increases the input box
will increase in height to accommodate it but its width remains constant (Fig. 35).

Buttons: The same combination of buttons is always displayed (OK and Cancel). Clicking
the OK button returns the value of the text box as a string. Clicking the Cancel button
returns a zero length string (""). A Help button can also be added and appears automatically
when a help file is specified in the code. Unlike the VBA message box the input box can not
display other combinations of buttons.

Text Box: Any entry the user makes into the text box is returned as a text string, although
the programming of the input box allows this input to be handled in different ways. A default
entry can be specified if required.

© Martin Green www.fontstuff.com 27


VBA Message Boxes

Fig. 35 The input box displaying its maximum amount of prompt text.

© Martin Green www.fontstuff.com 28


VBA Message Boxes

Programming Input Boxes


The VBA InputBox Function
The input box in VBA is represented by the keyword InputBox. Since the input box returns
a value (the user's input) it is constitutes a Function. The most convenient way to make use
of it is to store its returned value in a variable.

When programming an input box, if the Visual Basic Editor's AutoQuickInfo feature is
enabled, help is displayed indicating what information is required (Fig. 36). The input box
can accept up to 7 parameters. All except Prompt are optional.

Fig. 36 The Visual Basic Editor displays AutoQuickInfo for an input box.

Here is a summary of the input box parameters:

Parameter Description

Prompt The Prompt is the text of the message and should be enclosed in quotes
("). The message can be up to 1024 characters long. Although the text
will automatically wrap within the input box, you can control the flow of
text by inserting commands that force a new line (see: Multi-line
Messages in the section on message boxes on page 10).

Title The Title parameter (optional) is the text that appears in the title bar at
the top of the input box and should be enclosed in quotes ("). The
amount of text possible is limited by the width of the input box and
depends upon your display settings. With normal Windows settings
about 50 characters can be displayed.

Default This optional parameter allows you to specify a default entry for the
input box. It must be supplied as a string (i.e. text enclosed in quotes)
and appears automatically in the text box when the input box opens. If
you do not supply a default entry the text box is displayed empty.

XPos Use the XPos parameter to optionally specify the horizontal distance of
the left edge of the input box from the left edge of the screen. If it is
omitted, the input box is horizontally centered on the screen.
Dimensions are specified in "twips".

YPos Use the YPos parameter to optionally specify the vertical distance of the
upper edge of the input box from the top of the screen. If it is omitted,
the input box is vertically positioned approximately one-third of the way
down the screen. Dimensions are specified in "twips".

HelpFile The HelpFile parameter can be used to specify the path to the relevant
Help file. The user can also access this help by pressing the F1 function
key whilst the input box is open or by clicking the Help button, which is
automatically displayed if the HelpFile parameter is supplied. This
parameter is used in combination with the Context parameter.

Context The Context parameter gives the location of the help within the help file
specified in the previous parameter. Both Help File and Context
parameters are optional but if used, both parameters must be supplied.

Accepting Input from the User


Since the input box returns a value it is usual for the value to be placed directly into a
variable. In the following example the user is asked to supply their name, which is then read
back to them with a message box (Fig. 37):

© Martin Green www.fontstuff.com 29


VBA Message Boxes

Dim strName As String


strName = InputBox("Please enter your name.", "Welcome")
MsgBox "Hello " & strName

Fig. 37 Getting information from the user with an input box.

If the value returned by the input box is going to be used immediately it might not be
necessary to store it in a variable. The code could pass the value direct to it's destination.
For example, a value could be passed directly into a cell on an Excel worksheet:

ActiveCell.Value = InputBox("Enter the branch code.")

The following statement passes the user's response directly to a bookmark in a Microsoft
Word document (Fig. 38):

ActiveDocument.Bookmarks("Recipient").Range.Text = _
InputBox("Enter the recipient's name.")

Fig. 38 Passing a value from an input box directly to a bookmark in a Word document.

The value returned from an input box can be passed directly to a calculation or included as
an argument in another function. This statement asks the user to supply two numbers which
it then multiplies and displays the result in a message box:

MsgBox "Total: " & InputBox("Unit Price") * InputBox("Quantity")

Checking the User's Response


The InputBox function contains no built-in error-checking so you can either rely on the user
to enter the information you asked for, or check their response yourself. (HINT: Don't rely on
the user to do what you asked!)

The InputBox function always returns a string. Since any typed input can be treated as a
string this is not a problem. Dates, numbers and text are all just strings of characters. What
your code subsequently does with that input, and what can go wrong, depends upon whether
or not you get what you were expecting.

If you want to error-check the user's input it makes sense to pass it to a variable. You can
then carry out whatever checks are necessary before proceeding. There are two ways to do
this. You can use a string variable, or a variable of the data type matching what you are
expecting to receive.
© Martin Green www.fontstuff.com 30
VBA Message Boxes

Using a String Variable

Whatever the user types is returned as a string so there's no problem placing it into a string
variable. You can then test the value of the variable to see what it is.

Suppose you ask the user for a date. You can use the VBA IsDate() function to check the
result...

Dim strDate As String


strDate = InputBox("Please enter a date.")
If IsDate(strDate) = False Then
MsgBox "You did not enter a valid date"
Else
MsgBox "You entered: " & DateValue(strDate)
End If
Normally you would expect someone to enter a date as a string of numbers and slashes (e.g.
27/9/2005 or 9/27/2005 depending on your regional settings). When the user enters a piece
of text the IsDate() function tries to interpret it as a date. If it can't then it returns False
and the user's entry is rejected (Fig. 39):

Fig. 39 Text that can't be interpreted as a date is rejected.

But it does its best to work "intelligently" so even if an incomplete date is supplied you might
get an acceptable result. If just month and day are supplied the system assumes you want
the current year (Fig. 40):

Fig. 40 The system tries to build a date if the input is incomplete.

We know that each date can be represented by a number (its DateSerial) but since, in this
case, the number is arriving as a string and the system can't interpret it as a date (Fig. 41):

Fig. 41 A numerical input is rejected.

© Martin Green www.fontstuff.com 31


VBA Message Boxes

Numbers and slashes will usually be interpreted as dates even when a full date is not
supplied (Fig. 42):

Fig. 42 A partial date might be accepted.

The system juggles the input to see if a valid date can be created, so you might not get the
result you expected (Fig. 43):

Fig. 43 The system tries hard to create a date from the input.

Don't let this deter you from using an input box to collect information from the user! You just
need to use the right approach. To begin with, you might suggest a date format to the user
as part of the input box prompt (Fig. 44). Then check their input before making further use
of it.

Fig. 44 Suggesting a format can help avoid input errors.

Using a Specific Data Type Variable

An alternative method is to use a variable of the data type that matches the type of input
you want from the user. You will find that the results might differ by this method because
the input is checked for data type by the variable itself. A date variable will accept only a
value that can be interpreted as a date, so unlike the example above (Fig. 41), any valid
date serial will be accepted (Fig. 45):

© Martin Green www.fontstuff.com 32


VBA Message Boxes

Fig. 45 A date variable accepts a valid date serial number.

When, as in this example, a date variable is used you need to approach the checking of the
input in a different way. If the user supplied an input that is not accepted by the variable
then an error results (error number 13 – "Type Mismatch").

The following example uses the On Error Resume Next statement to allow the code to
proceed after an error occurs. An If Statement then checks to see if Error #13 has occurred
and proceeds accordingly. The On Error GoTo 0 statement clears any error that might have
occurred and reverts the code to the default error handler...

Dim datDate As Date


On Error Resume Next
datDate = InputBox("Please enter a date")
If Err.Number = 13 Then
MsgBox "You did not enter a valid date"
Else
MsgBox "You entered: " & DateValue(datDate)
End If
On Error GoTo 0

Which Method is Best?

My preference is to avoid errors so I usually pass the input to a string variable and do
whatever is necessary to check its validity. Sometimes this requires a bit of ingenuity since
there are only a few ready-made functions for checking data: IsDate() (is it a date?),
IsNumeric() (is it a number?) and IsLogical() (is it True or False?).

On the other hand, variables can be declared in a variety of different data types: Date,
Integer, Long, Double etc. each of which will only accept values which strictly conform to
their type, so this method might involve less work testing the input.

Let the User Try Again


You will probably want to give the user the opportunity to correct their mistake or try again.
You can use a code loop to display the input box again and test the user's input until they
make an acceptable entry.

This example uses the VBA IsNumeric() function to test if the user has input a number. If it
passes the test (it isn't necessary to use = True in your code as this is assumed with logical
functions) then the Exit Do statement causes the procedure to jump out of the Do...Loop
loop and proceed (Fig. 46). If it doesn't pass the test the user is asked to try again (Fig. 47)
the loop repeats until a satisfactory input is received.

Dim myNumber As String


Do
myNumber = InputBox("Please enter a number.")
If IsNumeric(myNumber) Then Exit Do
MsgBox "You did not enter a valid number." & _
vbCrLf & "Please try again."
Loop
MsgBox "Your entered: " & myNumber

This is what the user sees if their input is OK:

© Martin Green www.fontstuff.com 33


VBA Message Boxes

Fig. 46 The user's input is accepted.

This is what the user sees if their input is rejected:

Fig. 47 The user's input is rejected.

What If the User Cancels?


When incorporating an input box into your code you should consider the possibility that the
user might click the OK button without making an entry in the text box, or click the Cancel
button (or click the input box's close button or press their [Escape] key). All of these would
have the same result. The input box would close and return a zero length string.

A zero length string is a text object containing no text. It is represented in VBA by a pair of
quote marks with nothing between them ("").

You will probably want to take a different course of action, such as aborting the procedure, if
the user decides they don't want to supply the requested information. A simple If Statement
will do the job. Here's an example (Fig. 48):

Dim strUserName As String


strUserName = InputBox("Enter your username...")
If strUserName = "" Then
MsgBox "Login cancelled"
Exit Sub
End If
The If Statement checks to see if the variable contains a zero length string and if it does, the
user is shown a message and the procedure exits.

Fig. 48 If the user cancels a zero length string is returned.

An alternative would be to use the If Statement to measure the length of the string held in
the variable using the VBA Len() function. If the length is zero then you know that the user
has cancelled. The first line of the If Statement would read:

© Martin Green www.fontstuff.com 34


VBA Message Boxes

If Len(strUserName) = 0 Then

Bear in mind that the user might have cancelled by mistake. Making them start over might
be a little harsh! With a little extra code you can give them the opportunity to try again.
Contrast the following code with that suggested earlier (see: Let the User Try Again on page
33) where the user is forced to keep trying until they get it right. This example asks them if
they want another attempt and allows them cancel the procedure if they don't.

Dim strUserName As String


Dim intResponse As Integer
Do
strUserName = InputBox("Enter your username...", "Login Required")
If strUserName = "" Then
intResponse = MsgBox("Invalid username. Try again?", vbYesNo)
If intResponse = vbNo Then
MsgBox "Login cancelled"
Exit Sub
End If
Else
Exit Do
End If
Loop
The whole process is enclosed in a Do...Loop loop. First the user is shown an input box. An
If Statement checks the value returned and if it is a zero length string they are shown a
Yes/No message box asking if they would like to try again. A second ("nested")
If Statement checks their response and if they responded No the procedure exits (Exit Sub).
If they responded Yes (this is assumed and does not require any code) the loop repeats. But
if (returning to the first (outer) If Statement ) the value returned was not a zero length
string then the code exits the loop (Exit Do) and they are allowed to proceed.

NOTE: I have used a simple example here. If you were really asking someone to log in you
would need to check that their username was acceptable by checking it against a list or
seeing if it conformed to a certain pattern.

Supplying a Default Value


You might be able to assist the user by suggesting a default value. If you supply a value for
this parameter it is already entered in the text box when the input box is displayed. The user
can accept the default by clicking the OK button or type something else. (NOTE: If the user
cancels, the input box returns a zero length string even if a default value is specified.)

Your default value might be a simple piece of text...

strYear = InputBox("Which Year?", "Acme Donuts", "2005")


or you might want to calculate the default, for example the previous year...

strYear = InputBox ("Which Year?", "Acme Donuts", Year(Date)-1)

I often take this opportunity to suggest a filename when using VBA to save a file. Here's an
example which creates a filename which is time-stamped by adding the current date and
time (created with the VBA Now function) and formatted using two digits for each unit
(year, month, day, hour, minute and second) created with the help of the VBA Format()
function.

Dim strFileName As String


Dim strDefault As String
strDefault = "SalesAnalysis_" & Format(Now, "yymmddhhnnss")
strFileName = InputBox("You may enter a different filename..." _
, , strDefault)
strFileName = "C:\" & strFileName & ".xls"
ActiveWorkbook.SaveAs strFileName
MsgBox "The Sales Analysis file has been saved as:" & _
vbCrLf & strFileName

When an input box containing a default value is displayed the entry is already selected (Fig.
49) so that, if they want to change it, the user just has to start typing...

© Martin Green www.fontstuff.com 35


VBA Message Boxes

Fig. 49 In this input box a default value has been suggested.

The last line of the code displays a confirmation message (Fig. 50) to let the user know that
the file has been saved successfully:

Fig. 50 A confirmation that the file was saved successfully.

NOTE: You might think that time-stamping to the second is excessive but I have a good
reason for doing it. If the time-stamp were accurate only to the nearest minute for example,
and the user ran the macro a second time, you would have to deal with the problem of two
files with the same filename. Even if you wanted the second to overwrite the first you would
have to include code to check for a conflict and deal with it accordingly.

Excel's InputBox Method


In Excel (but not in any of the other Microsoft Office programs) there is an alternative kind of
input box, the InputBox method. It differs from the VBA InputBox function in having an
additional parameter that is used to specify the type of data that is returned.

In Excel it is more likely that the user's input will need to be validated so the InputBox
method's built-in data type validation can prove very useful. (NOTE: The VBA InputBox
function is still available to you in Excel so, if you don't require the additional features the
InputBox method offers you can still use the VBA one.)

Another major difference between the VBA InputBox function and the Excel InputBox
method is that whereas the former is application modal (i.e. the user can not work anywhere
else in the host program when it is open) the latter is not. In fact, when using the Excel
InputBox method you are probably going to ask the user to click on a particular cell or
select a range of cells for the appropriate values to be read into the input box. This feature
can be very useful when gathering information from the user since, if you know that the
value you require from them is displayed on the worksheet, you have the option of asking
them to click on the cell in which it is displayed to retrieve it and avoid the possibility of
typing errors.

When programming this type of input box it is important to insert the keyword "Application"
into the input box statement to make it clear which sort of input box you want. When you do
so you will see that the Visual Basic Editor's AutoQuickInfo help displays an additional
parameter called Type (Fig. 51).

Fig. 51 The InputBox method has an additional parameter: Type

The Type parameter is expressed as a number. There are seven to choose from:

© Martin Green www.fontstuff.com 36


VBA Message Boxes

Parameter Value Data Type

0 A formula

1 A number

2 Text (a string)

4 A logical value (True or False)

8 A cell reference as a Range object

16 An error value (e.g. #N/A)

64 An array of values

This simple statement asks the user for a number which it places into a variable called
Response.

Dim Response As Variant


Response = Application.InputBox("Please enter a number", , , , , , , 1)

The input box that Excel displays looks a little different from the VBA input box. It is a
slightly different shape and the buttons are below the text box instead of above it. As the
screenshot shows (Fig. 52) the title bar displays the word Input if no title is specified in the
code. It also displays a help button (actually a What's This button) on the title bar which
functions only if a help file and context are specified in the code (see: Using the Help Button
on page 18).

Fig. 52 A typical input box displayed using the Excel InputBox method.

NOTE: An alternative way to write this sort of statement, and avoid having to type so many
commas for all the skipped parameters, is to use Named Parameters (alternatively Named
Arguments). When permitted, this technique of code writing involves stating the name of the
parameter or argument followed by a colon and an equals sign (:=) and the value itself. Only
the parameters used need be specified although they still must be separated with commas.
It is also customary, to make the code easy to read, to place each on a separate line. Here's
an example:

Dim Response As Variant


Response = Application.InputBox( _
Prompt:="Please enter a number", _
Title:="Acme Construction", _
Type:=1)
If you omit the Type argument the Excel InputBox method behaves just like the VBA
InputBox function and returns a string, whatever the user enters.

Declaring a Data Type for the Input Box Value


It is good coding practice to specify a data type when declaring a variable (e.g. Dim strName
As String rather than simply Dim strName). When used in conjunction with a VBA input box
the variable's data type can be used to validate the user's input. But since the Excel
InputBox method has built-in validation you might consider that declaring a data type for
the variable is superfluous.

© Martin Green www.fontstuff.com 37


VBA Message Boxes

My recommendation is that you always declare a data type for your variables. If you don't
know what that data type will be, or if several different ones are acceptable, you can declare
the variable as a Variant. If you declare a data type for your variable you can add an
additional layer of validation to your InputBox statement, but make sure that the data type
of your variable does not conflict with the data type you specified for the input box.

Suppose you are asking your user for a number, and you are expecting a small whole
number. You could, for example, declare your variable as a Byte. Using a Type 1 input box
will ensure that the user enters a numerical value (see: If the User Enters the Wrong Data
Type below). If the user enters a number greater than 255 an error will occur (Error #6 –
Overflow) when the input box tries to return the value to the variable. You can trap that
error and deal with it as you wish.

If the User Enters the Wrong Data Type


When the user clicks the input box's OK button the code first checks that the user's input
has matched the data type specified in the Type parameter. If it fails to do so one of several
different message boxes will be displayed, depending on the Type setting. Examples are
shown below:

Fig. 53 A Type:0 InputBox Error Message.

Fig. 54 A Type:1 InputBox Fig. 55 A Type:4 InputBox Fig. 56 A Type:64 InputBox


Error Message. Error Message. Error Message.

Fig. 57 A Type:8 InputBox Error Message.

If the input box rejects the user's input, and displays one of the messages shown above, the
user is returned to the input box when they acknowledge the message. Your code does not
have to take account of this as the input box does not attempt to return a value until it has
received something acceptable, or until the user cancels (see: If the User Cancels the Input
Box below).

If the user's input is accepted by the input box a second check is performed when the input
box passes the value to the variable. Your code should include a procedure to deal with this.
You can avoid this second check causing problems by simply declaring your variable as a
Variant which accepts all data types.

© Martin Green www.fontstuff.com 38


VBA Message Boxes

If the User Cancels the Input Box


The user can cancel the input box by clicking its Cancel button or by pressing the [Escape]
key on their keyboard. If they do this the input box returns the value False.

Working with Input Formulas (Type 0)


The Type 0 input box allows the user to construct a formula. This can be done by either
typing directly into the input box's text box, or by a combination of typing and selecting cells
on a worksheet. The resulting formula is returned as a string.

The process works in a similar way to entering a formula directly into a cell. If the user is
constructing a formula in the text box they must start by entering an equals sign (just as if
they were typing in a cell). If the equals sign is omitted their typing is simply returned as a
string. In combination with their typing they can click on a cell to select it (they are
permitted to move to other worksheets or workbooks), or click and drag to select a range of
cells. The address of their selection is entered into the formula in the text box (Fig. 58).

Fig. 58 Constructing a formula in a Type 0 input box.

When the user clicks the OK button the input box checks that an acceptable formula has
been entered and displays a warning message if any errors are found (Fig. 53) but unlike
Excel it does not automatically correct minor errors such as a missing closing parenthesis (as
shown in the unfinished example in Fig. 58).

Formulas involving cell addresses are returned in R1C1 format so when, as in this example,
the user enters the formula =SUM(A1:A5) the formula returned is =SUM(R1C1:R5C1). Both
formulas will produce the same result but if you prefer to see the formula in A1 format you
can convert it with the VBA ConvertFormula function. The following code displays both
formula styles in a message box (Fig. 59)...

Dim Response As Variant


Response = Application.InputBox( _
Prompt:="Enter a formula", Type:=0)
MsgBox Response & vbCrLf & _
Application.ConvertFormula(Response, xlR1C1, xlA1)

Fig. 59 The ConvertFormula function can be used to change


the notation style of a formula.

A more practical use of this feature is to write the formula into a cell or range of cells. If the
formula to be entered was likely to be the same each time, you could use the input box's
Default parameter to assist the user by writing some of it for them:

© Martin Green www.fontstuff.com 39


VBA Message Boxes

Dim Response As Variant


Response = Application.InputBox( _
Prompt:="Complete the formula by entering the cell addresses", _
Default:="=SUM()", Type:=0)
If Response = False Then Exit Sub
Range("E5,F22,G19").FormulaR1C1 = Response

Working with Input Numbers (Type 1)


A Type 1 input box checks that the value entered by the user is a numerical value or
something that can be evaluated as a number. If a numerical value is not detected then an
error message is displayed (Fig. 53 or Fig. 54) and the user is returned to the input box.

The user can type directly into the input box's text box or click on a cell which contains a
numerical value. In the latter case, the input box displays the cell's address but returns its
numerical value (Fig. 60). If the cell contains a non-numerical value (such as some text)
then the input will be rejected just as if the user had typed the text directly into the input
box.

Fig. 60 When a cell is selected the Type 1 input box returns its numerical value.

If a date is entered into a Type 1 input box, or if the user selects a cell containing a date, the
date serial (a numerical representation of the date) is returned (Fig. 61). This value can be
handled by one of the many VBA date/time functions and converted back to a conventional
date format with the Format or FormatDateTime functions as illustrated in the following
example:

Dim Response As Variant


Response = Application.InputBox( _
Prompt:="Enter a number or select a cell", Type:=1)
If Response = False Then Exit Sub
MsgBox "You entered: " & Response
MsgBox "You entered: " & FormatDateTime(Response, vbShortDate)

© Martin Green www.fontstuff.com 40


VBA Message Boxes

Fig. 61 A Type 1 input box returns a date as its DateSerial.

Working with Input Text (Type 2)


In practice any user input can be evaluated as text. The user can make a text entry directly
into the input box's text box or click on a cell to have its displayed value returned by the
input box (Fig. 62). If a cell is displaying a date it's date serial is returned, not the formatted
date as displayed in the cell.

Fig. 62 A Type 2 input box returns the text value of a selected cell.

Working with Logical Values (Type 4)


A Type 4 input box accepts and returns a logical value, which you would normally understand
to be either True or False. This is the case but in practice it is a little more flexible (and
possibly confusing too!). If the user clicks on a cell containing a value they are interpreted as
follows:

© Martin Green www.fontstuff.com 41


VBA Message Boxes

Input Value Returned Value

Any number (positive or negative) other than zero TRUE

Zero FALSE

A date FALSE

An empty cell FALSE

The word TRUE TRUE

The word FALSE FALSE

Any other text NOT ACCEPTED

An error value NOT ACCEPTED

The same applies to entries typed directly into the input box's text box with the exception
that, unlike an empty cell which is interpreted as false, an empty text box is not accepted as
a valid entry.

Working with Cell References (Type 8)


This is one of the more useful, and probably most used, types of Excel input box. It is not
uncommon when writing applications to want to ask the user to supply a cell reference,
either as a single cell or a range of cells. Sometimes you base your code around a range that
was selected when the macro was run, providing that you can rely on the user knowing that
they have to select a specific cell or range before they start.

It is much more reliable, to include in your code a message asking the user to specify a
range of cells. This is where the Excel input box has a considerable advantage over the VBA
input box. With a VBA input box the user would have to type, accurately and in the correct
format, an address for the cell or range. But with the Excel input box they can simply use
their mouse to select the cells. They can see clearly which cells they have selected and,
especially with complex selections, there is no chance that an incorrect reference will be
returned.

When using a Type 8 input box you should declare the variable that is to receive the cell
reference as a Range and, because this is an object variable you must use the keyword Set
when applying a value to it. For example:

Dim ChosenRange As Range


Set ChosenRange = Application.InputBox( _
Prompt:="Select the cells to be processed", Type:=8)
MsgBox "You selected: " & ChosenRange.Address
This code would produce the following result (Fig. 63):

Fig. 63 A Type 8 input box can receive simple or complex cell references.

© Martin Green www.fontstuff.com 42


VBA Message Boxes

If the user clicks the OK button without having selected any cells, or having made an invalid
entry (such as a piece of text, a number or a bad cell reference) the input box's own
validation takes over and a message is displayed (Fig. 57) after which the user is returned to
the input box to try again.

If, however, the user cancels (by clicking the Cancel button or pressing they [Escape] key)
then the input box returns the value False which will cause the code to crash since the code
is attempting to place it into a Range variable. For this reason you must include some error
handling to deal with this possibility. The error that occurs if the user cancels is Error 424.
Here's an example of how to deal with it:

Dim ChosenRange As Range


On Error Resume Next
Set ChosenRange = Application.InputBox( _
Prompt:="Select the cells to be processed", Type:=8)
If Err.Number = 424 Then
MsgBox "You cancelled the operation"
Exit Sub
End If
On Error GoTo 0
MsgBox "You selected: " & ChosenRange.Address
In the code listing above the statement On Error Resume Next allows the error to occur
(otherwise the code would crash) then the If Statement checks to see if error 424 has
occurred. If it has, the code displays a message to the user before exiting. If error 424 did
not occur then the On Error Resume Next instruction is cancelled with On Error GoTo 0
and the code continues.

Once you have the range specified by the user it can be treated like any range in VBA
(remember that you have the Range object not just its Address property). For example, you
can manipulate the data within the cells by creating a loop that visits each cell in turn – this
example increases the values by 10%:

Dim cell As Object


For Each cell In ChosenRange.Cells
cell.Value = cell.Value * 110 / 100
Next cell
You can assign a name to the range:

ChosenRange.Name = "TestData"
You can read and make use of the properties of the range (Fig. 64):

MsgBox "Range: " & ChosenRange.Address & vbCrLf & _


"Total: " & WorksheetFunction.Sum(ChosenRange) & vbCrLf & _
"Average: " & WorksheetFunction.Average(ChosenRange) & vbCrLf & _
"Cells: " & ChosenRange.Cells.Count & vbCrLf & _
"Rows: " & ChosenRange.Rows.Count & vbCrLf & _
"Columns: " & ChosenRange.Columns.Count

Fig. 64 Displaying the properties of the selected range.

When using this type of input box it is worth considering whether the user might have
already selected the cells they want to process. You could save them the effort of selecting
the cells again by specifying the address of the current selection as the default value of the
input box:

© Martin Green www.fontstuff.com 43


VBA Message Boxes

Set ChosenRange = Application.InputBox( _


Prompt:="Select the cells to be processed", _
Default:=Selection.Address, _
Type:=8)

Working with Error Values (Type 16)


Sometimes I struggle to find a reason why anyone would need to use certain features of VBA
and this is one of those times! I expect one day someone will ask me to write them a
program and I'll find that I couldn't do it without a Type 16 input box. If that should happen
I'll be sure to let everyone know. So...

A Type 16 input box accepts error values, those messages you see in a cell when something
has gone wrong. Excel displays 7 different error values, each corresponding to a particular
error number, as listed in the table below:

Error Cell Error Cause of Error


Number Value

2000 #NULL! Occurs when you specify an intersection of two areas that do not
intersect. The intersection operator is a space between references.

2007 #DIV/0! Occurs when a number is divided by zero (0).

2015 #VALUE! Occurs when the wrong type of argument or operand is used.

2023 #REF! Occurs when a cell reference is not valid.

2029 #NAME? Occurs when Microsoft Excel doesn't recognize text in a formula.

2036 #NUM! Occurs with invalid numeric values in a formula or function.

2042 #N/A Occurs when a value is not available to a function or formula.

To retrieve the error value the user can either click on the cell in which it is displayed or type
the message directly into the input box's text box. The input box code is set up in the usual
way, passing the error value to a Variant type variable.

The best (only?) way to deal with the value passed to the variable is to convert it to a
readable error number using the VBA CInt() function (which converts the error value to an
integer).

The following code tells the user why they are getting an error. The user should click on a
cell that is displaying an error code. If they prefer they can type the error code directly into
the input box's text box.

Dim Response As Variant


Response = Application.InputBox( _
Prompt:="Click on the cell showing an error code", Type:=16)
Select Case CInt(Response)
Case 0
Exit Sub
Case 2000
MsgBox "This error means that the formula specifies " & _
"an intersection of two areas that do not intersect." _
, vbInformation, "#NULL! Error"
Case 2007
MsgBox "This error means that the formula is trying " & _
"to divide by zero (impossible)." _
, vbInformation, "#DIV/0! Error"
Case 2015
MsgBox "This error means that the formula is using " & _
"the wrong type of argument or operand." _
, vbInformation, "#VALUE! Error"
Case 2023
MsgBox "This error means that the formula contains " & _
"a cell reference that is not valid." _
, vbInformation, "#REF! Error"
© Martin Green www.fontstuff.com 44
VBA Message Boxes

Case 2029
MsgBox "This error means that the formula contains text " & _
"that Excel doesn't recognise." _
, vbInformation, "#Name? Error"
Case 2036
MsgBox "This error means that the formula contains " & _
"invalid numeric values." _
, vbInformation, "#NUM! Error"
Case 2042
MsgBox "This error means that a value specified in " & _
"the formula is not available." _
, vbInformation, "#N/A Error"
Case Else
MsgBox "Excel does not recognise this an error code." _
, vbInformation, "Not recognised"
End Select
The code uses a Case Statement to display an appropriate message for the integer value of
the error code it finds in the cell. If the user cancels, the input box returns False which has
an integer value of zero. If this happens the code exits without displaying a message.

You can test the code by creating a faulty formula which produces an error code or (easier!)
type the code directly into a cell.

Unfortunately, if the user clicks on an empty cell or a types something other than an error
value into the input box's text box, the input box interprets this as Error 2015. I haven't
managed to find a way of avoiding this!

Working with Arrays of Values (Type 64)


The Type 64 input box is extremely useful and a real time-saver. Use it to ask the user to
select a block of cells. When they click the input box's OK button the values from the
selected cells are read into an array variable. Reading the data from the array is quite simple
and is handled in the same way as you would read any other multi-dimensional array, except
that you don't know the size of the array in advance. Programming an array variable can be
tricky if you haven't done it before so I'll explain things in detail and as simply as I can.

An array variable is a variable that can hold more than one value. If you think of a variable
as a box, into which a piece of data can be placed, then an array variable could be likened to
an egg-box, divided into sections so that it can hold several pieces of data, each in its own
compartment.

An array variable can be one-dimensional, containing a single "row" of data, or multi-


dimensional, containing two or more rows of data. The data from a multi-dimensional array
can be read in rows or columns. Each item in a row is called an element, and each row is
called a dimension. There is no theoretical limit to the number of elements (in practice the
number is limited by the amount of available memory in your computer) but in VBA an array
variable has a maximum of 60 dimensions.

Another way of thinking of an array variable is to liken it to a "virtual" spreadsheet, with


each "cell" capable of holding a piece of data.

When you present the user with a Type 64 input box they select a block of cells on their
worksheet and click the input box's OK button. Excel reads the data from the selected cells
into an array variable, creating (to continue the analogy) a "virtual spreadsheet" whose
arrangement of data matches that of the selected cells. This data is held in the computer's
memory ready for you to read it from the array variable and do whatever you want with it.

When working with array variables in VBA it is customary to either specify the number of
elements and dimensions when declaring the variable, or to allow the variable to create as
many as it needs when data is placed into it, and then figure out the resulting number of
elements and dimensions afterwards.

When you are using a Type 64 input box you don't know how many cells, rows or columns
the user is going to select so you have to use the latter approach. Programming a Type 64
input box starts something like this:

Dim arrData() As Variant


arrData() = Application.InputBox(Prompt:="Select the cells", Type:=64)
© Martin Green www.fontstuff.com 45
VBA Message Boxes

NOTE: The pair of parentheses () after the variable name indicate that this variable is an
array. When dimensioning an array (specifying its size) that information is entered between
these parentheses.

The array variable for a Type 64 input box must be declared as a variant, even if you know
what type the data will be. If you try to declare it as a specific data type, such as String or
Double, the code will fail.

When reading data from the array variable you need to specify the item's location in the
array. In a one-dimensional array it is necessary only to specify the number of the element,
for example: arrData(1) specifies element 1, arrData(25) specifies element 25 etc. For a
multi-dimensional array it is necessary also to specify which dimension you are interested in,
for example: arrData(2,3) specifies the second element in the third dimension, arrData(32,6)
specifies the thirty-second element in the sixth dimension.

If you want to retrieve all the data from an array variable, or look through the variable for a
specific piece of data, the best method is to use a code loop.

When numbering the elements and dimensions of the array variable, a Type 64 input box
starts counting from 1 (it's important to remember this as in other circumstances the default
in VBA is to start counting from zero).

Since you probably have no idea in advance how many cells the user will select, or the shape
of the selection, you must assume that they might select more than one cell, and more than
one column and row. You can use the VBA UBound() function to determine the number of
elements in the array but there is no such function to tell you the number of dimensions. To
work around this handicap, my code reads the dimensions one at a time. If it tries to read
the data from a dimension that does not exist an error occurs and this tells me that I have
read all the existing dimensions.

The following code examples use two integer variables (x and y) to act as counters for the
elements and dimensions. They loop through the elements and dimensions of the array and
use the Debug.Print statement to "print" the value found in each element in the Visual
Basic Editor's Immediate Window (find it on the View menu or use [Control]+G to display
it). In practice you will probably want to substitute this statement with something else to
examine or manipulate the data you find.

Consider the example shown in the illustration below (Fig. 65):

Fig. 65 A Type 64 input box collecting data from a worksheet.

There are four rows of data so the UBound() function returns the value 4 being the number
of elements in the array; and there are three columns of data so the array has 3 dimensions.

The first code example returns the data by column:

Dim arrData() As Variant


Dim x As Integer
Dim y As Integer
arrData() = Application.InputBox(Prompt:="Select the cells", Type:=64)
y = 1
On Error Resume Next
Do
For x = 1 To UBound(arrData)
© Martin Green www.fontstuff.com 46
VBA Message Boxes

Debug.Print arrData(x, y)
If Err Then Exit Do
Next x
y = y + 1
Loop
On Error GoTo 0
This code reads the data from the array to the Immediate Window thus (Fig. 66):

Fig. 66 The data is returned by column.

Here's an explanation of how the above code works...

This code uses a loop within a loop. To begin with the counter y (representing the dimension
number) is set to 1. The outer (Do...Loop) loop has no specified limit and will continue until
it is told to stop when an error occurs (by the statement If Err Then Exit Do). The inner
(For...Next) loop cycles four times (1 To 4 as specified by the value returned by the
UBound() function) and returns the data from elements 1,2,3 and 4 of dimension 1. When
the inner loop finishes the value of y is increased to 2 (to represent the second dimension)
and the outer loop cycles so that the inner loop runs again. This time it returns the data from
elements 1,2,3 and 4 of dimension 2. This continues until the value of y has reached 4 and
the inner loop tries to read the data from element 1 of dimension 4. Since the user selected
a block of cells three columns by four rows, there are only three dimensions in our array, so
this causes an error. The earlier On Error Resume Next statement allows the code to
continue after the error but the If Err Then Exit Do statement spots that there has been an
error and terminates the outer loop (also terminating the inner loop) and the reading of the
data from the array is complete.

The next code example returns the same data but this time by row:

Dim arrData() As Variant


Dim x As Integer
Dim y As Integer
arrData() = Application.InputBox(Prompt:="Select the cells", Type:=64)
y = 1
On Error Resume Next
For x = 1 To UBound(arrData)
Do
Debug.Print arrData(x, y)
y = y + 1
If Err Then
y = 1
Err.Clear
Exit Do
End If
Loop
Next x
On Error GoTo 0
This code reads the data from the array to the Immediate Window thus (Fig. 67):

© Martin Green www.fontstuff.com 47


VBA Message Boxes

Fig. 67 The data is returned by row.

Here's an explanation of how the above code works...

Again the code has a loop within a loop but this time the outer loop represents the elements
and the inner one the dimensions. The outer (For...Next) loop will run four times (1 To 4)
as determined by the value returned by the UBound() function. To start with it will look at
the data in element 1. The inner (Do...Loop) loop returns the data from element 1 of
dimension 1, then dimension 2, and so on until it tries to read data in a dimension that
doesn't exist. At this point an error occurs. If that happens (If Err Then...) the dimension
counter is reset to 1, the error is "cleared" to take the code out of error mode (Err.Clear)
and the inner loop terminated (Exit Do). Returning to the outer loop, the procedure now
looks at element 2 of each dimension, then element 3 of each dimension and so on,
terminating the inner loop each time it runs out of dimensions, until the outer loop has
cycled the specified number of times.

© Martin Green www.fontstuff.com 48


VBA Message Boxes

Step-by-Step: Exploring Message Boxes


This exercise demonstrates the use of VBA Message Boxes (and an Input Box) to interact
with the user. Message boxes are used to gather and process information, and provide
feedback to the user allowing them to control the running of a macro.

Although this exercise uses Excel, the techniques it uses can be applied equally to any Office
program.

The exercise starts by adding data to an empty workbook. Then a basic macro is written, and
gradually improved by adding user interaction.

Part 1: Prepare the Workbook


Step 1: Open Excel and in a new workbook. Use the keyboard shortcut Ctrl+G to open the
Go To dialog. You cursor will already be in the Reference box. Type: A1:A10000
and click OK. This selects the range A1:A10000.
Step 2: Do not click on the worksheet! Type the formula: =INT(RAND()*1001) and
press Ctrl+Enter. The key press Ctrl+Enter gives the command Block Fill which
fills the entire selection with the entry you typed. The formula has filled the
selected range with random whole numbers between 1 and 1000.
Step 3: The range is still selected. Press Ctrl+C (or right click the selection and choose
Copy), then right-click the selection and choose Paste Special (or go to Edit >
Paste Special). Choose Values from the Paste Special dialog and click OK. Press
Esc to cancel Copy Mode.
You have filled ten thousand cells in column A (from A1 to A10000) with random whole
numbers between zero and 1000. The reason for using Paste Special was to remove the
formulas behind the visible numbers. This is important because the RAND function is one of
Excel's volatile functions, one which recalculates itself whenever the worksheet calculates. If
you left the formulas in place the numbers would change each time another calculation was
performed. Removing the formulas effectively "freezes" the numbers.

Part 2: Write the Basic Macro


This macro will loop through the column of numbers. When it finds a number larger that a
specific value, the number is copied into the next column, making a continuous list of
numbers.

Step 4: Open the Visual Basic Editor (Keys: Alt+F11). Locate and select the current
workbook in the Project Explorer window and choose Insert > Module. In the
new module's code window type:

Sub MessageDemo

and press Enter.


The Visual Basic Editor adds the End Sub statement, placing your cursor in the empty line
between the two statements.
First, you need to declare the variables that will be used in the macro...
Step 5: Press Tab to indent your code and type:

Dim i As Integer
Dim x As Integer
Step 6: Add the following lines to set the value of both variables to zero:

i = 0
x = 0
Step 7: Add the line:

Range("A1").Select

© Martin Green www.fontstuff.com 49


VBA Message Boxes

This starts the macro by making sure that the correct cell (A1) is selected. Cell A1 is now the
Active Cell.

Step 8: Now type the loop code that does the main work of the macro:
Do
If ActiveCell.Offset(i, 0).Value > 900 Then
ActiveCell.Offset(i, 0).Copy _
Destination:=ActiveCell.Offset(x, 1)
x = x + 1
End If
i = i + 1
Loop Until IsEmpty(ActiveCell.Offset(i, 0))

This procedure uses a Do...Loop Until loop to repeat the macro code until it finds an empty
cell in column A. The data in column A contains no gaps so this method will loop through all
the data.

The If Statement checks to see if a cell contains a value greater than 900. The cell that gets
checked depends upon the value of the variable i. This is achieved by defining the cell's
address location as ActiveCell.Offset(i, 0). The value if i is going to change each time the
loop repeats. It starts with a value of zero, so the first cell to get checked is
ActiveCell.Offset(0, 0) which is cell A1 itself (no offsets). The next cell is
ActiveCell.Offset(1, 0) which is cell A2, and so on. Later in the loop the line i = i + 1
increments the value of the variable by one.

If the If Statement finds that the cell contains a suitable number, it copies the value to
another cell using a similar method to decide its address. This uses the value of the variable
x. The value of x is going to change each time a number is copied. This is done with the line
x = x + 1. Note that x is inside the If Statement so its value is incremented only when a
number is copied, unlike i which is incremented ever time the loop cycles. The value of x
starts at zero, so the first cell to receive a number is ActiveCell.Offset(0, 1) which is cell
B1. The next cell is ActiveCell.Offset(0, 2) which is cell B2, and so on.

Part 3: Add a Confirmation Message


Step 9: Type the following line to display a confirmation message when the macro
finishes:

MsgBox "The values have been copied to column B" _


, vbInformation, "Macro Complete"

It is good practice to add confirmation messages to macros when it is not always obvious to
the user that the macro has finished.

You finished code should look like this:

Sub MessageDemo()
Dim i As Integer
Dim x As Integer
i = 0
x = 0
Range("A1").Select
Do
If ActiveCell.Offset(i, 0).Value > 900 Then
ActiveCell.Offset(i, 0).Copy _
Destination:=ActiveCell.Offset(x, 1)
x = x + 1
End If
i = i + 1
Loop Until IsEmpty(ActiveCell.Offset(i, 0))
MsgBox "The values have been copied to column B" _
, vbInformation, "Macro Complete"
End Sub

© Martin Green www.fontstuff.com 50


VBA Message Boxes

Part 4: Test the Macro


This is a good time to check your code and test run the macro...

Step 10: First let the Visual Basic Editor carry out a check of the code by choosing Debug
> Compile VBAProject. Then click the Save button on the Visual Basic Editor
toolbar (or choose File > Save) to save your work.
Compiling causes the code compiler to perform a "dry run" of the macro. Whilst not
completely infallible, this tool helps to locate any undeclared variables, spelling errors or
other typos before running the macro for real.
Step 11: Switch to Excel and make sure that you are on the worksheet containing the
column of numbers. Press Alt+F8 (or go to Tools > Macro > Macros) to open
the Macros dialog and select MessageDemo. Click Run.
When the macro finishes click the OK button on the confirmation message box to
close the box and terminate the macro.
Step 12: Clear the contents of column B, ready for the next test, but leave column A intact.

Part 5: Add a Timer


This step uses the VBA Timer function to calculate how long the macro takes to run. Timer
returns the number of seconds since the previous midnight. You will write code to make a
note of this is value at the start of the macro, and again when the macro finishes,
subtracting one from the other to give the total time elapsed.

You will code two message boxes. One will ask the user if they want to time the macro, the
other will display the elapsed time.

This procedure requires two new variables...

Step 13: Add the following lines after the existing variable declarations at the start of the
macro:

Dim Response As VbMsgBoxResult


Dim StartTime As Double
NOTE: If you are using Office 97, change VbMessageBoxResult to Variant (the former
VBA data type was not introduced until Office 2000).
Step 14: Add the following lines before the line Do (the start of the loop):

Response = MsgBox("Would you like to time this operation?" _


, vbQuestion + vbYesNo)
StartTime = Timer

The first line uses a Yes/No message box to put a value into the Response variable. The
second line makes a not of the time by placing the Timer value in the StartTime variable.

Step 15: Move to the end of the loop, to the line for the confirmation message box
(MsgBox "The values have been copied... ) and type these additional lines so
the result looks like this:

If Response = vbNo Then


MsgBox "The values have been copied to column B" _
, vbInformation, "Macro Complete"
Exit Sub
End If

This code uses an If Statement to check the users response to the earlier message box
asking whether they wanted to time the macro. The user's answer was stored in the
Response variable. If the user answered "No" they are shown the confirmation message and
the macro is terminated with the line Exit Sub. If the user answered "Yes" the macro
continues without displaying the confirmation message.

© Martin Green www.fontstuff.com 51


VBA Message Boxes

Step 16: Add this final line to the end of the macro to display a different confirmation
message, showing how long the macro took:

MsgBox "The procedure took " & Timer - StartTime & _


" seconds.", vbInformation, "Macro Complete"

At this point your code should look like this:

Sub MessageDemo()
Dim i As Integer
Dim x As Integer
Dim Response As VbMsgBoxResult
Dim StartTime As Double
i = 0
x = 0
Range("A1").Select
Response = MsgBox("Would you like to time this operation?" _
, vbQuestion + vbYesNo)
StartTime = Timer
Do
If ActiveCell.Offset(i, 0).Value > 900 Then
ActiveCell.Offset(i, 0).Copy _
Destination:=ActiveCell.Offset(x, 1)
x = x + 1
End If
i = i + 1
Loop Until IsEmpty(ActiveCell.Offset(i, 0))
If Response = vbNo Then
MsgBox "The values have been copied to column B" _
, vbInformation, "Macro Complete"
Exit Sub
End If
MsgBox "The procedure took " & Timer - StartTime & _
" seconds.", vbInformation, "Macro Complete"
End Sub

Step 17: Compile the code, save your changes then test run the macro as before.
This time you are asked a question at the start and shown a confirmation message at the
end. The confirmation message you see depends upon your answer to the question.

Part 6: Add Statistics to the Confirmation Message


In this step you will ask the user if they want to see some macro statistics, by changing the
confirmation message into a question. The variables i and x have recorded how many cells
were checked and how many numbers were copied. These variables will form the basis of a
message box that the user will see if they answer "Yes".

Step 18: Change the last line of the macro (the confirmation message) as follows:

Response = MsgBox("The procedure took " & Timer - StartTime _


& " seconds." & vbCrLf _
& "Would you like to see the statistics?" _
, vbQuestion + vbYesNo, "Macro complete")

There are several changes here. The message box is being used as a function to place a
value into the Response variable. You can reuse a variable as many times as you want, but
take care to be aware of which value it is holding at any time. When MsgBox is used as a
function (i.e. when it follows an equals sign) its parameters must be enclosed in brackets.

The icon has been changed to vbQuestion and the box will display both "Yes" and "No"
buttons, and a question has been added to the prompt.

© Martin Green www.fontstuff.com 52


VBA Message Boxes

Step 19: After the above lines, type the following If Statement which examines the
response to the question about viewing statistics:

If Response = vbNo Then Exit Sub

This is an If Statement at its simplest with only one condition and a simple command that
can be written in a single line. If the user answered "No" then the macro finishes, otherwise
it continues.
Step 20: Finally, add code for a message box to display the macro statistics which are
contained in the variables i and x:

MsgBox "The macro processed " & i & " rows." _


& vbCrLf & x & " values were found." _
, vbInformation, "Statistics"

At this point your code should look like this:

Sub MessageDemo()
Dim i As Integer
Dim x As Integer
Dim Response As VbMsgBoxResult
Dim StartTime As Double
i = 0
x = 0
Range("A1").Select
Response = MsgBox("Would you like to time this operation?" _
, vbQuestion + vbYesNo)
StartTime = Timer
Do
If ActiveCell.Offset(i, 0).Value > 900 Then
ActiveCell.Offset(i, 0).Copy _
Destination:=ActiveCell.Offset(x, 1)
x = x + 1
End If
i = i + 1
Loop Until IsEmpty(ActiveCell.Offset(i, 0))
If Response = vbNo Then
MsgBox "The values have been copied to column B" _
, vbInformation, "Macro Complete"
Exit Sub
End If
Response = MsgBox("The procedure took " & Timer - StartTime _
& " seconds." & vbCrLf _
& "Would you like to see the statistics?" _
, vbQuestion + vbYesNo, "Macro complete")
If Response = vbNo Then Exit Sub
MsgBox "The macro processed " & i & " rows." _
& vbCrLf & x & " values were found." _
, vbInformation, "Statistics"
End Sub

Step 21: Compile the code, save your changes then test run the macro as before.
If you answer "Yes" to the question about timing the macro at the start, you are shown the
time taken when the macro concludes but this time the confirmation message also asks you
if you want to see statistics. If you answer "Yes" again you will see a message showing the
number of cells checked and values copied.

Part 7: Let the User Choose the Minimum Number


It is always a good thing to build into your macros as much flexibility as possible. Until now
the macro has selected numbers greater than 900. In this step you will ask the user if they
would like to specify a minimum number. To do this you will make use of a VBA Input Box. If

© Martin Green www.fontstuff.com 53


VBA Message Boxes

the user prefers not to choose a number the computer will choose a number at random and
the user will be informed of its choice.

This procedure needs another variable to hold the user's choice of number (or the
computer's choice)...

Step 22: Add the following variable declaration to the list at the beginning of the macro:

Dim MinNumber As Integer

In the next step you will enter the code to ask the user if they want to specify a minimum
number. Their choice will be placed in the existing Response variable. It is safe to do this
because the macro will have read the value before the variable is needed again.
Step 23: Type this code near the start of the macro, above the line Range("A1").Select :

Response = MsgBox("The computer can pick a number or " & _


"you can pick one yourself. Would you like to choose?" _
, vbQuestion + vbYesNoCancel, "Number required")
This message box will be the first one the user sees, so it includes a "Cancel" button that you
will program to allow the user to cancel the macro. The user now has a choice of three
buttons to press (Yes, No and Cancel) so their response now has to be evaluated...
Step 24: Immediately underneath the code you just typed, enter the following If Statement
which will evaluate the users response to the message box and take three possible
courses of action:

If Response = vbCancel Then


MsgBox "You chose to terminate the procedure." _
& vbCrLf & "The worksheet has not been altered." _
, vbInformation, "Macro Cancelled"
Exit Sub
ElseIf Response = vbYes Then
MinNumber = InputBox("The macro will look for numbers " _
& "greater than the number you choose." & vbCrLf _
& "Please enter a whole number between 1 and 999" _
, "Enter a number")
Else
Randomize
MinNumber = Int(Rnd * 1000)
MsgBox "The computer chose " & MinNumber, vbInformation _
, "Number Chosen"
End If
The If Statement has three conditions: "vbCancel", "vbYes" and "anything else" which by
definition must mean "vbNo".
If the user chooses "Cancel" They are shown a message box which confirms that they have
cancelled the macro. The macro is then cancelled with the line Exit Sub.
If the user chooses "Yes" they are shown an input box inviting them to enter a number,
which is stored in the MinNumber variable.
If the user chooses "No" the command Randomize initialises the random number generator
before a random number is calculated and stored in the MinNumber variable. The user is
then notified of the computer's choice of number.
Step 25: All that remains is to change the reference to a minimum number in the loop. Find
the number 900 in the code of the loop and change it to: MinNumber.
(The code for the completed macro is shown on the at the end of this document.)
Step 26: Compile the code, save your changes as before. Then run the macro and explore
all the different ways that is can be run by asking the user to make choices.

© Martin Green www.fontstuff.com 54


VBA Message Boxes

Part 8: Add an Error Handler


It is always important to anticipate any errors that might arise and write the code to deal
with them. Since an error is likely to make your code "crash" you should always add error
handling code to your macros before distributing them.

Error handling code has several purposes:

• To notify the user that something has gone wrong.

• To take control of the situation so that the user does not see the standard and (to
them) confusing VBA error message.

• To rescue the situation and, if possible, correct things so that they can proceed
normally.

Before writing you error handler test your code thoroughly and try to spot places where
things could go wrong. If you manage to cause an error note the circumstances and the error
number that is displayed in the VBA error message.

In this exercise the most obvious errors would arise from the user making an invalid entry in
the Input Box. If the user typed a text entry error 13 (type mismatch) would occur because
the number they enter is being placed into a variable that has a numerical data type. If they
typed a very large number (greater than 32767) error 6 (overflow) would occur because the
variable's data type is Integer which accepts numbers in the range zero to 32767.

When your macro includes an error handler the first line of the macro should be a statement
directing the procedure to the error handler if an error occurs...

Step 27: Immediately below the line Sub MessageDemo() add the following line of code:

On Error GoTo MessageDemo_Err


The text MessageDemo_Err is the name of a label that you will place in the code in the
next step. Labels are like bookmarks in your code. They are not executable code but you can
use a GoTo (for "jump forward") or Resume (for "jump back") statement to instruct your
macro to jump to the label, skipping the code in between, and continuing from there.

Step 28: Make a new line immediately above the line End Sub (the last line of the macro)
and enter the code:

MessageDemo_Err:
Note the colon (:) immediately following this text. This tells the Visual Basic Editor that this
text is a label and, if your code was indented, the Visual Basic Editor removes the indent so
that the label is flush with the left margin of the code window.

Just as the direction to the error handler is always the first statement in a macro, the error
handler itself is always placed right at the end. It is important that the procedure does not
continue into the error handler unless there has been an error so, to prevent this happening,
the procedure must be stopped before it gets there. To achieve this...

Step 29: Make a new line immediately above the MessageDemo_Err: label and enter the
statement:

Exit Sub
The statement Exit Sub works in the same way as End Sub and tells the procedure that it is
finished.

Now for the error handler itself. The On Error GoTo MessageDemo_Err statement at the
start of the macro instructs the macro to jump straight to the MessageDemo_Err: label
when an error occurs and proceed from there. At this point we will use a Case Statement to
check the identifying number of the error that just occurred and act accordingly...

© Martin Green www.fontstuff.com 55


VBA Message Boxes

Step 30: Insert the following code between the MessageDemo_Err: label and the End
Sub statement.

Select Case Err.Number


Case 6
MsgBox "The number you entered was too large." & _
vbCrLf & "Your number must not exceed 32767." & _
vbCrLf & "Please start again." _
, vbExclamation, "Error"
Case 13
MsgBox "You did not enter a number." & _
vbCrLf & "Please start again." _
, vbExclamation, "Error"
Case Else
MsgBox "An unexpected error has occurred." & _
vbCrLf & "Please note the following..." & _
vbCrLf & "Error number: " & Err.Number & _
vbCrLf & "Description: " & Err.Description _
, vbCritical, "Error"
End Select
When testing the macro we found that two obvious errors could occur (numbers 6 and 13) so
the Case Statement has customised messages for each of these (Case 6 and Case 13). The
Case Else section takes care of anything we hadn't anticipated by displaying a message
showing the number and description of the error.

Responding to an error often involves more than just displaying a message and aborting the
procedure. If additional steps need to be taken the code can be added to the appropriate
part of the Case Statement. You could, for example, give the user another opportunity to
make an entry in the input box by placing a label immediately above the line of code that
displays the input box, and using a Resume statement in the Case Statement to direct the
macro to it.

Finally, and although not strictly necessary in this example, we are going to add an exit
routine to the error handler. Many macros end with a number of lines of "tidying up" code. If
specific processes are necessary because of an error they would be included in appropriate
parts of the Case Statement. But general processes that would have occurred even if the
error had not taken place would be missed if, following an error, the procedure moved
straight from the Case Statement to the End Sub statement.

This "tidying up" code would normally be placed at the end of the macro but before the error
handler, and immediately before the Exit Sub statement.

So that the procedure, after being dealt with by the error handler, can be directed back to
the "tidying up" code we add another label before it. As I mentioned earlier, this macro
doesn't have any "tidying up" code but even so it is good practice add an exit routine in case
some is added at a later date....

Step 31: Make a new line immediately above the Exit Sub statement and enter the label:

MessageDemo_Exit:

Finally insert the following code as the last line of the error handler, between the
End Select and End Sub statements:

Resume MessageDemo_Exit

That completes the code for the Exploring Message Boxes exercise. The final code listing is
shown below (see: Final Code Listing for the MessageDemo Macro on page 57).

Run the macro several times, making different choices from the message boxes you see. The
exercise has demonstrated some of the many different ways that message boxes and input
boxes can be used.

© Martin Green www.fontstuff.com 56


VBA Message Boxes

Final Code Listing for the MessageDemo Macro


The completed macro should look like this:

Sub MessageDemo()
On Error GoTo MessageDemo_Err
Dim i As Integer
Dim x As Integer
Dim Response As VbMsgBoxResult
Dim StartTime As Double
Dim MinNumber As Integer
i = 0
x = 0
Response = MsgBox("The computer can pick a number or " & _
"you can pick one yourself. Would you like to choose?" _
, vbQuestion + vbYesNoCancel, "Number required")
If Response = vbCancel Then
MsgBox "You chose to terminate the procedure." _
& vbCrLf & "The worksheet has not been altered." _
, vbInformation, "Macro Cancelled"
Exit Sub
ElseIf Response = vbYes Then
MinNumber = InputBox("The macro will look for numbers " _
& "greater than the number you choose." & vbCrLf _
& "Please enter a whole number between 1 and 999" _
, "Enter a number")
Else
Randomize
MinNumber = Int(Rnd * 1000)
MsgBox "The computer chose " & MinNumber, vbInformation _
, "Number Chosen"
End If
Range("A1").Select
Response = MsgBox("Would you like to time this operation?" _
, vbQuestion + vbYesNo)
StartTime = Timer
Do
If ActiveCell.Offset(i, 0).Value > MinNumber Then
ActiveCell.Offset(i, 0).Copy _
Destination:=ActiveCell.Offset(x, 1)
x = x + 1
End If
i = i + 1
Loop Until IsEmpty(ActiveCell.Offset(i, 0))
If Response = vbNo Then
MsgBox "The values have been copied into column B" _
, vbInformation, "Macro Complete"
Exit Sub
End If
Response = MsgBox("The procedure took " & Timer - StartTime _
& " seconds." & vbCrLf _
& "Would you like to see the statistics?" _
, vbQuestion + vbYesNo, "Macro Complete")
If Response = vbNo Then Exit Sub
MsgBox "The macro processed " & i & " rows." _
& vbCrLf & x & " values were found." _
, vbInformation, "Statistics"
MessageDemo_Exit:
Exit Sub
MessageDemo_Err:
Select Case Err.Number
Case 6
MsgBox "The number you entered was too large." & _
vbCrLf & "Your number must not exceed 32767." & _
© Martin Green www.fontstuff.com 57
VBA Message Boxes

vbCrLf & "Please start again." _


, vbExclamation, "Error"
Case 13
MsgBox "You did not enter a number." & _
vbCrLf & "Please start again." _
, vbExclamation, "Error"
Case Else
MsgBox "An unexpected error has occurred." & _
vbCrLf & "Please note the following..." & _
vbCrLf & "Error number: " & Err.Number & _
vbCrLf & "Description: " & Err.Description _
, vbCritical, "Error"
End Select
Resume MessageDemo_Exit
End Sub

© Martin Green www.fontstuff.com 58


VBA Message Boxes

Flow Diagram for the MessageDemo Macro


When planning a macro that has several different possible paths, it is often helpful to draw a
flow diagram. This diagram describes the possible paths of the MessageDemo macro:

START

MsgBox MsgBox EXIT


Choose a CANCEL Macro SUB
number? cancelled

YES NO

InputBox MsgBox
Enter a Computer
number chose...

MsgBox
Time the
macro?

YES NO

RUN MACRO RUN MACRO

MsgBox EXIT
Macro SUB
complete

MsgBox EXIT
Time taken. NO SUB
See Stats?

YES

MsgBox EXIT
Show SUB
Statistics

© Martin Green www.fontstuff.com 59


VBA Message Boxes

Appendix: VBA Message Box Constants


The following table lists the VBA constants used in message boxes to specify the number and
type of buttons displayed, the icon style and the message box's modality. You can enter
either the constant (e.g. vbYesNoCancel) or its value (e.g. 3) into the MsgBox statement.

Constant Value Description

vbOKOnly 0 Display OK button only (default).

vbOKCancel 1 Display OK and Cancel buttons.

vbAbortRetryIgnore 2 Display Abort, Retry, and Ignore buttons.

vbYesNoCancel 3 Display Yes, No, and Cancel buttons.

vbYesNo 4 Display Yes and No buttons.

vbRetryCancel 5 Display Retry and Cancel buttons.

vbCritical 16 Display Critical Message icon.

vbQuestion 32 Display Warning Query icon.

vbExclamation 48 Display Warning Message icon.

vbInformation 64 Display Information Message icon.

vbDefaultButton1 0 First button is default (default).

vbDefaultButton2 256 Second button is default.

vbDefaultButton3 512 Third button is default.

vbDefaultButton4 768 Fourth button is default.

vbApplicationModal 0 Application modal (default). The user must


respond to the message box before continuing
work in the current application.

vbSystemModal 4096 System modal. All applications are suspended


until the user responds to the message box.

vbMsgBoxHelpButton 16384 Adds Help button to the message box.

VbMsgBoxSetForeground 65536 Specifies the message box window as the


foreground window.

vbMsgBoxRight 524288 Text is right aligned.

vbMsgBoxRtlReading 1048576 Specifies text should appear as right-to-left


reading on Hebrew and Arabic systems.

The following table lists the VBA return values used to determine which message box button
was pressed by the user:

Constant Value Description

vbOK 1 OK button pressed.

vbCancel 2 Cancel button pressed.

vbAbort 3 Abort button pressed.

vbRetry 4 Retry button pressed.

vbIgnore 5 Ignore button pressed.

vbYes 6 Yes button pressed.

vbNo 7 No button pressed.

© Martin Green www.fontstuff.com 60


VBA Message Boxes

Notes and Further Information


About the Author
This document was written and published by Martin Green. Martin Green is a software
trainer, applications developer and author. His main areas or work are Microsoft Excel,
Microsoft Access and Visual Basic for Applications (VBA).

For further information and tutorials on these and other topics visit his Office Tips web site
at: http://www.fontstuff.com

For further copies of this document or for information regarding Martin Green's training,
development or authoring services please contact him at: training@fontstuff.com

Copyright
This document is copyright ©2005 Martin Green.

No part of this document may be copied, photocopied or reproduced in any form or by any
means without permission in writing from the copyright owner.

All trademarks, service marks, products or services are trademarks or registered trademarks
of their respective holders and are acknowledged by the author.

Limitation of Liability
Every effort has been made to ensure complete and accurate information concerning the
material presented in this document. However, the author cannot be held legally responsible
for any mistakes in printing or faulty instructions contained within this document. The author
appreciates receiving notice of any errors or misprints.

Information in this document is subject to change without notice. Companies, names and
data used in examples herein are fictitious unless otherwise noted.

This document is supplied for training and is intended to familiarise the user with the
operation of software programs. The author urges the user to review the manuals provided
by the software publisher regarding specific questions as to the operation of the programs.

There are no warranties, expressed or implied, including warranties of merchantability or


fitness for a particular purpose, made with respect to the materials or any information
provided to the user herein. The author nor publisher shall be liable for any direct, indirect,
special, incidental or consequential damages arising out of the use or inability to use the
contents of this document.

© Martin Green www.fontstuff.com 61

You might also like