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

时间:2013-12-16 02:59:29

标签: vba excel-vba excel-2010 excel

我有这段代码:

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

我想要做的是使用每天根据日期更改的动态密码来保护工作簿中的工作表 我遇到的问题是如何每天更改设置的密码 我添加了errhandler例程但它不起作用。
create_pass是我创建的用于生成编码传递的函数,我已经对其进行了测试,并返回了正确的值。

此处出现错误:

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

没有突出显示的行,所以我无法确定它是哪一行。
我在Prev_passx添加了监视,然后获取第一个值然后抛出错误 返回的错误是:

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

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:4)

就像我在评论中提到的那样,我们可以使用临时表来存储密码。原因很简单。让我们来看看这个场景。假设16122013上的16/12作为密码保护工作簿。现在,此密码也将存储在隐藏的临时表中。我们需要这样做是因为,如果您在17th或任何其他日期(可能是1年后?)打开文件,那么它将读取旧密码并取消保护表单,然后再使用新密码保护它密码。为了保护纸张,如果纸张受到保护,则必须先取消保护。要知道旧密码,您必须从某个地方检索它或者将其删除。

这是另一种方法。

这将循环365次并尝试根据您的函数create_pass取消保护工作表。我已经对代码进行了评论,因此您不应该在理解它时遇到任何问题。但是,如果你那么简单回发。

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

编辑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

这会在开启时取消保护WS,然后使用当前密码保护它。