我的VBA代码经常替换工作簿中的工作表。因此,我无法直接在工作表模块中使用代码,因为它最终会在此过程中被删除。
我使用用户定义的类来处理我的事件(强烈启发来自Chip Pearson's withevents article)
Public WithEvents ws As Worksheet
Private Sub ws_Activate()
If ActiveSheet.Name = FREEBOM_SHEET_NAME Then
Call FREEBOM_Worksheet_Activate_Handler
End If 'ActiveSheet.Name = FREEBOM_SHEET_NAME
End Sub
Private Sub ws_Change(ByVal Target As Range)
'MsgBox Target.Parent.Name
If Target.Parent.Name = FREEBOM_SHEET_NAME Then
Call FREEBOM_Worksheet_Change_Handler(Target)
End If 'Target.Parent.Name = FREEBOM_SHEET_NAME
If Target.Parent.Name = BOM_SHEET_NAME Then
Call BOM_Worksheet_Change_Handler(Target)
End If 'Target.Parent.Name = BOM_SHEET_NAME
End Sub
在打开工作簿时实例化该类。
Private Sub Workbook_Open()
Dim WSObj_FreeBOM As FreeBOM_CWorkSheetEventHandler
Dim WSObj_BOM As FreeBOM_CWorkSheetEventHandler
If Freebom_EventCollection Is Nothing Then
Set Freebom_EventCollection = New Collection
End If
Set WSObj_FreeBOM = New FreeBOM_CWorkSheetEventHandler
Set WSObj_FreeBOM.ws = Sheets(FREEBOM_SHEET_NAME)
Set WSObj_BOM = New FreeBOM_CWorkSheetEventHandler
Set WSObj_BOM.ws = Sheets(BOM_SHEET_NAME)
Freebom_EventCollection.Add Item:=WSObj_FreeBOM, Key:=Sheets(FREEBOM_SHEET_NAME).Name
Freebom_EventCollection.Add Item:=WSObj_BOM, Key:=Sheets(BOM_SHEET_NAME).Name
End Sub
在我阅读这个主题时,我看到将你的对象链接到一个公共集合(声明是在另一个模块中(普通模块 - 不是工作表模块而不是类模块)。:Public Freebom_EventCollection As Collection
会即使执行离开当前initianlization函数的范围,也要保持我的实例处于活动状态。
在大多数情况下,我只会引发一个ws_change事件。之后,工作表的行为就像我的代码中没有事件处理程序一样。没有任何东西被提出,而不仅仅是工作表事件。
我看了Application.EnableEvents
,但在第一次运行后总是设置为True
。
此外,当我在Private Sub Worksheet_Change(ByVal Target As Range)
函数中使用构建时,它运行良好。
对我而言,这可能与我使用一个类并且在第一次运行后它没有活着这一事实有关。但是,我不知道我做错了什么。
提前感谢您在这件事上的时间和帮助。
答案 0 :(得分:1)
您需要在普通模块(不是Worksheet模块而不是Class模块)中声明模块级别Collection的公共实例。您也可以将代码放在那里来管理集合,并且只需从工作表模块的事件处理程序中调用。删除工作表时,可能需要重新初始化集合,因为这可能会触发重新编译并重置项目,这将终止对象。
在标准模块中拥有集合后,您可以通过添加手表(VBE中的SHIFT-F9)来监控其生命周期。然后,您可以准确地跟踪正在发生的事情。