Week of
You want to do everything possible to keep errors from occurring. When possible, you want to make your code robust enough so that it can catch and fix as many errors as possible without resorting to "error handling". Although sometimes, the user is bound to get the best of your program by doing something you never considered remotely possible.
If an error occurs and your program cannot recover, you want to at least have your program exit in a graceful manner. Ideally in a way that doesn't require the system to be rebooted!
Here are some tips to follow to ensure a graceful exit even when an error occurs:
(paraphrased from Chapter 6 - VBA For Dummies by John Paul Mueller)
Custom Error Handling Example - Example6-2.xls
6 - Overflow (entered a value too large like 30000 where it
should be stored as a Byte)
9 - Subscript Out of Range
11 - Division By Zero
13 - Type Mismatch
The process of error handling (also known as trapping or catching errors) deals with catching runtime errors before they cause your program to stop and can be broken down into 4 steps:
Here is an example that you could use as a template for your own programs:
Sub BasicErrorHandling() ' Turn on Error Handling - Setting the trap On Error GoTo ErrorHandler ' Code that might cause an error goes here ' Turn off Error Handling - Disable the trap On Error GoTo 0 CleanExit: ' Exit the application so error handlers aren't executed Exit Sub ErrorHandler: ' An error occurred, so explain it nicely, with options to fix it. MsgBox "The " & Chr(34) & Err.Description & Chr(34) & " error occurred [" & Err.Number & "].", _ vbCritical, "Error Handled" ' Clear the error so its values aren't used again by mistake Err.Clear Resume CleanExit End Sub
When a runtime error (such as an index out of range error, Division By
Zero, Typemismatch etc.) occurs, an object of type ErrObject gets
created and is referred as Err
. This Err
object can be examined to see what the problem was, and then your code
can take steps to either ask for the user to re-enter the value, or your
code can correct the problem with some sort of default value or possibly
even just ignore the error.
Here are some basic properties and methods of the Err
object. Check the online help for more info:
Properties | Methods |
---|---|
Err.Name | Err.Clear |
Err.Description | Err.Raise |
Err.Source |
If you want to provide information about the errors you could write a function such as the one below to output the error info in a more readable format:
Public Function formatErrorMessage(e As ErrObject) As String ' Formats the info from the ErrObject and returns a nicely formatted String Dim msg As String msg = "Error Number: " & e.Number & vbCrLf msg = msg & "Description: " & e.Description & vbCrLf ' Return the string of a nicely formatted error formatErrorMessage = msg End Function
It is possible to use the Err.Raise
method to create your
own custom errors for more complex programs. Usage:
Sub CustomErrorHandlingExample() Dim result As VbMsgBoxResult ' Turn on Error Handling On Error GoTo ErrorHandler ' More code... result = MsgBox("As an example, I will throw an error if you click Abort.", _ vbAbortRetryIgnore, "Try this") If result = vbAbort Then Err.Raise 65535, "CustomSource", "You clicked Abort!" End If ' Turn off Error Handling On Error GoTo 0 CleanExit: ' Exit the application so error handlers aren't executed Exit Sub ErrorHandler: ' An error occured, so explain it nicely, with options to fix it. MsgBox "The " & Chr(34) & Err.Description & Chr(34) & " error occurred [" & Err.Number & "]", vbCritical, "Error Handled" MsgBox "The source of the error was: " & Err.Source ' Clear the error so its values aren't used again by mistake Err.Clear Resume CleanExit End Sub
Other key points:
Exit Sub
(or Exit Function
if your code is inside a
function), or else on normal execution of your program the error
message will still display.
Err.Clear
to clear the error code after you
are done with it. This keeps if from being confused with partially
created custom errors later in the program.
vbObjectError
constant (-2147221504) to make sure your custom error number
doesn't conflict with any Office built-in error numbers. For
example, to generate the error number -2147220504, assign
vbObjectError + 1000 to the Err.Number
property.
vbObjectError
to it.
Err.Number
AND NOT vbObjectError
The IsError
function can be used in combination with an If
statement inside a spreadsheet cell to display meaningful error messages
instead of the cryptic ones that Excel displays, such as the one shown
below:
The IsError(value)
function takes a value that could refer
to any resulting value: Value refers to any error value (#N/A
,
#VALUE!
, #REF!
, #DIV/0!
, #NUM!
,
#NAME?
, or #NULL!
). It is a Boolean
function which returns True
if an error occurred, or False
if it didn't.
If used in VBA code, the function still returns True
or False
and should still take a value, such as the code shown below:
If IsError(myCell.Value) Then ' Do something since an error occurred Else ' An error did not occur End If
Using this basic code, you can create a number of different standard dialog boxes:
' This code allows users to select multiple Excel files and then opens them Sub OpenFiles() Dim fd As Office.FileDialog Dim file As Variant Set fd = Application.FileDialog(msoFileDialogOpen) With fd If .Show Then For Each file In .SelectedItems ' If using a FilePicker or FolderPicker, you don't execute the files, ' you do other things. .Execute Next file End If End With End Sub
The values for the msoFileDialogTypes
are msoFileDialogOpen
,
msoFileDialogSaveAs
, msoFileDialogFolderPicker
,
and msoFileDialogFilePicker
.
The following code works fine with an age less than 256. If words, or a larger value is entered, it generates runtime errors. Copy and paste it into a code module:
Sub ch12task1() Dim age As Byte age = InputBox("How old are you?", "Age") MsgBox "Your age in 2021 will be " & age + (2021 - Year(Now)) & ".", _ vbOKOnly + vbInformation, "Doomsday" End Sub
Run the program before you make any changes to learn the error numbers and descriptions associated with these common runtime errors. Enter the following values and see the error description and error number that gets generated:
1000 twentyfive
Use Error Handling, not just If
statements and modify the
code so it displays an appropriate error message and ends cleanly if
invalid data is entered.
Error Handling - External Link
Date & Time functions in VBA - External Link
Save the spreadsheet file as a Macro Enabled Workbook (.xlsm
)
file before you write more code. Name your spreadsheet with your
network login followed by _l08.xlsm
. For example, if
your network login was barn4520
, then your lab file
should be named barn4520_l08.xlsm
. Save often.
All tasks are to be completed on your own.
Show the Developer Tab in Excel. Click File / Options Customize Ribbon and check the option for Developer Tab.
Put all code into a Module. Use a different Module for each task and name them appropriately as Task1 or Task2 etc.
Copy and paste this header into your code modules and fill it out:
Option Explicit ' ==== CP212 Windows Application Programming ===============+ ' Name: Your Name ' Student ID: ' Date: ' Program title: ' Description: '===========================================================+
Make sure you test your tasks submitting your lab to the dropbox.
When finished upload your file to the Lab 8 Task Dropbox in MyLearingSpace.
Open a new workbook, get into the VBE, insert a user form, add a text box named txtLastName, and add a Last Name label to its left. Add a Cancel button to the userform. This text box is supposed to capture a person's last name. Therefore, it should contain alphabetical characters only. The userform may look like:
You could perform an error check in a Valid function subroutine, but you might want to check for
nonalphabetical characters at the same time the user is typing the name. You can do this with the
Change
event for a text box. In this case, the event handler's name is
txtLastName_Change
. This event fires each time any change occurs to the contents of
the text box, including the insertion of a new character.
Write the appropriate code for this event handler. It should check whether the last character
(the one most recently typed) is alphabetical. You can use the Right
string function to check if the entered
character is a character or not:
If Not (UCase(Right(name, 1)) >= "A" And UCase(Right(name, 1)) <= "Z") Then --------- ' Other code here
If not, it should display an appropriate message box telling the user to type alphabetical
characters only, set the focus to the text box, and exit the sub. For example,
if the user types Smi7
, it should recognize that the fourth character is nonalphabetical
and respond accordingly.
Inside the same file, copy the code below into a new module named Task2
:
Sub OpenAFile() ' Opens a file from the folder this workbook is saved in Dim strFileName As String strFileName = "sample.xlsx" ' Turn off the default Excel messages Application.DisplayAlerts = False Workbooks.Open Filename:=ThisWorkbook.Path & "\" & strFileName ' Turn on the alerts again Application.DisplayAlerts = True End Sub
Try running the code. Since you don't have the sample file in your folder, it displays a runtime error.
FileCheck
and place a
button that runs the subroutine.
Note
You have to use Button(s) on worksheet to run the tasks in this lab and all next labs and assignments.
Marks will be deducted if you do not use Buttons