Worksheet_Activate新表的代码

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

我有几个表单设置。

主| | Worksheet1 | 工作表2 | 注意| 工作订单| 联系信息

1)我在Notes,工作订单,联系信息上设置了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)现在,当我导航到不同的工作表(如Master)时,我希望额外的窗口closures,并且主表工作表处于活动状态。 我在主表上使用下面的代码。

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

这个代码的问题是,如果额外的窗口没有打开,那么它会出错。 我可以做一些逻辑检查来使这个工作? 我不知道要检查什么值

3)最后一个问题是工作簿中的macros由dynamic生成了新的工作表。 这些新的工作表将不会携带上面的closures多个窗口的代码,并关注活动页面。 有一个不同的对象,我应该把代码,以便适用于主| Worksheet1 | 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 

然后插入一个标准模块(插入 – 模块)并粘贴这个代码

 Option Explicit Public gclsAppEvents As CAppEvents Sub Auto_Open() Set gclsAppEvents = New CAppEvents Set gclsAppEvents.wb = ThisWorkbook End Sub 

以下是发生了什么事情:打开工作簿时,Auto_Open将运行,并将创build一个新的CAppEvents对象实例。 由于gclsAppEvents是公共的(又名全局的),只要工作簿处于打开状态,它就不会丢失范围。 它将坐在那里监听事件(因为我们在课堂上使用了WithEvents关键字)。

在这个类中有一个叫做mobjWb_SheetActivate的子类。 这是什么将激活此工作簿中的任何工作表激活。 首先检查你刚刚激活的工作表(Shvariables)是否是你想分割的工作表(使用IsSplitSheet)。 如果是,它会检查是否已经被拆分。 如果不是的话,它会分裂它们。

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

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

因为我们正在使用自定义类并在工作簿级别嗅探事件,所以您可以添加和删除表单。

1)要testing一个窗口是否已经打开,使用这个函数

 Function IsWindowOpen(windowTitle As String) As Boolean Dim i As Long For i = 1 To Windows.Count If Windows(i).Caption = windowTitle Then IsWindowOpen = True Exit Function End If Next IsWindowOpen = False End Function 

例如:

 if not IsWindowOpen("Mastersheet.xlsm:2") then ' code to open windows end if 

2)你可以再次使用这个函数,同样的想法:

 if IsWindowOpen("Mastersheet.xlsm:2") then ' code to close windows end if 

3)将你的代码添加到模块,而不是表单。 然后从macros中调用例程,在完成此操作后添加新的工作表。 如果这个macros是在不同的模块,你可能需要确保你的Sub是公开的。