如何通过Excel VBA中的复制/粘贴捕获工作表

我正试图捕获从另一个工作簿复制到工作簿的工作表。
从其他工作簿复制工作表时,不会触发Workbook_NewSheet事件。 仅当用户手动插入(Insert-> Worksheet菜单选项),或者当您通过VBA将新工作表添加为ThisWorkbook.Worksheets.Add时,才会触发它。

我试图捕获的基本上是一个粘贴操作,导致一个新的工作表。

这可能来自任何下面的用户操作:

  1. 用户通过拖动控制键(添加新工作表)来复制现有工作表
  2. 用户从另一个工作簿中复制工作表
  3. 用户从另一个工作簿移动工作表

或任何下面的VBA代码:

 SourceWorkbook.Sheets(“SourceSheet”).Copy Before:=TargetWorkbook.worksheets(“SheetNameIn Target”) 'copy across workbook' SourceWorkbook.Sheets(“SourceSheet”).Move Before:=TargetWorkbook.worksheets(“SheetNameIn Target”) 'move across workbook' ThisWorkbook. Sheets(“SheetName”).Copy 'copy within workbook' 

如果你知道在VBA中捕获这个动作/macros结果的任何方法,这将是非常有帮助的。

请注意,我不想避免这样的用户操作(所以我不想保护工作簿),但是我想要以编程方式处理粘贴的工作表来validation数据,并且如果类似工作表已经存在,那么更新现有工作表而不是在两张相同的数据。

SheetActivate事件将在所有这些情况下触发。 显然它也会在很多其他的情况下发生。 这听起来像一个皇家的痛苦,但你可以维护自己的工作表集合,并将您的collections集与ThisWorkbook.Sheets集合进行比较,以查看是否添加/删除了某些内容。

如果你试图阻止它,你可能会考虑保护工作簿结构,而不是在代码中进行。

复印纸时,其名称始终以“(2)”或至less“)”结尾。 你可以这样检查

 Private Sub Workbook_SheetActivate(ByVal Sh As Object) If Sh.Name Like "*(2)" Then Application.DisplayAlerts = False Sh.Delete Application.DisplayAlerts = True End If End Sub 

我所拥有的方式是

 Private Sub Workbook_WindowActivate(ByVal Wn As Window) ToggleMenuOptions False, 848, 889 End Sub Private Sub Workbook_WindowDeactivate(ByVal Wn As Window) ToggleMenuOptions True, 847, 848, 889 End Sub Public Function ToggleMenuOptions(bToggle As Boolean, ParamArray ControlID() As Variant) As Boolean '848 Move or Copy Sheet... '889 Rename Sheet '847 Delete Sheet On Error GoTo lblError Dim oControl As CommandBarControl, oControls As CommandBarControls, iControl As Integer If IsMissing(ControlID) Then ToggleMenuOptions = False Exit Function End If For iControl = LBound(ControlID) To UBound(ControlID) For Each oControl In Application.CommandBars.FindControls(ID:=ControlID(iControl)) oControl.Enabled = bToggle Next Next ToggleMenuOptions = True Exit Function lblError: If Err.Number Then ToggleMenuOptions = False Exit Function End If End Function Private Sub Workbook_NewSheet(ByVal Sh As Object) MsgBox "Please use Add New Project option in custom Toolbar to add new sheets!!", vbExclamation, "Not Supported" Application.DisplayAlerts = False Sh.Delete Application.DisplayAlerts = True End Sub 

所以我的用户将无法重新命名,添加或删除工作表。 目前这工作很好。

唯一可以这样做的方法是不用维护单独的图纸集合,而是维护一个静态的图表名称(或图纸代号名称)数组,并在每次触发SheetActivate事件检测添加时将其与工作簿中的实际图纸进行比较。 如果您不希望/不能将列表保留在数组中,则可以始终使用隐藏工作表来存储列表。 这是否比维护一个单独的集合更多或更less的是值得商榷的:)

我正在做类似的事情,但不能阻止任何用户菜单操作。 我有床单,其types是重要的 – 每个床单要么是主人或从属 – 每个主表单总结其下的奴隶床单,我需要保持这些公式清洁。

我不是在一张额外的隐藏纸张中保留一张纸张清单,而是在每张纸上定义2个隐藏名称,logging纸张索引到其链接的主纸张的偏移量,以及对链接的主纸张的引用。 因此,如果我的工作表是从其母表(例如)+2个选项卡,然后在表激活/停用(不知道哪些这是最好跟踪在这个阶段),如果有任何插入,删除或移动此偏移量已经改变。 这涵盖了移动或复印纸张所引起的大部分或全部事件。

如果工作表已被移动,则循环浏览工作簿并为每个工作表计算新的主/从索引参考。

当我得到这个相当稳定的代码时,会发布代码,但这似乎是一个可以在各种情况下工作的scheme。