Err объект
При возникновении ошибки вы можете просмотреть детали
ошибки, используя объект Err.
При возникновении ошибки времени выполнения VBA
автоматически заполняет объект Err деталями.
Приведенный ниже код выведет «Error Number: 13 Type
Mismatch», которое возникает, когда мы пытаемся поместить строковое значение в
длинное целое число.
Sub IspErr() On Error Goto eh Dim total As Long total = "aa" Done: Exit Sub eh: Debug.Print "Номер ошибки: " & Err.Number _ & " " & Err.Description End Sub
Err.Description предоставляет подробную информацию об ошибке, которая происходит. Это текст, который вы обычно видите, когда возникает ошибка, например, «Несоответствие типов»
Err.Number — это идентификационный номер ошибки, например, номер ошибки для «Несоответствие типов» — 13. Единственное время, когда вам действительно нужно это, если вы проверяете, что произошла конкретная ошибка, и это необходимо только в редких случаях.
Свойство Err.Source кажется отличной идеей, но оно не работает при ошибке VBA. Источник вернет имя проекта, которое вряд ли сузит место возникновения ошибки. Однако, если вы создаете ошибку с помощью Err.Raise, вы можете установить источник самостоятельно, и это может быть очень полезно.
Получение номера строки
Функция Erl используется для возврата номера строки, где
произошла ошибка.
Это часто вызывает путаницу. В следующем коде Erl вернет ноль.
Sub IspErr() On Error Goto eh Dim val As Long val = "aa" Done: Exit Sub eh: Debug.Print Erl End Sub
Это потому, что нет номеров строк. Большинство людей не
понимают этого, но VBA позволяет вам иметь номера строк.
Если мы изменим подпрограмму, указав номер строки, она теперь выведет 20.
Sub IspErr() 10 On Error Goto eh Dim val As Long 20 val = "aa" Done: 30 Exit Sub eh: 40 Debug.Print Erl End Sub
Добавление номеров строк в код вручную затруднительно.
Однако есть инструменты, которые позволят вам легко добавлять и удалять номера
строк в подпрограмме.
Когда вы закончите работу над проектом и передадите его
пользователю, в этот момент может быть полезно добавить номера строк. Если вы
используете стратегию обработки ошибок в последнем разделе этого поста, то VBA
сообщит строку, где произошла ошибка.
Использование Err.Raise
Err.Raise позволяет нам создавать ошибки. Мы можем
использовать его для создания пользовательских ошибок для нашего приложения,
что очень полезно. Это эквивалент оператора Throw в Java \ C #.
Формат следующий
Err.Raise , ,
Давайте посмотрим на простой пример. Представьте, что мы
хотим убедиться, что в ячейке есть запись длиной 5 символов. Мы могли бы иметь конкретное сообщение для
этого
Public Const ERROR_INVALID_DATA As Long = vbObjectError + 513 Sub ReadWorksheet() On Error Goto eh If Len(Sheet1.Range("A1")) <> 5 Then Err.Raise ERROR_INVALID_DATA, "ReadWorksheet" _ , "Значение в ячейке A1 должно иметь ровно 5 символов." End If ' продолжить, если ячейка имеет действительные данные Dim id As String id = Sheet1.Range("A1") Done: Exit Sub eh: ' Err.Raise отправит код сюда MsgBox " Обнаружена ошибка: " & Err.Description End Sub
Когда мы создаем ошибку, используя Err.Raise, нам нужно присвоить ей номер. Мы можем использовать любое
число от 513 до 65535 для нашей ошибки. Мы должны использовать vbObjectError с номером,
например
Err.Raise vbObjectError + 513
Использование Err.Clear
Err.Clear используется для очистки текста и чисел из объекта
Err.Object. Другими словами, он очищает описание и номер.
Редко вам понадобится его использовать, но давайте
рассмотрим пример, где вы могли бы.
В приведенном ниже коде мы подсчитываем количество ошибок,
которые могут возникнуть. Для простоты мы генерируем ошибку для каждого
нечетного числа.
Мы проверяем номер ошибки каждый раз, когда проходим цикл.
Если число не равно нулю, то произошла ошибка. Как только мы посчитаем ошибку,
нам нужно установить номер ошибки на ноль, чтобы он был готов проверить
следующую ошибку.
Sub IspErrClear() Dim count As Long, i As Long ' Продолжите, если ошибка, так как мы проверим номер ошибки On Error Resume Next For i = 0 To 9 ' генерировать ошибку для каждого второго If i Mod 2 = 0 Then Error (13) ' Проверьте на ошибку If Err.Number <> 0 Then count = count + 1 Err.Clear ' Очистить Err, как только он считается End If Next Debug.Print " Количество ошибок было: " & count End Sub
Примечание: Err.Clear сбрасывает текст и цифры в объекте ошибки, но не очищает ошибку — см. On Error Goto -1 для получения дополнительной информации об очистке фактической ошибки.
A Simple Error Handling Strategy
With all the different options you may be confused about how to use error handling in VBA. In this section, I’m going to show you how to implement a simple error handling strategy that you can use in all your applications.
The Basic Implementation
This is a simple overview of our strategy
- Place the On Error GoTo Label line at the start of our topmost sub.
- Place the error handling Label at the end of our topmost sub.
- If an expected error occurs then handle it and continue.
- If the application cannot continue then use Err.Raise to jump to the error handling label.
- If an unexpected error occurs the code will automatically jump to the error handling label.
The following image shows an overview of how this looks
The following code shows a simple implementation of this strategy:
' https://excelmacromastery.com/ Public Const ERROR_NO_ACCOUNTS As Long = vbObjectError + 514 Sub BuildReport() On Error Goto eh ' If error in ReadAccounts then jump to error ReadAccounts ' Do something with the code Done: Exit Sub eh: ' All errors will jump to here MsgBox Err.Source & ": The following error occured " & Err.Description End Sub Sub ReadAccounts() ' EXPECTED ERROR - Can be handled by the code ' Application can handle A1 being zero If Sheet1.Range("A1") = 0 Then Sheet1.Range("A1") = 1 End If ' EXPECTED ERROR - cannot be handled by the code ' Application cannot continue if no accounts workbook If Dir("C:\Docs\Account.xlsx") = "" Then Err.Raise ERROR_NO_ACCOUNTS, "UsingErr" _ , "There are no accounts present for this month." End If ' UNEXPECTED ERROR - cannot be handled by the code ' If cell B3 contains text we will get a type mismatch error Dim total As Long total = Sheet1.Range("B3") ' continue on and read accounts End Sub
This is a nice way of implementing error handling because
- We don’t need to add error handling code to every sub.
- If an error occurs then VBA exits the application gracefully.
Обработка ошибок VBA
Различные типы ошибок в VBA
Вышеуказанные ошибки могут быть исправлены с помощью нижеупомянутой отладки и различных операторов ‘On Error’, вставленных между кодом.
При ошибке возобновить следующее
При ошибке Перейти к 0
При ошибке Перейти к
Обработка ошибок VBA с помощью различных операторов ‘ON ERROR’
При возникновении ошибки в утверждении или синтаксисе кода VBA, при неправильном вводе кода по ошибке он будет выделен красным цветом в зависимости от параметров настройки в инструментах (если вы выбрали автоматическую проверку синтаксиса).
При запуске кода с неправильным синтаксисом появится всплывающее сообщение об ошибке компиляции.
В приведенном выше примере я не объявил тип переменной как String, поэтому возникает эта ошибка. Итак, мне нужно объявить переменную как Dim A As String.
Когда невозможные математические операторы или термины присутствуют в операторе, возникает ошибка во время выполнения.
Эти ошибки очень трудно отследить, они не подсвечиваются и не появляется всплывающее сообщение об ошибке. это приведет к неожиданным действиям и неправильным результатам.
Пример: если в коде присутствуют две переменные, они могут содержать неверную. В этом случае возникает логическая ошибка.
Как предотвратить ошибки в VBA?
Давайте посмотрим, как предотвратить различные типы ошибок в VBA Excel.
Шаг 2. Чтобы создать пустой модуль, в объектах Microsoft Excel щелкните правой кнопкой мыши лист 1 (VB_ERROR HANDLING) и вставьте модуль, чтобы создать новый пустой модуль.
Обработка ошибок VBA с опцией отладки
Лучше скомпилировать код, прежде чем мы его запустим. Чтобы выполнить компиляцию, необходимо выполнить следующие шаги. На панели инструментов меню VB под опцией Debug нам нужно выбрать компилируемый проект VBA. Когда вы нажимаете на него, он проверяет код шаг за шагом, как только он находит ошибку, он выделяет ее и появляется всплывающее сообщение, поэтому вам необходимо исправить его. как только это исправлено, вам нужно скомпилировать, чтобы найти следующую ошибку в коде.
Примечание. С помощью опции компиляции мы можем только исправить ошибку компиляции и синтаксиса.
Обработка ошибок VBA с помощью различных операторов ‘ON ERROR’
1. При ошибке возобновить следующее
Здесь ошибка будет игнорироваться, и код будет двигаться дальше.
В приведенном ниже примере значение 6 не может быть разделено на ноль, если вы запустите его, не введя оператор On Error Resume Next, то произойдет ошибка, упомянутая ниже.
Если On Error Resume Next вводится вверху кода после оператора Sub, он игнорирует ошибку времени выполнения и переходит к следующему оператору, что приводит к выводу 6/2, то есть 3 (всплывающее окно сообщения с результатом этого).
«On Error GoTo 0» остановит код в конкретной строке, которая вызывает ошибку, и отобразит окно сообщения, которое описывает или указывает на ошибку.
Как правило, он демонстрирует поведение проверки ошибок по умолчанию, это важно, когда он используется вместе с «On Error Resume Next». On Error GoTo 0 с On Error Resume Next
On Error GoTo 0 с On Error Resume Next
В приведенном выше коде он будет игнорировать ошибки, пока не достигнет оператора On Error GoTo 0. После оператора On Error GoTo 0 код возвращается или переходит к обычной проверке ошибок и вызывает ожидаемую ошибку впереди. когда я запускаю приведенный выше код, он демонстрирует ошибку деления, то есть несоответствие типов (числовое значение не может быть разделено на текст).
3. При ошибке GoTo <LABEL
VBA для передачи управления программой в строку, за которой следует метка, если обнаружены какие-либо ошибки во время выполнения, т. Е. Код переходит к указанной метке. Здесь операторы кода между строкой исключения и меткой не будут выполняться.
Этот метод более подходит и важен для корректного выхода из программы, если во время выполнения возникает серьезная фатальная ошибка.
В приведенном ниже коде VBA, как только ошибка возникает в строке 3, программа передает управление в строку 6, т. Е. Метку (всплывающее сообщение отображается как «Обработчик исключения» ).
Здесь вы можете заметить, что «Exit Sub» следует использовать непосредственно перед меткой «Error_handler:», это делается для того, чтобы блок кода обработчика ошибок останавливался или не выполнялся, если нет ошибки. Теперь вы можете сохранить свою книгу как «книгу с поддержкой макросов Excel». Кликните на сохранить как в левом углу листа.
Еще раз, если вы откроете файл, вы можете нажать на клавишу быстрого доступа, например, Fn + Alt + f8, появится диалоговое окно «Макрос», где вы можете запустить сохраненный код макроса по вашему выбору или вы можете нажать Fn + Alt + F11 для полное окно макроса.
The VBA Err Object
Whenever a VBA error is raised the Err object is updated with relevant information needed to diagnose the error. Let look at this object for a second.
Err Object functions and properties
The Err object facilitates the following functions and properties:
- Number – the most important property of the Err Object, the error number raised. On MSDN you can find the full list of VBA errors. The available range for custom user errors is 513-65535.
- Clear – clear the current Error. Useful when using the Resume Next statement.
- Raise(Number, , , , ) – raises an error. You need to provide an error Number. See here for a whole list of VBA error Numbers. Want to raise a custom error? The available range for custom user errors is 513-65535.
- Source – the source of the error – usually your VBAProject.
- Description – the description of the error.
Dim errMsg As String On Error Resume Next '7 = Out of Memory Err.Raise (7) If Err.Number <> 0 Then errMsg = "Error number: " & Str(Err.Number) & vbNewLine & _ "Source: " & Err.Source & vbNewLine & _ "Description: " & Err.Description Debug.Print errMsg Err.Clear End If
This is the expected output:
Логирование
Ведение журнала означает запись информации из вашего
приложения, когда оно запущено. При возникновении ошибки вы можете записать
детали в текстовый файл, чтобы у вас была запись об ошибке.
Код ниже показывает очень простую процедуру регистрации
Sub Logger(sType As String, sSource As String, sDetails As String) Dim sFilename As String sFilename = "C:\temp\logging.txt" ' Архивный файл определенного размера If FileLen(sFilename) > 20000 Then FileCopy sFilename _ , Replace(sFilename, ".txt", Format(Now, "ddmmyyyy hhmmss.txt")) Kill sFilename End If ' Откройте файл для записи Dim filenumber As Variant filenumber = FreeFile Open sFilename For Append As #filenumber Print #filenumber, CStr(Now) & "," & sType & "," & sSource _ & "," & sDetails & "," & Application.UserName Close #filenumber End Sub
Вы можете использовать это так:
' Создать уникальный номер ошибки Public Const ERROR_DATA_MISSING As Long = vbObjectError + 514 Sub CreateReport() On Error Goto eh If Sheet1.Range("A1") = "" Then Err.Raise ERROR_DATA_MISSING, "CreateReport", "Данные отсутствуют в ячейке A1" End If ' другой код здесь Done: Exit Sub eh: Logger "Error", Err.Source, Err.Description End Sub
Журнал не только для записи ошибок. Вы можете записывать
другую информацию во время работы приложения. При возникновении ошибки вы
можете проверить последовательность событий до того, как произошла ошибка.
Ниже приведен пример регистрации. То, как вы реализуете
журналирование, зависит от характера приложения и его полезности.
Sub ReadingData() Logger "Information", "ReadingData()", "Starting to read data." Dim coll As New Collection ' Read data Set coll = ReadData If coll.Count < 10 Then Logger "Warning", "ReadingData()", "Number of data items is low." End If Logger "Information", "ReadingData()", "Number of data items is " & coll.Count Logger "Information", "ReadingData()", "Finished reading data." End Sub
Наличие большого количества информации при работе с ошибкой
может быть очень полезным. Часто пользователь может не дать вам точную информацию
об ошибке, которая произошла. Глядя на журнал, вы можете получить более точную
информацию об информации.
Ошибки выполнения
Ошибки выполнения возникают в процессе выполнения кода и приводят к остановке выполнения программы. Этот тип ошибок VBA, как правило, также не сложно обнаружить и исправить, так как сообщается информация о характере ошибки и место в коде, где произошла остановка.
Примером такой ошибки может служить попытка выполнить деление на ноль. В результате будет показано сообщение «Run-time error ’11’: Division by zero«.
В зависимости от структуры проекта VBA, может быть предложено выполнить отладку кода (как показано на рисунке ниже). В этом случае при нажатии на кнопку Debug (в окне сообщения о необходимости отладки) будет выделена цветом строка кода, которая стала причиной ошибки VBA.
Получив такое сообщение и видя выделенную строку кода, как в приведённом выше примере, обнаружить причину ошибки будет совсем не сложно.
В случае если код сложнее, чем в нашем примере, то, чтобы получить больше информации о причине возникновения ошибки VBA, можно проверить значения используемых переменных. В редакторе VBA для этого достаточно навести указатель мыши на имя переменной, или можно открыть окно отслеживания локальных переменных (в меню редактора View > Locals Window).
Коды различных ошибок выполнения расшифрованы на сайте Microsoft Support (на английском). Наиболее часто встречающиеся ошибки VBA перечислены в этой таблице:
5 | Недопустимый вызов процедуры (Invalid procedure call) |
7 | Недостаточно памяти (Out of memory) |
9 | Индекс вне заданного диапазона (Subscript out of range)
Эта ошибка возникает при попытке обратиться к элементу массива за пределами заданного размера массива – например, если объявлен массив с индексами от 1 до 10, а мы пытаемся обратиться к элементу этого же массива с индексом 11. |
11 | Деление на ноль (Division by zero) |
13 | Несоответствие типа (Type mismatch)
Эта ошибка возникает при попытке присвоить переменной значение не соответствующего типа – например, объявлена переменная i типа Integer, и происходит попытка присвоить ей значение строкового типа. |
53 | Файл не найден (File not found)
Иногда возникает при попытке открыть не существующий файл. |
Перехват ошибок выполнения
Не все ошибки выполнения бывают вызваны недочётами в коде. Например, ошибки VBA не удастся избежать, если для работы макроса необходимо открыть файл с данными, а этого файла не существует. В таких случаях признаком профессионализма будет перехват ошибок и написание кода VBA, который будет выполняться при их возникновении. Таким образом, вместо неприятных сбоев будет происходить изящное завершение работы макроса.
Для того, чтобы помочь справиться с возникающими ошибками, VBA предоставляет разработчику операторы On Error и Resume. Эти операторы отслеживают ошибки и направляют выполнение макроса в специальный раздел кода VBA, в котором происходит обработка ошибки. После выполнения кода обработки ошибки, работа программы может быть продолжена с того места, где возникла ошибка, или макрос может быть остановлен полностью. Далее это показано на примере.
'Процедура Sub присваивает переменным Val1 и Val2 значения, 'хранящиеся в ячейках A1 и B1 рабочей книги Data.xlsx расположенной в каталоге C:\Documents and Settings Sub Set_Values(Val1 As Double, Val2 As Double) Dim DataWorkbook As Workbook On Error GoTo ErrorHandling 'Открываем рабочую книгу с данными Set DataWorkbook = Workbooks.Open("C:\Documents and Settings\Data") 'Присваиваем переменным Val1 и Val2 данные из рабочей книги DataWorkbook Val1 = Sheets("Лист1").Cells(1, 1) Val2 = Sheets("Лист1").Cells(1, 2) DataWorkbook.Close Exit Sub ErrorHandling: 'Если файл не найден, предлагаем пользователю разместить его в 'нужном месте и продолжить работу MsgBox "Рабочая книга не найдена! " & _ "Пожалуйста добавьте книгу Data.xlsx в каталог C:\Documents and Settings и нажмите OK." Resume End Sub
В этом коде производится попытка открыть файл Excel с именем Data. Если файл не найден, то пользователю будет предложено поместить этот файл в нужную папку. После того, как пользователь сделает это и нажмёт ОК, выполнение кода продолжится, и попытка открыть этот файл повторится. При желании вместо попытки открыть нужный файл, выполнение процедуры Sub может быть прервано в этом месте при помощи команды Exit Sub.
Полная стратегия обработки ошибок
Стратегия выше имеет один недостаток. Он не сообщает вам, где произошла ошибка. VBA не наполняет Err.Source чем-либо полезным, поэтому мы должны сделать это сами.
В этом разделе я собираюсь представить более полную стратегию ошибок. Я написал два сабвуфера, которые выполняют всю тяжелую работу, поэтому все, что вам нужно сделать, это добавить их в свой проект.
Целью этой стратегии является предоставление вам стека * и номера строки в случае возникновения ошибки.
Это наша стратегия
- Разместите обработку ошибок во всех подпрограммах.
- Когда происходит ошибка, обработчик ошибок добавляет подробности к ошибке и вызывает ее снова.
- Когда ошибка достигает самой верхней подпрограммы, она отображается.
Мы просто «всплываем» из-за ошибки. Следующая диаграмма показывает простое визуальное представление о том, что происходит, когда в Sub3 возникает ошибка
Это две вспомогательные подводные лодки
Пример использования этой стратегии
Вот простое кодирование, которое использует эти Sub. В этой стратегии мы не размещаем какой-либо код в верхнем подпрограмме. Мы только вызываем подводные лодки.
Результат выглядит так
Если в вашем проекте есть номера строк, результат будет содержать номер строки ошибки.
Примечание: вы можете получить следующую ошибку при использовании этого кода:
Возбуждение ошибки может быть сделано самой операционной системой (VBA) или исполняемой процедурой(почти все они классифицированы и каждая из них однозначно идентифицируется своим номером).
Собственные или пользовательские ошибки, возбуждение которых предусматривает программист,например, при работе с объектом пользовательского класса .
При возбуждении ошибки (внутренней или пользовательской), в момент возбуждения ошибки заполняются свойства объекта Err, так что он содержит всю информацию о последней возникшей ошибке.
Синтаксически охраняемый блок окружен специальными операторами On Error.
Обработчик ошибок, как правило, завершается специальным оператором Resume, который задает точку в процедуре, которой передается управление после завершения обработки ошибки.
Схема процедуры с тремя охраняемыми блоками (разные варианты обработки ошибок):
Варианты комбинаций операторов On Error и Resume:
On Error GoTo строка; On Error Resume Next; On Error GoTo 0; On Error Resume (или On Error Resume (0) )
On Error GoTo строка — управление покидает охраняемый блок и передается на указанную строку, запуская, тем самым, обработчик ошибок, начинающийся в этой строке.
On Error Resume Next — такая ситуация разумна, когда вслед за оператором, при выполнении которого потенциально возможна ошибка,помещается оператор, анализирующий объект Err.
On Error GoTo 0 -он завершает охраняемый блок. Оператор можно опускать, если охраняемый блок завершается вместе с самой процедурой.
On Error Resume (или On Error Resume (0) ) — выполнение программы продолжается с повторного выполнения оператора, вызвавшего ошибку. Используется,например, когда ошибка вызвана вводом неверных данных пользователем, а в обработчике ошибок у него запрашиваются новые правильные данные.
Объект Err содержит информацию о последней ошибке выполнения. Объект Err создается системой вместе с проектом. Очистка объекта Err может производиться принудительно (использование метода Clear): Err.Clear
Автоматическая очистка свойств объекта Err происходит также при выполнении операторов:
оператора Resume любого вида; Exit Sub, Exit Function, Exit Property ; оператора On Error любого вида.
-
Как сбросить биос на ноутбуке
-
Outlook 2016 подключение к exchange очень долго
-
Копировать css в фотошопе что это
-
Asus p5k настройка bios на максимальную производительность
- Как удалить доску в pinterest на компьютере
Ошибки компиляции
Компилятор VBA рассматривает ошибки компиляции как недопустимые и выделяет их в коде ещё до того, как дело дойдёт до запуска макроса.
Если при написании кода допущена синтаксическая ошибка, то редактор VBA сигнализирует об этом немедленно: либо при помощи окна с сообщением, либо выделяя ошибку красным цветом, в зависимости от статуса режима Auto Syntax Check.
Примечание: При включённом режиме Auto Syntax Check каждый раз, при появлении в редакторе Visual Basic во введённом коде синтаксической ошибки, будет показано соответствующее сообщение. Если же этот режим выключен, то редактор VBA продолжит сообщать о синтаксических ошибках, просто выделяя их красным цветом. Опцию Auto Syntax Check можно включить/выключить в меню Tools > Options редактора Visual Basic.
В некоторых случаях ошибка компиляции может быть обнаружена при выполнении компиляции кода, непосредственно перед тем, как макрос будет выполнен. Обычно ошибку компиляции несложно обнаружить и исправить, потому что компилятор VBA даёт информацию о характере и причине ошибки.
Например, сообщение “Compile error: Variable not defined” при попытке запустить выполнение кода VBA говорит о том, что происходит попытка использовать или обратиться к переменной, которая не была объявлена для текущей области (такая ошибка может возникнуть только если используется Option Explicit).
Other VBA Error Terms
VBA Catch Error
Unlike other programming languages, In VBA there is no Catch Statement. However, you can replicate a Catch Statement by using On Error Resume Next and If Err.Number <> 0 Then. This is covered above in .
VBA Ignore Error
To ignore errors in VBA, simply use the On Error Resume Next statement:
However, as mentioned , you should be careful using this statement as it doesn’t fix an error, it just simply ignores the line of code containing the error.
VBA Throw Error / Err.Raise
To through an error in VBA, you use the Err.Raise method.
This line of code will raise Run-time error ’13’: Type mismatch:
A VBA Error Message looks like this:
When you click ‘Debug’, you’ll see the line of code that is throwing the error:
VBA Error Handling in a Loop
The best way to error handle within a Loop is by using On Error Resume Next along with Err.Number to detect if an error has occurred (Remember to use Err.Clear to clear the error after each occurrence).
The example below will divide two numbers (Column A by Column B) and output the result into Column C. If there’s an error, the result will be 0.