在不循环的情况下隐藏或取消隐藏所有 Excel 个工作表
Hide or Unhide all Excel Sheets Without Looping
我有一个包含 179 个工作表的工作簿。我想隐藏所有工作表(根据 Excel 的规则不隐藏一个),或者取消隐藏所有工作表。
目前我的代码看起来像这样(根据我们是否是 hiding/unhiding 张进行适当的修改):
For Each Sht in Wb.Worksheets
Sht.Visible = xlSheetVisible
Next Sht
有 179 个工作表,这需要 4-5 秒才能 运行,我希望 运行 快得多。
我知道如果我进入一个工作簿,手动 select 所有工作表(一张除外),然后右键单击并 select "Hide"
,所有工作表都会立即隐藏。我无法在 VBA 代码中重现此内容。
如上所述,我需要以某种方式快速隐藏工作簿中的所有(但一个)工作表并取消隐藏工作簿中的所有工作表而不循环。非常感谢任何帮助!
也许试试这个:
Application.ScreenUpdating = False
For Each Sht in Wb.Worksheets
If Sht.Visible = xlSheetHidden Then
Sht.Visible = xlSheetVisible
End If
Next Sht
Application.ScreenUpdating = True
按照建议,您可以关闭屏幕更新。在下面添加IF语句,省略你想要的sheet(我的叫'Main',改成你想要的)
Sub HideSheets()
Dim sht As Worksheet
Application.ScreenUpdating = False
For Each sht In ActiveWorkbook.Worksheets
If sht.Name <> "Main" Then sht.Visible = False
Next sht
Application.ScreenUpdating = True
End Sub
Caleeco
假设您的工作簿未受保护,这里有一个子程序可以在不系统循环的情况下执行可能的操作。支持图表类型工作表。
我刚刚了解到,只有当它们都可见时,通过数组引用工作表才有效,因此在使工作表可见时需要循环。
'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
你可以这样调用sub:
HideAllSheetsBut Sheet1
或
HideAllSheetsBut Application.Workbooks("MyWorkbook.xlsx").Worksheets("MyWorksheet")
隐藏除一个工作表之外的所有工作表,像这样:
HideAllSheetsBut Nothing
显示所有工作表。
编辑
正如 paul bica 的回答中提到的,自定义视图是快速翻转多个工作表可见性的好方法。在我的回答中,它将用于显示所有工作表,而不必遍历它们。
尝试这个...从录制的宏
Option Explicit
Sub HideSheets()
Worksheets.Select
Sheets("Main").Activate
ActiveWindow.SelectedSheets.Visible = False
End Sub
如前所述,您只能隐藏 多个工作表而不用循环,如以下语句:
Worksheets(Array(1,2,3,4,5,6,7,8,9,10,11,...,200)).Visible = True
但取消隐藏多张纸需要循环
但是,有一种更快的方法可以使用自定义视图(在“视图”选项卡中)
下面的代码生成 2 个视图 1."ShowAllWs" 和 2."HideAllWs"
性能方面:
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)
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
调用它使用这个:
Public Sub UpdateWsVisibility()
SetWsVisibility 0, 5 'or 0 to hide them (or True / False respectively)
End Sub
我有一个包含 179 个工作表的工作簿。我想隐藏所有工作表(根据 Excel 的规则不隐藏一个),或者取消隐藏所有工作表。
目前我的代码看起来像这样(根据我们是否是 hiding/unhiding 张进行适当的修改):
For Each Sht in Wb.Worksheets
Sht.Visible = xlSheetVisible
Next Sht
有 179 个工作表,这需要 4-5 秒才能 运行,我希望 运行 快得多。
我知道如果我进入一个工作簿,手动 select 所有工作表(一张除外),然后右键单击并 select "Hide"
,所有工作表都会立即隐藏。我无法在 VBA 代码中重现此内容。
如上所述,我需要以某种方式快速隐藏工作簿中的所有(但一个)工作表并取消隐藏工作簿中的所有工作表而不循环。非常感谢任何帮助!
也许试试这个:
Application.ScreenUpdating = False
For Each Sht in Wb.Worksheets
If Sht.Visible = xlSheetHidden Then
Sht.Visible = xlSheetVisible
End If
Next Sht
Application.ScreenUpdating = True
按照建议,您可以关闭屏幕更新。在下面添加IF语句,省略你想要的sheet(我的叫'Main',改成你想要的)
Sub HideSheets()
Dim sht As Worksheet
Application.ScreenUpdating = False
For Each sht In ActiveWorkbook.Worksheets
If sht.Name <> "Main" Then sht.Visible = False
Next sht
Application.ScreenUpdating = True
End Sub
Caleeco
假设您的工作簿未受保护,这里有一个子程序可以在不系统循环的情况下执行可能的操作。支持图表类型工作表。
我刚刚了解到,只有当它们都可见时,通过数组引用工作表才有效,因此在使工作表可见时需要循环。
'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
你可以这样调用sub:
HideAllSheetsBut Sheet1
或
HideAllSheetsBut Application.Workbooks("MyWorkbook.xlsx").Worksheets("MyWorksheet")
隐藏除一个工作表之外的所有工作表,像这样:
HideAllSheetsBut Nothing
显示所有工作表。
编辑 正如 paul bica 的回答中提到的,自定义视图是快速翻转多个工作表可见性的好方法。在我的回答中,它将用于显示所有工作表,而不必遍历它们。
尝试这个...从录制的宏
Option Explicit
Sub HideSheets()
Worksheets.Select
Sheets("Main").Activate
ActiveWindow.SelectedSheets.Visible = False
End Sub
如前所述,您只能隐藏 多个工作表而不用循环,如以下语句:
Worksheets(Array(1,2,3,4,5,6,7,8,9,10,11,...,200)).Visible = True
但取消隐藏多张纸需要循环
但是,有一种更快的方法可以使用自定义视图(在“视图”选项卡中)
下面的代码生成 2 个视图 1."ShowAllWs" 和 2."HideAllWs"
性能方面:
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)
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
调用它使用这个:
Public Sub UpdateWsVisibility()
SetWsVisibility 0, 5 'or 0 to hide them (or True / False respectively)
End Sub