Remkomplekty.ru

IT Новости из мира ПК
7 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Коды ошибок vba excel

Коды ошибок vba excel

Поискав по рунету материал на тему обработки ошибок в VBA, не увидал на первых двух страницах результатов поиска чего-то, что мне понравилось. Может плохо смотрел, но решил написать на эту тему свою статью.

Простите, но — немного словоблудия 🙂

Ошибки в программе

Ошибки времени исполнения программы возникают, когда среда программирования не может выполнить то, что вы хотите. Таких ситуаций может быть много. Например:

Вы обращаетесь к объекту по имени, а объекта с таким именем в коллекции нет

Вы хотите выделить ячеку на одном листе, а этот лист в данный момент не является активным (типичнейшая ошибка новичков в Excel VBA)

Вы хотите удалить отфильтрованные автофильтром строки, а фильтр вообще не вернул записей и удалять нечего

Вы ссылаетесь на элемент массива, который находится за пределами его границ.

Вы пытаетесь присвоить переменной значение, которое оно не может хранить. Например, переменной типа Long нельзя присвоить строковую константу или переменной типа Integer присвоить знанчение превышающее число 32767 .

На любую из этих и сотни других ситуаций среда выполнения реагирует стандартно — прерывает ход выполнения программы на том операторе, где возникла ошибка или, как ещё принято говорить, исключение. На экран выводится информация о возникшей ошибке и предлагаются стандартные варианты для продолжения работы:

Continue (продолжить) — этот пункт во время возникновения ошибки всегда не активен. Он активен, когда по ходу выполнения программы вы использовали оператор Stop . Кстати это очень полезный оператор для отладки программы.

End (завершить) — завершение исполнения программы

Debug (отладка) — переход в режим отладки, в котором можно посмотреть, на каком операторе возникла ошибка, что содержат переменные, можно даже перетащить жёлтую полоску, подсвечивающую текущий оператор, назад, и модифицировать знанчение переменных через окно Immediate window (впрочем это экзотика). В общем случае кнопка Debug позволяет посмотреть, где случилась ошибка и попытаться понять почему так случилось.

Если вы — автор программы, в которой случилась ошибка, то вы, должно быть, в начале будете рады увидеть подобное окно, ибо только так вы сможете отловить основные ошибки, скрытые в вашем коде. Однако, если эту ошибку видит пользователь, то для него это, мягко говоря, безрадостное и малопонятное зрелище. Ещё хуже, если за эту программу вам заплатили деньги. Поэтому в среде худо-бедно профессиональных программистов принято предусматривать обработку ошибок в своих программах.

Почему вообще в коде возникают ошибки?

Много ошибок во время написания кода возникает по невнимательности или не совсем адекватного понимания того, что делаешь. Таких ошибок, как правило, очень много, особенно у начинающих программистов, но эти ошибки довольно легко отловить и исправить, так как, пока вы их не исправите, ничего не работает. Ну, например, вы должны извлечь данные из 5-го столбца, а вы извлекаете из 6-го, а их там банально нет. Ясно, что вы это очень быстро заметите.

Вторая группа ошибок — это ошибки оптимиста. Когда программа написана в целом правильно, но алгоритм не готов к ударам судьбы в виде неожиданных действий со стороны пользователя, ошибок ввода-вывода (вы рассчитывали считать данные из файла, а файла с таким именем не оказалось, либо он заблокирован другим приложением), особенностей конфигурации компьютера (разные версии ОС или офиса, которые в некоторых мелочах отличаются).

Тонкие логические ошибки. Чем сложнее программа, тем больше шансов, что модель задачи в вашей голове, ваша программа и реальность не совсем согласованы между собой. Пока вы не достигните достаточного погружения в задачу вы такие ошибки не найдёте и не исправите. Порой на это уходит много времени. Но это характерно для сложных задач.

