密码保护工作表 Excel VBA
Password protection worksheet Excel VBA
我正在尝试为 Excel 工作簿中的多个 sheet 提供次要形式的访问保护。我知道这并不容易实现,并且仍然存在保护问题。
我在下面有关于如何实现此目标的工作代码。但是,它仅适用于工作簿中的一个 sheet。有没有办法向这段代码中添加多个 sheet。
注意:我不想创建同一工作簿的多个版本。我只想要一个简单的密码来访问 sheet。我知道这不提供万无一失的方法或限制访问
Private Sub Workbook_Open()
End Sub
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySheetName As String
MySheetName = "Sheet1" 'The first sheet which I want to hide.
MySheetName = "Sheet2" 'The second sheet which I want to hide.
If Application.ActiveSheet.Name = MySheetName Then
Application.EnableEvents = False
Application.ActiveSheet.Visible = False
response = Application.InputBox("Password", "Enter Password", "", Type:=2)
If response = "1234" Then 'Unhide Password.
Application.Sheets(MySheetName).Visible = True
Application.Sheets(MySheetName).Select
End If
End If
Application.Sheets(MySheetName).Visible = True
Application.EnableEvents = True
End Sub
此代码仅适用于单个作品sheet。它能否适应为多个 sheet 提供保护?
这是真正快速且肮脏的方法。
MySheetName = "Sheet1 Sheet2 Sheet_Named_Fred"
..只需列出所有 sheet 名称,并在它们之间添加 space(或其他任何内容)。
然后替换你的行
如果 Application.ActiveSheet.Name = MySheetName 那么
有
如果 Instr(MySheetName,Sh.Name)>0 那么
如果您愿意,请使用 "Application.Activesheet.Name" 而不是我的 "Sh.Name"。 "Sh" 是传递给那个标准事件函数的参数,并且是刚刚被激活的工作 sheet,所以如果将 "Application.ActiveSheet.Name" 替换为 [=47=,您的代码看起来会更简洁一些] 自始至终。
"INSTR"函数returns>0 如果第二个字符串出现在第一个字符串的任意位置(具体来说,字符位置编号)。因此,如果 activesheet 名称出现在一长串 sheet 名称中的任何位置,它将接受您的密码测试。
这是 "quick and dirty",因为如果您的任何作品sheet 名称是另一个作品sheet 名称的子字符串,它将失败。例如,如果您有名为 "Totals" 和 "GrandTotals" 的工作sheet,那么如果您将 "GrandTotals" 放入长字符串中,那么激活 "Totals" 也会触发INSTR 函数。
[代码已删除]
我刚刚编辑了它,通过检查一组工作 sheet 名称来删除执行此操作的代码 "for sure"。下面的其他人建议使用集合或其他数据结构。但是有一种简单的方法可以防止上述最简单的解决方案发生故障。不允许在 worksheet 名称中使用 *(或其他几个字符)。所以需要密码的名称字符串可以是:
MySheetName = "*Sheet1
* *Sheet2
* *Sheet_Named_Fred
*"
然后您的 INSTR 搜索名称只需要 sheet 名称两边的星号:
IF INSTR(MySheetName, "*"+Sh.Name+"
*")>0 Then
...大功告成。无需集合或其他复杂的名称搜索。
我认为这就是您所关注的。您需要一个集合,或者更一般地说,一个可以保存多个值的数据结构。在这里,您可以将您的值列表与当前激活的 sheet.
进行比较
Option Explicit
Private PreviousSheet As Worksheet
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim SheetNames As Collection: Set SheetNames = New Collection
Dim SheetName As Variant
Dim response As String
Dim ws As Excel.Worksheet
'List of sheet names you want to hide
SheetNames.Add "Sheet1"
SheetNames.Add "Sheet2"
For Each SheetName In SheetNames
On Error Resume Next
Set ws = ThisWorkbook.Worksheets(SheetName)
On Error GoTo 0
If Not ws Is Nothing Then
If ws.Name = Sh.Name Then
Application.EnableEvents = False
response = Application.InputBox("Password", "Enter Password", "", Type:=2)
If response = "1234" Then
ws.Visible = xlSheetVisible
ws.Activate
ElseIf response = "False" Or response = vbNullString Then
If Not PreviousSheet Is Nothing Then PreviousSheet.Activate
Else
ws.Visible = xlSheetHidden
End If
End If
Application.EnableEvents = True
End If
Next
End Sub
Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
Set PreviousSheet = Sh
End Sub
我正在尝试为 Excel 工作簿中的多个 sheet 提供次要形式的访问保护。我知道这并不容易实现,并且仍然存在保护问题。
我在下面有关于如何实现此目标的工作代码。但是,它仅适用于工作簿中的一个 sheet。有没有办法向这段代码中添加多个 sheet。
注意:我不想创建同一工作簿的多个版本。我只想要一个简单的密码来访问 sheet。我知道这不提供万无一失的方法或限制访问
Private Sub Workbook_Open()
End Sub
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySheetName As String
MySheetName = "Sheet1" 'The first sheet which I want to hide.
MySheetName = "Sheet2" 'The second sheet which I want to hide.
If Application.ActiveSheet.Name = MySheetName Then
Application.EnableEvents = False
Application.ActiveSheet.Visible = False
response = Application.InputBox("Password", "Enter Password", "", Type:=2)
If response = "1234" Then 'Unhide Password.
Application.Sheets(MySheetName).Visible = True
Application.Sheets(MySheetName).Select
End If
End If
Application.Sheets(MySheetName).Visible = True
Application.EnableEvents = True
End Sub
此代码仅适用于单个作品sheet。它能否适应为多个 sheet 提供保护?
这是真正快速且肮脏的方法。
MySheetName = "Sheet1 Sheet2 Sheet_Named_Fred"
..只需列出所有 sheet 名称,并在它们之间添加 space(或其他任何内容)。
然后替换你的行 如果 Application.ActiveSheet.Name = MySheetName 那么
有
如果 Instr(MySheetName,Sh.Name)>0 那么
如果您愿意,请使用 "Application.Activesheet.Name" 而不是我的 "Sh.Name"。 "Sh" 是传递给那个标准事件函数的参数,并且是刚刚被激活的工作 sheet,所以如果将 "Application.ActiveSheet.Name" 替换为 [=47=,您的代码看起来会更简洁一些] 自始至终。
"INSTR"函数returns>0 如果第二个字符串出现在第一个字符串的任意位置(具体来说,字符位置编号)。因此,如果 activesheet 名称出现在一长串 sheet 名称中的任何位置,它将接受您的密码测试。
这是 "quick and dirty",因为如果您的任何作品sheet 名称是另一个作品sheet 名称的子字符串,它将失败。例如,如果您有名为 "Totals" 和 "GrandTotals" 的工作sheet,那么如果您将 "GrandTotals" 放入长字符串中,那么激活 "Totals" 也会触发INSTR 函数。 [代码已删除] 我刚刚编辑了它,通过检查一组工作 sheet 名称来删除执行此操作的代码 "for sure"。下面的其他人建议使用集合或其他数据结构。但是有一种简单的方法可以防止上述最简单的解决方案发生故障。不允许在 worksheet 名称中使用 *(或其他几个字符)。所以需要密码的名称字符串可以是:
MySheetName = "*Sheet1
**Sheet2
**Sheet_Named_Fred
*"
然后您的 INSTR 搜索名称只需要 sheet 名称两边的星号:
IF INSTR(MySheetName, "*"+Sh.Name+"
*")>0 Then
...大功告成。无需集合或其他复杂的名称搜索。
我认为这就是您所关注的。您需要一个集合,或者更一般地说,一个可以保存多个值的数据结构。在这里,您可以将您的值列表与当前激活的 sheet.
进行比较Option Explicit
Private PreviousSheet As Worksheet
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim SheetNames As Collection: Set SheetNames = New Collection
Dim SheetName As Variant
Dim response As String
Dim ws As Excel.Worksheet
'List of sheet names you want to hide
SheetNames.Add "Sheet1"
SheetNames.Add "Sheet2"
For Each SheetName In SheetNames
On Error Resume Next
Set ws = ThisWorkbook.Worksheets(SheetName)
On Error GoTo 0
If Not ws Is Nothing Then
If ws.Name = Sh.Name Then
Application.EnableEvents = False
response = Application.InputBox("Password", "Enter Password", "", Type:=2)
If response = "1234" Then
ws.Visible = xlSheetVisible
ws.Activate
ElseIf response = "False" Or response = vbNullString Then
If Not PreviousSheet Is Nothing Then PreviousSheet.Activate
Else
ws.Visible = xlSheetHidden
End If
End If
Application.EnableEvents = True
End If
Next
End Sub
Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
Set PreviousSheet = Sh
End Sub