感觉VB中的错误处理机制似乎有点奇怪啊》?
明明Raise了,意思就是希望在此处出现错误时,向上(调用者)抛出。
而调用者在on error goto handleErr时,却一直捕捉不到。
比如一个取消按钮时err.number=32755时,既然在调用函数中去条件捕捉也无济于事!
反而是每次程序运行出现时,说没有进行错误处理,程序自动定位到Raise语句那个地方!既然如此,这Raise语句岂不是没有用处啊!!也没怎么搞过VB,最近一师弟问及此问题。
故发贴请教大家!!

解决方案 »

  1.   

    是vb写的active控件在其他vb程序中调用?带事件的控件声明时要加 with event 关键字
      

  2.   

    代码如下:
    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
      

  3.   

    感觉楼主是会错意了。以下摘自MSDN:
    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 属性中说明生成错误的来源,可以引用该错误的联机帮助。
      

  4.   

     调用api不会产生vb那种常规的对象错误, 而你也没有写错误捕捉语句, 从 handleerror 那个 case else 产生的错误即便产生了也无法回溯到上一个调用者还是在调用者处添加上错误捕捉,然后跟踪一下错误触发过程是否运行正确,我觉得那个过程好像没法触发错误
      

  5.   


    要看你是想干什么,如果你只是想知道子函数内部引发了什么错误,可以老老实实将错误包装一下放在子函数返回值里面,或者是放在子函数的参数里面进行返回。返回之后自己分析一下,如果有必要的话可以在调用函数中用Raise抛出来。(个人感觉就没有必要了,除非特殊要求)
      

  6.   

    按照楼主的思路随便写了一段代码,楼主看看是不是这个效果。Option ExplicitPrivate Sub Command1_Click()
    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
      

  7.   

    你在cmd1中自己抛给自己处理?我是希望过程A抛出异常,过程B来截获进行处理。
      

  8.   


    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
    是这个意思吗?
      

  9.   

    好好看看MSDN吧,说的很明白了:Err 对象
                   含有关于运行时错误的信息。说明
    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 对象是具有全局范围的固有对象。在代码中没有必要建立这些对象的实例。
      

  10.   

    楼主的问题我以前也遇到过,向上级调用模块抛出错误时,如果用Err.Raise错误处理一定要用On Error Resume Next而不用on error goto handleErr,在可能出错的地方加上If Err.Number <> 0 Then Err.Raise Err.Number;这样处理错误就可以了,楼主不妨试下
      

  11.   

    调用者应该是这样的结构
    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