简体   繁体   English

如何使用动态密码保护Workbook_Open事件上的工作表

[英]How to Protect Sheet on Workbook_Open event with a dynamic password

I have this code: 我有这个代码:

Private Sub Workbook_Open()

Dim wSheet As Worksheet
Dim my_code As String
Dim x As Long, y As Integer
Dim Pass_word, Prev_pass As String

my_code = Val(Format(Date, "#")) * 397

Pass_word = create_pass(my_code)

For Each wSheet In Worksheets
    On Error GoTo errhandler
    wSheet.protect Password:=Pass_word, _
    UserInterFaceOnly:=True
Next wSheet

Exit Sub
errhandler:

x = 1
Do
my_code = Val(Format(Date - x, "#")) * 397
Prev_pass = create_pass(my_code)
For Each wSheet In Worksheets
    On Error GoTo move
    wSheet.Unprotect (Prev_pass)
Next wSheet
move:
If Err.Number <> 0 Then
    x = x + 1
    y = 0
    Err.Clear
Else
    For Each wSheet In Worksheets
        wSheet.protect Password:=Pass_word, _
        UserInterFaceOnly:=True
    Next wSheet
    y = 1
End If
Loop Until y = 1

Resume Next

End Sub

What I want to do is to protect sheets inside a workbook with a dynamic password that changes everyday based on the date. 我想要做的是使用动态密码保护工作簿中的工作表,该密码每天根据日期更改。
What i'm having trouble with is how to change the set password every day. 我遇到的问题是如何每天更改设置的密码。
I added the errhandler routine but it doesn't work. 我添加了errhandler例程,但它不起作用。
create_pass is a function i created to generate the coded pass and i already tested it and it returns the right value. create_pass是我创建的一个函数,用于生成编码传递,我已经测试过它并返回正确的值。

Error occurs in this somewhere here: 这里的某处出现错误:

For Each wSheet In Worksheets
    On Error GoTo move
    wSheet.Unprotect (Prev_pass)
Next wSheet

No line is highlighted so i cannot determine which is it exactly. 没有突出显示的行,所以我无法确定它是哪一行。
I added watch on Prev_pass and x and it gets the first values then throws up the error. 我在Prev_passx上添加了监视,它获得了第一个值然后抛出了错误。
the returned error is: 返回的错误是:

Run-time error '1004":
Application-defined or object-defined error

Any help is much appreciated. 任何帮助深表感谢。

Like I mentioned in the comments, we can use a temp sheet which will store the password. 就像我在评论中提到的那样,我们可以使用临时表来存储密码。 And the reason is very simple. 原因很简单。 let's take this scenario. 让我们来看看这个场景。 Let's say the workbook is protected with 16122013 as a password on 16/12 . 比方说,工作簿与保护16122013作为密码16/12 Now this password will also be stored in a hidden temp sheet. 现在,此密码也将存储在隐藏的临时表中。 We need to do this because, if you open the file on the 17th or any other day (could be after 1 year?) then it will read the old password and unprotect the sheet and then protect it again with the new password. 我们需要这样做是因为,如果您在17th或任何其他日期(可能是1年后?)打开文件,那么它将读取旧密码并取消保护表单,然后使用新密码再次保护它。 For protecting a sheet, you will have to unprotect it first if the sheet is protected. 为了保护纸张,如果纸张受到保护,则必须先取消保护。 And to know the old password, you will have to retrieve it from somewhere or Hack it. 要知道旧密码,您必须从某个地方检索它或者破解它。

Here is another method. 这是另一种方法。

This will loop 365 times and try to unprotect your sheet based on your function create_pass . 这将循环365次并尝试根据您的函数create_pass取消保护工作表。 I have commented the code so you shouldn't face any problem in understanding it. 我已经对代码进行了评论,因此您不应该在理解它时遇到任何问题。 But if you do then simple post back. 但如果你那么简单回帖。

Sub Sample()
    Dim my_code As String, Ret As String
    Dim PrevDt As Date
    Dim n As Long

    my_code = Val(Format(Date, "#")) * 397

    '~~> Create the password
    Ret = create_pass(my_code)

    '~~> Loop till the password is not found
    Do
        '~~> Attempt to unprotect the sheet
        On Error Resume Next
        ActiveSheet.Unprotect Ret
        On Error GoTo 0

        '~~> Check if the sheet was unprotected
        If ActiveSheet.ProtectContents = False Then Exit Do

        '~~> If not then go back one date
        If PrevDt = #12:00:00 AM# Then PrevDt = Date - 1 Else PrevDt = PrevDt - 1

        my_code = Val(Format(PrevDt, "#")) * 397

        Ret = create_pass(my_code)

        '~~> This counter is required so that we can exit the loop after 365 days
        n = n + 1

        If n > 365 Then
            MsgBox "More than 365 passwords have been checked. Exiting now"
            Exit Do
        End If
    Loop
End Sub

Edit 1: (posting the actual Workbook_Open event) 编辑1 :(发布实际的Workbook_Open事件)

Private Sub Workbook_Open()

Dim ws As Worksheet
Dim my_code As String, Ret As String, my_pass As String
Dim PrevDt As Date
Dim n As Long

my_code = Val(Format(Date, "#")) * 397

'~~> Create the password
Ret = create_pass(my_code)
my_pass = Ret

'~~> loop in all WS
For Each ws In Worksheets
    '~~> Loop till the password is not found
    Do
        '~~> Attempt to unprotect the sheet
        On Error Resume Next
        ws.Unprotect Ret
        On Error GoTo 0

        '~~> Check if the sheet was unprotected
        If ws.ProtectContents = False Then Exit Do

        '~~> If not then go back one date
        If PrevDt = #12:00:00 AM# Then PrevDt = Date - 1 Else PrevDt = PrevDt - 1

        my_code = Val(Format(PrevDt, "#")) * 397

        Ret = create_pass(my_code)

        '~~> This counter is required so that we can exit
        '~~> the loop after 365 days
        n = n + 1

        If n > 365 Then
            MsgBox "More than 365 passwords have been checked. Exiting now"
            Exit Do
        End If
    Loop
    '~~> protect with the current day password
    ws.protect my_pass, , , , True
Next ws

End Sub

This unprotects WS's on opening then protect it with the current password. 这会在开启时取消保护WS,然后使用当前密码保护它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM