0

我改编了一些在这里找到的代码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
4

1 回答 1

1

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

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

然后,修改您的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,以及它工作得很好。

于 2013-05-31T02:33:53.040 回答