我非常是业余爱好者!!目前,我有一个工作表,其中将列出用户列表,然后是工作表名称/数字列表
总体预期是,如果用户在工作表下方的单元格中有一个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
如果您需要更多信息,请告诉我。
我想要实现的只是以下步骤;
我承认,对于那些有更好理解的人来说,这也许是更好的脚本
###编辑经过改进和建议的最终代码,发现一些额外的错误后又进行了一些更改
本工作簿
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>
答案 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