Ошибки на стыке вашего приложения и сервисов ОС, приводящие к неожиданным крахам приложения. Такого вообще возникать не должно, но как мы понимаем, и ОС и офис содержат ошибки, да и вы (что более вероятно) можете пользоваться системными вызовами не правильно. Подобные ошибки — сущий кошмар, особенно когда они проявляются лишь на некоторых конфигурациях, при определенных условиях, их трудно поймать и надёжно воспроизвести.

Задачи механизмов обработки ошибок

Обеспечить стабильную работу программы . Возникновение ошибки, появление которой вы не предусмотрели, приведёт в большинстве случаев к аварийному завершению всей программы или её части. При определенном уровне подобных ситуаций это ведёт к тому, что программой пользоваться становится невозможно.

Информирование . Мало обработать ошибку и предотвратить завершение программы. Надо ещё и адекватно проинформировать пользователя о причинах нестандартного поведения программы. Частно причиной ошибок в программе являются некорректные действия пользователя, поэтому важно сообщать ему о них.

Защита данных от повреждения . Программа обязана защищать от непреднамеренных повреждений результаты своей или пользовательской работы. Деструктивные действия должны быть снабжены соответствующими предупредительными диалоговыми окнами. Часто ошибка, не обработанная должным образом может повредить нужные данные.

Файл примера

Скачать

Код без обработки ошибок

Вот простой пример с потолка. Если вызвать Example_00 , то она прекрасно отработает без ошибок и вернёт это:

В функцию GetCalories передаётся строка с блюдом, а она должна вернуть его калорийность, сверившись с таблицей в A1:B7 .

Давайте поищем слабые места в этом коде. Первое, что должно прийти в голову — если мы ищем, то, что произойдёт, если мы не найдём? А произойдёт, конечно же, ошибка. Её инициирует метод Match .

Ещё одно слабое место этой подпрограммы: функция возвращает вещественный тип Double , и даже, если поиск оказался удачным, то в Cells(intRow, 2) может случайно находиться текстовая строка, а потому, когда вы числовому типу попытаетесь присвоить строковый тип, также произойдёт ошибка. И, если вы второй ошибки сможете избежать за счёт дополнительного оператора if с проверкой через IsNumber (), то избежать первой ошибки таким способом нельзя. Что же делать? А вот тут на сцену выходят операторы обработки ошибок.

Есть 2 подхода к обработке ошибок: автономный подход и выносной . Эти термины я придумал только что, чтобы проще было их обсуждать.

Автономный подход

Смысл автономного подхода в том, чтобы не выносить сор из избы. Если в подпрограмме возникла ошибка, то мы должны предположить, на каком месте она возникнет и поджидать её там с дубиной. С ошибкой, в этом случае, разбираются обычно в операторе, идущем сразу после потенциально опасного места. Давайте смотреть, как это может выглядеть:

Итак, что тут сделано:

Сразу после объявления функции GetCalories_v1 идёт оператор on error resume next , который в случае возникновения в каком-либо месте ошибки, предписывает VBA просто передавать управление на следующий оператор, идущий после ошибочного.

Мы объявили переменные. Необъявленные переменные получают тип Variant и значение по умолчанию Empty . Объявленные переменные числовых типов инициируются нулём, строковые — пустой строкой, то есть я наперёд знаю, что они содержат, а это хорошо для обработки ошибок.

На вызове метода WorksheetFunction.Match у нас возникает ошибка, так как искомого значения в таблице нет. А это, между прочим, был оператор присваивания ( = ). Прежде, чем левой части оператора присваивания ( intRow ) что-то будет присвоено, необходимо вычислить правую часть оператора присваивания ( WorksheetFunction.Match . ), а поскольку в процессе этого вычисления возникает ошибка, то переменная intRow остаётся такой, какой была! А, как я уже сказал, VBA автоматически её инициализирует нулём до начала исполнения подпрограммы. Получается, что, если в этом операторе возникнет ошибка, то в intRow будет ноль. Если ошибки во время поиска не возникнет, то ноля там не будет ни при каких раскладах, так как строки на листе нумеруются с единицы.

И вот этот ноль мы и контролируем, добавляя оператор If . Если intRow больше нуля, то WorksheetFunction.Match отработала штатно, а если нет — то работу подпрограммы надо прерывать, но об этом чуть позже.

