3

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

我试图捕捉的基本上是一个粘贴操作,它会产生一个新的工作表。

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

  1. 用户通过按住 Control 键拖动现有工作表(添加新工作表)来复制现有工作表
  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 中捕获此动作/宏结果的任何方法,那将非常有帮助。

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

4

5 回答 5

3

复制工作表时,其名称将始终以“(2)”结尾,或者至少以“)”结尾。你可以像这样检查

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
于 2012-02-15T09:58:29.587 回答
2

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

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

于 2009-04-06T19:14:35.283 回答
1

我暗示它的方式是

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

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

于 2010-05-28T20:32:15.533 回答
0

在不维护单独的工作表集合的情况下,我能想到的唯一方法是维护工作表名称(或工作表代号)的静态数组,并在每次触发 SheetActivate 事件以检测任何添加时将其与工作簿中的实际工作表进行比较。如果您不想/不能将列表保存在数组中,您始终可以使用隐藏表来存储列表。这是否比维护单独的集合更痛苦还是有争议的:)

于 2013-02-13T16:59:46.027 回答
0

我正在做类似的事情,但不能阻止任何用户菜单操作。我有类型很重要的工作表——每张工作表要么是主工作表,要么是从工作表 - 每个主工作表总和在它下面的从工作表上,我需要保持这些公式的清洁。

我不是在额外的隐藏工作表中维护工作表列表,而是在每张工作表上定义 2 个隐藏名称,记录工作表索引与其链接的主工作表的偏移量,以及对链接的主工作表的引用。因此,如果我的工作表是(比如说)其主工作表中的 +2 个选项卡,那么在工作表上激活/停用(不确定在此阶段哪个更好跟踪)如果有任何内容被插入、删除或移动,这个偏移量将会改变。这涵盖了移动或复制工作表可能引起的大部分或所有事件。

如果工作表已被移动,我会循环浏览工作簿并为每张工作表计算新的主/从索引引用。

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

于 2016-04-05T07:09:21.077 回答