0

我发现 Siddharth Rout 的用于添加新工作表和代码的出色代码,但我的需要有点不同。

我想将激活代码添加到现有工作表。我尝试用该工作表名称代替使用该.Name属性,删除

Set ws = Worksheets.Add

并替换ws.Name为我现有的工作表名称“工作”。它在那个时候爆炸。

使用现有示例中的代码检查 ws 对象显示 ws 对象的属性 Name 是一个简单的字符串,因此无法使用我现有的工作表的名称代替让我感到困惑。

为什么:

现有工作表“工作”最初是在没有激活代码的情况下创建的。它在这个多页多功能系统中的许多步骤中被大量使用,如果用户手动选择它,我想防止用户更改它 - 有理由让他在暂停交互期间查看它,做出决定 - - 但当我的 VBA 往返于它之间时,让它不受保护。

所以,我想插入保护工作表的激活代码——取消保护的停用代码可以是工作表的永久部分,不会造成伤害——因此,只要用户决定手动查看工作表,就可以保护工作表,每当我的 VBA 允许用户交互时,然后在用户离开工作表并返回交互时通过其 Deactivate 删除/更改该代码,因此它通常可以免费供我的代码使用,否则每次我的代码切换到它时都不会添加保护.

我将创建并永久保留 Unprotect deactivate 代码 - 不会造成伤害 - 所以它不会改变自己(这是一个可怕的禁忌)。如何?

对不起所有的话。我在 VBA 中用谷歌搜索“自我修改代码”的时间没有找到好的答案。

4

1 回答 1

1

如果您只想暂时捕获另一个工作表上的事件,则可以使用类模块。如果您想将代码永久添加到工作表代码中,则需要使用@Sorceri 提到的 VBA 可扩展性内容。

使用类模块捕获工作簿的事件

在类模块中(名称:SheetEvent)

Public WithEvents Sheet As Worksheet

Public Sub Capture(ByVal Worksheet As Worksheet)
Set Sheet = Worksheet
End Sub

Private Sub Class_Terminate()
Set Sheet = Nothing
End Sub

Private Sub Sheet_Activate()
Debug.Print "Sheet_Activate Fired! (Sheet:" & Sheet.Name & ")"
End Sub

Private Sub Sheet_Change(ByVal Target As Range)
Debug.Print "Sheet_Activate Fired! (Sheet:" & Sheet.Name & " Target:" & Target.Address & ")"
End Sub

Private Sub Sheet_Deactivate()
Debug.Print "Sheet_Deactivate Fired! (Sheet:" & Sheet.Name & ")"
End Sub

在一个模块中:

Public S As SheetEvent

Sub Main()
Set S = New SheetEvent
S.Capture ThisWorkbook.Worksheets("Sheet1")

End Sub

此方法的问题在于,如果您的 VBA 出现错误或停止执行,您将需要重新启动它。

使用上面的示例,如果您运行Main()然后从 Sheet1 切换到 Sheet2 并返回,或者更改 Sheet1 中的任何单元格,您将在即时窗口中收到一条消息。

如果通过在工作表之间“弹跳”表示您正在激活工作表以读取(或设置一些单元格)然后重新激活前一个工作表,您可能会发现使用工作表对象更容易(更快)。

Dim Sheet1 As Worksheet
Dim Sheet2 As Worksheet

Set Sheet1 = ThisWorkbook.Worksheets("Sheet1")
Set Sheet2=  ThisWorkbook.Worksheets("Sheet2")

使用上面的代码,您可以通过这两个对象访问 sheet1 和 sheet2 中的数据。不必先激活任何一个(即使也隐藏了)

于 2013-04-15T22:24:56.720 回答