VBA处理不正确的密码运行时错误

时间:2018-10-12 12:21:26

标签: excel vba excel-vba

首次发布,但用户已久!首先,我想对你们发布的所有代码反馈表示感谢。它帮助我开发了VBA代码,超出了您的想象!

好吧,这个问题:

背景
我正在开发一个针对VBA的插件,供我自己和同事使用。其中的一部分包括您可能会在Excel中包含但不存在的包含函数。其中一些很容易做到(例如,反向滤波器),但事实证明有些困难。这就是这些例子之一。

问题:
以下代码旨在循环显示用户对工作表的选择,应用用户定义的密码或删除现有的密码。该功能的一部分是捕获无法删除的密码(即,由于用户输入了错误的密码)。它对于第一次发生错误非常有用,但对于第二次发生并在以后重复发生的运行时错误(1004),则可以通过。我对运行时错误处理没有太多经验(尝试避免错误!),但是我无法使它正常工作。任何阻止运行时错误弹出的想法/帮助都很好。

代码:

Dim SHT As Worksheet, Password As String, SHT_Names(0 To 30) As String
'PREP
    'DISABLE APPLICATION FUNCTIONS
    Call Quicker_VBA(False)
    Application.EnableEvents = False

'USER PASSWORD OPTION
    Password = InputBox("Please enter a password (leave blank for no password)", "Password")

    'USER INFORMATION MESSAGES SETUP
        MSG_Protect = "Added to-"
        Protect_check = MSG_Protect

        MSG_Unprotect = "Removed from-"
        Unprotect_check = MSG_Unprotect

        MSG_unable = "Unable to remove protection from-"
        Unable_check = MSG_unable

    'ID SHEETS SELECTED
        For Each SHT In ActiveWindow.SelectedSheets
            a = a + 1
            SHT.Activate
            SHT_Names(a) = SHT.name
        Next

'MAIN
    HomeSHT = ActiveSheet.name

    'PROTECT SHEETS SELECTED BY USER
        For b = 1 To a
            Sheets(SHT_Names(b)).Select
            Set SHT = ActiveSheet

            'ENABLE OR REMOVE PROTECTION FROM SELECTED SHEET
            If SHT.ProtectContents Then
                On Error GoTo Password_FAIL
                Application.DisplayAlerts = False
                SHT.Unprotect Password
                On Error GoTo 0

                MSG_Unprotect = MSG_Unprotect & vbNewLine & Chr(149) & " " & SHT.name
            Else:

                'ENABLE FILTER CHECK
                FilterOn = False
                If ActiveSheet.AutoFilterMode Then FilterOn = True

                'PROTECT SHEET
                SHT.Protect Password, AllowFiltering:=FilterOn

                'UPDATE USER MESSAGE
                MSG_Protect = MSG_Protect & vbNewLine & Chr(149) & " " & SHT.name & " - Users can: Select locked and unlocked cells"
                If FilterOn = True Then MSG_Protect = MSG_Protect & " and use filters"
            End If
200     Next

'INFORM USER
    If Protect_check <> MSG_Protect Then msg = MSG_Protect & vbNewLine & "___________________" & vbNewLine
    If Unprotect_check <> MSG_Unprotect Then msg = msg & MSG_Unprotect & vbNewLine & "___________________" & vbNewLine
    If Unable_check <> MSG_unable Then msg = msg & MSG_unable

    MsgBox msg, , "Protection summary"

'TIDY UP
    Sheets(HomeSHT).Activate
    'ENABLE APPLICATION FUNCTIONS
    Call Quicker_VBA(True)
Exit Sub
Password_FAIL:
    MSG_unable = MSG_unable & vbNewLine & Chr(149) & " " & SHT.name
    Application.EnableEvents = False
    GoTo 200
End Sub

1 个答案:

答案 0 :(得分:0)

乍一看,问题似乎出在您处理错误的方式上。您使用行On Error GoTo Password_FAIL跳到错误处理程序。错误处理程序记录一些信息,然后跳到标签“ 200”。我无法确定格式是否已关闭,但看起来'200'的标签指向Next,表示循环应从下一页开始。

那么,问题出在哪里?您实际上从未重置过原始错误。在On Error GoTo Password_FAIL下面三行中,您明确调用了On Error GoTo 0来重置错误处理程序,但实际上不会在错误中到达该行。该程序将跳转到错误处理程序,然后从那里跳转到循环迭代器。使用GoTo语句进行控制流很容易导致这些类型的问题,这就是为什么大多数开发人员建议不要使用它。

我将在下面发布一些示例代码,以显示另一种(可能更好)的处理代码异常的方法。在下面的示例中,代码仅循环遍历工作簿中的所有工作表并切换保护。我没有记录很多日志,也没有包含仅切换所选工作表的约束。我想专注于错误处理。此外,通过阅读代码,您似乎可以管理更多的外围细节。如果仍有困惑,请发送消息

Sub ToggleProtectionAllSheets()
    Dim sht As Worksheet
    Dim password As String

    On Error Resume Next

    password = InputBox("Please enter a password (leave blank for no password)", "Password")
    For Each sht In ActiveWorkbook.Worksheets
        If sht.ProtectContents Then
            sht.Unprotect password

            If Err.Number <> 0 Then
                Err.Clear
                MsgBox "Something did not work according to plan unprotecting the sheet"
            End If
        Else
            sht.Protect password

            If Err.Number <> 0 Then
                Err.Clear
                MsgBox "Something went wrong with protection"
            End If
        End If

    Next sht
End Sub