首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >最大Err.Raise数量?

最大Err.Raise数量?
EN

Stack Overflow用户
提问于 2012-09-22 01:10:38
回答 4查看 5.2K关注 0票数 9

为什么当我使用Err.Raise 65536时,Err.Number的实际值是5而不是65536?

根据Raise的定义:Sub Raise(Number As Long, [Source], [Description], [HelpFile], [HelpContext])。传递的参数是LongErr.Number也是Long

那么为什么我不能使用大于65535的值呢?

代码语言:javascript
复制
Private Sub Command1_Click()
Dim a As Long
    On Error GoTo ErrCatch
    For a = 0 To 99999
        Err.Raise a
        DoEvents
    Next a
    Exit Sub
ErrCatch:
    ' this is where Err.Number is evaluated
    Resume Next
End Sub`
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-22 01:14:41

MSDN documentation:

编号

必填项。标识错误性质的长整型。Visual Basic错误的范围是0-65535;0-512的范围是为系统错误保留的;用户定义的错误的范围是513-65535。在类模块中将Number属性设置为您自己的错误代码时,需要将错误代码编号添加到vbObjectError常量中。例如,若要生成错误号513,请将vbObjectError + 513指定给number属性。

因此,即使您可以提交一个大于65535的值,但任何大于65535的值都将变成错误5。

票数 11
EN

Stack Overflow用户

发布于 2012-09-22 23:39:02

除了“微软这么说”之外,还有更深一层的东西。您引发的错误号是一个32位整数,因为这是用于在组件之间传递错误的COM规范的一部分。组件的所有公共方法实际上都是返回HRESULT作为返回值的函数;如果您有一个VB函数,它会秘密地将函数的返回值映射到out参数。HRESULT值是一个由整个值堆组成的位域;但为了简单起见,您可以将其分为两个16位部分。较低的16位包含实际错误号,恰好介于0和65535之间-无符号16位范围。对于高16位,有许多标准。最重要的是0x0000____。所有使用此参数的常量都以"S_“开头(表示成功)。最常用的32位值是S_OK (0x00000000)。如果返回此值,则函数已成功。大多数VB方法调用都会返回这个值。但是,设置了顶部位的任何值都表示存在错误。在十六进制中,这些值看起来像0x8___。有许多类别的错误。VB默认返回的是0x800A。然而,COM规范只为您提供了一个可以正式使用的类,0x8004 -它在VB中表示为常量vbObjectError。

事实上,VB建议您在ActiveX DLL或EXE中的公共方法上引发错误时使用vbObjectError常量。不管你做不做,都没有区别。这只意味着调用代码接收到的错误非常大且为负,因此您必须将错误号与&H0000FFFF进行and运算才能恢复16位整数。有趣的是,它还建议您不要对ActiveX控制方法执行此操作,这可能是因为与ActiveX控制方法相关的高16位是0x800A000。更有趣的是,默认情况下,当您引发错误号时,VB本身会将所有错误号与0x800A0000进行AND运算。同样,它会检测错误号是否像0x800A____一样-如果是,它会为您删除高16位,因此您只需处理错误号本身。在我的工作场所,我们有很多VB组件。我们的标准是与vbObjectError不对错误代码进行OR运算。这就省去了我们随后不得不在调用代码中屏蔽它的麻烦。

例如,如果您有COMPONENT1.CLASS1和COMPONENT2.CLASS2。CLASS1.Method1调用CLASS2.Method1。如果我在CLASS2中引发错误,那么我必须在CLASS1.Method1中处理它。按照微软的指示,我会这样写:

COMPONENT1.CLASS1

代码语言:javascript
复制
Function Method1()
    On Error GoTo ErrorHandler
    ...
ErrorHandler:
    If (Err.Number And vbObjectError) = vbObjectError Then
        Select Case Err.Number And (Not vbObjectError)
        Case Component2.EErrComponent2.ecBlahBlahError
            ... handle ...
        End Select
    End If
End Function

COMPONENT2.CLASS2

代码语言:javascript
复制
Enum EErrComponent2
    ecBlahBlahError = 513 ' Minimum error code
End Enum

Function Method1()
...
    Err.Raise EErrComponent1 Or vbObjectError
...
End Function

对多个组件重复此操作,这个模板会让人有点厌烦,而且似乎没有给我们带来任何实际的回报。

我们可能会这样做:

COMPONENT1.CLASS1

代码语言:javascript
复制
Function Method1()
    On Error GoTo ErrorHandler
    ...
ErrorHandler:
    Select Case Err.Number
    Case Component2.EErrComponent2.ecBlahBlahError
        ... handle ...
    End Select
End Function

COMPONENT2.CLASS2枚举EErrComponent2 ecBlahBlahError End枚举

代码语言:javascript
复制
Function Method1()
...
    Err.Raise EErrComponent1
...
End Function

我想知道是否有人在不使用vbObjectError时遇到过问题。我们当然没有。

票数 10
EN

Stack Overflow用户

发布于 2012-09-22 01:13:56

错误5是

代码语言:javascript
复制
Run-Time Error '5': Invalid Procedure Call or Argument”

加上贾斯汀的回答,这将是有意义的。当使用大于65535的整数调用Raise函数时,它会抛出错误5,因为它是一个无效参数。

你能展示一些代码吗?我可以帮你做得更好一些。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12535054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档