上下文: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”之类的东西)
这个问题出现在一个更加复杂的现实世界的情况中,而且似乎与某些安全问题紧密相关。我试图用一个简单的例子来理解行为
答案 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实际上显示工作表。