错误处理
在前面的例子里,我多次提到了让大家输入正确的数值再进行计算操作,但在实际的软件使用中,我们又怎么能保证用户在使用时输入的总是正确的数据呢?
如,对于要进行算术计算的数值,如果用户输入的不是正确的数字将会出现致命的错误,这样常常会毁掉一个程序,这当然是作为开发人员所不愿看到的,所以,认真对待错误是一个很重要的话题,这一章里,我们将看看在VB6是如何处理错误的。
我们还是先打开在前面使用的工程1,我们还是在Form1窗体中来演示错误的处理。
1 错误处理语句
在VB6中,错误处理语句有两种,即:
l On Error Goto 标号
l On Error Resume Next
下面分别介绍。
(1) On Error Goto 标号
关于这个错误处理语句,其中的On、Error、Goto为VB6的关键字,而标号则是用于标明代码位置的一个“标签”,它由“标识符+冒号”组成,如:
ProcessError:
而这个错误处理语句的含义就是:从此语句的下一条代码开始,如果出现错误,则跳转到标号,继续执行标号后面的代码。现在,我们就以除法为例来说明它的用法,在这里可以新建一个按钮(Caption属性可以设置为“错误处理1”),并添加以下响应代码:
Private Sub Command8_Click()
'错误处理示例,On Error Goto 标号
On Error GoTo subError
Dim n1 As Currency
Dim n2 As Currency
Dim result As Currency
n1 = CCur(Text1.Text)
n2 = CCur(Text2.Text)
result = n1 / n2
Text3.Text = CStr(result)
Exit Sub
subError:
MsgBox Err.Description
Err.Clear
End Sub
在代码中,我们定义了一个标号“subError”。然后,我们分别使用n1和n2来保存被除数和除数来进行除法计算,结果保存到变量result中;最后将结果显示在Text3中。
想一想,在代码中可能出现的错误:
l Text1中的内容不能正确转成数值
l Text2中的内容不能正确转成数值
l Text2中的内容为0,而除数是不能为零的
现在,我们按F5键运行程序,试一试可能出现的错误,看看和没有加上错误处理时有什么区别。
这里,我们可以发现,在没有添加错误处理时,程序可能就要退出了;而加上了错误处理的时候,出错的时候就会给出一个提示窗口,这样是不是友好多了呢?想一想在实际的开发中,对于数字处理不只是能不能正确转成数值和能不能为零,还有就是可能要判断数值的范围,格式等操作,以后面的学习中,我们将学习更多的错误处理方法。
再回头看看代码,在这一段代码中,是不是有了一些新的内容。
其中,Exit Sub语句用于退出当前的子程序;在这段代码中也就是当没有错误时,执行完成正常工作的代码后就要退出这个事件处理子程序了。你可以将这行删除或变成注释看看会什么结果,程序会变成无论是否出错都将出现提示窗口的情况。
再者,就是我们使用了Err对象,这是一个系统对象,用于保存最后一个错误的信息,这里我们使用了Err对象的Description属性,它是对错误的文本描述,这里就可以通过MsgBox函数来显示错误信息。在显示错误信息后,我们使用了Err对象的Clear方法,它用于清除Err对象中的错误信息,以防止对Err对象的错误调用会出现不正确的错误信息。对于Err对象更详细的使用方法,可以在实践中慢慢掌握,而我们最常用的就是Description属性和Clear方法了。
(2) On Error Resume Next
这个语句的含义非常简单,就是当遇到错误时,程序会跳过出错的语句,而继续执行下一条。
这里,我可以很明显的看出它的不足,如上例中的除法运算,三种可以出现的错误情况有一种出现,结果就会不正确,那么即使我们将代码执行完毕了,结果也是毫无意义的,所以在这种需要进行数值计算的情况使用这条错误处理语句显然是不合适的。
那这条错误处理语句在什么情况下使用呢?
我一般将其使用在一些不太重要的操作上,如,你可以将它使用在清除文本框内容的方法中。此外,就是一些前后操作没有关联性的地方,并且操作的内容对最终结果不应存在潜在的影响。
在实际开发中,我还是建议大家多使用“On Error Goto 标号”语句来处理可能的错误,这样就可以明了的向用户展现错误信息,以便能在第一时间改正它。
2 错误的可控性
还以上面中的除法运算为例,我们列出的三种可能出现的错误虽然都能被程序自动捕捉,但也只是很机械的显示出错误信息,但我们还可以将它做的更人性化一点,根据以下代码,在窗体的“通用”代码段中添加函数checkData:
Private Function checkData() As Boolean
checkData = False
With Text1
If IsNumeric(.Text) = False Then
MsgBox "请输入一个正确的数字"
.SelStart = 0
.SelLength = Len(.Text)
.SetFocus
Exit Function
End If
End With
With Text2
If IsNumeric(.Text) = False Then
MsgBox "请输入一个正确的数字"
.SelStart = 0
.SelLength = Len(.Text)
.SetFocus
Exit Function
End If
If CCur(.Text) = 0 Then
MsgBox "除数不能为0,请输入一个非0的数值"
.SelStart = 0
.SelLength = Len(.Text)
.SetFocus
Exit Function
End If
End With
checkData = True
End Function
在函数的一开始,我们将函数的返回值设置为False,然后开始进行可能的错误判断。
代码中,我们使用With…End With语句,从实例中我们不难看出,当With关键字后面跟一个控件名以后,在最近的End With语句以前的代码块中,对于此控件属性和方法的调用可以省略控件名,这样就大大简化了代码的编写。
在第一个With块中,我们使用了IsNumeric函数来判断Text1的Text是否可以转成数字,如果不能,则显示一个提示窗口,告诉用户要输入一个正确的数值。然后,使用SelStart和SelLength属性来设置Text1中选择的内容,在这里是全选;其中的Len函数返回一个整数,说明了参数(这里是Text1的内容)的长度,这里就是指Text1文本框中有多少个字符。
当全选了Text1的内容后,我们使用Text1的SetFocus方法,将输入的焦点设置在Text1控件上来,最后退出函数,这时函数的返回值就是False,也就是检查数据时发现了不正确的数据输入。
在第二个With块中,我们同样先判断了Text2中的内容是否为数字,然后又多加了一个判断条件,即看它是否为0,如果将除数输入了0,则同样退出函数,并且函数返回False。
最后,当检查数据没有出错时,则函数返回True,说明检查通过。
为了测试这个函数,我们只要在前一小节中的代码中的On Error Goto subError语句后加上如下一条代码即可:
If checkData = False Then Exit Sub
它的含义就是,当检查不通过时,将退出事件处理,而不进行下面的计算。这时,我们可以运行程序,输入不同的内容看看程序会有什么反应,是不是看上去很体贴、很人性化呢。
要注意的是,虽然我们通过一个checkData函数可以进行很多可预知错误的处理,但也不要放弃对On Error Goto语句的使用,因为还有一些我们不太容易预先处理的情况出现,如用户输入过大的数值的时候。
3 小结
在本章,我们了解了VB6中的错误处理语句,也了解了一个预先处理可预知错误的方法,这样我们就可以在自己的程序创建一个相对稳定的运行流程了。
此外,对于错误的处理,我们会发现处理语句是很简单的,但软件中的错误还是不能完整的被处理;对于开发人员来讲,重要的不只是熟练掌握开发环境中的处理方法,更重要的是对可能出现的错误的全面把握,以及对错误处理工作的态度。