我有一个包含多个工作表的Excel工作簿。我想根据主工作表单元格B3:B8中的单元格值隐藏/取消隐藏工作表。用户可以从预定义列表中更改主表中的值。
例如。如果“配置”列中存在“ A”,请取消隐藏工作簿中的工作表“ A”。
目前,我有以下代码可以正常工作,但看起来 笨拙,每次在“配置”列中更改值时,Excel都会随着代码运行而闪烁:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Integer
Sheets("A").Visible = False
Sheets("B").Visible = False
Sheets("C").Visible = False
Sheets("D").Visible = False
For i = 3 To 8
If InStr(1, Cells(i, 2), "A") Then
Sheets("A").Visible = True
ElseIf InStr(1, Cells(i, 2), "B") Then
Sheets("B").Visible = True
ElseIf InStr(1, Cells(i, 2), "C") Then
Sheets("C").Visible = True
ElseIf InStr(1, Cells(i, 2), "D") Then
Sheets("D").Visible = True
End If
Next i
End Sub
我也尝试通过按钮运行此宏,但是它以第一个TRUE值停止(工作表变为隐藏状态)。
答案 0 :(得分:1)
我会使用这种方法:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Integer
Sheets("A").Visible = xlSheetHidden
Sheets("B").Visible = xlSheetHidden
Sheets("C").Visible = xlSheetHidden
Sheets("D").Visible = xlSheetHidden
Application.ScreenUpdating = False
For i = 3 To 8
If InStr(1, Cells(i, 2), "A") Then Sheets("A").Visible = xlSheetVisible
If InStr(1, Cells(i, 2), "B") Then Sheets("B").Visible = xlSheetVisible
If InStr(1, Cells(i, 2), "C") Then Sheets("C").Visible = xlSheetVisible
If InStr(1, Cells(i, 2), "D") Then Sheets("D").Visible = xlSheetVisible
Next i
Application.ScreenUpdating = True
End Sub
答案 1 :(得分:1)
另一种方法是:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim RNG As Range, CL As Range
Dim WS As Worksheet
Application.ScreenUpdating = False
Set RNG = Sheets("Main").Range("B3:B8")
If Not Intersect(Target, RNG) Is Nothing Then
Application.ScreenUpdating = False
For Each WS In ThisWorkbook.Worksheets
If WS.Name <> "Main" Then
With RNG
Set CL = .Find(What:=WS.Name, LookIn:=xlValues, LookAt:=xlWhole)
If Not CL Is Nothing Then
WS.Visible = xlSheetVisible
Else
WS.Visible = xlSheetHidden
End If
End With
End If
Next WS
End If
Application.ScreenUpdating = True
End Sub
更通用,更动态
编辑:还要检查Target
是否与您的查找范围相交,以防止触发不需要的宏。
答案 2 :(得分:0)
使用Application.ScreenUpdating
可以帮助优化运行并使其看起来更好。通过在Sub完成运行之前不尝试重新绘制scrren,将减少闪烁。如果程序的其余部分都没有问题,那应该就是您所需要的
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Integer
Sheets("A").Visible = False
Sheets("B").Visible = False
Sheets("C").Visible = False
Sheets("D").Visible = False
For i = 3 To 8
If InStr(1, Cells(i, 2), "A") Then
Application.ScreenUpdating = False
Sheets("A").Visible = True
ElseIf InStr(1, Cells(i, 2), "B") Then
Application.ScreenUpdating = False
Sheets("B").Visible = True
ElseIf InStr(1, Cells(i, 2), "C") Then
Application.ScreenUpdating = False
Sheets("C").Visible = True
Application.ScreenUpdating = False
ElseIf InStr(1, Cells(i, 2), "D") Then
Sheets("D").Visible = True
End If
Next i
Application.sScreenUpdating = True
End Sub
我也同意的评论。 Ifs
会更好。 ElseIf
假设可能存在多次迭代时,只有一种条件是正确的条件。
编辑:
还有一个问题:看起来您打算以这种方式设置B3:B8之间的任何具有“ A”的值都将显示页面“ A”。如果您以其他方式专用于B3 =“ A”,B4 =“ B”等,则可以将条件更改为If Target.Address = "$B$3"
然后,让B#成为工作表“ A”的开/关对象,其中包含非空值。
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
If Target.Address = "$B$3" Then
If IsEmpty(Sheet1.Range("B3")) = False Then
Sheets("A").Visible = True
Else
Sheets("A").Visible = False
End If
End If
''etc etc and so on
Application.ScreenUpdating = True
End Sub