密码保护工作表 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