首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不循环地隐藏或取消隐藏所有Excel工作表

不循环地隐藏或取消隐藏所有Excel工作表
EN

Stack Overflow用户
提问于 2017-10-25 21:49:46
回答 5查看 4.6K关注 0票数 2

我有一本有179张工作表的工作簿。我想要么隐藏所有工作表(根据Excel规则保留一个未隐藏的工作表),要么取消隐藏所有工作表。

目前,我有如下代码(根据我们是否隐藏/取消隐藏表进行了适当的修改):

代码语言:javascript
复制
For Each Sht in Wb.Worksheets
    Sht.Visible = xlSheetVisible
Next Sht

有179个工作表,运行时间为4-5秒,我更希望它运行得更快。

我知道,如果我进入一个工作簿,手动选择所有的工作表(除了一个),然后右击并选择"Hide",所有的工作表都会立即被隐藏。我无法在VBA代码中再现这一点。

如前所述,我需要在工作簿中快速隐藏所有工作表(只有一个工作表除外),并在没有循环的情况下将所有工作表隐藏在工作簿中。任何帮助都是非常感谢的!

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-10-26 03:49:43

如前所述,您只能在没有循环的情况下隐藏多个工作表,如下所示:

代码语言:javascript
复制
Worksheets(Array(1,2,3,4,5,6,7,8,9,10,11,...,200)).Visible = True

但是,取消隐藏多个工作表需要循环。

但是,有一个更快的方法可用于此,使用自定义视图(在视图选项卡中)

下面的代码生成两个视图1。“所有的表演”,和2。“所有的人”

性能方面:

代码语言:javascript
复制
For 201 Worksheets

Loop HideAll - Time: 0.039 sec (initial setup - sets array, except one Ws in one operation)
Loop ShowAll - Time: 0.648 sec (initial setup - unhides all using a loop)

View ShowAll - Time: 0.023 sec (consecutive runs - no loop)
View HideAll - Time: 0.023 sec (consecutive runs - no loop)
代码语言:javascript
复制
Option Explicit

Public Sub SetWsVisibility(Optional ByVal vis As Boolean = False, _
                           Optional ByVal visibleWs As Long = 0)

    Static vSet As Boolean, hSet As Boolean, wsCount As Long, lastV As Long, i As Long

    With ThisWorkbook

        wsCount = .Worksheets.Count - 1

        'if visibleWs is 0 last ws is visible, or use any other valid sheet index
        visibleWs = IIf(visibleWs < 1 Or visibleWs > wsCount, wsCount + 1, visibleWs)

        If wsCount <> .Worksheets.Count - 1 Or visibleWs <> lastV Then
            vSet = False
            hSet = False
        Else
            If vSet And vis Then .CustomViews("ShowAllWs").Show:        Exit Sub
            If hSet And Not vis Then .CustomViews("HideAllWs").Show:    Exit Sub
        End If

        Application.ScreenUpdating = False
        If vis Then
            For i = 1 To wsCount + 1
                With .Worksheets(i)
                    If Not .Visible Then .Visible = vis
                End With
            Next
            .Worksheets(1).Activate
            .CustomViews.Add ViewName:="ShowAllWs"  'Save View (one-time operation)
            vSet = True
        Else
            If visibleWs <> lastV Then
                For i = 1 To wsCount + 1
                    With .Worksheets(i)
                        If Not .Visible Then .Visible = 1
                    End With
                Next
            End If

            Dim arr() As Variant, j As Long
            ReDim arr(1 To wsCount)
            j = 1
            For i = 1 To wsCount + 1
                If i <> visibleWs Then arr(j) = i Else j = j - 1
                j = j + 1
            Next
            .Worksheets(arr).Visible = vis
            .CustomViews.Add ViewName:="HideAllWs"  'Save View (one-time operation)
            hSet = True
            lastV = visibleWs
        End If
        Application.ScreenUpdating = True
    End With
End Sub

要调用它,请使用以下命令:

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

    SetWsVisibility 0, 5    'or 0 to hide them (or True / False respectively)

End Sub
票数 3
EN

Stack Overflow用户

发布于 2017-10-25 22:58:36

假设您的工作簿不受保护,这里有一个子程序可以完成不需要系统循环的工作。支持图表类型工作表。

我刚刚了解到,通过数组引用工作表只有在它们都是可见的情况下才能工作,因此在使工作表可见时需要一个循环。

代码语言:javascript
复制
'Hides all sheets in the workbook containing pExceptThisSheet, except pExceptThisSheet.
'Note: pExceptThisSheet is declared as an Object so as to support both the Worksheet and Chart types.
Public Sub HideAllSheetsBut(ByVal pExceptThisSheet As Object)
    On Error GoTo errHandler

    Dim vntAllSheetsBut() As Variant
    Dim oSht As Object
    Dim lIndex As Long
    Dim bScreenUpdating As Boolean

    bScreenUpdating = Application.ScreenUpdating
    Application.ScreenUpdating = False

    'Show all sheets.
    'Note: for some reason, an array can't be used here; must loop.
    For Each oSht In pExceptThisSheet.Parent.Sheets
        If oSht.Visible <> xlSheetVisible Then
            oSht.Visible = xlSheetVisible
        End If
    Next

    If Not pExceptThisSheet Is Nothing Then
        If pExceptThisSheet.Parent.Sheets.Count > 1 Then        
            'Hide all sheets but the specified one.        
            ReDim vntAllSheetsBut(0 To pExceptThisSheet.Parent.Sheets.Count - 2) As Variant

            lIndex = 0
            For Each oSht In pExceptThisSheet.Parent.Sheets
                If Not oSht Is pExceptThisSheet Then
                    vntAllSheetsBut(lIndex) = oSht.Name
                    lIndex = lIndex + 1
                End If
            Next
            'Note: for some reason, this only works for hiding, and if all sheets in vntAllSheetsBut are visible.
            'A possible explanation would be that, behind the scene, Excel attempts to select the sheets, and fails when it encounters hidden ones.
            pExceptThisSheet.Parent.Sheets(vntAllSheetsBut).Visible = xlSheetHidden
        End If
    End If

Cleanup:
    On Error Resume Next
    Set oSht = Nothing
    Application.ScreenUpdating = bScreenUpdating
    Exit Sub

errHandler:
    MsgBox Err.Description, vbExclamation + vbOKOnly, "Error"
    Resume Cleanup
End Sub

你可以这样称呼潜艇:

代码语言:javascript
复制
HideAllSheetsBut Sheet1

代码语言:javascript
复制
HideAllSheetsBut Application.Workbooks("MyWorkbook.xlsx").Worksheets("MyWorksheet")

隐藏除一个工作表之外的所有内容,如下所示:

代码语言:javascript
复制
HideAllSheetsBut Nothing

展示所有床单。

正如paul的答案中提到的,编辑是快速翻转几个工作表的可见性的一个很好的方法。在我的回答中,它将用于显示所有工作表,而不必遍历它们。

票数 2
EN

Stack Overflow用户

发布于 2017-10-25 22:00:42

不妨试试这个:

代码语言:javascript
复制
Application.ScreenUpdating = False

For Each Sht in Wb.Worksheets
    If Sht.Visible = xlSheetHidden Then
        Sht.Visible = xlSheetVisible
    End If
Next Sht

Application.ScreenUpdating = True
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46942603

复制
相关文章

相似问题

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