Читать еще:  Как создать надстройку в excel

Далее мы помним, что Cells(intRow, 2) может теоретически вернуть строковое значение, которое вызовет ошибку Type missmatch при присвоении переменной типа Double ( GetCalories_v1 ), поэтому мы вставляем дополнительную проверку промежуточной переменной varTemp тому, что она числовая. И если это так, то присваиваем GetCalories_v1 значение из varTemp .

В случае возникновения любой ошибки внутри GetCalories_v1 она просто вернёт ноль. Почему ноль? Потому что переменная GetCalories_v1 тоже инициализируется нулём и об этом не надо заботиться, а в случае ошибки она останется в неприкосновенности.

Соответственно родительский код (в нашем случае его роль играет процедура Example_01 ) должен проверить, а не вернёт ли GetCalories_v1 ноль, и быть готовым к этой ситуации.

А вот теперь тонкий момент, который не все понимают. Почему я использовал промежуточные переменные intRow и varTemp ? Вроде бы есть очевидный ответ — чтобы не вычислять значение выражений с Match и Cells 2 раза. Отчасти это, конечно, так. Но это, в данном случае, не главная причина. Главная причина в том, что такой код

вызовет неправильное поведение программы. Если у нас Match вызовет исключение, то VBA передаст управление на СЛЕДУЮЩИЙ оператор, а следующий оператор в данном случае это то, что идёт после Then — присваивание переменной varTemp значения. Таким образом наша проверка на наличие ошибки сработает с точностью до наоборот, передав управление в ту часть кода, которая должна быть защищена от ситуации, когда Match не нашла строку в таблице. Вот почему важно в операторе If не иметь ничего такого, что могло бы вызвать ошибку.

Как видите, в этом подходе мне зачастую даже нет необходимости проверять объект Err , чтобы понять, что произошла ошибка, так как я ориентируюсь на то, что промежуточные переменные остаются неинициализированными, что является показателем наличия ошибки.

Выносной подход

Данный метод основан на том, что, когда возникает ошибка, то VBA передаёт управление на специальный участок кода — обработчик ошибок, который обычно размещают в конце подпрограммы. Это может выглядеть так:

Обратите внимание, что:

Оператор on error теперь в случае ошибки предписывает передавать управление на метку ErrorHandler , которая объявлена в конце кода процедуры GetCalories_v2

В коде мы никак не заботимся о каких-либо проверках. Возникла ошибка? Иди на метку — там разберутся.

Если ошибки не случилось, то, чтобы программа не стала исполнять строчки, предназначенные для обработки ошибок, перед меткой ErrorHandler обычно ставят оператор Exit Sub или Exit Function (в зависимости от типа подпрограммы).

Принципиальный момент — наличие оператора On Error Resume Next сразу после метки ErrorHandler . Дело в том, что после того, как вы перешли на метку ErrorHandler , очень опасно иметь действующим оператор On Error GoTo ErrorHandler , так как, если у вас в обработчике ошибки случится любая ошибка, то управление будет передано опять на метку и, как нетрудно понять, образуется бесконечный цикл. Поэтому сразу после метки мы возможность возникновения цикла ликвидируем оператором On Error Resume Next .

Что лучше?

Какой метод лучше применять зависит от ваших предпочтений и конкретных ситуаций. Грамотную обработку ошибок можно сделать и так и эдак. Вот несколько соображений по преимуществам и недостакам данных подходов:

excel-vba Обработка ошибок

пример

Хорошая обработка ошибок не позволяет конечным пользователям видеть ошибки времени выполнения VBA и помогает разработчику легко диагностировать и исправлять ошибки.

Существует три основных метода обработки ошибок в VBA, два из которых следует избегать для распределенных программ, если это специально не требуется в коде.

По ошибке GoTo 0

