2016-08-20 280 views
0

我正在开发一个项目,以最大限度地减少任何时候在Excel工作簿中可见的工作表数量。我正在尝试创建一个父表(用作切换按钮)来显示/隐藏子表。例如,我在工作簿中有6个工作表:输入,输入1和输入2,输出,输出1 &输出2.输入和输出将激活时切换隐藏并取消隐藏其他工作表。我创建了2个工作表级别的子函数来尝试并执行此操作。第一个很好,但另一个只有在第一个被激活并再次隐藏时才有效。任何建议,更好的方式来做到这一点会很好。我不知道为什么excel已经没有这个功能。我尝试使用数组,但这似乎不起作用。我认为你需要单独取消隐藏每个标签。Excel VBA工作表事件在隐藏/取消隐藏之间切换

'1. Inputs: 

Private Sub Worksheet_Activate() 

On Error Resume Next 
Sheets("Input 1").Visible = True = Not Sheets("Input 1").Visible = True 
Sheets("Input 2").Visible = True = Not Sheets("Input 2").Visible = True 
Sheets("Input 1").Activate 'needed to deactivate inputs sheet 

End Sub 

'2. Outputs 

Private Sub Worksheet_Activate() 

On Error Resume Next 
Sheets("Output 1").Visible = True = Not Sheets("Output 1").Visible = True 
Sheets("Output 2").Visible = True = Not Sheets("Output 2").Visible = True 
Sheets("Output 1").Activate 'needed to deactivate Outputs sheet 

End Sub 
+0

显然,您正在使用'Worksheet_Activate()'事件来显示或隐藏工作表。但是,此外,您正在使用此事件**激活**另一张表。通过这样做,您(递归)激活该表单的事件'Worksheet_Activate()'。如果Worksheet_Activate()中的表单上还有代码,那么它也会被激活(依此类推)。因此,在激活此代码中的工作表之前,您可能需要添加'Application.EnableEvents = False'。一旦另一张纸被激活,您可以重新启用它:'Application.EnableEvents = True'。 – Ralph

+0

你的实际目标是什么?哪些表应该是可见/隐藏的,什么时候? – user3598756

+0

嗨拉尔夫,我给了它一个去,但它似乎没有工作。第一个标签“输入”继续工作,但第二个“输出”仍然没有。 –

回答

0

按照user3598756,这个问题可能需要一些澄清,但它听起来像你试图仿效类似这样的行为:

Action    Visible Worksheet 
------    ----------------- 
Open Workbook  [Input], [Output] 
Activate [Input] [Input], [Output], [Input1], [Input2] ' (shows InputX) 
Activate [Input1] [Input], [Output], [Input1], [Input2] ' (no change) 
Activate [Output] [Input], [Output], [Output1], [Output2] ' (hides InputX, shows OutputX) 

这使得[Input][Output]你唯一的网关工作表,所以以下[Input](以及[Output]的逆向)将实现此目的。

Private Sub Worksheet_Activate() 
    Sheets("Input 1").Visible = True 
    Sheets("Input 2").Visible = True 
    Sheets("Output 1").Visible = False 
    Sheets("Output 2").Visible = False 
End Sub 

注意事项使用On Error Resume Next除非你有特殊原因,

  1. 避免。如果你的代码有什么错误,你的代码就会停下来,这样做通常是件好事,而不是把它的小秘密保留在自己身上,而让你更聪明。

  2. .Visible属性本身是Boolean,所以条件.Visible = True等于仅使用.Visible本身。您的.Visible声明可能不会解决您的意图。每一行中只有一个=将为分配运算符,其他将为等于检查。在没有括号的情况下,这将是你的第一个=,而其他的=将一步一步地等于检查从右到左工作。这是运营商优先在工作。凡我所相信的目的是

    Sheets("Input 1").Visible = True = Not Sheets("Input 1").Visible = True 
    Sheets("Input 1").Visible = True = Not     <True> = True 
    Sheets("Input 1").Visible = True = Not      <True> 
    Sheets("Input 1").Visible = True = <False> 
    Sheets("Input 1").Visible = <False> 
    

关于最后一点,说片输入1是可见的,你的第一行会解决

Sheets("Input 1").Visible = Not Sheets("Input 1").Visible ' i.e. toggle my visibility 

这些事情可能很难与布尔变量相提并论,因为即使您的逻辑错误,结果可能是“一半”的时间。

+0

感谢您的回复。这会起作用,但随着我的工作表变得更加复杂,即我有第三个“网关”(如进程),我需要添加所有不希望看到的工作表。我宁愿只从“父”工作表管理这个,并将其作为一个切换按钮。另一个原因是,如果有15个左右不同的输入,我将无法在不滚动的情况下看到输出选项卡。它是一个很好的替代解决方案。你会如何将我的论点放在括号内? –

+0

我明白了为什么你重新激活非父母表单。如果您的问题之一是维护代码无处不在,也许您可​​以在工作簿本身的单个“Workbook_SheetActivate”事件上统一所有“父”工作表的所有功能? (我会更新答案以展开'='事物)。 – Jon

+0

我想出了一个可行的解决方案。见下面 –

0

我已经设法完成了这项工作。当“Input 1”工作表被激活和隐藏时,尝试使用“Outputs”Private Sub Worksheet_Activate()函数时遇到了问题。我添加了另一个名为“Main”的选项卡来替换此选项卡,因此在功能激活后,“Main”将始终为活动选项卡。这样可以解决这个问题,但如果在浏览每个“文件夹”中的内容时,重点不会围绕工作簿跳过,那将会更好。这里是更新的代码...

'Inputs "Parent folder" sheet 
Private Sub Worksheet_Activate() 


