excel - Worksheet_新工作表的激活代码

标签 excel vba worksheet

我有三个关于 VBA 和控制/操作新窗口的问题。

我设置了几张表。

大师|工作表1 |工作表2 |笔记|工单 |联系方式

1) 我在注释、工单、联系信息上设置了 WorkSheet_Activate 函数,这些函数在单独的窗口中打开所有三个工作表并垂直排列它们。

Private Sub WorkSheet_Activate()

    ActiveWindow.NewWindow
    ActiveWindow.NewWindow
    Windows.Arrange ArrangeStyle:=xlVertical
    Sheets("Notes").Select
    Windows("Mastersheet.xlsm:2").Activate
    Sheets("Work Orders").Select
    Windows("Mastersheet.xlsm:1").Activate
    Sheets("Contact Info").Select

End Sub

它的问题是,如果我可以再次激活这些工作表,它将打开更多窗口。我希望代码能够检测窗口是否已经打开,如果打开则中断。

2) 现在,当我导航到不同的工作表(例如主工作表)时,我希望关闭额外的窗口并使主工作表处于事件状态。我在主表上使用了以下代码。

Private Sub WorkSheet_Activate()


    Windows("Mastersheet.xlsm:2").Activate
    ActiveWindow.Close
    Windows("Mastersheet.xlsm:1").Activate
    ActiveWindow.Close
    ActiveWindow.WindowState = xlMaximized

End Sub

此代码的问题是,如果未打开额外的窗口,则会出错。我可以进行某种逻辑检查以使其正常工作吗?我不知道要检查哪些值...

3) 最后一个问题是工作簿中的宏动态生成了新工作表。这些新工作表不会携带上述关闭多个窗口并专注于事件工作表的代码。是否有一个不同的对象我应该将代码放入其中,以便它适用于主|工作表1 | Worksheet2 工作表和任何新工作表吗?

最佳答案

有很多问题。 :) 对于 3,您需要将事件移出其所在位置并移至处理应用程序级事件的自定义类模块中。首先将一个新的类模块插入到您的项目中(插入 - 类模块)。将该模块命名为 CAppEvents(F4 显示属性表,您可以在其中更改名称)。然后将此代码粘贴到类模块中

Option Explicit

Private WithEvents mobjWb As Workbook

Private Sub Class_Terminate()

    Set mobjWb = Nothing

End Sub

Public Property Get wb() As Workbook

    Set wb = mobjWb

End Property

Public Property Set wb(objwb As Workbook)

    Set mobjWb = objwb

End Property

Private Sub mobjWb_SheetActivate(ByVal Sh As Object)

    Dim wn As Window

    If IsSplitSheet(Sh) Then
        If Not IsSplit(Sh) Then
            CreateSplitSheets Sh
        End If
    Else
        If IsSplit(Sh) Then
            For Each wn In Me.wb.Windows
                If wn.Caption Like Me.wb.Name & ":#" Then
                    wn.Close
                End If
            Next wn
            ActiveWindow.WindowState = xlMaximized
            Sh.Activate
        End If
    End If

End Sub

Private Function IsSplitSheet(Sh As Object) As Boolean

    Dim vaNames As Variant
    Dim i As Long

    IsSplitSheet = False
    vaNames = GetSplitSheetNames

    For i = LBound(vaNames) To UBound(vaNames)
        If vaNames(i) = Sh.Name Then
            IsSplitSheet = True
            Exit For
        End If
    Next i

End Function

Private Function IsSplit(Sh As Object) As Boolean

    Dim wn As Window

    IsSplit = False

    For Each wn In Me.wb.Windows
        If wn.Caption Like Sh.Parent.Name & ":#" Then
            IsSplit = True
            Exit For
        End If
    Next wn

End Function

Private Sub CreateSplitSheets(Sh As Object)

    Dim vaNames As Variant
    Dim i As Long
    Dim wn As Window
    Dim wnActive As Window

    vaNames = GetSplitSheetNames
    Set wnActive = ActiveWindow

    For i = LBound(vaNames) To UBound(vaNames)
        If vaNames(i) <> Sh.Name Then
            Set wn = Me.wb.NewWindow
            wn.Activate
            On Error Resume Next
                wn.Parent.Sheets(vaNames(i)).Activate
            On Error GoTo 0
        End If
    Next i

    Sh.Parent.Windows.Arrange xlVertical
    wnActive.Activate
    Sh.Activate

End Sub

Private Function GetSplitSheetNames() As Variant

    GetSplitSheetNames = Array("Notes", "Work Orders", "Contact Info")

End Function

然后插入一个标准模块(Insert - Module)并粘贴此代码

Option Explicit

Public gclsAppEvents As CAppEvents

Sub Auto_Open()

    Set gclsAppEvents = New CAppEvents
    Set gclsAppEvents.wb = ThisWorkbook

End Sub

发生的情况如下:当您打开工作簿时,Auto_Open 将运行,并且它将创建 CAppEvents 对象的新实例。由于 gclsAppEvents 是公共(public)的(也称为全局的),只要工作簿打开,它就不会失去范围。它将坐在那里监听事件(因为我们在类中使用了 WithEvents 关键字)。

该类中有一个名为 mobjWb_SheetActivate 的子组件。每当激活此工作簿中的任何工作表时都会触发此操作。首先,它检查您刚刚激活的工作表(Sh 变量)是否是您要拆分的工作表之一(使用 IsSplitSheet)。如果是,它就会检查它是否已经被分割。如果不是,它会将它们分开。

如果 Sh(您刚刚激活的工作表)不是“拆分工作表”之一,则它会检查是否已完成拆分 (IsSplit)。如果有,它将关闭所有拆分窗口。

如果您甚至想添加、更改或删除导致拆分的工作表,您可以转到 GetSplitSheetNames 函数并更改数组参数。

由于我们使用自定义类并在工作簿级别嗅探事件,因此您可以根据需要添加和删除工作表。

关于excel - Worksheet_新工作表的激活代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2113008/

相关文章:

excel - 如何判断 Excel 工作簿是否 protected

java - 无法从 java 代码运行宏

excel - 如何保存正在打开的文件?

excel - 函数更改工作表中的值

Excel VBA - 索引和匹配 VBA 错误

excel - 如何将范围从 Excel 复制到 Outlook,忽略适用过滤器的第一列?

excel - 基于单元格颜色逐行计算

vba - 如何通过枚举值来声明(初始化)一维和二维固定大小的数组?

variables - Snowflake使用变量来设置数据库和架构