Если в вашем коде не установлена ​​ошибка, On Error GoTo 0 является обработчиком ошибок по умолчанию. В этом режиме любые ошибки времени выполнения запускают типичное сообщение об ошибке VBA, позволяющее либо закончить код, либо ввести режим debug , идентифицируя источник. При написании кода этот метод является самым простым и полезным, но его всегда следует избегать для кода, который распространяется среди конечных пользователей, поскольку этот метод очень непригляден и затруднен для понимания конечными пользователями.

On Error Resume Next VBA будет игнорировать любые ошибки, возникающие во время выполнения для всех строк, следующих за вызовом ошибки, до тех пор, пока обработчик ошибок не будет изменен. В очень конкретных случаях эта строка может быть полезна, но ее следует избегать за пределами этих случаев. Например, при запуске отдельной программы из макроса Excel вызов On Error Resume Next может быть полезен, если вы не уверены, открыта ли программа или нет:

Если бы мы не использовали GetObject вызов On Error Resume Next и приложение Powerpoint еще не было открыто, метод GetObject бы ошибку. Таким образом, для устранения двух экземпляров приложения необходимо было On Error Resume Next .

Примечание. Также рекомендуется сразу же сбросить обработчик ошибок, как только вам больше не понадобится On Error Resume Next вызова»

Вкл. Ошибка GoTo

