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

时间:2015-05-12 15:36:46

标签: 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

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

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

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

1 个答案:

答案 0 :(得分:5)

您没有处理没有工作簿处于活动状态的情况。在开始工作簿被激活之前,Workbook_Open被称为,因此当代码运行时Application.ActiveWorkbook很可能是Nothing - 任何时候Excel实际启动。

简单的解决方案是使用wb中的Workbook_Open引用 - {<1}},直到 该事件完成后才会设置。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

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