[英]Why is the workbook protected upon Workbook_Open Event?
I adapted some code found here http://www.vbaexpress.com/kb/getarticle.php?kb_id=379 for a neat solution that forces users to enable macros. 我修改了一些http://www.vbaexpress.com/kb/getarticle.php?kb_id=379上的代码,以提供一种简洁的解决方案,迫使用户启用宏。 This method is a really good way of getting around this problem. 此方法是解决此问题的一种非常好的方法。 However, my additional requirements are: one particular user needs a more sensitive version of 2 sheets within the workbook. 但是,我的其他要求是:一个特定用户需要工作簿中2张纸的更敏感版本。 Depending on the answer to a MsgBox an InputBox requires password verification and then shows the sensitive versions of these sheets. 根据MsgBox的答案,InputBox需要密码验证,然后显示这些表的敏感版本。 I believe the answer lies in how the workbook is saved and then how all sheets are unhidden upon re-opening the workbook (since two of the sheets are effectively password locked) but somehow now when I open this workbook the password used for unhiding the two sensitive versions of the sheets is required to open the workbook. 我相信答案在于如何保存工作簿,然后在重新打开工作簿时如何取消隐藏所有工作表(因为其中两个工作表已有效地密码锁定),但是现在我打开此工作簿时以某种方式使用的密码隐藏了两个工作表必须打开工作表的敏感版本才能打开工作簿。 So I changed the password required for verification of the said sheets but the Original password is still required to open the workbook: Any assistance in diagnosing this problem would be a help: Creating a spread-sheet and testing the code on your system shouldn't be too difficult and a good place to start! 因此,我更改了验证上述工作表所需的密码,但是打开工作簿仍需要原始密码:诊断此问题的任何帮助都将有所帮助:创建电子表格并测试系统上的代码不应该太难了,是一个很好的起点!
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
You don't need to protect the whole workbook to hide the sheets. 您无需保护整个工作簿即可隐藏工作表。 xlVeryHidden
will hide the sheet and prevent it from being shown on the Hide/Unhide list. xlVeryHidden
将隐藏工作表并阻止其在“隐藏/取消隐藏”列表中显示。
First, unprotect the workbook. 首先,取消保护工作簿。 You can do this by the Review tab, and then clicking on the Protect Workbook and clear any protection you have checked. 您可以通过“审阅”选项卡,然后单击“保护工作簿”并清除所有已检查的保护来执行此操作。 I'd also click on the Protect Sheet button for each sheet and clear any protection set there. 我还要单击每个工作表的“保护工作表”按钮,然后清除那里的所有保护设置。
Then, modify your Workbook_Open
subroutine to do something like this: 然后,修改您的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
Basically, the workbook is unprotected when opened. 基本上,工作簿在打开时不受保护。 If the user is not the special user, then it hides the two special sheets. 如果用户不是特殊用户,则它将隐藏两个特殊工作表。 If they are the special user, then it hides the two special sheets and they can't be unhidden. 如果他们是特殊用户,则它将隐藏这两个特殊工作表,并且不能将其隐藏。
Additional Suggestion 附加建议
You'll run into a problem with the sheet visibility when the user saves - if it's the special user, once the save is complete they won't be able to see the sensitive sheets, because your ShowAllSheets
subroutine will hide them. 用户保存时,工作表可见性会出现问题-如果是特殊用户,保存完成后,他们将无法看到敏感工作表,因为ShowAllSheets
子例程会将其隐藏。
To get around this, set a global variable to record whether the user is the special user or not, and use that to determine what sheets to show in ShowAllSheets
, like this: 要解决此问题,请设置一个全局变量以记录该用户是否为特殊用户,并使用该变量来确定在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
This code will set a flag ( IsMasterUser
) depending on the selection in Workbook_Open
. 此代码将根据Workbook_Open
的选择设置一个标志( IsMasterUser
)。 Then when ShowAllSheets
is called, it will determine whether to show the standard sheets or the special sheets based on IsMasterUser
. 然后,当ShowAllSheets
时,它将基于IsMasterUser
确定是显示标准图纸还是特殊图纸。 Note that IsMasterUser
is defaulted to "N" when its declared. 请注意, IsMasterUser
在声明时默认为“ N”。
EDIT 编辑
A couple of minor problems with the code above. 上面的代码有几个小问题。 First, the global variable needs to be declared as Public IsMasterUser As String
, and secondly it needs to be set to a value inside a function, so I set it to "N" at the start of the Workbook_Open
subroutine. 首先,需要将全局变量声明为Public IsMasterUser As String
,其次需要将其设置为函数内部的值,因此我在Workbook_Open
子例程的开头将其设置为“ N”。
I tested the posted code (the second set), along with the unaltered code from the original post in a Excel 2010 workbook with 6 sheets - Macros, User, Standard Sheet 1, Standard Sheet 2, Sensitive Sheet 1 and Sensitive Sheet 2, and it worked just fine. 我测试了已发布的代码(第二组),以及Excel 2010工作簿中原始帖子的未更改代码,其中包含6个工作表-宏,用户,标准工作表1,标准工作表2,敏感工作表1和敏感工作表2,以及它工作得很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.