应用WithEvents

时间:2015-11-05 10:49:01

标签: vba class excel-vba excel

我想控制我的所有应用程序事件,并发现使用WithEvents将提供该解决方案。我通过cpearson阅读了帖子的Application Events In A Dedicated Class Module部分。

我想弄清楚的是:您是否需要为您创建的每个类事件过程设置一个ThisWorkbook事件过程?

ThisWorkbook模块中:

Private ExcelEvents As CApplicationEvents

Private Sub Workbook_Open()
    Set ExcelEvents = New CApplicationEvents
End Sub

Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    Set ExcelEvents = New CApplicationEvents
End Sub

Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
    Set ExcelEvents = New CApplicationEvents
End Sub

并在CApplicationEvents类模块中:

Private WithEvents appExcel As Application

Private Sub appExcel_SheetActivate(ByVal Sh As Object)
    Debug.Print "worked!"
End Sub

Private Sub appExcel_SheetCalculate(ByVal Sh As Object)
    Debug.Print "calculating... !"
End Sub

Private Sub appExcel_WorkbookOpen(ByVal Wb As Workbook)
    Debug.Print "workbook name:" & Wb.Name
End Sub

Private Sub Class_Initialize()
    Set appExcel = Application
End Sub

我原本以为Workbook_Open模块中的ThisWorkbook过程允许在类模块中创建任何事件过程,但是如果没有在ThisWorkbook模块中创建相应的事件过程,我的类模块中的事件代码不会触发并运行。

我基本上在澄清之后,如果我在我的类模块中创建一个新的appExcel_WorkbookBeforeClose事件过程,那么它是否也必须在Workbook_BeforeSave模块中创建ThisWorkbook过程,再次声明Set ExcelEvents = New CApplicationEvents?如果是这样,在这种情况下使用类模块有什么优势?这似乎是我的代码重复。

2 个答案:

答案 0 :(得分:4)

您不需要一次又一次地实例化Set ExcelEvents = New CApplicationEvents。您只需要在Workbook_Open中创建一次并在其上保留引用。

只要您在该实例上持有参考,它就会保持活力,但如果VBA项目卸载,则:

  • 通过代码中某处的显式End语句(不太可能)

  • 或者如果代码在调试期间中断;例如,抛出未处理的错误

  • 或者在调试器中手动停止执行

在这些情况下,您将丢失实例。您可以通过询问?ThisWorkbook.ExcelEvents Is Nothing

在即时窗口中验证它

当实例丢失时,您不需要退出并重新打开工作簿,您只需再次手动执行Workbook_Open例程(将光标置于其中并按{ {1}})。将再次创建实例,您可以正常继续开发会话。

P.S。上述推理实际上适用于所有全局变量。每当项目由于上述任何原因而卸载时,它们都会重置:字符串为F5,数字为"",对象为0 ...但您可以重新创建或者重新创建它们或者在即时窗口中设置它们,或者通过启动任何一段代码来设置它们。

答案 1 :(得分:0)

不确定你的意思是什么,但是在类appExcel中需要设置为Application。喜欢这个

Private Sub Workbook_Open()

Set c = New cApplication

c.INITIALISE Application

End Sub

并在班级

Option Explicit

    Private WithEvents app As Excel.Application

    Public Sub INITIALISE(x As Excel.Application)
        Set app = x
    End Sub

希望这有帮助,我没有完全理解这篇文章。

感谢

森。