Простая обработка ошибок VBA Excel
Я смотрел онлайн столько, сколько мог (за исключением веб-сайта поддержки Microsoft, который почему-то заблокирован на работе). Я пытаюсь просто пропустить ошибку. Мой код, написанный здесь, упрощен, но должен работать одинаково.
Что должен делать мой код:
Один из моих подмножеств создает фигуры в цикле и называет их (btn_1, btn_2 и т.д.). Но перед их созданием он вызывает sub, который пытается удалить их, чтобы не создавать дубликаты. Этот вспомогательный цикл проходит через (btn_1, btn_2 и т.д.) И удаляет фигуры с помощью:
for i = 1 to (a certain number)
Set shp = f_overview.Shapes("btn_" & i)
shp.delete
next
Конечно, бывает, что форма не может быть удалена, потому что ее просто не существует. Я обнаружил, что большую часть времени исправленное исправление заключается в том, чтобы добавить (при ошибке возобновить дальше) перед установкой фигуры, так как я получаю сообщение об ошибке, которое не существует. Я пробовал его внутри цикла, перед циклом и т.д., Например:
for i = 1 to (a certain number)
On Error Resume Next
Set shp = f_overview.Shapes("btn_" & i)
shp.delete
next
Насколько я понимаю, предполагается, что он должен пройти прямо, если форма не существует, но я все равно получаю ту же самую ошибку, добавлю ли я снова сообщение об ошибке включения? Что я делаю неправильно?
ИЗМЕНИТЬ: нет ошибок, когда формы существуют.
Ответы
Ответ 1
Похоже, что у вас установлена неправильная опция захвата ошибок. В редакторе VBA выберите Tools -> Options
. В открывшемся окне выберите General tab
и выберите переключатель Break on Unhandled Errors
. Это должно позволить Excel правильно обрабатывать команду On Error Resume Next
.
Я подозреваю, что вы выбрали Break on All Errors
.
Ответ 2
Я обнаружил, что большую часть времени исправленное исправление заключается в том, чтобы добавить (при повторении ошибки дальше) перед установкой фигуры, так как я получаю сообщение об ошибке, которое не существует.
НЕТ!
Рекомендуемый способ обработки ошибок во время выполнения - не, чтобы засунуть их под ковер и продолжить выполнение, как будто ничего не произошло - это именно то, что делает On Error Resume Next
.
Самый простой способ избежать ошибок во время выполнения - проверить условия ошибки и избежать выполнения кода, который приводит к 100% частоте отказов, например попытке запустить метод по ссылке на объект, который Nothing
:
For i = 1 To (a certain number)
Set shp = f_overview.Shapes("btn_" & i)
If Not shp Is Nothing Then shp.Delete
Next
В случаях, когда вы не можете проверить условия ошибки и должны обрабатывать ошибки, рекомендуется использовать их:
Private Sub DoSomething()
On Error GoTo CleanFail
'...code...
CleanExit:
'cleanup code here
Exit Sub
CleanFail:
If Err.Number = 9 Then 'subscript out of range
Err.Clear
Resume Next
Else
MsgBox Err.Description
Resume CleanExit
End If
End Sub
Ответ 3
Вместо того, чтобы пытаться слепо удалять фигуры и пропускать ошибки, почему бы не запустить список известных фигур и удалить их. Тогда вам не нужно беспокоиться о On Error Resume Next
, который часто заканчивается злоупотреблением.
Sub Test(TheSheet As Worksheet)
Dim Shp as Shape
For Each Shp in TheSheet.Shapes
If left(Shp.Name, 4) = "btn_" Then
Shp.Delete
End if
Next
End Sub
Если вы хотите удалить все фигуры, удалите оператор If
. Если вы хотите удалить несколько разных именованных фигур, измените инструкцию If
соответствующим образом.
Ответ 4
Нет ничего НЕПРАВИЛЬНОГО использования OERN (при повторном повторении ошибок Next), если вы понимаете, что вы делаете, и как оно повлияет на ваш код.
В вашем случае совершенно нормально использовать OERN
Dim shp As Shape
For i = 1 To (a certain number)
On Error Resume Next
Set shp = f_overview.Shapes("btn_" & i)
shp.Delete
On Error GoTo 0
Next
В то же время убедитесь, что вы не делаете что-то вроде
On Error Resume Next
<Your Entire Procedure>
On Error GoTo 0
Это будет подавлять ВСЕ ошибки. Используйте правильную обработку ошибок, как показано Matt
Edit
Вот еще один прекрасный пример того, как использовать OERN. Эта функция проверяет, существует ли конкретный рабочий лист или нет.
Function DoesWSExist(wsName As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Sheets(wsName)
On Error GoTo 0
If Not ws Is Nothing Then DoesWSExist = True
End Function
Если вы хотите, вы также можете просмотреть все листы, чтобы проверить, существует ли лист или нет!
Ответ 5
Try:
On Error Resume Next
for i = 1 to (a certain number)
Set shp = f_overview.Shapes("btn_" & i)
if err<>0 then err.clear else shp.delete
next
on Error Goto 0