Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 如果只能存在一个错误对象,那么声明一个ErrObject变量有什么用?_Vba_Error Handling_Ms Office - Fatal编程技术网

Vba 如果只能存在一个错误对象,那么声明一个ErrObject变量有什么用?

Vba 如果只能存在一个错误对象,那么声明一个ErrObject变量有什么用?,vba,error-handling,ms-office,Vba,Error Handling,Ms Office,我们都知道VBA中只能有一个错误对象。 在帮助同事处理错误以及为什么他不应该在错误简历上使用“下一步”时,我有一个想法: 将错误对象存储在某个位置,以便以后引用回它 考虑这段测试代码: Sub Test() Dim t As ErrObject On Error Resume Next Err.Raise 1 Set t = Err On Error GoTo 0 Debug.Print t.Number On Error Resume N

我们都知道VBA中只能有一个错误对象。 在帮助同事处理错误以及为什么他不应该在错误简历上使用“下一步”时,我有一个想法: 将错误对象存储在某个位置,以便以后引用回它

考虑这段测试代码:

Sub Test()
    Dim t As ErrObject
    On Error Resume Next
    Err.Raise 1
    Set t = Err
    On Error GoTo 0
    Debug.Print t.Number
    On Error Resume Next
    Err.Raise 1
    Debug.Print t.Number
End Sub
它会将0打印到即时窗口,因为在出现错误时,0会重置错误对象,然后打印1,因为它仍然保留对唯一错误对象的引用

如果我们创建一个新类,并给它一些与ErrorObject相关的属性,如下所示:

(TestClass)
Option Explicit
Public oError As ErrObject
Private Sub Class_Initialize(): End Sub
Private Sub Class_Terminate()
    If Not oError Is Nothing Then Set oError = Nothing
End Sub
Public Property Get Error()
    Error = oError
End Property
Public Property Set Error(ByVal ErrorObject As ErrObject)
    Set oError = ErrorObject
End Property
然后像这样创建我们的实例:

Sub Test2()
    Dim t As TestClass
    On Error Resume Next
    Set t = New TestClass
    Err.Raise 1
    Set t.Error = Err
    On Error GoTo 0
    Debug.Print t.oError.Number
    On Error Resume Next
    Err.Raise 1
    Debug.Print t.oError.Number
End Sub
我们仍然分别得到0和1作为输出

这就引出了我的问题:当我们无法创建一个新对象本身,但它只是成为指向VBA中唯一错误对象的另一个指针时,将变量声明为ErrObject有什么用

Err通常被视为某种全局ErrObject实例,但事实是,它是一个返回一个实例的函数-如对象浏览器中所示:

这个函数是以这样的方式实现的,你总是得到相同的对象

对象需要公开一个可用的接口,因此Err函数返回的对象公开了ErrObject类的接口-这并不意味着ErrObject类的存在可以通过用户代码实例化或封装:它只提供一个接口来访问当前运行时错误状态的属性

当你像以前那样封装一个ErroObject时,你本质上只是给自己提供了除Err函数之外的另一种方式来访问ErroObject实例——但它仍然是保持当前运行时错误状态属性的完全相同的对象

当一个对象的属性发生变化时,指向该对象的封装副本将开始报告新值,而您想要记住的旧值将被覆盖

请注意,这适用于任何对象,而不仅仅是ErroObject

假设我有一个类,它完成了您对ErrObject引用所做的操作,但它有一个集合:

如果我创建了该类的一个实例,让我们将其命名为Class1,并将c分配给其InternalCollection,然后将项添加到c

输出为2,因为c和InternalCollection/encapsuated coll引用是同一个对象,这就是封装的ErroObject发生的情况

解决方案是不封装ErrObject本身,而是将其值拉入封装ErrObject状态的get-only属性的支持字段:

现在,这是否有用还有待讨论——在我看来,如果在全局错误状态已经包含相同信息的时刻使用状态,那么就没有必要这样做

该类可以很容易地被[ab]用作一个函数的返回类型,该函数不返回任何表示成功的内容,以及失败时封装的错误状态——问题是该语言是围绕引发错误而设计的,而不是返回错误;在不验证其返回值的情况下,很容易触发和忘记这样的函数,而且由于在调用站点,实际运行时错误状态不会触发On error语句,因为程序数据不是惯用的,所以会携带错误状态,这会生成一个令人惊讶的API,很容易导致代码忽略所有错误

惯用错误处理会尽快处理全局运行时错误状态,或者在同一范围内恢复,或者让错误状态在调用堆栈中冒泡到可以处理的位置。在错误得到处理之前,可以通过全局Err函数访问ErrObject状态。

Err通常被视为某种全局ErrObject实例,但事实是,它是一个返回一个实例的函数-如对象浏览器中所示:

这个函数是以这样的方式实现的,你总是得到相同的对象

对象需要公开一个可用的接口,因此Err函数返回的对象公开了ErrObject类的接口-这并不意味着ErrObject类的存在可以通过用户代码实例化或封装:它只提供一个接口来访问当前运行时错误状态的属性

当你像以前那样封装一个ErroObject时,你本质上只是给自己提供了除Err函数之外的另一种方式来访问ErroObject实例——但它仍然是保持当前运行时错误状态属性的完全相同的对象

当一个对象的属性发生变化时,指向该对象的封装副本将开始报告新值,而您想要记住的旧值将被覆盖

请注意,这适用于任何对象,而不仅仅是ErroObject

假设我有一个类,它完成了您对ErrObject ref所做的操作 erence,但有一个集合:

如果我创建了该类的一个实例,让我们将其命名为Class1,并将c分配给其InternalCollection,然后将项添加到c

输出为2,因为c和InternalCollection/encapsuated coll引用是同一个对象,这就是封装的ErroObject发生的情况

解决方案是不封装ErrObject本身,而是将其值拉入封装ErrObject状态的get-only属性的支持字段:

现在,这是否有用还有待讨论——在我看来,如果在全局错误状态已经包含相同信息的时刻使用状态,那么就没有必要这样做

该类可以很容易地被[ab]用作一个函数的返回类型,该函数不返回任何表示成功的内容,以及失败时封装的错误状态——问题是该语言是围绕引发错误而设计的,而不是返回错误;在不验证其返回值的情况下,很容易触发和忘记这样的函数,而且由于在调用站点,实际运行时错误状态不会触发On error语句,因为程序数据不是惯用的,所以会携带错误状态,这会生成一个令人惊讶的API,很容易导致代码忽略所有错误

惯用错误处理会尽快处理全局运行时错误状态,或者在同一范围内恢复,或者让错误状态在调用堆栈中冒泡到可以处理的位置。在错误得到处理之前,可以通过全局Err函数访问ErrObject状态

Private coll As Collection

Public Property Set InternalCollection(ByVal c As Collection)
    Set coll = c
End Property

Public Property Get InternalCollection() As Collection
    Set InternalCollection = coll
End Property
Dim c As Collection
Set c = New Collection
With New Class1
    Set .InternalCollection = c

    c.Add 42
    .InternalCollection.Add 42

    Debug.Print .InternalCollection.Count
End With
Private errNumber As Long
Private errDescription As String
'...

Public Sub SetErrorInfo() 'note: an ErrObject argument would be redundant!
    With Err
        errNumber = .Number
        errDescription = .Description
        '...
    End With
End Sub

Public Property Get Number() As Long
    Number = errNumber 
End Property

Public Property Get Description() As String
    Description = errDescription
End Property

'...