如何在新建工作簿中应用工作簿事件?SheetDeactivate事件未触发问题
问题分析与解决方案
问题根源
你当前的Workbook_SheetDeactivate事件写在加载项的ThisWorkbook模块中,这个事件只会监听加载项自身工作簿的工作表切换,对其他打开的普通工作簿完全无效,所以切换其他工作簿的工作表时,LstSht根本不会被赋值,自然会出现对象未定义的错误。
修复方案:使用Application级全局事件监听
要实现对所有打开工作簿的工作表切换监控,必须用Application级别的事件。以下是完整实现步骤:
1. 创建类模块捕获全局事件
- 打开加载项的VBA编辑器,右键点击项目→插入→类模块,将类模块命名为
clsAppEvents - 在类模块中写入以下代码:
Private WithEvents App As Application Private LastSheets As New Collection ' 存储每个工作簿对应的最后激活工作表 Private Sub Class_Initialize() Set App = Application End Sub Private Sub App_SheetDeactivate(ByVal Sh As Object) ' 用工作簿完整路径作为唯一标识,避免不同工作簿冲突 Dim wbUniqueKey As String wbUniqueKey = Sh.Parent.FullName ' 先移除旧记录,再添加新的最后激活工作表 On Error Resume Next LastSheets.Remove wbUniqueKey On Error GoTo 0 LastSheets.Add Sh, wbUniqueKey End Sub ' 对外提供获取当前工作簿最后激活工作表的方法 Public Function GetLastSheet(targetWb As Workbook) As Worksheet On Error Resume Next Set GetLastSheet = LastSheets(targetWb.FullName) On Error GoTo 0 End Function
2. 修改通用模块代码
在你的通用模块中替换原有代码为:
Global AppEvents As clsAppEvents ' 加载项启动时初始化全局事件监听 Sub Auto_Open() Set AppEvents = New clsAppEvents End Sub Sub Sht_tab() Dim currentWb As Workbook Set currentWb = ActiveWorkbook If ActiveSheet.Index = 1 Then Dim lastActivatedSht As Worksheet Set lastActivatedSht = AppEvents.GetLastSheet(currentWb) ' 确保存在有效记录,防止报错 If Not lastActivatedSht Is Nothing Then lastActivatedSht.Activate Else MsgBox "无可用的上一个工作表记录" End If Else currentWb.Sheets(1).Activate End If End Sub
3. 设置快捷键
- 打开Excel,点击「开发工具」选项卡→「宏」
- 在宏列表中找到
Sht_tab,点击「选项」 - 在弹出的窗口中设置快捷键(例如
Ctrl+Shift+T),点击确定即可
关键改进点
- 用Application级事件监听所有工作簿的工作表切换,不再局限于加载项自身
- 用集合存储每个工作簿的最后激活工作表,避免不同工作簿之间的记录冲突
- 增加了空值判断,防止因无记录导致的运行时错误
内容的提问来源于stack exchange,提问作者Duckbae
相关产品推荐
相关产品推荐

