检查表格是否存在,并根据单元格值隐藏/取消隐藏

时间:2018-11-14 13:12:44

标签: excel vba

我非常是业余爱好者!!目前,我有一个工作表,其中将列出用户列表,然后是工作表名称/数字列表

总体预期是,如果用户在工作表下方的单元格中有一个1,则该工作表是可见的,否则工作表应该非常隐藏

此代码位于模块1中,但不确定是否应在工作簿级别使用。

我在函数外部声明以下内容,以便可以在每个函数中调用它们;

Dim lRow As Long, wsStatus As Boolean, shtloc As Integer

这是我的主要功能(不确定,它应该是工作簿级别的子功能)

    Function CheckSheetPermission()

Sheet9.Visible = xlSheetVisible
For Each ws In ActiveWorkbook.Worksheets
    If ws.Name <> "Welcome" Then ws.Visible = xlSheetVeryHidden
Next ws
Sheet12.Visible = xlSheetVisible
Sheet12.Activate
With ActiveSheet
Dim sht As Worksheet
Call GetRowNum(Range("A3:A200"), LCase(Environ("UserName")))
    For Each Cell In Range("B" & lRow & ":GS" & lRow)
    If Abs(Cell.Value) = "1" Then
        shtloc = Cell(2, ActiveCell.Column).Value
        Call wsExists(Sheets(shtloc))
        If wsStatus = False Then
            Sheets(shtloc).Visible = xlSheetVisible
        End If
    Else
        shtloc = Cell(2, ActiveCell.Column).Value
         Call wsExists(Sheets(shtloc))
        If wsStatus = False Then
            Sheets(shtloc).Visible = xlSheetVeryHidden
        End If
    End If
    Next
End With
End Function

这看下面的工作表,最初是要确保欢迎和工作表1都是临时可见的,直到执行代码,然后为所有工作表设置正确的可见性为止(我认为工作表必须对工作表可见)读取单元格的代码)

工作表图像

获取行号只是查找用户并获取行号

Call GetRowNum(Range("A3:A200"), LCase(Environ("UserName")))

那个功能代码是

Function GetRowNum(rng As Range, user As String)


    On Error Resume Next
    lRow = Application.WorksheetFunction.Match(user, rng, 0) + 2
    On Error GoTo 0


End Function

当前似乎出错的地方是当我调用下一个函数时;

Call wsExists(Sheets(shtloc))

我得到下标超出范围错误。可能是由于变量没有正确设置,或者是我正在调用的函数本身,但是我不确定最好从哪里开始修改代码并检查结果以进一步隔离问题

在此阶段将有限的错误处理视为试图捕获错误。如果我在主要功能中添加了错误处理功能,它就会通过,除了开始时设置的那些(工作表控件和欢迎按钮)以外,没有其他隐藏或可见的工作表

Function wsExists(wsSheet As Worksheet)
On Error Resume Next
On Error GoTo 0
If Not wsSheet Is Nothing Then
wsStatus = "True"
Else
wsStatus = "False"
End If

End Function

如果您需要更多信息,请告诉我。

我想要实现的只是以下步骤;

  1. 检查用户哪些文件应该通过循环打开文件可见
  2. 使用工作表编号变量结合用户名旁边的行下的0/1值来遍历每个工作表编号,并设置工作表可见性(1 =允许。0=不允许)

我承认,对于那些有更好理解的人来说,这也许是更好的脚本

###编辑

经过改进和建议的最终代码,发现一些额外的错误后又进行了一些更改

本工作簿

Private Sub Workbook_Open()

Dim ws As Worksheet
Dim shtloc As String
Dim c As Long
Dim lRow2 As Long
Sheet9.Visible = xlSheetVisible

For Each ws In ActiveWorkbook.Worksheets
    If ws.Name <> "Welcome" Then ws.Visible = xlSheetVeryHidden
Next ws
Sheet12.Visible = xlSheetVisible
Sheet12.Activate
With Sheet12
    lRow2 = Module2.lRow2(Range("A3:A5"), LCase(Environ("UserName")))


        For c = 2 To ActiveWorkbook.Worksheets.Count + 1
        shtloc = Cells(1, c).Value2
             With Cells(lRow2, c)
             perm = Cells(lRow2, c).Value2
                Select Case perm
                    Case ("V")
                    'Visible
                        Sheets(shtloc).Visible = xlSheetVisible
                    Case ("P")
                    'visible protected
                        Sheets(shtloc).Visible = xlSheetVeryHidden
                        Sheets(shtloc).Protect Password:="*********"
                    Case ("D")
                    'Access denied
                        Sheets(shtloc).Visible = xlSheetVeryHidden
                    End Select
             End With
        Next c

End With

End Sub

模块

Function lRow2(rng As Range, user As String)

    On Error Resume Next
    With ActiveSheet
    lRow2 = Application.WorksheetFunction.Match(user, rng, 0)

    lRow2 = lRow2 + 2

    End With
End Function

我不再检查工作表是否存在,因为我进行了工作表计数并且不对空白单元格进行下一个循环,等待新的工作表创建被填充...也加快了代码的执行速度< / p>

1 个答案:

答案 0 :(得分:0)

您的代码中有一些错误。为了避免混淆,我要做的一件事是在for循环中使用其他迭代器。代替

For Each Cell In Range("B" & lRow & ":GS" & lRow)

我会用

For Each currentCell In Range("B" & lRow & ":GS" & lRow)

这可以避免我提到的第一个错误:

shtloc = Cell(2, ActiveCell.Column).Value

此行将不会返回您想要的内容。首先,在“单元格”的末尾需要一个“ s”。第二,您的工作表名称位于第1行,第三,您的代码不清楚当前在哪个单元格上处于激活状态,这可能会返回奇怪的行为。尝试改为:

shtloc = Cells(1, currentCell.Column).Value

现在,您的主要错误是您尝试通过触发错误来检查工作表是否存在。这会产生超出范围的错误。

相反,您应该使用其他功能来检查已读取工作表名称是否存在。这个答案正是您想要的

https://stackoverflow.com/a/6040454/10645669

  

Function sheetExists(sheetToFind As String) As Boolean sheetExists = False For Each sheet In Worksheets If sheetToFind = sheet.name Then sheetExists = True Exit Function End If Next sheet End Function


另一方面,在我看来,您正在使用全局变量是因为您没有从函数中正确返回值。例如

Function wsExists(wsSheet As Worksheet)
On Error Resume Next
On Error GoTo 0
If Not wsSheet Is Nothing Then
wsStatus = "True"
Else
wsStatus = "False"
End If

End Function

可以这样写:

Function wsExists(wsSheet As Worksheet) as boolean
On Error Resume Next
On Error GoTo 0
If Not wsSheet Is Nothing Then
wsExists = "True"
Else
wsExists = "False"
End If

End Function

这使您可以像下面这样直接在代码中使用该函数:

If wsExists(Sheets(shtloc)) = False Then

不再有全局变量,也不再使用关键字调用。

此外,根据经验,如果编写的代码未返回任何内容,则应为“ sub”。仅通过声明不带括号的参数就可以调用这些函数而无需关键字调用。示例:

subCalled argument1, argument2, argumentN