为什么工作簿受Workbook_Open事件保护?

时间:2013-05-31 01:43:33

标签: excel vba excel-vba password-protection

我修改了http://www.vbaexpress.com/kb/getarticle.php?kb_id=379中的一些代码,以获得一个强制用户启用宏的简洁解决方案。这种方法是解决这个问题的一种非常好的方法。但是,我的附加要求是:一个特定用户需要工作簿中更敏感的2张表格。根据MsgBox的答案,InputBox需要密码验证,然后显示这些工作表的敏感版本。 我相信答案在于如何保存工作簿,然后在重新打开工作簿时如何取消隐藏所有工作表(因为其中两个工作表实际上是密码锁定的)但不知何故,当我打开此工作簿时,用于取消隐藏两个工作簿的密码打开工作簿需要敏感版本的工作表。 所以我更改了验证所述表所需的密码,但仍需要原始密码才能打开工作簿: 诊断此问题的任何帮助都是有帮助的:创建电子表格并测试系统上的代码应该不是太困难,也不是一个好的起点!

Option Explicit

Const WelcomePage = "Macros"

Private Sub Workbook_BeforeClose(Cancel As Boolean)
     'Turn off events to prevent unwanted loops
    Application.EnableEvents = False

     'Evaluate if workbook is saved and emulate default propmts
    With ThisWorkbook
        If Not .Saved Then
            Select Case MsgBox("Do you want to save the changes you made to '" & .Name & "'?", _
                vbYesNoCancel + vbExclamation)
            Case Is = vbYes
                 'Call customized save routine
                Call CustomSave
            Case Is = vbNo
                 'Do not save
            Case Is = vbCancel
                 'Set up procedure to cancel close
                Cancel = True
            End Select
        End If

         'If Cancel was clicked, turn events back on and cancel close,
         'otherwise close the workbook without saving further changes
        If Not Cancel = True Then
            .Saved = True
            Application.EnableEvents = True
            .Close savechanges:=False
        Else
            Application.EnableEvents = True
        End If
    End With
End Sub

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
     'Turn off events to prevent unwanted loops
    Application.EnableEvents = False

     'Call customized save routine and set workbook's saved property to true
     '(To cancel regular saving)
    Call CustomSave(SaveAsUI)
    Cancel = True

     'Turn events back on an set saved property to true
    Application.EnableEvents = True
    ThisWorkbook.Saved = True
End Sub

Private Sub Workbook_Open()
     'Unhide all worksheets


    Application.ScreenUpdating = False
    Call ShowAllSheets
    Application.ScreenUpdating = True

        Dim msg1, msg2, Pwd As String

    Pwd = "5555"

    Do

    msg1 = MsgBox("Are you the Master User?", vbYesNo)

    Loop Until msg1 = vbNo Or msg1 = vbYes

    If msg1 = vbNo Then
    Worksheets("Sensitive Sheet 1").Visible = xlVeryHidden
    Worksheets("Sensitive Sheet 2").Visible = xlVeryHidden

    ThisWorkbook.Unprotect Password:=Pwd
    ElseIf msg1 = vbYes Then

    Do
    msg2 = InputBox("Please Enter the Password", "Password Checker", vbOKOnly)
    Loop Until msg2 = Pwd

    Worksheets("Sensitive Sheet 1").Visible = True
    Worksheets("Sensitive Sheet 2").Visible = True
    Worksheets("Standard Sheet 1").Visible = xlVeryHidden
    Worksheets("Standard Sheet 2").Visible = xlVeryHidden

    End If





End Sub

Private Sub CustomSave(Optional SaveAs As Boolean)
    Dim WS As Worksheet, aWs As Worksheet, newFname As String
     'Turn off screen flashing
    Application.ScreenUpdating = False

     'Record active worksheet
    Set aWs = ActiveSheet

     'Hide all sheets
    Call HideAllSheets

     'Save workbook directly or prompt for saveas filename
    If SaveAs = True Then
        newFname = Application.GetSaveAsFilename( _
        fileFilter:="Macro Enabled Excel Files (*.xlsm), *.xlsm")
        If Not newFname = "False" Then ThisWorkbook.SaveAs newFname
    Else
        ThisWorkbook.Save
    End If

     'Restore file to where user was
    Call ShowAllSheets
    aWs.Activate

     'Restore screen updates
    Application.ScreenUpdating = True
End Sub

Private Sub HideAllSheets()
     'Hide all worksheets except the macro welcome page
    Dim WS As Worksheet

    Worksheets(WelcomePage).Visible = xlSheetVisible

    For Each WS In ThisWorkbook.Worksheets
        If Not WS.Name = WelcomePage Then WS.Visible = xlSheetVeryHidden
    Next WS

    Worksheets(WelcomePage).Activate
End Sub

