Upload
deng-qiang
View
217
Download
0
Embed Size (px)
Citation preview
8/11/2019 (1)Error Handling
1/6
11/9/20
Error Handling
The Three Types of Errors
Syntax error: an error in the form of yourprogram that prevents it from running. Also
called a compiler error in VBA Run-time error: an error that arises at run
time and makes your program terminateabnormally (crash)
Logic error: an error in which your programappears to run normally but produces ananswer that is not correct
Type 1: Syntax Errors
These errors are caught by the VBAenvironment, which also attempts to suggestfixes
They can be very annoying, but since you cantrun your program with one of these errors inplace, they are actually not that much of aproblem once you have programmed a bit
The built-in Help can be very useful indiagnosing and correcting these
Type 2: Logic Errors
These are the most insidious, because yourprogram appears to run normally
In fact, it does exactly what you told it to, onlythere is a logic error so what you told it to dois not actually what you wanted
The only defense is thorough testing. Youneed to develop a good set of tests BEFOREyou start coding. You should also test complexspreadsheets even if there is no code involved
The Infamous Disclaimer
Have you ever read the fine print on the
agreements you must authorize before you
download software?
Most commercial software has at least a few
bugs, including logic errors
The disclaimer says you cant sue the company
for damages if you relied on a faulty answer
from their software
Why?
In the software business, the theory is that
the first product of a given type to market
grabs the big market share
So software firms may put their product out
before it is thoroughly tested
Since this strategy has worked well in the past,
it is hard to blame them too much, though it is
unprofessional
8/11/2019 (1)Error Handling
2/6
11/9/20
Type 3: Run-time Errors
Run time errors happen when the programencounters an unexpected condition that it cant
handle Division by zero, needing a file thats not there, or
user error entering a value, are common causesof runtime errors
A well-written program should recover gracefullyfrom errors, ideally allowing the user anotherchance to enter their data, say, if that was thecause of the problem
Testing for Errors
In addition to your normal use cases, youshould also develop cases for all the user
mistakes or other error conditions you canthink of
For each of these error cases, you should haveone or more tests
Your program should recover gracefully ineach case; if it crashes, you need to figure outa way to avoid this
Code to Handle Errors (Example 1)
Weve already seen some error-handlingexamples in our code for reading from a file:
'*** get the name of the file to use
fName = Application.GetOpenFilename()
If fName = False Then'user cancelled
Exit Sub
End If
This jumps out of the subroutine if the userleaves a blank entry or otherwise fails to entera file name. Ideally there would be a message.
Code to Handle Errors (Example 2)
On Error GoTo EndMacro: 'bail out if there is an error
EndMacro:
On Error GoTo 0 'just quit if there's an error
This code uses the GoTo construct to jump to
the end of the program, and then out, if there
is an error
The first GoTo uses a user-defined label as a
target. The second one uses a system label
GoTo
In the olden days of programming, there were
no structures like If-Then-Else or Do-While
If you didnt want your program to just execute
in a straight line, you used an Ifand a GoTo:
If Then GoTo
You can write a program that does what you need
it to do with just theIf and GoTo and some labels,
but unless you are a very good and careful
programmer, it can be very hard to understand
GoTo Considered Harmful
Starting in the late 1960s, a big and largely
successful effort was made to replace the needfor GoTo with structured statements like If-Then-Else, For-Next, and Do-While
The one place where you still often need to jumpout of the orderly code execution is when anerror occurs
Hence, although GoTo is usually avoided, inhandling run-time errors it may often be the bestway to go
8/11/2019 (1)Error Handling
3/6
11/9/20
Other Approaches: Exit
Before looking at the GoTo approach, we
consider some alternatives
In our first example, we tested the return value of
the GetOpenFilename function; if it returns False,
we exit the subroutine. This exit is similar to a
GoTo in that we are just jumping out of the
middle of a subroutine to wherever it was called
from. We could also give a message to the user
before exiting, using a message box
Other Approaches: Defaults
One common cause of errors is where the user
doesnt enter a required value in a field such as a
text box, or enters an unacceptable value
You can set a text box to a default value in the
UserForm_Initialize procedure to help prevent
such errors. Many shopping sites initialize the
quantity box to 0 or 1 for this reason (and also
because 1 is the most common value in most
cases)
Other Approaches: Limit Choices
Instead of having the users type something in
a text box, you can have them choose a value
from a drop-down menu
In this way you limit the choices to correct
ones
You often see this approach on shopping sites
where you choose your state or the expiration
year of your credit card from a drop-down list
Other Approaches: Scrutiny
Another way to avoid run-time errors causedby unexpected inputs, such as non-numberswhere a number was expected, is to writecode that will scrutinize the input stringcarefully before trying to convert it into anumber, and ask the user to re-enter a faultyvalue
This requires sophisticated use of the string
manipulation functions
On Error GoTo
Information for this section was found athttp://www.cpearson.com/excel/errorhandling.htm
There are three forms of On Error GoTo, which
we will consider next
On Error GoTo 0
The simplest form of the On Error GoTo is
On Error GoTo 0
This makes VBA display a standard run time
error message box; you can also enter code in
debug mode
Basically this is the same behavior you get if
you have no error handler at all, so you should
try to do better if you have the time
http://www.cpearson.com/excel/errorhandling.htmhttp://www.cpearson.com/excel/errorhandling.htm8/11/2019 (1)Error Handling
4/6
11/9/20
On Error Resume Next
The next option is to use
On Error Resume Next
With this statement, you are telling VBA that if arun-time error occurs, it should just ignore it andexecute the next line
The problem here is that there may beunintended consequences as a result of the error(like a missing value that never got set), so justcontinuing as if nothing happened could be a badidea
On Error GoTo
The third option is to have VBA jump to a label
where you try to correct the error, or at least exit
gracefully
For example, our file reading program goes to a
place at the end of the subroutine where any
open file is closed before exiting
A typical structure is to have the ErrorHandler
label at the end of the code, with an Exit Sub just
before it to exit normally if there were no errors
Example Structure
SubExample ()
On Error GoTo ErrorHandler
Exit Sub
ErrorHandler:
Msgbox(A fatal error has occurred)
End Sub
Resume
Instead of exiting your subprocedure after
going to the error label, you might want to
resume executing it. The Resume statement
allows you to do this
There are three forms of resume:
Resume
Resume Next
Resume
Plain Resume
This tells VBA to go back to the line that
caused the error and try again
Obviously, this means you have to dosomething to fix the error before going back!
Part of the problem here is that your programneeds to know what kind of error occurred
When there is an error, VBA sets a propertycalled Err.Number to communicate the type oferror
Error Numbers
VBA provides an error description to go with
each error number
These can be extremely valuable when you
are debugging your code
The next page shows a sample code structure,
based on an example found at
http://www.ozgrid.com/VBA/ExcelVBAErrors.htm
http://www.ozgrid.com/VBA/ExcelVBAErrors.htmhttp://www.ozgrid.com/VBA/ExcelVBAErrors.htm8/11/2019 (1)Error Handling
5/6
11/9/20
Showing the Error Description
SubExample()
On Error GoTo ErrorHandler
Exit Sub avoid error handler if no error
ErrorHandler:
MsgBox Err.Number & & Err.Description
End Sub
Resume Next
With Resume Next, the program starts
executing at the next line after where the
error occurred
As with the previous case, your program
should do something to diagnose and fix the
error before resuming
Resume
Here the program resumes execution at the
line with the specified label
This allows you to skip a chunk of code where
things might be problematic
Of course you should compensate for the
skipped code, if needed, by setting variable
values or otherwise patching things up after
the error
An Illustration of Checking
The application RealEstateErrorHandler shows
how to use string functions to scrutinize user
input for errors.
It also illustrates checking that an option has
been chosen in a list box or a set of option
buttons
Well look at how each of these is done
Checking Listboxes
'*** get the agent and neighborhood from listboxes
'*** exit if either is null
If(lstAgents.ListIndex = -1) Or _
(lstNeighborhoods.ListIndex = -1) Then
MsgBox ("You must select an agent and a
neighborhood")
Exit Sub
End If
Checking Option Buttons
FunctionCheckCommission() As Boolean
'*** check that an option has been chosen
IfoptSolo.Value = True Or optShared.Value = True Then
CheckCommission = True
Else 'error, no commission chosen
CheckCommission = False
End If
End Function
8/11/2019 (1)Error Handling
6/6
11/9/20
Checking the Price: Declarations
Const DIGITS As String = "0123456789"
Dim testStr As String
DimtestStrLength As Integer
DimBadCharFound As Boolean
Dimj As Integer'loop control
DimjChar As String jth character in the input string
Checking the Price: Initial Steps
testStr = txtPrice.Text
PriceOK = True
'get ready to check each character in the test string'each character should be a digit
testStr = Trim(inputStr)
testStrLength = Len(testStr)
'Take care of the empty input string case
IftestStrLength = 0 Then
PriceOK = False
Exit Function
End If
Checking the Price: Main Loop
j = 1 'index of first character in testStr
BadCharFound = False
'stop as soon as a bad character is found
Do While (j