首次发布,但用户已久!首先,我想对你们发布的所有代码反馈表示感谢。它帮助我开发了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
答案 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