Этот метод обработки ошибок рекомендуется для всего кода, который распространяется среди других пользователей. Это позволяет программисту точно контролировать, как VBA обрабатывает ошибку, отправив код в указанную строку. Тег можно заполнить любой строкой (включая числовые строки) и отправить код в соответствующую строку, за которой следует двоеточие. Несколько блоков обработки ошибок можно использовать, выполняя различные вызовы On Error GoTo

  • . Нижеприведенная подпрограмма демонстрирует синтаксис вызова On Error GoTo
  • .

    Примечание. Важно, чтобы строка Exit Sub была помещена над первым обработчиком ошибок и перед каждым последующим обработчиком ошибок, чтобы предотвратить естественный переход кода в блок без вызываемой ошибки. Таким образом, лучше всего использовать функцию и читаемость для размещения обработчиков ошибок в конце блока кода.

    Если вы выйдете из своего метода с кодом обработки ошибок, убедитесь, что вы очистили:

    • Отменить все, что частично завершено
    • Закрыть файлы
    • Сбросить обновление экрана
    • Сбросить режим расчета
    • Сбросить события
    • Сбросить указатель мыши
    • Вызов метода выгрузки для экземпляров объектов, которые сохраняются после End Sub
    • Сброс строки состояния

    Типы ошибок в VBA

    При выполнении макросов Excel могут возникнуть ошибки, которые в VBA делят на три категории:

    Далее мы поговорим о каждом из трёх типов ошибок VBA подробно.

    Ошибки компиляции

    Компилятор 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).

    Читать еще:  Vba excel округление до целого

    Ошибки выполнения

    Ошибки выполнения возникают в процессе выполнения кода и приводят к остановке выполнения программы. Этот тип ошибок VBA, как правило, также не сложно обнаружить и исправить, так как сообщается информация о характере ошибки и место в коде, где произошла остановка.

    Примером такой ошибки может служить попытка выполнить деление на ноль. В результате будет показано сообщение “Run-time error ’11’: Division by zero“.

    В зависимости от структуры проекта VBA, может быть предложено выполнить отладку кода (как показано на рисунке ниже). В этом случае при нажатии на кнопку Debug (в окне сообщения о необходимости отладки) будет выделена цветом строка кода, которая стала причиной ошибки VBA.

    Получив такое сообщение и видя выделенную строку кода, как в приведённом выше примере, обнаружить причину ошибки будет совсем не сложно.

    В случае если код сложнее, чем в нашем примере, то, чтобы получить больше информации о причине возникновения ошибки VBA, можно проверить значения используемых переменных. В редакторе VBA для этого достаточно навести указатель мыши на имя переменной, или можно открыть окно отслеживания локальных переменных (в меню редактора View > Locals Window).

    Коды различных ошибок выполнения расшифрованы на сайте Microsoft Support (на английском). Наиболее часто встречающиеся ошибки VBA перечислены в этой таблице:

    11. Типы ошибок в программах. Перехват ошибок времени выполнения

    Лабораторная работа 11.1 Перехват ошибок времени выполнения

    Обработка ошибок в макросах VBA в Excel, ошибки времени выполнения (run-time errors)

    Подготовка:

    1. Создайте новый файл Excel и сохраните его как C:ErrorHandling. xls .

    2. В ячейку A1 этого файла введите значение «Результат деления:».

    3. Щелкните правой кнопкой мыши по любой панели инструментов или меню и в открывшемся списке доступных панелей инструментов выберите Элементы управления.

    4. На панели инструментов Элементы управления нажмите кнопку Режим конструктора (верхняя левая кнопка) и в этом режиме поместите на лист Excel новую кнопку. Для этого нужно щелкнуть по объекту Кнопка на панели инструментов Элементы управления и на листе определить местонахождение и размеры этой кнопки.

    5. Щелкните по созданной вами кнопке правой кнопкой мыши и в контекстном меню выберите Свойства. Определите для нее свойства по вашему усмотрению.

    6. В режиме конструктора щелкните по кнопке правой кнопкой мыши и в контекстном меню выберите Исходный текст. Откроется редактор кода Visual Basic с созданной процедурой для события Click данной кнопки. Поместите в него следующий код :

    Private Sub CommandButton1_Click()

    Dim nNum1 As Integer

    Dim nNum2 As Integer

    Dim nResult As Integer

    nNum 1 = InputBox («Введите первое число»)

    nNum 2 = InputBox («Введите второе число»)

    nResult = nNum1 / nNum2

    7. Вернитесь на ваш лист Excel , выйдите из режима конструктора (щелкнув по кнопке Выход из режима конструктора на панели инструментов Элементы управления) и нажмите на созданную вами на листе кнопку. Убедитесь, что если вводить допустимые значения для делимого и делителя, то код работает правильно и выводит результат деления в ячейку B2.

    Задание:

    Измените эту программу таким образом, чтобы обеспечить защиту от ввода пользователем недопустимых значений (например, строковых значений делимого и делителя или значения делителя, равного 0).

    Не обязательно оставлять код по приему значений от пользователя и выполнению деления в обработчике события Click вашей кнопки. Этот код при желании можно перенести во внешние процедуры или функции.

    Решение:

    Существует множество вариантов решения этой задачи. Примеры приведены далее.

    Так, например, может выглядеть решение с обработкой кода ошибки и повторным вызовом функцией самой себя:

    Private Sub CommandButton1_Click()

    Public Sub subPrepare()

    Dim nReturnCode As Integer

    Dim nAnswer As Integer

    Select Case nReturnCode

    MsgBox («Делить на ноль нельзя!»)

    nAnswer = MsgBox(«Повторить?», vbYesNo)

    If nAnswer = vbYes Then

    MsgBox (» Нужно число !»)

    nAnswer = MsgBox(«Повторить?», vbYesNo)

    If nAnswer = vbYes Then

    MsgBox (» Неизвестная ошибка «)

    nAnswer = MsgBox(«Повторить?», vbYesNo)

    If nAnswer = vbYes Then

    On Error Resume Next

    Dim nNum1 As Integer

    Dim nNum2 As Integer

    Dim nResult As Integer

    nNum1 = InputBox(» Введите первое число «)

    nNum 2 = InputBox («Введите второе число»)

    nResult = CInt(nNum1) / CInt(nNum2)

    Select Case Err.Number

    А вот решение с обработкой кода ошибки и циклом:

    Private Sub CommandButton1_Click()

    Dim nNum1 As Variant

    Dim nNum2 As Variant

    Dim nResult As Integer

    Dim nError As Integer

    nNum1 = InputBox(» Введите первое число :»)

    On Error Resume Next

    If Err.Number = 13 Then

    MsgBox (» Нужно число «)

    On Error GoTo 0

    Loop While (nNum1 = «»)

    nNum2 = InputBox(» Введите второе число :»)

    On Error Resume Next

    If Err.Number = 13 Then

    MsgBox (» Нужно число «)

    ElseIf nNum 2 = 0 Then

    MsgBox («Делить на ноль нельзя!»)

    On Error GoTo 0

    Loop While (nNum2 = «»)

    nResult = nNum1 / nNum2

    Еще один вариант решения вообще не допускает возникновения ошибок:

    Private Sub CommandButton1_Click()

    Dim nNum1 As Variant

    Dim nNum2 As Variant

    Dim nResult As Integer

    nNum 1 = InputBox («Введите первое число:»)

    If IsNumeric(nNum1 & «») Then Exit Do

    MsgBox «Нужно число»

    nNum 2 = InputBox («Введите второе число:»)

    Коды ошибок vba excel

    Pearson Software Consulting Services

    Error Handling In VBA

    Error handling refers to the programming practice of anticipating and coding for error conditions that may arise when your program runs. Errors in general come in three flavors: compiler errors such as undeclared variables that prevent your code from compiling; user data entry error such as a user entering a negative value where only a positive number is acceptable; and run time errors, that occur when VBA cannot correctly execute a program statement. We will concern ourselves here only with run time errors. Typical run time errors include attempting to access a non-existent worksheet or workbook, or attempting to divide by zero. The example code in this article will use the division by zero error (Error 11) when we want to deliberately raise an error.

    Your application should make as many checks as possible during initialization to ensure that run time errors do not occur later. In Excel, this includes ensuring that required workbooks and worksheets are present and that required names are defined. The more checking you do before the real work of your application begins, the more stable your application will be. It is far better to detect potential error situations when your application starts up before data is change than to wait until later to encounter an error situation.

    If you have no error handling code and a run time error occurs, VBA will display its standard run time error dialog box. While this may be acceptable, even desirable, in a development environment, it is not acceptable to the end user in a production environment. The goal of well designed error handling code is to anticipate potential errors, and correct them at run time or to terminate code execution in a controlled, graceful method. Your goal should be to prevent unhandled errors from arising.

    A note on terminology: Throughout this article, the term procedure should be taken to mean a Sub , Function , or Property procedure, and the term exit statement should be taken to mean Exit Sub , Exit Function , or Exit Property . The term end statement should be taken to mean End Sub , End Function , End Property , or just End .

    The On Error Statement

    The heart of error handling in VBA is the On Error statement. This statement instructs VBA what to do when an run time error is encountered. The On Error statement takes three forms.

    Читать еще:  Excel to sql

    On Error Goto 0
    On Error Resume Next
    On Error Goto :

    The first form, On Error Goto 0 , is the default mode in VBA. This indicates that when a run time error occurs VBA should display its standard run time error message box, allowing you to enter the code in debug mode or to terminate the VBA program. When On Error Goto 0 is in effect, it is the same as having no enabled error handler. Any error will cause VBA to display its standard error message box.

    The second form, On Error Resume Next , is the most commonly used and misused form. It instructs to VBA to essentially ignore the error and resume execution on the next line of code. It is very important to remember that On Error Resume Next does not in any way «fix» the error. It simply instructs VBA to continue as if no error occured. However, the error may have side effects, such as uninitialized variables or objects set to Nothing. It is the responsibility of your code to test for an error condition and take appropriate action. You do this by testing the value of Err.Number and if it is not zero execute appropriate code. For example,

    On Error Resume Next
    N = 1 / 0 ‘ cause an error
    If Err.Number <> 0 Then
    N = 1
    End If

    This code attempts to assign the value 1 / 0 to the variable N . This is an illegal operations, so VBA will raise an error 11 — Division By Zero — and because we have On Error Resume Next in effect, code continues to the If statement. This statement tests the value of Err.Number and assigns some other number to N .

    The third form On Error of is On Error Goto : which tells VBA to transfer execution to the line following the specified line label. Whenever an error occurs, code execution immediately goes to the line following the line label. None of the code between the error and the label is executed, including any loop control statements.

    On Error Goto ErrHandler:
    N = 1 / 0 ‘ cause an error

    ‘ more code

    Exit Sub
    ErrHandler:
    ‘ error handling code
    Resume Next
    End Sub

    Enabled And Active Error Handlers

    An error handler is said to be enabled when an On Error statement is executed. Only one error handler is enabled at any given time, and VBA will behave according to the enabled error handler. An active error handler is the code that executes when an error occurs and execution is transferred to another location via a On Error Goto : statement.

    Error Handling Blocks And On Error Goto

    An error handling block, also called an error handler, is a section of code to which execution is tranferred via a On Error Goto : statement. This code should be designed either to fix the problem and resume execution in the main code block or to terminate execution of the procedure. You can’t use to the On Error Goto : statement merely skip over lines. For example, the following code will not work properly:

    On Error GoTo Err1:
    Debug.Print 1 / 0
    ‘ more code
    Err1:
    On Error GoTo Err2:
    Debug.Print 1 / 0
    ‘ more code
    Err2:

    When the first error is raised, execution transfers to the line following Err1: . The error hander is still active when the second error occurs, and therefore the second error is not trapped by the On Error statement.

    The Resume Statement

    The Resume statement instructs VBA to resume execution at a specified point in the code. You can use Resume only in an error handling block; any other use will cause an error. Moreover, Resume is the only way, aside from exiting the procedure, to get out of an error handling block. Do not use the Goto statement to direct code execution out of an error handling block. Doing so will cause strange problems with the error handlers.

    The Resume statement takes three syntactic form:

    Resume
    Resume Next
    Resume

    Used alone, Resume causes execution to resume at the line of code that caused the error. In this case you must ensure that your error handling block fixed the problem that caused the initial error. Otherwise, your code will enter an endless loop, jumping between the line of code that caused the error and the error handling block. The following code attempts to activate a worksheet that does not exist. This causes an error (9 — Subscript Out Of Range), and the code jumps to the error handling block which creates the sheet, correcting the problem, and resumes execution at the line of code that caused the error.

    On Error GoTo ErrHandler:
    Worksheets(«NewSheet»).Activate
    Exit Sub

    ErrHandler:
    If Err.Number = 9 Then
    ‘ sheet does not exist, so create it
    Worksheets.Add.Name = «NewSheet»
    ‘ go back to the line of code that caused the problem
    Resume
    End If

    The second form of Resume is Resume Next . This causes code execution to resume at the line immediately following the line which caused the error. The following code causes an error (11 — Division By Zero) when attempting to set the value of N. The error handling block assigns 1 to the variable N, and then causes execution to resume at the statement after the statement that caused the error.

    On Error GoTo ErrHandler:
    N = 1 / 0
    Debug.Print N
    Exit Sub

    ErrHandler:
    N = 1
    ‘ go back to the line following the error
    Resume Next

    The third form of Resume is Resume : . This causes code execution to resume at a line label. This allows you to skip a section of code if an error occurs. For example,

    On Error GoTo ErrHandler:
    N = 1 / 0

    ‘ code that is skipped if an error occurs

    Label1:

    ‘ more code to execute

    Exit Sub

    ErrHandler:
    ‘ go back to the line at Label1:
    Resume Label1:

    All forms of the Resume clear or reset the Err object.

    Error Handling With Multiple Procedures

    Every procedure need not have a error code. When an error occurs, VBA uses the last On Error statement to direct code execution. If the code causing the error is in a procedure with an On Error statement, error handling is as described in the above section. However, if the procedure in which the error occurs does not have an error handler, VBA looks backwards through the procedure calls which lead to the erroneous code. For example if procedure A calls B and B calls C, and A is the only procedure with an error handler, if an error occurs in procedure C, code execution is immediately transferred to the error handler in procedure A, skipping the remaining code in B.

    A Note Of Caution

    It is tempting to deal with errors by placing an On Error Resume Next statement at the top of the procedure in order to get the code to run without raising an error. This is very bad coding practice. Remember that using On Error Resume Next does not fix errors. It merely ignores them.

  • Ссылка на основную публикацию
    ВсеИнструменты
    Adblock
    detector
    ×
    ×