VBA加载项ActiveWorkBook何时变为活动状态?

use*_*991 3 excel vba excel-vba

上下文:Excel 2013 VBA.使用外接程序时,术语"ActiveWorkBook"应该引用正在编辑的文档,而"ThisWorkBook"引用后台中的外接程序.考虑一下代码

在加载项的ThisWorkBook模块中

Private WithEvents App As Application

Private Sub Workbook_Open()
Set App = Application
End Sub

Private Sub App_WorkBookOpen(ByVal Wb As Workbook)

MsgBox Wb.Name & " " & Wb.Worksheets(1).Cells(1, 1)
If Wb.Worksheets(1).Cells(1, 1) = "AAA" Then
    MsgBox "Cell OK", 
    MsgBox ActiveWork.Name
End If
End Sub
Run Code Online (Sandbox Code Playgroud)

加载项已启用,Excel已启动.到现在为止还挺好.现在,如果我在Sheet1的单元格(1,1)中打开包含"AAA"的文件"Book1",我会收到:

"Book1.xlsm AAA"(在消息框中,如预期的那样),然后"Cell OK",如预期的那样.
但是然后错误"Object Required"引用了MsgBox行"ActiveWorkBook.Name".所以当时Book1还不是ActiveWorkBook.什么时候变成这样?或者我该怎么做呢?(在MsgBox没有帮助之前,像"Wb.Activate"之类的东西)

这个问题出现在一个更加复杂的现实世界中,而且似乎与某些安全问题紧密相关.我试图通过一个简单的例子来理解这种行为

Mat*_*don 5

您没有处理没有工作簿处于活动状态的情况.在打开工作簿被激活之前Workbook_Open调用,因此很可能在代码运行时 - Excel实际启动时.Application.ActiveWorkbookNothing

简单的解决方案是使用wb引用Workbook_Open- ActiveWorkbook直到该事件完成才会设置.如果它已经设置,那么它不是您认为的工作簿:它是wb开始打开时活动的工作簿.

亲眼看看(在附加ThisWorkbook代码中):

Private WithEvents app As Application

Private Sub app_WorkbookActivate(ByVal Wb As Workbook)
    MsgBox "activated"
End Sub

Private Sub app_WorkbookOpen(ByVal Wb As Workbook)
    MsgBox "opened"
End Sub

Private Sub Workbook_Open()
    Set app = Excel.Application
End Sub
Run Code Online (Sandbox Code Playgroud)

当加载项开始时,您将看到"已打开"消息框(背景仍然显示没有任何工作簿的空白工作区) - 然后一旦Excel实际显示工作表,弹出"激活"消息框.