感觉VB中的错误处理机制似乎有点奇怪啊》?
明明Raise了,意思就是希望在此处出现错误时,向上(调用者)抛出。
而调用者在on error goto handleErr时,却一直捕捉不到。
比如一个取消按钮时err.number=32755时,既然在调用函数中去条件捕捉也无济于事!
反而是每次程序运行出现时,说没有进行错误处理,程序自动定位到Raise语句那个地方!既然如此,这Raise语句岂不是没有用处啊!!也没怎么搞过VB,最近一师弟问及此问题。
故发贴请教大家!!
明明Raise了,意思就是希望在此处出现错误时,向上(调用者)抛出。
而调用者在on error goto handleErr时,却一直捕捉不到。
比如一个取消按钮时err.number=32755时,既然在调用函数中去条件捕捉也无济于事!
反而是每次程序运行出现时,说没有进行错误处理,程序自动定位到Raise语句那个地方!既然如此,这Raise语句岂不是没有用处啊!!也没怎么搞过VB,最近一师弟问及此问题。
故发贴请教大家!!
Private Sub HandleDlgError(errCode As Long)
Dim sDesc As String
Select Case errCode Case cdlAlloc
sDesc = "Couldn't allocate memory for FileName or Filter property" Case cdlCancel, 0 '就是符合此处条件时
If CancelError Then
errCode = cdlCancel
sDesc = "Cancel was selected"
Else
errCode = 0
End If '还有一大把Case语句 Case Else
Err.Raise errCode, "CommonDialog"
Exit Sub
End Select '最后会执行到这里,但却说没有处理异常(此处就是希望向上抛出异常)
If errCode <> 0 Then Err.Raise errCode, "CommonDialog", sDesc, "cmdlg98.chm", errCode
End Sub
'调用者代码:
Public Sub ShowOpen()
Dim l As Long
piAction = 1 With OFN
.nStructSize = Len(OFN)
.hWndOwner = 0&
.sFilter = Replace(Filter, "|", vbNullChar)
.nFilterIndex = FilterIndex
.sFile = Left$(FileName & Space$(1024), MaxFileSize - 2) & vbNullChar & vbNullChar
.nMaxFile = MaxFileSize
.sDefFileExt = DefaultExt & vbNullChar & vbNullChar
.sFileTitle = vbNullChar & Space$(512) & vbNullChar & vbNullChar
.nMaxTitle = Len(OFN.sFileTitle)
.sInitialDir = InitDir & vbNullChar & vbNullChar
.sDialogTitle = DialogTitle
.Flags = Flags
End With
l = GetOpenFileName(OFN)
Select Case l Case 1
FileName = TrimNull(OFN.sFile) 'Path and File
FileTitle = TrimNull(OFN.sFileTitle) 'File Only Case Else
' Extended error:
HandleDlgError CommDlgExtendedError() '此处执行错误处理
End Select
End Sub
Raise 方法
产生运行时错误。语法object.Raise number, source, description, helpfile, helpcontextRaise 方法具有下列对象限定符和命名参数:参数 描述
object 必需的。总是 Err 对象。
Number 必需的。Long整数,识别错误性质。Visual Basic 错误(既有 Visual Basic 定义的错误也有用户定义的错误)的范围在 0–65535 之间。从 0–512 的范围保留为系统错误;从 513–65535 的范围可以用做用户定义的错误。当在类模块中将 Number 属性设置成自己的错误代码时,可将错误代码号添加到 vbObjectError 常数上。例如,为了产生错误号 513,可将 vbObjectError + 513 赋值到 Number 属性。
source 可选的。字符串表达式,为产生错误的对象或应用程序命名。当设置对象的这一属性时,要使用窗体 project.class。如果没有指定 source,则使用当前 Visual Basic 工程的程序设计 ID。
description 可选的。描述错误的字符串表达式。如果没有指定,则检查 Number 的值。如果可以将错误映射成 Visual Basic 运行时错误代码,则将 Error 函数返回的字符串作为 Description 使用。如果没有与 Number 对应的 Visual Basic 错误,则要用到消息“应用程序定义的错误或对象定义的错误”。
helpfile 可选的。帮助文件的完整限定的路径,在帮助文件中可以找到有关错误的帮助信息。如果没有指定,则 Visual Basic 会使用 Visual Basic 帮助文件的完整限定的驱动器、路径和文件名。
helpcontext 可选的。识别 helpfile 内的标题的上下文 ID,而 helpfile 提供有助于了解错误的描述。如果省略,则使用处理有关错误的 Visual Basic 帮助文件的上下文 ID,该 ID 与 Number 属性对应。
说明除了 number 之外,所有参数都是可选的。如果使用 Raise 而不指定一些参数,并且 Err 对象的属性设置含有未清除的值,则视这些值为错误的值。Raise 被用来生成运行时错误,并可用来代替 Error 语句。当书写类模块时要生成错误,Raise 是有用的,因为 Err 对象比 Error 语句可能提供更丰富的信息。例如,用 Raise 方法,可以在 Source 属性中说明生成错误的来源,可以引用该错误的联机帮助。
要看你是想干什么,如果你只是想知道子函数内部引发了什么错误,可以老老实实将错误包装一下放在子函数返回值里面,或者是放在子函数的参数里面进行返回。返回之后自己分析一下,如果有必要的话可以在调用函数中用Raise抛出来。(个人感觉就没有必要了,除非特殊要求)
On Error GoTo ErrWork2
Dim Errnum As Long
Dim ErrDesc As String
Test 0, Errnum, ErrDescIf Errnum <> 0 Then
Err.Raise Errnum, , ErrDesc
End IfExit Sub
ErrWork2:
MsgBox Err.Description
End Sub
Private Function Test(a As Long, Errnum As Long, ErrDesc As String)
On Error GoTo ErrWork
'do some work
Debug.Print 1 / 0 '有一个错误
Exit Function
ErrWork:
Errnum = Err.Number
ErrDesc = Err.Description
End Function
Private Sub Form_Load() On Error GoTo l1 Call funA Exit Subl1: If Err.Number <> 0 Then Debug.Print Err.Description
End SubPrivate Function funA()
Err.Raise 1000 + vbObjectError, , "qwer"
End Function
是这个意思吗?
含有关于运行时错误的信息。说明
Err 对象的属性由错误的生成者来设置,这个生成者或者是 Visual Basic,或者是对象,或者是程序设计员。Err 对象的缺省属性是 Number。因为该缺省属性可以用对象名称 Err 表示,所以不必修改以前用 Err 函数或 Err 语句书写的代码。当运行时错误发生时,Err 对象的属性被填入明确识别错误的信息以及处理这个错误所使用的信息。为了在代码中生成运行时错误,请用 Raise 方法。在任意形式的 Resume 或 On Error 语句之后以及在错误处理子程序内的 Exit Sub、Exit Function、或 Exit Property 语句之后,将 Err 对象的属性重新设置为零或长度为零的字符串 ("")。可使用 Clear 方法重新明确设置 Err 。为了对系统错误和类模块生成运行时错误,要使用 Raise 方法而不使用 Error 语句。在其它代码中是否使用 Raise 方法,这要看想要返回的信息量有多大。Err 对象是具有全局范围的固有对象。在代码中没有必要建立这些对象的实例。
Public Sub ShowOpen()
On Error GoTo ErrHandler '<-开始捕获错误'
Dim l As Long piAction = 1 With OFN
...
End With
l = GetOpenFileName(OFN)
Select Case l
...
End SelectExitEntry: '<-下面进行资源释放,无论正常或错误都能被调用'
On Error Resume Next '<-避免释放可能触发的错误引起死循环'
...
Exit Sub
ErrHandler: '<-错误处理'
MsgBox Err.Description & vbCrLf & _
"Number = " & Err.Number & vbCrLf & _
"Source = " & Err.Source, _
vbCritical, , Err.HelpFile, Err.HelpContext
Resume ExitEntry '<-结束错误处理,跳转到统一的出口'
End Sub