基于多个单元格值隐藏/取消隐藏Excel工作表

时间:2019-03-13 13:07:46

标签: excel vba

我有一个包含多个工作表的Excel工作簿。我想根据主工作表单元格B3:B8中的单元格值隐藏/取消隐藏工作表。用户可以从预定义列表中更改主表中的值。

例如。如果“配置”列中存在“ A”,请取消隐藏工作簿中的工作表“ A”。

Workbook

目前,我有以下代码可以正常工作,但看起来 笨拙,每次在“配置”列中更改值时,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值停止(工作表变为隐藏状态)。

3 个答案:

答案 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