excel - 如何在不破坏对象的情况下停止 VBA 宏

标签 excel vba exception error-handling garbage-collection

我编写了一个 VBA 程序,它在 Workbook_Open 上创建,将错误写入错误日志的文件流。如果我遇到 fatal error (因此需要停止执行宏),程序将执行 End声明,突然停止宏。我知道这个解决方案不是一个理想的解决方案,但是如果我有多个函数深入(即一个函数调用了另一个函数,另一个函数又调用了另一个函数,而第三个函数产生了错误)。退出发生错误的函数只会影响该特定函数,从而可能导致无效数据、意外的单元格值等。

但是这种方法给我带来了另一个问题——当End时执行它会破坏我的所有对象,包括错误流。因此,当用户执行新操作并遇到 fatal error 时,他们会收到 VBA 运行时错误(91:对象...未设置),因为代码写入现在设置为 Nothing. 的文件流。

有没有更好的方法来结束宏(从而避免错误后的意外行为)而不丢失所有对象?官方的VBA文档没有任何帮助。提前致谢。

最佳答案

结束:

Terminates execution immediately. Never required by itself but may be placed anywhere in a procedure to end code execution, close files opened with the Open statement and to clear variables. When executed, the End statement resets all module-level variables and all static local variables in all modules.

此工作簿模块:

Public fileSystem As FileSystemObject
Public errorStream As TextStream

Private Sub Workbook_Open()

    Set fileSystem = New FileSystemObject
    Set errorStream = fileSystem.CreateTextFile("c:\temp\error.log", True)

End Sub

标准模块:

Public Sub First()
    If (Not ThisWorkbook.errorStream Is Nothing) Then
        Debug.Print VBA.TypeName(ThisWorkbook.errorStream)
    End If

    End
    ' Exit Sub
End Sub

Public Sub Second()
    If (Not ThisWorkbook.errorStream Is Nothing) Then
        Debug.Print VBA.TypeName(ThisWorkbook.errorStream)
    End If
End Sub

当“First”方法首先执行且其中包含“End”,然后执行“Second”方法时,errorStream 将为 Nothing。 'End'代替'ExitSub',则变量不会被重置。

或者您可以在 Thisworkbook 类模块中将错误流变量设置为私有(private)并添加属性,如果变量为 Nothing,这将创建流。 HTH

此工作簿模块:

Private m_errorStream As TextStream
Private Const FILE_PATH_NAME As String = "c:\temp\error.log"

Public Property Get ErrorStream() As TextStream
    If (m_errorStream Is Nothing) Then
        Dim fileSystem As FileSystemObject
        Set fileSystem = New FileSystemObject
        If (fileSystem.FileExists(FILE_PATH_NAME)) Then
            Set m_errorStream = fileSystem.GetFile(FILE_PATH_NAME).OpenAsTextStream
        Else
            Set m_errorStream = fileSystem.CreateTextFile(FILE_PATH_NAME, False)
        End If
    End If

    Set ErrorStream = m_errorStream
End Property

标准模块:

Public Sub First()
    If (Not ThisWorkbook.ErrorStream Is Nothing) Then
        Debug.Print VBA.TypeName(ThisWorkbook.ErrorStream)
    End If

    End
End Sub

Public Sub Second()
    If (Not ThisWorkbook.ErrorStream Is Nothing) Then
        Debug.Print VBA.TypeName(ThisWorkbook.ErrorStream)
    End If
End Sub

关于excel - 如何在不破坏对象的情况下停止 VBA 宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17995886/

相关文章:

dynamic - 动态创建的用户窗体、命令按钮和文本框 : not registering textbox changes

java - 为什么会抛出空指针异常?

excel - VBA比较行,如果相同则计数

Python Pandas - 使用 read_excel 或 csv 时是否可以通过引用列号来转换数据类型?

json - 如何在不编码的情况下将 JSON 文件导入 Excel?

用于将 x 轴设置为绘图范围内的最小值和最大值的 Excel VBA 代码

php - 导出到 XLS 单元格时如何使 <td> 宽度适合内容

vba - 在 Excel 中插入具有特定单元格中的值的行

c# - 如何查找运行 WPF 应用程序时抛出的异常?

java - 解密加密消息摘要时出现非法 block 大小异常