Обработка ошибок в VBA Excel с помощью оператора On Error. Синтаксис выражений с оператором On Error. Пример кода с простым обработчиком ошибок.
On Error – это оператор, который используется для отслеживания ошибок во время исполнения кода VBA. При возникновении ошибки On Error передает информацию о ней в объект Err и включает программу обработки ошибок, начинающуюся с указанной строки.
В первую очередь, обработчик ошибок нужен для пользователей файлов Excel с кодами VBA. Любая ошибка приводит к прекращению выполнения программы, открытию редактора VBA с непонятным для пользователя сообщением или даже к полному зависанию приложения.
Обработчик ошибок позволяет завершить выполнение программы при возникновении ошибки и вывести сообщение пользователю с ее описанием.
Синтаксис выражений с On Error
Включает алгоритм обнаружения ошибок и, в случае возникновения ошибки, передает управление операторам обработчика ошибок с указанной в выражении строки. Stroka – это метка, после которой расположены операторы обработчика ошибок.
Включает алгоритм обнаружения ошибок и, в случае возникновения ошибки, передает управление оператору, следующему за оператором, вызвавшем ошибку.
Отключает любой включенный обработчик ошибок в текущей процедуре.
Простой обработчик ошибок
Шаблон простейшего обработчика ошибок:
Sub Primer() On Error GoTo Stroka ‘Блок операторов процедуры Exit Sub Stroka: MsgBox «Произошла ошибка: « & Err.Description End Sub |
Оператор On Error GoTo
размещается в начале процедуры, метка и обработчик ошибок – в конце процедуры. Название метки можно сменить на другое, в том числе на кириллице.
Оператор Exit Sub
обеспечивает выход из процедуры, если блок операторов выполнен без ошибок. Для вывода описания ошибки используется свойство Description
объекта Err
.
Примеры обработки ошибок
Пример 1
Деление на ноль:
Sub Primer1() On Error GoTo Инструкция Dim a As Double a = 45 / 0 Exit Sub Instr: MsgBox «Произошла ошибка: « & Err.Description End Sub |
Результат выполнения кода VBA Excel с обработчиком ошибок:
Пример 2
Выход за границы диапазона:
Sub Primer2() On Error GoTo Instr Dim myRange As Range Set myRange = Range(«A1:D4»).Offset(—2) Exit Sub Instr: MsgBox «Произошла ошибка: « & Err.Description End Sub |
Результат выполнения кода VBA Excel с оператором On Error GoTo
:
Пример использования выражений On Error Resume Next
и On Error GoTo 0
смотрите в статье: Отбор уникальных значений с помощью Collection.
demonikas Пользователь Сообщений: 53 |
Подскажите пожалуйста VBA код, чтобы отключить проверку листа на ошибки. |
Sanja Пользователь Сообщений: 14849 |
#2 14.02.2016 09:45:52
Запишите п.1 цитаты макрорекордером и будет Вам п.2. Согласие есть продукт при полном непротивлении сторон. |
||
JayBhagavan Пользователь Сообщений: 11833 ПОЛ: МУЖСКОЙ | Win10x64, MSO2019x64 |
Опять мухлюете?
|
demonikas Пользователь Сообщений: 53 |
JayBhagavan, да Sanja, а можно попросить код. нубский нуб не знает что такое макроредактор. мне нужно к ячейке с27 например. |
Sanja Пользователь Сообщений: 14849 |
#5 14.02.2016 09:50:20
Лучше почитайте про макрорекордер. Способ 2 . Согласие есть продукт при полном непротивлении сторон. |
||
gling Пользователь Сообщений: 4030 |
#6 14.02.2016 09:52:33 Включите запись макроса макрорекордером, зайдите в параметры, выключите фоновые ошибки, выключите запись макроса, получите такой код
|
||
demonikas Пользователь Сообщений: 53 |
Sanja, Application.ErrorCheckingOptions.BackgroundChecking = False Изменено: demonikas — 14.02.2016 11:39:51 |
demonikas Пользователь Сообщений: 53 |
gling, макрос- не вариант, к сожалению. |
Sanja Пользователь Сообщений: 14849 |
#9 14.02.2016 10:01:15
А если в «другом экселе» макросы не будут разрешены?
По ссылке выше есть не много теории про макросы.
А что такое по Вашему код? Согласие есть продукт при полном непротивлении сторон. |
||||||
demonikas Пользователь Сообщений: 53 |
смысл в том, чтобы изменить сумму числового формата 2660 на текстовый 2660. тогда в формуле она не будет учтена. но будет видна ошибка мол записано в текстовом формате. так вот нужно чтобы этой ошибки не было видно ни у меня, ни на другом компьютере, если это например будет не 07 ворд а 2013. |
demonikas Пользователь Сообщений: 53 |
Sanja, вопрос в том, возможно ли сделать ячейку несчитаемой через текст, так чтобы предупреждение об ошибках не выводилось ни у меня ни на другом компе в другом экселе например. |
Sanja Пользователь Сообщений: 14849 |
#12 14.02.2016 10:07:04
Вы уверены? См. файл. Желтая ячейка имеет формат Текстовый Прикрепленные файлы
Согласие есть продукт при полном непротивлении сторон. |
||
Sanja Пользователь Сообщений: 14849 |
Офф. Вспомнил Вас Согласие есть продукт при полном непротивлении сторон. |
demonikas Пользователь Сообщений: 53 |
Sanja, как вы это сделали? |
demonikas Пользователь Сообщений: 53 |
Sanja, пока неизвестно. вот сейчас решил что ну их нафиг эти имена если просто можно попробовать текстовую ячейку. вот думаю как же сделать. сейчас скину пример. |
Sanja Пользователь Сообщений: 14849 |
В файле Ваша задаче НЕ решена. Я просто показал, что ячейка с Текстовым форматом все равно участвует в вычислении. Вам нужно что-то другое Согласие есть продукт при полном непротивлении сторон. |
demonikas Пользователь Сообщений: 53 |
|
demonikas Пользователь Сообщений: 53 |
Sanja, ячейка с27 например. внизу формула которая суммирует общее кол-во. как сделать чтоб с27 не участвовала в подсчете но предупреждение об ошибке не выводилось) Прикрепленные файлы
|
Юрий М Модератор Сообщений: 60762 Контакты см. в профиле |
Я вчера показывал , как ячейку подменить ТекстБоксом )) Пишем в него любое число — всё равно считаться не будет )) |
demonikas Пользователь Сообщений: 53 |
Юрий М, я почитал но откровенно говоря там ничего не понял. |
demonikas Пользователь Сообщений: 53 |
Юрий М, как-то можете показать на моем примере? |
Юрий М Модератор Сообщений: 60762 Контакты см. в профиле |
Смотрите мой пример. Да и это больше шутка, чем рекомендация )) |
demonikas Пользователь Сообщений: 53 |
|
Юрий М Модератор Сообщений: 60762 Контакты см. в профиле |
См. файл. Фактически в ячейке А1 «двойка». В ТекстБокс, который находится над ячейкой, можно ввести любое число — формула этого просто не увидит. |
demonikas Пользователь Сообщений: 53 |
Юрий М, я не знаю как делать чекбоксы и как вы это сделали,но по факту число отличается от своих соотечественников и нет номера ячейки. |
Юрий М Модератор Сообщений: 60762 Контакты см. в профиле |
Не нравится — не используйте ) Ищите другой вариант фальсификации ) |
demonikas Пользователь Сообщений: 53 |
Юрий М, в том то и дело, что я не знаю. Если бы знал)) |
Sanja Пользователь Сообщений: 14849 |
Формат ячейки Изменено: Sanja — 14.02.2016 13:18:44 Согласие есть продукт при полном непротивлении сторон. |
demonikas Пользователь Сообщений: 53 |
Sanja, я тупой в этом. меня не спрашивайте. я по-моему нашел решение на свой вопрос. Изменено: demonikas — 14.02.2016 13:58:36 |
demonikas Пользователь Сообщений: 53 |
#30 14.02.2016 12:48:04 Sanja, по вашему файлу тоже интересно. как значение может вычитаться дважды… |
I have an excel workbook was has lots of the green «error checking» triangles.
Is there any way using Excel VBA that I can this off when I open the workbook.
asked Jan 21, 2011 at 0:04
2
I think this is what you’re looking for:
Application.ErrorCheckingOptions.BackgroundChecking = False
answered Jan 21, 2011 at 2:35
Marc ThibaultMarc Thibault
1,7081 gold badge13 silver badges14 bronze badges
1
I found the answer that I was after:
Sub Auto_Open()
Application.ErrorCheckingOptions.BackgroundChecking = False
End Sub
answered Jan 21, 2011 at 2:34
Craig TCraig T
2,7615 gold badges25 silver badges33 bronze badges
0
I usually split my workbook tabs into Data, Calculations and Presentation. As such, I don’t like the green error checking triangles for tables within my ‘Presentation’ tabs. One approach is to protect the sheet…the green checks go away! (and only for that tab)
If you still want the protected tab to be accessible then just unlock all the cells and select the appropriate protection options prior to protecting it.
I’d stay away from using macros as this may affect the users settings across various workbooks and tabs.
answered May 26, 2016 at 14:58
Simply use this:
With Application.ErrorCheckingOptions
.BackgroundChecking = False
.EvaluateToError = False
.TextDate = False
.NumberAsText = False
.InconsistentFormula = False
.OmittedCells = False
.UnlockedFormulaCells = False
.ListDataValidation = False
End With
If you use the above code, it turns off this future forever and for all excel documents.
But If you would like to do it just for your excel document (not for all) do this:
'''''''''''''''' IN A MODULE '''''''''''''''''''
Public AE_BackgroundChecking As Boolean
Public AE_EvaluateToError As Boolean
Public AE_TextDate As Boolean
Public AE_NumberAsText As Boolean
Public AE_InconsistentFormula As Boolean
Public AE_OmittedCells As Boolean
Public AE_UnlockedFormulaCells As Boolean
Public AE_ListDataValidation As Boolean
Public AE_EmptyCellReferences As Boolean
''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''' IN WORKBOOK OPEN EVENT '''''''''''''
AE_BackgroundChecking = Application.ErrorCheckingOptions.BackgroundChecking
AE_EvaluateToError = Application.ErrorCheckingOptions.EvaluateToError
AE_TextDate = Application.ErrorCheckingOptions.TextDate
AE_NumberAsText = Application.ErrorCheckingOptions.NumberAsText
AE_InconsistentFormula = Application.ErrorCheckingOptions.InconsistentFormula
AE_OmittedCells = Application.ErrorCheckingOptions.OmittedCells
AE_UnlockedFormulaCells = Application.ErrorCheckingOptions.UnlockedFormulaCells
AE_ListDataValidation = Application.ErrorCheckingOptions.ListDataValidation
AE_EmptyCellReferences = Application.ErrorCheckingOptions.EmptyCellReferences
With Application.ErrorCheckingOptions
.BackgroundChecking = False
.EvaluateToError = False
.TextDate = False
.NumberAsText = False
.InconsistentFormula = False
.OmittedCells = False
.UnlockedFormulaCells = False
.ListDataValidation = False
.EmptyCellReferences = False
End With
''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''' IN WORKBOOK CLOSE EVENT '''''''''''''
Application.ErrorCheckingOptions.BackgroundChecking = AE_BackgroundChecking
Application.ErrorCheckingOptions.EvaluateToError = AE_EvaluateToError
Application.ErrorCheckingOptions.TextDate = AE_TextDate
Application.ErrorCheckingOptions.NumberAsText = AE_NumberAsText
Application.ErrorCheckingOptions.InconsistentFormula = AE_InconsistentFormula
Application.ErrorCheckingOptions.OmittedCells = AE_OmittedCells
Application.ErrorCheckingOptions.UnlockedFormulaCells = AE_UnlockedFormulaCells
Application.ErrorCheckingOptions.ListDataValidation = AE_ListDataValidation
Application.ErrorCheckingOptions.EmptyCellReferences = AE_EmptyCellReferences
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
answered May 7, 2015 at 6:26
1
Return to VBA Code Examples
This tutorial will demonstrate how to ensure that VBA Ignores an Error when running your code.
Sometimes when you construct VBA code, you actually want VBA to ignore a line of code when an error occurs. This can actually be quite useful if, for example, you want to delete a sheet if it exists, but ignore that line of code if the sheet doesn’t exist.
(See our Error Handling Guide for more information about VBA Errors)
On Error Resume Next
To ignore a line of code in a procedure, we use the On Error Resume Next statement.
Sub TestErrorIgnore()
On Error Resume Next
ActiveWorkbook.Sheets("Sheet4").select
ActiveSheet.Delete
'more code here
End Sub
In the example above, an On Error Resume Next statement has been placed at the top of the procedure. The code is then constructed to select Sheet4 and then delete it.
However, due to the On Error Resume Next statement, if the code does not find Sheet4, it will just carry on to the next line, and delete whichever active sheet it finds.
This can be quite dangerous if it was only Sheet 4 you wanted to delete and not just the Sheet that is active. To prevent this error, we can set a variable to sheet 4 and delete only that sheet IF it exists.
Sub TestErrorIgnore()
Dim ws As Worksheet
On Error Resume Next
Set ws = ActiveWorkbook.Sheets("Sheet4")
ws.Delete
'more code here
End Sub
Now when the code is run, only Sheet4 will be deleted IF Sheet4 actually exists. If Sheet 4 does not exist, VBA will ignore the error and carry on going.
Another example of this is if you want to delete all the sheets from your workbook using a loop. As an Excel workbook has to have at least one sheet, the code will delete all the sheets except one.
Sub DeleteSheets()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Sheets
ws.Delete
Next ws
End Sub
The code above will stop with an error.
Clicking Debug will take us into the code with the offending line highlighted!
However, adding the On Error Resume Next line to the code will prevent the error and the routine will always leave one sheet in the workbook.
Sub DeleteSheets()
'add error line here
On Error Resume Next
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Sheets
ws.Delete
Next ws
End Sub
On Error GoTo 0
Often if you use On Error Resume Next to ignore an error, you want error trapping later on in the code, or you want your code to stop running if an error occurs in the future. We can re-set the error handling so that the code will once again break on errors by adding the line On Error GoTo 0.
Sub TestErrorIgnore()
Dim ws As Worksheet
On Error Resume Next
Set ws = ActiveWorkbook.Sheets("Sheet4")
ws.Delete
On Error GoTo 0
'more code here
End Sub
VBA Coding Made Easy
Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!
Learn More!
Активизирует подпрограмму обработки ошибок и указывает положение подпрограммы в процедуре; используется также для отключения подпрограммы обработки ошибок.
- On Error GoTo строка — Активизирует подпрограмму обработки ошибок, начало которой определяется обязательным аргументом строка, значением которого может быть любая метка строки или номер строки. Если возвращается ошибка выполнения, управление передается на указанную строку и запускается обработчик ошибок. Аргумент строка должен определять строку в той же процедуре, в которой находится инструкция On Error; в противном случае возникает ошибка компиляции.
- On Error Resume Next — Указывает, что возникновение ошибки выполнения приводит к передаче управления на инструкцию, непосредственно следующую за инструкцией, при выполнении которой возникла ошибка. Рекомендуется при доступе к объектам использовать эту форму инструкции, а не On Error GoTo.
- On Error GoTo 0 — Отключает любой активизированный обработчик ошибок в текущей процедуре.
Замечания
Если не выполнена инструкция On Error, то любая ошибка выполнения является фатальной; это означает, что выводится сообщение об ошибке и выполнение программы прекращается.
«Включенным» обработчиком ошибок называют подпрограмму, которая указана в инструкции On Error; «активным» обработчиком ошибок является включенный обработчик ошибок, который обрабатывает текущую ошибку. Если ошибка возникает в самом обработчике ошибок (в промежутке между возникновением ошибки и выполнением инструкции Resume, Exit Sub, Exit Function или Exit Property), то обработчик ошибок, определенный в текущей процедуре, не может обработать ошибку. Управление в этом случае возвращается в вызывающую процедуру; если в вызывающей процедуре включен обработчик ошибок, то обработка ошибки передается ему. Если этот обработчик ошибок является в данный момент активным, т.е. уже обрабатывает ошибку, то управление снова передается назад в вызывающую процедуру и т.д. до тех пор, пока не будет найден включенный, но не активный обработчик ошибок. Если включенный, но неактивный обработчик ошибок найден не будет, ошибка становится фатальной в том месте программы, в котором она впервые возникла. При каждой передаче управления обработчиком ошибок в вызывающую процедуру эта процедура становится текущей. После завершения обработки ошибки обработчиком в любой процедуре возобновляется выполнение текущей процедуры с той ее части, которая указана в инструкции Resume.
Подпрограмма обработки ошибок не может быть процедурой Sub или Function. Эта подпрограмма должна быть частью программы, которая отмечается с помощью метки строки или номера строки.
Для определения причины ошибки в подпрограммах обработки ошибок используют значение свойства Number объекта Err. Необходимо обеспечить в подпрограммах обработки ошибок проверку или сохранение существенных значений свойств объекта Err перед тем, как может возникнуть новая ошибка или перед вызовом процедуры, в которой может возникнуть новая ошибка. Значения свойств объекта Err описывают последнюю ошибку. Текст сообщения об ошибке, соответствующего коду ошибки Err.Number содержится в свойстве Err.Description.
Конструкция On Error Resume Next задает продолжение выполнения с инструкции, непосредственно следующей за инструкцией, которая привела к ошибке выполнения, или с инструкции, непосредственно следующей за вызывающей инструкцией в процедуре, содержащей конструкцию On Error Resume Next. Это позволяет продолжить исполнение программы несмотря на ошибку выполнения. Это позволяет также встроить подпрограмму обработки ошибок в процедуру, а не передавать управление в другую часть процедуры. Конструкция On Error Resume Next становится неактивной при вызове новой процедуры, поэтому для внутренней обработки ошибок необходимо выполнять инструкцию On Error Resume Next в каждой вызываемой процедуре.
При обработке ошибок, возникающих при доступе к другим объектам, рекомендуется использовать конструкцию On Error Resume Next, а не конструкцию On Error GoTo. Проверка объекта Err после каждого взаимодействия с другим объектом позволяет устранить неопределенность в том, при доступе к какому объекту возникла ошибка. Это позволяет всегда точно знать, какой объект поместил значение кода ошибки в свойство Err.Number, а также в каком объекте возникла ошибка (эта информация содержится в свойстве Err.Source).
Конструкция On Error GoTo 0 отключает обработку ошибок в текущей процедуре. Эта конструкция не задает переход на строку 0 для обработки ошибок, даже если в процедуре имеется строка с номером 0. Если инструкция On Error GoTo 0 не выполнялась, то обработчик автоматически отключается при выходе из процедуры.
Для того, чтобы предотвратить выполнение программы обработки ошибок в тех случаях, когда ошибка не возникла, следует помещать соответствующую инструкцию Exit Sub, Exit Function или Exit Property сразу после подпрограммы обработки ошибки, как в следующем примере:
Sub InitializeMatrix(Var1, Var2, Var3, Var4) On Error GoTo ОбработкаОшибок . . . Exit Sub ОбработкаОшибок: . . . Resume Next End Sub
В этом примере программа обработки ошибок помещена между инструкциями Exit Sub и End Sub, что позволяет отделить ее от части программы, соответствующей нормальному выполнению процедуры. Программу обработки ошибок можно разместить в любом месте процедуры.
Ошибки, которые не были перехвачены, возвращаются в управляющее приложение, если объект был запущен как исполняемый файл. В среде разработчика такие ошибки возвращаются в управляющее приложение только при указании соответствующих параметров. За описанием необходимых значений этих параметров и способов их задания следует обращаться к документации главного приложения. Там же следует проверить, позволяет ли главное приложение создавать классы.
Err.Number = vbObjectError + 1052
Системные ошибки при вызовах библиотек динамической компоновки (DLL) не приводят к возникновению исключений и не перехватываются средствами Visual Basic. При вызове функций из библиотек DLL необходимо проверять, успешно ли возвращается каждое значение (согласно спецификациям API), и в случае неудачи проверять значение свойства LastDLLError объекта Err.
Пример
В начале этой программы инструкция On Error GoTo определяет положение подпрограммы обработки ошибок в процедуре. В данном примере попытка удалить открытый файл приводит к возникновению ошибки с кодом 55. Ошибка обрабатывается в подпрограмме, после чего управление возвращается инструкции, которая привела к возникновению ошибки. Инструкция On Error GoTo 0 отключает перехват ошибок. После этого инструкция On Error Resume Next задает отложенный перехват ошибок, что позволяет точно определить, в каком контексте возникла ошибка, генерируемая в следующей инструкции. Следует отметить, что после обработки ошибки вызывается метод Err.Clear для сброса значений свойств объекта Err.
Sub OnErrorStatementDemo() On Error GoTo ErrorHandler ' Включаем программу обработки ' ошибок. Open "TESTFILE" For Output As #1 ' Открываем файл. Kill "TESTFILE" ' Попытка удалить открытый ' файл. On Error Goto 0 ' Отключаем перехват ошибок. On Error Resume Next ' Откладываем перехват ошибок. ObjectRef = GetObject("MyWord.Basic") ' Запускаем несуществующий ' объект, а затем проверяем ' ошибку механизма управления ' программируемыми объектами. If Err.Number = 440 Or Err.Number = 432 Then ' Выводим сообщение для пользователя и очищаем объект Err. Msg = "Ошибка при попытке открыть программируемый объект!" MsgBox Msg, , "Проверка отложенной ошибки" Err.Clear ' Очищаем поля объекта Err. End If Exit Sub ' Выходим из процедуры, чтобы ' не попасть в обработчик. ErrorHandler: ' Обработчик ошибок. Select Case Err.Number ' Определяем код ошибки. Case 55 ' "Ошибка "Файл уже открыт". Close #1 ' Закрываем открытый файл. Case Else ' Здесь размещаются инструкции для обработки других ошибок... End Select Resume ' Возобновляем выполнение ' со строки, вызвавшей ошибку. End Sub