Private Sub ShowAllSheets()
     'Show all worksheets except the macro welcome page

    Dim WS As Worksheet


    For Each WS In ThisWorkbook.Worksheets

        If WS.Name <> "Sensitive Sheet 1" And WS.Name <> "Sensitive Sheet 2" Then

            If Not WS.Name = WelcomePage Then WS.Visible = xlSheetVisible

        End If

    Next WS

    Worksheets(WelcomePage).Visible = xlSheetVeryHidden

End Sub

1 个答案:

答案 0 :(得分:1)

您无需保护整个工作簿以隐藏工作表。 xlVeryHidden将隐藏工作表并阻止其显示在隐藏/取消隐藏列表中。

首先,取消保护工作簿。您可以通过“审阅”选项卡执行此操作,然后单击“保护工作簿”并清除已检查的所有保护。我还点击每张纸的Protect Sheet按钮并清除那里设置的任何保护。

然后,修改您的Workbook_Open子例程以执行以下操作:

Private Sub Workbook_Open()

    Dim msg1, msg2, Pwd As String

    Pwd = "5555"

    Do
        msg1 = MsgBox("Are you the Master User?", vbYesNo)
    Loop Until msg1 = vbNo Or msg1 = vbYes

    If msg1 = vbNo Then
        Worksheets("Sensitive Sheet 1").Visible = xlVeryHidden
        Worksheets("Sensitive Sheet 2").Visible = xlVeryHidden
    ElseIf msg1 = vbYes Then
        Do
            msg2 = InputBox("Please Enter the Password", "Password Checker", vbOKOnly)
        Loop Until msg2 = Pwd

        Worksheets("Sensitive Sheet 1").Visible = True
        Worksheets("Sensitive Sheet 2").Visible = True
        Worksheets("Standard Sheet 1").Visible = xlVeryHidden
        Worksheets("Standard Sheet 2").Visible = xlVeryHidden
    End If
End Sub

基本上,工作簿在打开时不受保护。如果用户不是特殊用户,则它会隐藏两个特殊工作表。如果他们是特殊用户,那么它会隐藏两张特殊的工作表,并且不能取消隐藏。

其他建议

当用户保存时,您将遇到工作表可见性问题 - 如果是特殊用户,一旦保存完成,他们将无法看到敏感工作表,因为您的ShowAllSheets子例程将隐藏它们。

要解决此问题,请设置一个全局变量来记录用户是否是特殊用户,并使用它来确定要在ShowAllSheets中显示的工作表,如下所示:

Option Explicit

Public IsMasterUser As String

Private Sub Workbook_Open()

    Dim msg1, msg2, Pwd As String

    Pwd = "5555"

    IsMasterUser = "N"

    Application.ScreenUpdating = False
    Call ShowAllSheets
    Application.ScreenUpdating = True

    Do
        msg1 = MsgBox("Are you the Master User?", vbYesNo)
    Loop Until msg1 = vbNo Or msg1 = vbYes

    If msg1 = vbNo Then
        IsMasterUser = "N"

        Worksheets("Sensitive Sheet 1").Visible = xlVeryHidden
        Worksheets("Sensitive Sheet 2").Visible = xlVeryHidden
    ElseIf msg1 = vbYes Then
        Do
            msg2 = InputBox("Please Enter the Password", "Password Checker", vbOKOnly)
        Loop Until msg2 = Pwd

        IsMasterUser = "Y"

        Worksheets("Sensitive Sheet 1").Visible = True
        Worksheets("Sensitive Sheet 2").Visible = True
        Worksheets("Standard Sheet 1").Visible = xlVeryHidden
        Worksheets("Standard Sheet 2").Visible = xlVeryHidden
    End If
End Sub

Private Sub ShowAllSheets()
'Show all worksheets except the macro welcome page

    Dim WS As Worksheet

    For Each WS In ThisWorkbook.Worksheets
        If Not WS.Name = WelcomePage Then
            If IsMasterUser = "N" _
               And WS.Name <> "Sensitive Sheet 1" _
               And WS.Name <> "Sensitive Sheet 2" Then
                WS.Visible = xlSheetVisible
            ElseIf IsMasterUser = "Y" _
               And WS.Name <> "Standard Sheet 1" _
               And WS.Name <> "Standard Sheet 2" Then
                WS.Visible = True
            End If
        End If
    Next WS

    Worksheets(WelcomePage).Visible = xlSheetVeryHidden
End Sub

此代码将根据IsMasterUser中的选择设置一个标记(Workbook_Open)。然后,当调用ShowAllSheets时,它将根据IsMasterUser确定是显示标准工作表还是特殊工作表。请注意,IsMasterUser在声明时默认为“N”。

修改

上述代码存在一些小问题。首先,需要将全局变量声明为Public IsMasterUser As String,其次需要将其设置为函数内的值,因此我在Workbook_Open子例程的开头将其设置为“N”。

我在Excel 2010工作簿中测试了已发布的代码(第二组)以及原始帖子中未更改的代码,包括6张 - 宏,用户,标准表1,标准表2,敏感表1和敏感表2,它运作得很好。