On Error Resume Next 
Sheets("Input 1").Visible = True = Not Sheets("Input 1").Visible = True 
Sheets("Input 2").Visible = True = Not Sheets("Input 2").Visible = True 
**Sheets("Main").Activate** 'needed to deactivate Inputs sheet 


End Sub 

'Outputs "Parent folder" sheet 
Private Sub Worksheet_Activate() 


On Error Resume Next 
Sheets("Output 1").Visible = True = Not Sheets("Output 1").Visible = True 
Sheets("Output 2").Visible = True = Not Sheets("Output 2").Visible = True 
**Sheets("Main").Activate** 'needed to deactivate Outputs sheet 


End Sub 

我认为这是一个很好的方式来简化带有可能标签的工作簿。它可以明显改进,所以期待听到任何建议。

这里是我的工作文件的链接

https://1drv.ms/x/s!AvtNNMCst1bIgxjCBCemZlCerHMo

0

下面就以一个文件的链接,你可以从onedrive下载:

https://1drv.ms/x/s!Ah_zTnaUo4DzjhWzQ3OTq9tq1APC

而非硬代码应该发生什么当选择每个工作表时,我在“控件”工作表上使用了一个ListObject(即Excel表)来存储“父”工作表与其各个“子”之间的关系。代码简单地检查这个ListObject,看看哪些孩子属于哪个父母,然后相应地采取行动。这有助于让不理解VBA的人轻松添加或修改需要的父/子表单关系,从而使其变得非常容易。

我也实现了一个'开发人员'模式,其中表单隐藏不会发生。没有什么比试图在仅将'用户'视为'用户'的应用程序上进行开发更令人沮丧的了:您可以使用键盘快捷键Ctrl + Shift + D(D for Developer)在“用户”和“开发者”模式之间切换)。

下面是我刚才放在一起的示例文件的外观。我已经添加了如下所示为一个名为“控件”的新表中的ListObject,并给予的ListObject“VisibleSheets”的名字: Controls

我还添加了名为DeveloperMode命名区域,与真值: Name Manager

下面是切换“用户”模式和“开发者”模式的应用程序的代码,即进入在标准代码模块:

Public Sub ToggleDeveloperMode() 
    Dim ws As Worksheet 

    If ActiveWorkbook.Names("DeveloperMode").Value = "=TRUE" Then 
     ActiveWorkbook.Names("DeveloperMode").Value = "=FALSE" 
    Else 
     ActiveWorkbook.Names("DeveloperMode").Value = "=TRUE" 
     For Each ws In ActiveWorkbook.Worksheets 
      ws.Visible = xlSheetVisible 
     Next ws 
    End If 

End Sub 

下面是实际执行所有的藏身代码,取消隐藏,这也是一个标准RD代码模块:

Sub DisplaySheets() 
    Dim ws As Worksheet 
    Dim lo As ListObject 
    Dim lc As ListColumn 
    Dim vMatch As Variant 

    Set lo = Range("VisibleSheets").ListObject 

    If Not [DeveloperMode] Then 
     For Each lc In lo.ListColumns 
      If lc.Name = ActiveSheet.Name Then 
       For Each ws In ActiveWorkbook.Worksheets 
        Set vMatch = Nothing 'Reset from last pass 
        vMatch = Application.Match(ws.Name, lo.HeaderRowRange, 0) 
        If IsError(vMatch) Then 'It's not one of our main sheets 
         Set vMatch = Nothing 'Reset from last pass 
         vMatch = Application.Match(ws.Name, lc.Range, 0) 
         If IsError(vMatch) Then 
          ws.Visible = xlSheetVeryHidden 
         Else 
          ws.Visible = xlSheetVisible 
         End If 
        End If 
       Next ws 
      End If 
     Next lc 
    End If 
End Sub 

这里的代码片段去指派按Ctrl +的键盘快捷键放在ThisWorkbook模块中按住Shift + d到ToggleDeveloperMode程序,让您可以轻松地模式之间进行切换。 (不要告诉用户该键盘快捷键是什么):

Private Sub Workbook_Open() 
Application.OnKey "^+D", "ToggleDeveloperMode" 
End Sub 

最后,这里的代码触发DisplaySheets程序,也去了的ThisWorkbook模块中:

Private Sub Workbook_SheetActivate(ByVal Sh As Object) 
    DisplaySheets 
End Sub 

它的工作原理一种享受。这是我看到的时候我又选择各3个父表: Inputs

Outputs

Throughputs

...这是会发生什么,当我使用Ctrl + Shift + d的快捷方式将应用程序置于'开发者'模式,所有表单都被隐藏,包括其上的控件。 Controls

我建议给父母标签与我在这里相同的颜色,以便用户更容易理解他们不会改变,无论有选择地出现/消失的其他标签。

如果有可能用户(或您)想要重命名工作表,请使用代号而不是工作表名称。如果你不确定我在说什么,请告诉我。

+0

感谢您的答案。我快速浏览了一下,但无法在我的Mac上运行。由于我主要在工作中使用excel,所以在这里我不太熟悉它,这是我的错。明天下班后我会看看。欢呼关于添加文件的提示。我编辑了我的答案,包括一个链接到我的工作文件。它工作正常,虽然需要通过代码手动添加页面,并且一旦打开/关闭“文件夹”,它将始终恢复为“主”页面。然而,我更担心的是,如果表单被隐藏,但是还没有进行测试和实现,一些旧的宏不起作用。感谢你的回应。 –

+0

我刚刚从onedrive上重新下载了它,它似乎没有像原来那样工作,所以它可能是一个onedrive问题。 –