Лист защиты паролем Excel VBA - PullRequest
0 голосов
/ 30 декабря 2018

Я пытаюсь обеспечить незначительную защиту доступа к нескольким листам в книге Excel.Я понимаю, что этого нелегко достичь, и все равно будут проблемы с защитой.

Ниже приведен рабочий код о том, как я хочу этого добиться.Однако он будет работать только на одном листе в рабочей книге.Есть ли способ добавить несколько листов в этот код.

Примечание: я не хочу создавать несколько версий одной и той же книги.Я просто хочу простой пароль для доступа к листу.Я понимаю, что это не обеспечивает надежный метод или ограничение доступа

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

Этот код будет работать только на одном листе.Можно ли его адаптировать для защиты нескольких листов?

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

Я думаю, это то, что вы ищете.Вам нужна коллекция или, в более общем смысле, структура данных, которая может содержать несколько значений.Отсюда вы сравниваете свой список значений с текущим активированным листом.

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
0 голосов
/ 30 декабря 2018

Вот очень быстрый и грязный способ.

MySheetName = "Sheet1 Sheet2 Sheet_Named_Fred"

.... просто перечислите все имена листов с пробелом (или чем-то еще) между ними.

Затем замените строкуIf Application.ActiveSheet.Name = MySheetName Then

С

If Instr (MySheetName, Sh.Name)> 0 Тогда

Если вы предпочитаете, используйте «Application.Activesheet».Имя "вместо моего" Sh.Name ".«Sh» - это параметр, передаваемый этой стандартной функции события, и это только что активированный рабочий лист, поэтому ваш код будет выглядеть немного чище, если вы замените «Application.ActiveSheet.Name» на «Sh.name» во всем.

Функция «INSTR» возвращает> 0, если вторая строка появляется где-либо в первой строке (в частности, номер позиции символа).Поэтому, если имя активной таблицы появляется где-либо вообще в длинной строке имен листов, оно будет подвергнуто проверке вашего пароля.

Это «быстро и грязно», потому что произойдет сбой, если какое-либо из имен вашей рабочей таблицыявляются подстроки другого имени листа.Например, если у вас есть рабочие таблицы с именами «Итоги» и «GrandTotals», то, если вы добавите «GrandTotals» в свою длинную строку, то активация «Итоги» ТАКЖЕ вызовет функцию INSTR.[код удален] Я только что отредактировал это, чтобы удалить код, который делает это «наверняка», сверяясь с массивом имен рабочих листов.Другие ниже предлагают коллекцию или другую структуру данных.Но есть простой способ защиты от сбоев вышеупомянутого простейшего решения.Не разрешается использовать * (или несколько других символов) в имени листа.Таким образом, строка имен, требующих ввода пароля, может быть просто:

MySheetName = "*Sheet1*  *Sheet2*  *Sheet_Named_Fred*"

И тогда при поиске имени в INSTR нужны звездочки по обе стороны от имени листа:

IF INSTR(MySheetName, "*"+Sh.Name+"*")>0 Then

... и все готово.Никакие коллекции или другие сложные поиски имен не нужны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...