首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在VBA中手动触发工作表的激活事件?

问如何在VBA中手动触发工作表的激活事件?
EN

Stack Overflow用户
提问于 2021-11-08 12:23:11
回答 2查看 254关注 0票数 1

我有一张工作表,上面有:

代码语言:javascript
复制
Private Sub Worksheet_Activate()
    MsgBox "Ran"
End Sub

我做的工具栏上有一个按钮。我想要做的是在当前选择的WorkSheet上触发此方法。

我想我可以执行Call ActiveWorksheet.Activate或Call Worksheet.Activate,但是虽然它们似乎没有错误地执行,但是方法不会被调用。

作为一种解决方法,我考虑了添加一个公共DoActivate方法,但它似乎有点蹩脚,我可能不得不使用CallByName来实现它(开发人员必须记住在每个工作表上实现这个方法)。

为什么我的激活方法没有通过上面的代码手动调用,或者有一个合适的解决方法来获得我正在寻找的东西呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-11-08 12:26:58

将代码移动到一个名为OnActivate的新Sub中

代码语言:javascript
复制
Private Sub Worksheet_Activate()
    OnActivate
End Sub

Private Sub OnActivate() 'or Public if you call from another module
    MsgBox "Ran"
End Sub

Worksheet_Activate()事件处理程序可以通过Worksheet_Activate从模块内部手动调用,就像其他子模块一样(尽管这不是一个很好的方法)。

如果您想确保所有工作表都有相同的方法,那么您可以让它们实现一个接口。

类模块:IActivateHandler

代码语言:javascript
复制
Public Sub OnActivate()
End Sub

然后在Sheet1,2,3等:

代码语言:javascript
复制
Implements IActivateHandler

Private Sub IActivateHandler_OnActivate()
    MeOnActivate
End Sub

Private Sub Worksheet_Activate()
    MeOnActivate
End Sub

Private Sub MeOnActivate() 
    MsgBox "Ran"
End Sub

还有按钮:

代码语言:javascript
复制
Private Sub Button1_Click()
    Dim sheetToCall As IActivateHandler
    ' Debug.Assert TypeOf ActiveSheet Is IActivateHandler
    Set sheetToCall = ActiveSheet 'gets the IActivateHandler of the sheet, ensuring it is defined. Will error if it isn't
    sheetToCall.OnActivate 'runs the IActivateHandler_OnActivate() method of sheet1
End Sub
票数 1
EN

Stack Overflow用户

发布于 2021-11-08 12:46:03

您可以这样调用任何活动表的激活事件(而不知道其名称):

在ThisWorkbook代码模块中创建下一个事件。或者,简单地复制以下代码。请注意,这样的事件并不存在:

代码语言:javascript
复制
Public Sub Workbook_SheetActivate(ByVal Sh As Object)
    MsgBox Sh.Name & " activated..."
    'the necessary code here...
End Sub

然后,以下一种方式从标准模块调用它:

代码语言:javascript
复制
ThisWorkbook.Workbook_SheetActivate ActiveSheet

如果要排除某些工作表,可以修改事件代码来执行此操作:

代码语言:javascript
复制
If sh.Name <> "MySheetName" then
    MsgBox Sh.Name & " activated..."
    'the necessary code here...
End if

如果应该排除多个工作表,则应该构建一个工作表名称数组,并使用Application.Match来区分要使用它们的事件的工作表和其他的工作表。

编辑的

如果需要在外接程序(或任何已启用宏的工作簿)中编写一段代码,可以在任何(其他)打开的工作簿中捕获工作表的事件,则应以下一种方式进行:

  1. 在外接程序ThisWorkbook代码模块的顶部复制下一个声明(在声明区域):

代码语言:javascript
复制
Public WithEvents appEvHandler As Application

  1. 在同一个代码模块中,复制下一个代码:

代码语言:javascript
复制
Private Sub appEvHandler_SheetActivate(ByVal sh As Object)
     If sh.Parent.Name <> ThisWorkbook.Name Then
        MsgBox sh.Parent.Name & " workbook, sheet " & sh.Name & " activated..."
    Else
       Debug.Print "changed in this workbook..."
   End If
End Sub

  1. 也复制下一个Sub,它将激活事件:

代码语言:javascript
复制
Sub activateAppEvHandler() 
    Set appEvHandler = Application 'It can be placed in `Workbook_Open` event to be run when workbook opens
End Sub

如果您想禁用它(出于某种原因.),请使用下一个Sub

代码语言:javascript
复制
Sub InactivateAppEvHandler() 
    Set appEvHandler = Nothing
End Sub

请测试并发送一些反馈。我必须承认,我不确定我是否正确地理解了你的需要。我想要一个场景,但我试着想象这是你想要的.

代码语言:javascript
复制
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69883396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档