Excel для Microsoft 365 Excel для Microsoft 365 для Mac Excel 2021 Excel 2021 для Mac Excel 2019 Excel 2019 для Mac Excel 2016 Excel 2016 для Mac Excel 2013 Excel 2010 Excel 2007 Excel 2007 для разработчиков Excel 2010 для разработчиков Excel 2013 для разработчиков Еще…Меньше
Если в выполняемом макросе произошел сбой, отображается сообщение об ошибке макроса.
В этом случае используемый метод не подходит для указанного объекта по одной из приведенных ниже причин.
-
Аргумент содержит недопустимое значение. Как правило, причина ошибок такого рода — попытка обратиться к несуществующему объекту, например Книга(5), когда открыты только три книги.
-
Указанный метод нельзя использовать в данном контексте. Например, некоторые методы объекта Range требуют, чтобы диапазон содержал данные. Если в диапазоне их нет, метод выдает ошибку.
-
Произошла внешняя ошибка, например не удалось выполнить чтение или запись файла.
-
(Эта проблема не относится к Mac)
Метод или свойство нельзя использовать с текущими параметрами безопасности. Например, свойства и методы объекта VBE для работы с кодом на языке Visual Basic для приложений (VBA), хранящимся в документах Microsoft Office, по умолчанию недоступны.Чтобы включить доверенный доступ к проектам Visual Basic, выполните указанные ниже действия.
-
В включить вкладку «Разработчик» на ленте. Дополнительные сведения см. в этой вкладке.
-
На вкладке Разработчик в группе Код выберите элемент Безопасность макросов.
-
В разделе Параметры макросов для разработчика установите флажок Доверять доступ к объектной модели проектов VBA.
Чтобы получить дополнительные сведения об использовании метода, выполните поиск по его имени в справке Visual Basic.
-
Нужна дополнительная помощь?
На чтение 25 мин. Просмотров 15.6k.
Эта статья содержит полное руководство по обработке ошибок VBA. Если вы ищете краткое резюме, посмотрите таблицу быстрого руководства в первом разделе.
Если вы ищете конкретную тему по обработке ошибок VBA, ознакомьтесь с приведенным ниже содержанием.
Если вы новичок в VBA, то вы можете прочитать пост от начала до конца, так как он выложен в логическом порядке.
Содержание
- Краткое руководство по обработке ошибок
- Введение
- Ошибки VBA
- Заявление об ошибке
- Err объект
- Логирование
- Другие элементы, связанные с ошибками
- Простая стратегия обработки ошибок
- Полная стратегия обработки ошибок
- Обработка ошибок в двух словах
Краткое руководство по обработке ошибок
| Пункт | Описание |
| On Error Goto 0 | При возникновении ошибки код останавливается и отображает ошибку. |
| On Error Resume Next | Игнорирует ошибку и продолжает. |
| On Error Goto [Label] | Переход к определенной метке при возникновении ошибки. Это позволяет нам справиться с ошибкой. |
| Err Object | При возникновении ошибки информация об ошибке сохраняется здесь. |
| Err.Number | Номер ошибки. (Полезно, только если вам нужно проверить, произошла ли конкретная ошибка.) |
| Err.Description | Содержит текст ошибки. |
| Err.Source | Вы можете заполнить это, когда используете Err.Raise. |
| Err.Raise | Функция, которая позволяет генерировать вашу собственную ошибку. |
| Error Function | Возвращает текст ошибки из номера ошибки. Вышло из употребления. |
| Error Statement | Имитирует ошибку. Вместо этого используйте Err.Raise. |
Введение
Обработка ошибок относится к коду, который написан для обработки ошибок, возникающих во время работы вашего приложения. Эти ошибки обычно вызваны чем-то вне вашего контроля, например отсутствующим файлом, недоступностью базы данных, недействительными данными и т.д.
Если мы считаем, что ошибка может произойти в какой-то
момент, рекомендуется написать специальный код для обработки ошибки, если она
возникнет, и устранить ее.
Для всех остальных ошибок мы используем общий код для их
устранения. Это где оператор обработки ошибок VBA вступает в игру. Они
позволяют нашему приложению корректно обрабатывать любые ошибки, которые мы не
ожидали.
Чтобы понять обработку ошибок, мы должны сначала понять
различные типы ошибок в VBA.
Ошибки VBA
В VBA есть три типа ошибок
- Синтаксис
- Компиляция
- Время выполнения
Мы используем обработку ошибок для устранения ошибок во
время выполнения. Давайте посмотрим на каждый из этих типов ошибок, чтобы было
ясно, что такое ошибка во время выполнения.
Синтаксические ошибки
Если вы использовали VBA в течение какого-то времени, вы
увидите синтаксическую ошибку. Когда вы набираете строку и нажимаете return,
VBA оценивает синтаксис и, если он неверен, выдает сообщение об ошибке.
Например, если вы введете If и забудете ключевое слово Then,
VBA отобразит следующее сообщение об ошибке.
Некоторые примеры синтаксических ошибок
' then отсутствует
If a > b
' не хватает = после i
For i 2 To 7
' отсутствует правая скобка
b = left("АБВГ",1
Синтаксические ошибки относятся только к одной строке. Они
возникают, когда синтаксис одной строки неверен.
Примечание. Диалоговое окно «Ошибка синтаксиса» можно отключить, выбрав «Сервис» -> «Параметры» и отметив «Автосинтаксическая проверка». Строка по-прежнему будет отображаться красным цветом в случае ошибки, но диалоговое окно не появится.
Ошибки компиляции
Ошибки компиляции происходят более чем в одной строке.
Синтаксис в одной строке правильный, но неверный, если учесть весь код проекта.
Примеры ошибок компиляции:
- Оператор If без соответствующего оператора End If
- For без Next
- Select без End Select
- Вызов Sub или Function, которые не существуют
- Вызов Sub или Function с неверными параметрами
- Присвоение Sub или Function того же имени, что и для модуля
- Переменные не объявлены (Option Explicit должен присутствовать в верхней части модуля)
На следующем снимке экрана показана ошибка компиляции,
которая возникает, когда цикл For не имеет соответствующего оператора Next.
Использование Debug-> Compile
Чтобы найти ошибки компиляции, мы используем Debug->
Compile VBA Project из меню Visual Basic.
Когда вы выбираете Debug-> Compile, VBA отображает первую
обнаруженную ошибку.
Когда эта ошибка исправлена, вы можете снова запустить
Compile, и VBA найдет следующую ошибку.
Debug-> Compile также будет включать синтаксические
ошибки в поиск, что очень полезно.
Если ошибок не осталось и вы запускаете Debug-> Compile,
может показаться, что ничего не произошло. Однако «Компиляция» будет недоступна
в меню «Отладка». Это означает, что ваше приложение не имеет ошибок компиляции
в текущий момент.
Debug->Compile Error Summary
Debug-> Compile находит ошибки компиляции (проекта).
Он также найдет синтаксические ошибки.
Он находит одну ошибку каждый раз, когда вы ее используете.
Если нет ошибок компиляции, оставленная опция Компиляция
будет отображаться серым цветом в меню.
Debug-> Compile Usage
Вы должны всегда использовать Debug-> Compile, прежде чем
запускать свой код. Это гарантирует, что ваш код не будет иметь ошибок
компиляции при запуске.
Если вы не запускаете Debug-> Compile, то VBA может
обнаружить ошибки компиляции при запуске. Их не следует путать с ошибками
времени выполнения.
Ошибки во время выполнения
Ошибки во время выполнения возникают, когда ваше приложение
работает. Обычно они находятся вне вашего контроля, но могут быть вызваны
ошибками в вашем коде.
Например, представьте, что ваше приложение читает из внешней
рабочей книги. Если этот файл будет удален, то VBA отобразит ошибку, когда ваш
код попытается открыть его.
Другие примеры ошибок времени выполнения
- база данных недоступна
- пользователь вводит неверные данные
- ячейка, содержащая текст вместо числа
Как мы уже видели, целью обработки ошибок является обработка
ошибок времени выполнения, когда они возникают.
Ожидаемые и неожиданные ошибки
Когда мы думаем, что может произойти ошибка во время
выполнения, мы помещаем код на место для ее обработки. Например, мы обычно
помещаем код на место, чтобы иметь дело с файлом, который не найден.
Следующий код проверяет, существует ли файл, прежде чем он
пытается его открыть. Если файл не существует, отображается сообщение, удобное
для пользователя, и код выходит из подпрограммы.
Sub OtkritFail()
Dim sFile As String
sFile = "C:ДокументыОтчет.xlsx"
' Используйте Dir, чтобы проверить, существует ли файл
If Dir(sFile) = "" Then
' если файл не существует, отобразить сообщение
MsgBox "Файл не найден" & sFile
Exit Sub
End If
' Код достигнет только если файл существует
Workbooks.Open sFile
End Sub
Когда мы думаем, что в какой-то момент может произойти
ошибка, рекомендуется добавить код для обработки ситуации. Мы обычно называем
эти ошибки ожидаемыми.
Если у нас нет специального кода для обработки ошибки, это
считается неожиданной ошибкой. Мы используем операторы обработки ошибок VBA для
обработки непредвиденных ошибок.
Ошибки времени выполнения, которые не являются ошибками VBA
Прежде чем мы рассмотрим VBA Handling, мы должны упомянуть
один тип ошибок. Некоторые ошибки во время выполнения не рассматриваются как
ошибки VBA, а только пользователем.
Позвольте мне объяснить это на примере. Представьте, что у
вас есть приложение, которое требует, чтобы вы добавили значения в переменные a
и b
Допустим, вы по ошибке используете звездочку вместо знака
плюс
Это не ошибка VBA. Ваш синтаксис кода является совершенно
законным. Однако, с вашей точки зрения, это ошибка.
Эти ошибки не могут быть обработаны с помощью обработки ошибок, поскольку они, очевидно, не будут генерировать никаких ошибок. Вы можете справиться с этими ошибками, используя Unit Testing and Assertions.
Заявление об ошибке
Как мы видели, есть два способа обработки ошибок во время
выполнения
- Ожидаемые ошибки — напишите конкретный код для
их обработки. - Неожиданные ошибки — используйте операторы
обработки ошибок VBA для их обработки.
Оператор VBA On Error используется для обработки ошибок.
Этот оператор выполняет некоторые действия при возникновении ошибки во время
выполнения.
Есть четыре различных способа использовать это утверждение
- On Error Goto 0 — код останавливается на строке с ошибкой и отображает сообщение.
- On Error Resume Next — код перемещается на следующую строку. Сообщение об ошибке не отображается.
- On Error Goto [label] — код перемещается на определенную строку или метку. Сообщение об ошибке не отображается. Это тот, который мы используем для обработки ошибок.
- On Error Goto -1 — очищает текущую ошибку.
Давайте посмотрим на каждое из этих утверждений по очереди.
On Error Goto 0
Это поведение по умолчанию VBA. Другими словами, если вы не
используете On Error, это поведение вы увидите.
При возникновении ошибки VBA останавливается на строке с
ошибкой и отображает сообщение об ошибке. Приложение требует вмешательства
пользователя с кодом, прежде чем оно сможет продолжить. Это может быть
исправление ошибки или перезапуск приложения. В этом случае обработка ошибок не
происходит.
Давайте посмотрим на пример. В следующем коде мы не
использовали строку On Error, поэтому VBA будет использовать поведение On Error
Goto 0 по умолчанию.
Sub IspDefault()
Dim x As Long, y As Long
x = 6
y = 6 / 0
x = 7
End Sub
Вторая строка присваивания приводит к ошибке деления на ноль. Когда мы запустим этот код, мы получим сообщение об ошибке, показанное на скриншоте ниже.
Когда появляется ошибка, вы можете выбрать End или Debug
Если вы выберете Конец, то приложение просто остановится.
Если вы выберете Отладить, приложение остановится на строке
ошибки, как показано на скриншоте ниже.
Это нормально, когда вы пишете код VBA, поскольку он
показывает вам точную строку с ошибкой.
Это поведение не подходит для приложения, которое вы
передаете пользователю. Эти ошибки выглядят непрофессионально и делают
приложение нестабильным.
Подобная ошибка, по сути, приводит к сбою приложения.
Пользователь не может продолжить работу без перезапуска приложения. Они могут
вообще не использовать его, пока вы не исправите для них ошибку.
Используя On Error Goto [label], мы можем дать пользователю
более контролируемое сообщение об ошибке. Это также предотвращает остановку
приложения. Мы можем заставить приложение работать предопределенным образом.
On Error Resume Next
Использование On Error Resume Next указывает VBA
игнорировать ошибку и продолжать работу.
Есть конкретные случаи, когда это полезно. Большую часть
времени вы должны избегать его использования.
Если мы добавим Resume Next к нашему примеру Sub, то VBA
проигнорирует ошибку деления на ноль
Sub UsingResumeNext()
On Error Resume Next
Dim x As Long, y As Long
x = 6
y = 6 / 0
x = 7
End Sub
Это не очень хорошая идея, чтобы сделать это. Если вы
игнорируете ошибку, то поведение может быть непредсказуемым. Ошибка может
повлиять на приложение несколькими способами. Вы можете получить неверные
данные. Проблема в том, что вы не знаете, что что-то пошло не так, потому что
вы подавили ошибку.
Приведенный ниже код является примером использования Resume
Next.
Sub OtprSoobsch()
On Error Resume Next
' Требуется ссылка:
' Библиотека объектов Microsoft Outlook 15.0
Dim Outlook As Outlook.Application
Set Outlook = New Outlook.Application
If Outlook Is Nothing Then
MsgBox " Не удается создать сеанс Microsoft Outlook." _
& " Письмо не будет отправлено."
Exit Sub
End If
End Sub
В этом коде мы проверяем, доступен ли Microsoft Outlook на компьютере. Все,
что мы хотим знать — это доступно или нет. Нас не интересует конкретная ошибка.
В приведенном выше коде мы продолжаем, если есть ошибка.
Затем в следующей строке мы проверяем значение переменной Outlook. Если произошла ошибка, тогда
значение этой переменной будет установлено равным Nothing.
Это пример того, когда Резюме может быть полезным. Дело в
том, что, хотя мы используем Resume,
мы все равно проверяем наличие ошибки. Подавляющее большинство времени вам не
нужно будет использовать Resume.
On Error Goto [label]
Вот как мы используем обработку ошибок в VBA. Это эквивалент функциональности Try and Catch, которую вы видите на
таких языках, как C # и
Java.
При возникновении ошибки вы отправляете ошибку на
определенный ярлык. Обычно это внизу саба.
Давайте применим это к подводной лодке, которую мы
использовали
Sub IspGotoLine()
On Error Goto eh
Dim x As Long, y As Long
x = 6
y = 6 / 0
x = 7
Done:
Exit Sub
eh:
MsgBox "Произошла следующая ошибка: " & Err.Description
End Sub
Снимок экрана ниже показывает, что происходит при возникновении ошибки.
VBA переходит на метку eh, потому что мы указали это в
строке «Перейти к ошибке».
Примечание 1: Метка, которую мы используем в операторе On… Goto, должна быть в текущей Sub / Function. Если нет, вы получите ошибку компиляции.
Примечание 2: Когда возникает ошибка при использовании On Error Goto [label], обработка ошибок возвращается к поведению по умолчанию, т.е. код остановится на строке с ошибкой и отобразит сообщение об ошибке. См. Следующий раздел для получения дополнительной информации об этом.
On Error Goto -1
Это утверждение отличается от других трех. Он используется
для очистки текущей ошибки, а не для настройки конкретного поведения.
При возникновении ошибки с помощью функции On Error Goto [label] поведение обработки ошибки возвращается к поведению по умолчанию, т.е. On Error Goto 0 . Это означает, что если произойдет другая ошибка, код остановится на текущей строке.
Это поведение относится только к текущей подпрограмме. Как
только мы выйдем из саба, ошибка будет очищена автоматически.
Посмотрите на код ниже. Первая ошибка приведет к переходу
кода на метку eh. Вторая ошибка остановится на строке с ошибкой 1034.
Sub DveOshibki()
On Error Goto eh
' генерировать ошибку «Несоответствие типов»
Error (13)
Done:
Exit Sub
eh:
' генерировать «определенную приложением» ошибку
Error (1034)
End Sub
Если мы добавим дальнейшую обработку ошибок, она не будет
работать, поскольку ловушка ошибок не была очищена.
В коде ниже мы добавили строку
после того как мы поймаем первую ошибку.
Это не имеет никакого эффекта, так как ошибка не была
очищена. Другими словами, код остановится на строке с ошибкой и отобразит
сообщение.
Sub DveOshibki()
On Error Goto eh
' генерировать ошибку «Несоответствие типов»
Error (13)
Done:
Exit Sub
eh:
On Error Goto eh_other
' генерировать «определенную приложением» ошибку
Error (1034)
Exit Sub
eh_other:
Debug.Print "ehother " & Err.Description
End Sub
Для устранения ошибки мы используем On Error Goto -1.
Думайте об этом как об установке ловушки для мыши. Когда ловушка сработает, вам
нужно установить ее снова.
В приведенном ниже коде мы добавляем эту строку, и вторая
ошибка теперь приведет к переходу кода на метку eh_other.
Sub DveOshibki()
On Error Goto eh
' генерировать ошибку «Несоответствие типов»
Error (13)
Done:
Exit Sub
eh:
' явная ошибка
On Error Goto -1
On Error Goto eh_other
' генерировать «определенную приложением» ошибку
Error (1034)
Exit Sub
eh_other:
Debug.Print "ehother " & Err.Description
End Sub
Примечание 1. Вероятно, в редких случаях полезно использовать On Error Goto -1. Мне лично никогда не приходилось пользоваться этой линией. Помните, что как только вы выйдете из Sub, ошибка все равно будет очищена.
Примечание 2. у объекта Err есть член Clear. Использование Clear очищает текст и цифры в объекте Err, но НЕ сбрасывает ошибку.
Использование On Error
Как мы уже видели, VBA будет делать одну из трех вещей при возникновении ошибки:
- Остановитесь и отобразите ошибку.
- Игнорируйте ошибку и продолжайте.
- Перейти к определенной строке.
VBA всегда будет настроен на одно из этих действий. Когда вы
используете On Error, VBA изменит ваше поведение и забудет о любом предыдущем.
В следующем подпункте VBA изменяет поведение ошибки каждый
раз, когда мы используем оператор On Error
Sub ErrorSostoyaniya()
Dim x As Long
' Перейти на этикетке, если ошибка
On Error Goto eh
' это проигнорирует ошибку в следующей строке
On Error Resume Next
x = 1 / 0
' это отобразит сообщение об ошибке в следующей строке
On Error Goto 0
x = 1 / 0
Done:
Exit Sub
eh:
Debug.Print Err.Description
End Sub
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 [error number], [error source], [error description]
Давайте посмотрим на простой пример. Представьте, что мы
хотим убедиться, что в ячейке есть запись длиной 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 для получения дополнительной информации об очистке фактической ошибки.
Логирование
Ведение журнала означает запись информации из вашего
приложения, когда оно запущено. При возникновении ошибки вы можете записать
детали в текстовый файл, чтобы у вас была запись об ошибке.
Код ниже показывает очень простую процедуру регистрации
Sub Logger(sType As String, sSource As String, sDetails As String)
Dim sFilename As String
sFilename = "C:templogging.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. Эти элементы считаются устаревшими, но я
включил их, поскольку они могут существовать в устаревшем коде.
Функция ошибки
Функция Error используется для печати описания ошибки с
заданным номером ошибки. Он включен в VBA для обеспечения обратной
совместимости и не нужен, поскольку вместо него можно использовать описание
Err.Description.
Ниже приведены некоторые примеры
' Распечатать текст «Деление на ноль» Debug.Print Error(11) ' Распечатать текст "Несоответствие типов" Debug.Print Error(13) ' Распечатать текст "Файл не найден" Debug.Print Error(53)
Заявление об ошибке
Заявление об ошибке позволяет имитировать ошибку. Он включен
в VBA для обратной совместимости. Вместо этого вы должны использовать
Err.Raise.
В следующем коде мы моделируем ошибку «Разделить на ноль».
Sub ZayavlObOshibke()
On Error Goto eh
' Это создаст деление на ноль ошибок
Error 11
Exit Sub
eh:
Debug.Print Err.Number, Err.Description
End Sub
Это утверждение включено в VBA для обратной совместимости.
Вместо этого вы должны использовать Err.Raise.
Простая стратегия обработки ошибок
Со всеми различными опциями вы можете быть озадачены тем,
как использовать обработку ошибок в VBA. В этом разделе я покажу вам, как
реализовать простую стратегию обработки ошибок, которую вы можете использовать
во всех своих приложениях.
Основная реализация
Это простой обзор нашей стратегии
- Поместите строку On Error Goto Label в начале нашего верхнего Sub.
- Поместите Label у обработки ошибок в конце нашего верхнего
Sub. - Если происходит ожидаемая ошибка, обработайте ее и продолжайте.
- Если приложение не может продолжить работу, используйте Err.Raise для перехода к метке обработки ошибок.
- В случае непредвиденной ошибки код автоматически перейдет к метке обработки ошибок.
На следующем рисунке показан обзор того, как это выглядит
Следующий код показывает простую реализацию этой стратегии
Public Const ERROR_NO_ACCOUNTS As Long = vbObjectError + 514
Sub BuildReport()
On Error Goto eh
' Если ошибка в ReadAccounts, то перейти к ошибке
ReadAccounts
' Сделай что-нибудь с кодом
Done:
Exit Sub
eh:
' Все ошибки будут прыгать сюда
MsgBox Err.Source & ": Произошла следующая ошибка " & Err.Description
End Sub
Sub ReadAccounts()
' ОЖИДАЕМАЯ ОШИБКА - Может обрабатываться кодом
' Приложение может обрабатывать A1 равным нулю
If Sheet1.Range("A1") = 0 Then
Sheet1.Range("A1") = 1
End If
' ОЖИДАЕМАЯ ОШИБКА - не может быть обработана кодом
' Приложение не может быть продолжено, если нет учетной записи
If Dir("C:ДокументыОтчет.xlsx") = "" Then
Err.Raise ERROR_NO_ACCOUNTS, "UsingErr" _
, "There are no accounts present for this month."
End If
' НЕОЖИДАННАЯ ОШИБКА - не может быть обработана кодом
' Если ячейка B3 содержит текст, мы получим ошибку несоответствия типов
Dim total As Long
total = Sheet1.Range("B3")
' продолжить и читать счета
End Sub
Это хороший способ реализации обработки ошибок, потому что
- Нам не нужно добавлять код обработки ошибок в
каждую подпрограмму. - Если возникает ошибка, то VBA корректно
завершает работу приложения.
Полная стратегия обработки ошибок
Стратегия выше имеет один недостаток. Он не сообщает вам,
где произошла ошибка. VBA не наполняет Err.Source чем-либо полезным, поэтому мы
должны сделать это сами.
В этом разделе я собираюсь представить более полную
стратегию ошибок. Я написал два сабвуфера, которые выполняют всю тяжелую
работу, поэтому все, что вам нужно сделать, это добавить их в свой проект.
Целью этой стратегии является предоставление вам стека * и
номера строки в случае возникновения ошибки.
* Стек — это список вспомогательных функций, которые
использовались в данный момент при возникновении ошибки.
Это наша стратегия
- Разместите обработку ошибок во всех
подпрограммах. - Когда происходит ошибка, обработчик ошибок
добавляет подробности к ошибке и вызывает ее снова. - Когда ошибка достигает самой верхней
подпрограммы, она отображается.
Мы просто «всплываем» из-за ошибки. Следующая диаграмма
показывает простое визуальное представление о том, что происходит, когда в Sub3
возникает ошибка
Единственная грязная часть этого — правильное форматирование
строк. Я написал две подводные лодки, которые справляются с этим, поэтому он
позаботится о вас.
Это две вспомогательные подводные лодки
Option Explicit
Public Const MARKER As String = "NOT_TOPMOST"
' Вызывает ошибку и добавляет номер строки и имя текущей процедуры
Sub RaiseError(ByVal errorno As Long, ByVal src As String _
, ByVal proc As String, ByVal desc As String, ByVal lineno As Long)
Dim sLineNo As Long, sSource As String
' Если маркера нет, тогда RaiseError вызывается впервые.
If Left(src, Len(MARKER)) <> MARKER Then
' Добавить номер строки ошибки, если она есть
If lineno <> 0 Then
sSource = vbCrLf & "Line no: " & lineno & " "
End If
' Добавить маркер и процедуру к источнику
sSource = MARKER & sSource & vbCrLf & proc
Else
' Если ошибка уже возникла, просто добавьте имя процедуры
sSource = src & vbCrLf & proc
End If
' Если код останавливается здесь, убедитесь, что DisplayError находится в верхней части Sub
Err.Raise errorno, sSource, desc
End Sub
' Отображает ошибку, когда она достигает самого верхнего sub
' Примечание: вы можете добавить вызов для входа из этого подпункта
Sub DisplayError(ByVal src As String, ByVal desc As String _
, ByVal sProcname As String)
' Удалить маркер
src = Replace(src, MARKER, "")
Dim sMsg As String
sMsg = " Произошла следующая ошибка: " & vbCrLf & Err.Description _
& vbCrLf & vbCrLf & " Расположение ошибки: "
sMsg = sMsg + src & vbCrLf & sProcname
' Показать сообщение
MsgBox sMsg, Title:="Ошибка "
End Sub
Пример использования этой стратегии
Вот простое кодирование, которое использует эти Sub. В этой стратегии мы не размещаем какой-либо код в верхнем подпрограмме. Мы только вызываем подводные лодки.
Sub Topmost()
On Error Goto EH
Level1
Done:
Exit Sub
EH:
DisplayError Err.source, Err.Description, "Module1.Topmost"
End Sub
Sub Level1()
On Error Goto EH
Level2
Done:
Exit Sub
EH:
RaiseError Err.Number, Err.source, "Module1.Level1", Err.Description, Erl
End Sub
Sub Level2()
On Error Goto EH
' Ошибка здесь
Dim a As Long
a = "7 / 0"
Done:
Exit Sub
EH:
RaiseError Err.Number, Err.source, "Module1.Level2", Err.Description, Erl
End Sub
Результат выглядит так
Если в вашем проекте есть номера строк, результат будет содержать номер строки ошибки.
Примечание: вы можете получить следующую ошибку при использовании этого кода:
“Programmatic Access to Visual Basic Project is not trusted”
Чтобы решить эту проблему, выполните следующие действия.
- Перейдите в раздел «Разработчик» на ленте и
нажмите «Macro Security», которая находится под кодом. - Нажмите «Настройка макроса» в левом списке.
- Поставьте флажок в поле «Доверительный доступ к
объектной модели проекта VBA». - Нажмите Ok.
Обработка ошибок в двух словах
- Обработка ошибок используется для обработки ошибок, возникающих во время работы приложения.
- Вы пишете определенный код для обработки ожидаемых ошибок. Вы используете оператор обработки ошибок VBA
On Error Goto [label] для отправки VBA на метку при возникновении непредвиденной ошибки. - Вы можете получить подробную информацию об ошибке из Err.Description.
- Вы можете создать свою собственную ошибку, используя Err.Raise.
- Использование одного оператора On Error в самой верхней подпрограмме перехватит все ошибки в подпрограммах, которые вызываются отсюда.
- Если вы хотите записать имя Sub с ошибкой, вы можете обновить ошибку и сбросить ее.
- Вы можете использовать журнал для записи информации о приложении, когда оно запущено.
Обработка ошибок в 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.
Не работают макросы в Excel? Включите их выполнение, добавьте специальный модель с кодом, проверьте версию ОС и Эксель, убедитесь в соответствии пакета приложений, активируйте Майкрософт Офис, снимите блокировку файла, проверьте систему безопасности и применяемые библиотеки. Ниже подробно рассмотрим, в чем могут быть причины подобной неисправности, и какие шаги предпринимать для ее устранения.
Причины
Для начала стоит разобраться, почему не работает макрос в Excel, ведь от этого зависят дальнейшие шаги. К основным причинам стоит отнести:
- Функция отключена.
- Отключение отслеживания событий.
- Устаревшая операционная система.
- Несоответствие разработчика пакета офисных приложений.
- Устаревшая версия Майкрософт Офис.
- Неактивированная версия Excel.
- Заблокированный файл.
- Неправильные настройки безопасности.
- Отсутствие необходимой библиотеки и т. д.
Выше рассмотрены основные причины, почему не удается выполнить макрос в Excel. Все они могут быть решены самостоятельно с помощью приведенных ниже рекомендации. Подробнее на решении вопроса остановимся ниже.
Что делать
Многие пользователи теряются в ситуации, когда не включаются или вообще не работают макросы в Excel. Такая проблема не дает нормально пользоваться приложением и заставляет искать альтернативные варианты.
Включите опцию
Первое, что необходимо сделать — включить функцию для обеспечения ее работоспособности. Здесь многое зависит от версии Эксель.
Если не работают макросы в Excel 2003, сделайте следующие шаги:
- Войдите в «Сервис».
- Перейдите в раздел «Безопасность».
- Кликните «Уровень макросов «Низкий».
В случае, когда не работают макросы в Excel 2007, включите их следующим образом:
- Жмите на кнопку «Офис».
- Войдите в параметры Excel.
- Кликните на «Центр управления безопасности».
- Войдите в «Параметры центра управления безопасностью».
- Жмите на «Параметры макросов».
- Кликните на «Разрешить все …».
В ситуации, когда не работают макросы в Excel 2016, сделайте следующие шаги:
- Войдите в раздел «Файл».
- Кликните на кнопку «Параметры».
- Зайдите в «Центр управления безопасностью».
- Войдите в «Параметры центра управления безопасностью».
- Кликните на «Параметры …».
- Жмите на «Разрешить все …».
После внесения изменений параметра безопасности перезапустите приложение Excel, а именно закройте его полностью и откройте снова. Лишь после этого изменения вступают в силу.
Добавьте нужный модуль в книгу
Бывают ситуации, когда макросы включены, но не работают в Excel из-за отключения каким-либо элементом отслеживания событий. В таком случае сделайте следующее:
- Перейдите в редактор VBA с помощью клавиш Alt+F11.
- Вставьте указанный ниже код.
Sub Reset_Events()
Application.EnableEvents = True
End Sub
- Для выполнения кода поставьте курсор в любой точке между началом и концом.
- Кликните F5.
Проверьте операционную систему
В ситуации, когда не отображаются макросы в Excel, обратите внимание на тип операционной системы. К примеру, Майкрософт Офис, который подходит для Виндовс, на Мак ОС уже работать не будет. Причина в том, что в приложении используются разные библиотеки. Даже если надстройки и функционируют, могут быть сбои в работе. Вот почему при появлении проблем нужно проверить ОС на соответствие.
Обратите внимание на разработчика
Если в Экселе не работают макросы, причиной может быть другой разработчик. Так, пользователи Excel часто применяют OpenOffice или LibreOffice. Эти пакеты созданы на разных языках программирования, которые имеют индивидуальные особенности. Так, если надстройки написаны на Visual Basic for Application, он может не работать в указанных выше офисных приложениях. Вот почему необходимо уточнять, для какого пакета создан макрос / надстройка.
Проверьте версию Майкрософт Офис
В Макрософт Офис 2003 применяются надстройки xla для Excel. В современных версиях расширение поменялось на xlam. Если ставить макросы старого типа в приложения Офис 2007 и больше, никаких трудностей не происходит. Если же вы попытаетесь поставить новую надстройку на старую версию Excel, она зачастую не работает. Вот почему важно обратить внимание на этот параметр при выборе.
Убедитесь в наличии пакета VBA
Одной из причин, почему не запускается макрос в Excel, может быть отсутствие пакета VBA. Для успешного запуска надстройки необходимо, чтобы этот пакет был установлен. Иногда он уже установлен в Офис, но так происходит не всегда. Для проверки жмите комбинацию на Alt+F11. Если после этого появляется Visual Basic, компонент можно считать установленным. В ином случае его нужно поставить. Для этого:
- Зайдите в «Пуск», а далее «Панель управления / Программы и компоненты».
- Выберите программу Майкрософт Офис.
- Жмите на кнопку «Изменить».
- Запустить файл установки Setup.exe.
- Кликните на «Добавить или удалить компоненты».
- Выберите в списке Visual Basic и установите его.
Активируйте Офис
Если в Excel 2007 не работает кнопка «макросы», причиной может быть отсутствие активации приложения. Для этого жмите на кнопку «Активировать» и следуйте инструкции. В большинстве случаев такая опция является платной.
Снимите блокировку файла
Учтите, что документ, полученный с другого ПК / ноутбука, может заблокироваться. Для разблокировки файла нужно нажать ПКМ и в разделе «Общие» кликнуть на «Разблокировать».
Проверьте библиотеки
В случае, когда параметры макросов не активны в Excel, причиной может быть появление ошибки «Can’t find project or library». При этом, надстройка работает на другом ПК / ноутбуке, а здесь возникают проблемы. Ошибку легко устранить, если в окне, которое идет за сообщением об ошибке, снять отметки в полях Missing. Для вызова окна можно выбрать пункт меню Tools / References.
Проверьте настройки безопасности
В ситуации, когда не работают макросы в Excel, можно добавить надежные расположения или настроить доступ к объектной модели VBA. Для этого в Офис 2007 необходимо сделать следующее:
- Войдите в Меню
- Кликните на пункт «Параметры».
- Жмите на «Центр управления безопасностью».
- Войдите в «Параметры центра управления безопасностью».
- Кликните на «Параметры макросов» и «Доверять доступ к объектной модели проектов».
Зная, почему не работают макросы в Excel, вы можете с легкостью исправить проблему и восстановить работоспособность. Если же сложности в работе возникают, вы всегда можете воспользоваться инструкцией в статье.
В комментариях расскажите, какой из приведенных выше вариантов вам помог, и что еще можно сделать.
Отличного Вам дня!
Хитрости »
21 Март 2015 94743 просмотров
Очень часто начинающие работать в VBA сталкиваются с различными ошибками, которые выдает код в момент выполнения. Если не знать как поступить в данном случае – то очень сложно будет исправить код быстро, а то и вообще невозможно будет определить причину ошибки без помощи более «продвинутых» пользователей. Новички зачастую делают правки наугад, что может порождать иные ошибки, а это в свою очередь не только затрудняет поиск первоначальной ошибки, но и может привести к невозможности исправить код вообще. Поэтому в этой статье я решил описать как производить отладку кода и определять ошибки.
Чтобы описанное в статье можно было сразу опробовать в практике советую скачать файл пример:

Что будет рассмотрено:
- Способы отладки кода в момент появления ошибки
- Использование окон Locals и Watches для отладки
- Пошаговая отладка кода — что это такое, как и когда применять
- Ошибок нет, но код все равно не выполняется
Помимо этого в конце статьи можно скачать файл с кодами ошибок VBA и их расшифровками.
Исходные данные
Допустим, имеется простая таблица
И код, который должен пройтись по каждой строке таблицы, перемножить цену (столбец Цена) на количество (столбец Продажи шт), просуммировать перемноженные данные и вывести результирующую сумму в ячейку В17:
Option Explicit Sub PrimitiveCode() Dim lr As Long, dblSumm As Double, dblIncr As Double 'цикл от первой строки таблицы до последней For lr = 1 To 14 'перемножение Цены на Количество (C*E) dblIncr = Cells(l, 3).Value * Cells(lr, 5).Value 'прибавление результата к переменной общей суммы dblSumm = dblSumm + dblIncr Next 'выводим результат в ячейку B17 Cells(17, 2).Value = dblSumm End Sub
Если посмотреть на код выше, то опытный программист VBA сразу поймет, что в таком виде код работать не будет – не выполнится и одна строка. Сразу появится ошибка:
Ошибка означает, что внутри кода есть переменная, которая ранее не была объявлена.
Сама переменная, которую VBA считает не объявленной будет выделена:
Подробнее об этой ошибке и её причинах можно почитать в статье: Variable not defined или что такое Option Explicit и зачем оно нужно?
Если строки Option Explicit нет, то ошибка появится в момент выполнения строки с этой переменной, т.к. значение этой переменной будет 0, что нельзя использовать в качестве номер строки на листе. Как определить причину ошибки в конкретной строке описано ниже.
Если кратко, то переменной l нет среди объявленных переменных(Dim l As) и мы не можем её использовать, если объявлена директива Option Explicit(настоятельно рекомендую Option Explicit использовать всегда во избежание опечаток). В данном случае это опечатка и там должна быть lr, а не l. Исправляем переменную и код будет выглядеть так:
Sub PrimitiveCode() Dim lr As Long, dblSumm As Double, dblIncr As Double 'цикл от первой строки таблицы до последней For lr = 1 To 14 'перемножение Цены на Количество (C*E) dblIncr = Cells(lr, 3).Value * Cells(lr, 5).Value 'прибавление результата к переменной общей суммы dblSumm = dblSumm + dblIncr Next 'выводим результат в ячейку B17 Cells(17, 2).Value = dblSumm End Sub
С виду код теперь выполнен правильно и ошибок вызывать не должен. Однако, если его попытаться выполнить опять получим ошибку – на этот раз ошибку типов данных — Type Mismatch:
В момент появления главное нажать Debug, а не End (если будет желание прочитать про тип ошибки подробнее – можно еще нажать Help, текст будет на английском). VBA подсветит желтым строку, вычисления или операции в которой вызывают ошибку:
Теперь самый важный этап – необходимо определить причину ошибки. С виду все хорошо – одна ячейка перемножается на другую. Без опыта сложно сходу понять, что это ошибка типов данных, хоть VBA прямо об этом говорит(Type Mismatch – в переводе «Несовпадение типов»). Поэтому самое надежное в этом случае – это определить значение каждой составляющей той строки, в которой возникла ошибка. В случае с кодом выше можно воспользоваться двумя методами:
- Навести курсор мыши на любую переменную(dblSum, lr) и посмотреть всплывающую подсказку, которая показывает имя переменной и её текущее значение:
Значение нашей переменной lr = 1. Запоминаем и переходим на лист с таблицей и смотрим, какое значение в ячейке первой строки третьего столбца(Cells(1,3)). Там значение Закуп цена, что явно не является числом. Следовательно перемножить его нельзя, т.к. это текст. Отсюда и ошибка типов – с текстом нельзя производить математические операции. Для вычислений предполагается в данном случае числовой тип данных(Integer,Long,Double). - Узнать сразу значение ячейки Cells(lr, 3).Value и ячейки Cells(lr, 5).Value. Наведение курсора мыши в данном случае не даст результата. Как правило наведение курсора мыши не имеет эффекта если это не объявленные как переменные объекты (как в этом случае — Cells). Такие объекты не всегда могут быть вычислены в памяти в момент отладки. Поэтому чтобы просмотреть значение ячейки сначала необходимо отобразить окно Immediate(отобразить можно сочетанием клавиш Ctrl+G или через меню View —Immediate Window). Выделить и скопировать полностью нужную переменную Cells(i, 3).Value и в окне Immediate написать:
?
и после вопр.знака вставить скопированное. Должно получиться:
?Cells(i, 3).Value
И нажать Enter. Строкой ниже в этом окне будет выведено значение для объекта или переменной (если оно может быть получено):
По сути результат будет как и в первом примере – мы увидим, что в ячейке текст. Чем второй метод лучше первого? Тем, что таким образом можно сразу получить значение, не переходя на лист и не выискивая нужный номер строки. Ведь это в примере он равен 1, в реальности же строка может быть и 24451.
Окна Locals и Watches
Так же для отслеживания значений переменных очень удобно использовать окно
Locals
и окно
Watches
.
Окно Locals
Окно Locals отображает все локальные переменные, задействованные в выполняемой в настоящий момент процедуре:
Как видно в этом окне отображается имя переменной, её тип и значение. Все хорошо, но в этом окне отображаются исключительно локальные переменные, объявленные на уровне модуля. Переменных других модулей, объявленные как Public и используемые в текущей процедуре там не отображаются. Подробнее про видимость переменных можно узнать в статье: Что такое переменная и как правильно её объявить?
Окно Watches
Окно Watches представляет большую ценность – в это окно можно просто «перетащить» нужную переменную или объект и в этом окне будут отражены все данные об имени переменной, её типе и текущем значении:
Теперь рассмотрим чуть подробнее как перетаскивать в это окно данные. На примере кода выше:
- Выделяем Cells(i, 3).Value
- Не снимая выделения наводим курсор мыши на это выделение
- Зажимаем левую кнопку мыши и не отпуская её переносим курсор в любое место окна Watches
Теперь данные по переменной загружены и доступны для просмотра. По сути все умеют это делать — процесс очень схож с обычным перемещением файлов и папок по рабочему столу. Выделили и с зажатой левой кнопкой мыши перенесли в нужное место.
В чем еще один плюс этого окна – в этом окне можно оставлять эти значения и просматривать в моменты пошаговой отладки только занесенные в это окно переменные(про пошаговую отладку будет рассказано ниже). Если вдруг какая-то переменная/объект стали не нужны для постоянного отслеживания их данных – можно удалить их из окна Watches, чтобы не мешалась. Для этого выделяем переменную-правая кнопка мыши – Delete Watch. Так же можно поиграть с иными пунктами, наибольший интерес из которых на мой взгляд, представляет пункт Edit Watch. После его нажатия появится окно
Самые основные пункты в этом окне, важные для отладки:
- Break Then value Changes. Если его установить, VBA будет отслеживать значение этой переменной и останавливать код при любом изменении значения переменной. Это может пригодится для отслеживания значений в циклах
- Break Then value Is True – пункт пригодится для переменных с типом Boolean или для логических выражений. Как только переменная или результат выражения примет значение True – код будет остановлен на этой строке.
Например, необходимо остановить код, если номер строки будет равен 10(т.е. переменная lr примет значение 10). Тогда выражение будет иметь вид:If lr = 10 Then 'код End if
Тогда надо будет выделить в строке If lr = 10 Then само условное выражение lr = 10, перенести её в окно Watches, выделить строку в окне Watches с этим выражением, нажать правую кнопку мыши и выбрать Edit Watch. Выбрать в окне Break Then value Is True. Теперь как только переменная lr достигнет значения 10(т.е. обрабатываться будет 10-я строка таблицы) – код остановится и строка с выражением будет выделена желтым. Можно будет проанализировать другие переменные или продолжить выполнение кода в пошаговом режиме(см.далее).
Пошаговая отладка кода
После знакомства с отладкой кода при возникновении ошибки работать с пошаговой отладкой будет проще.
Что такое вообще пошаговая отладка?
Это просмотр этапов выполнения кода строка за строкой.
Для чего это может быть нужно?
- Чтобы проанализировать чужой код и понять более точно, что он делает изнутри, а не только увидеть результат его выполнения
- Если вы начинающий программист и часто используете макрорекордер(записываете макросы) — то пошаговая отладка поможет понять какое действия выполняет каждая строка. Это поможет быстрее научиться понимать код и убирать из него лишнее, а так же совмещать различные коды
- Если внутри кода есть ошибка логики выполнения. Это, пожалуй, самая сложная ошибка, т.к. в этом случае VBA не останавливает работу и не говорит об ошибке. Код выполняется без ошибок, но результат не такой, как ожидалось. Это означает, что либо какой-то переменной назначается не то значение, либо какое-то условие неверно или выполняется не в тот момент, в который должно. В общем по сути это ошибка разработчика, не приводящая к ошибкам синтаксиса или типов, которые VBA может отследить.
Как делать пошаговую отладку? Все просто: устанавливаете курсор в любом месте внутри кода и нажимаете клавишу F8 (либо выбрать в меню Degub —Step Into). Теперь при каждом нажатии клавиши F8 код будет выполнять одну строку кода за другой в той очередности, в которой они расположены в процедуре. Если внутри процедуры будет вызов второй процедуры или функции – код пошагово выполнит и её и затем вернется в основную процедуру.
Так же хочу привести еще пару сочетаний клавиш, которые удобно применять при пошаговой отладке:
- Shift+F8(Degub —Step Over) — выполнение вложенной функции/процедуры без захода в неё. Если внутри основной процедуры или функции выполняется другая процедура или функция и Вы уверены, что она работает правильно — просматривать пошагово весь код вложенной процедуры/функции не имеет смысла. Чтобы вложенная процедура/функция выполнилась без пошагового просмотра надо просто нажать указанное сочетание клавиш тогда, когда строка вызова вложенной процедуры/функции будет подсвечена желтым
- Ctrl+Shift+F8(Degub —Step Out) — завершение вложенной функции/процедуры и выход в основную с остановкой. Если все же перестарались и перешли в пошаговый проход вложенной функции(или сделали это специально, но посмотрели все, что надо) — то нажимаете это сочетание и код быстро выполнить вложенную функцию, перейдет в основную и остановится для дальнейшей пошаговой отладки
- Ctrl+F8(Degub —Run to Cursor) — выполнение процедуры до строки, в которой на данный момент установлен курсор
Точки останова
Но куда чаще бывает нужно не просто весь код пройти пошагово, а начать пошаговое выполнение только начиная с какой-либо одной строки, чтобы не мотать строк 40 кода(да еще с циклами) ради достижения одной какой-то строки. Еще точки останова очень полезны при отладке событийных процедур(вроде Worksheet_Change, Worksheet_BeforeDoubleClick, событий элементов форм и т.п.), т.к. они в большинстве своем содержат аргументы и выполнить по F8 их просто невозможно и выполняются они только при наступлении самого события, которые они призваны обработать. Тоже самое справедливо для функций пользователя(UDF) именно для проверки их работы из листа, т.к. эти функции нельзя начать выполнять по F5 — они начинают выполняться только после их пересчета и зачастую ошибки можно выявить исключительно при вызове именно с листа.
Чтобы дать понять VBA на какой строке необходимо будет остановится необходимо установить курсор мыши в любое место нужной строки и нажать F9 или Debug —Toggle Breakpoint. Строка будет выделена темно-красным цветом.
Это еще называется установкой точки останова. Убрать точку останова можно так же, как она была установлена – F9 или Debug —Toggle Breakpoint. Так же точку основа можно установить с помощью мыши: для этого необходимо в области левее окна с кодом напротив нужной строки один раз щелкнуть левой кнопкой мыши:
Теперь можно запустить код любым удобным способом (в отладке это как правило делается клавишей F5 или с панели: Run —Run Sub/UserForm). Как только код дойдет до указанной точки останова он остановится и строка будет подсвечена желтым. Дальше можно либо продолжить выполнение в пошаговом режиме (нажимая F8), либо (проверив значения нужных переменных и объектов) нажать опять F5 и код продолжит выполняться автоматически, пока не выполнится или не достигнет другой точки останова. Самих же точек останова может быть сколько угодно и расположены они могут быть в любой процедуре или функции.
Следует помнить, что после закрытия файла с кодом точки останова не сохраняются и при следующем открытии книги их необходимо будет установить заново, если это необходимо.
Еще хочу добавить, что ошибки могут появляться не всегда, даже если они есть. Бывает и так, что код выполняется без ошибок, но однако либо выполняется не так, либо вообще ничего не делает. Как правило причин две:
- Логика кода построена неверно и ошибок VBA действительно не возникает. Но т.к. логика неверна — код выполняет не то, что от него ожидается. Решение одно — пошагово выполнить весь код и детально просмотреть всё, чтобы обнаружить в какой строке или строках нарушена логика
- Один из очень распространенных вариантов: в начале кода стоит обработчик ошибок On Error Resume Next и дальше обработчик не отменяется. Данный обработчик указывает VBA, что при возникновении ошибки её следует игнорировать и переходит к выполнению следующего оператора/строки. Таким образом ошибка хоть и возникает, но она пропускается и не показывается, а выполнение кода продолжается как ни в чем не бывало. Однако как правило одна ошибка влечет другую и третью и т.д. и может получиться так, что все строки после первой ошибочной станут так же ошибочными и как следствие не выполнятся. Данный оператор будет применяться либо до конца процедуры, либо до тех пор, пока в коде не будет поставлен иной обработчик ошибок:
On Error GoTo Метка — переход выполнения кода к указанной метке(Метка).
On Error GoTo 0 — по сути отменяет условный переход при возникновении ошибок. Метка 0 считается обнулением переходов
Один из примеров того, для чего может применяться обработчик ошибок можно найти в статье: Как из Excel обратиться к другому приложению. Там данный обработчик необходим, чтобы проверить открыто ли уже приложение Word. Если открыто — то ошибка не возникнет. Если же закрыто — то будет ошибка. И этот момент как правило и отслеживается. Я расставил подробные комментарии в коде, чтобы было более понятно что к чему:
Sub Check_OpenWord() Dim objWrdApp As Object On Error Resume Next 'необходимо, чтобы на первой же строке код не выдал ошибку при закрытом Word 'пытаемся подключится к объекту Word Set objWrdApp = GetObject(, "Word.Application") 'если Word закрыт - обязательно возникнет ошибка 429, 'указывающая на то, что невозможно подключиться к объекту Word 'при этом переменная objWrdApp будет равняться Nothing, т.к. значение не удалось присвоить If objWrdApp Is Nothing Then 'так же можно использовать и такую строку: 'If Err.Number = 429 Then 'если ошибка 429 - значит Word не запущен - надо создавать новый 'создаем новый экземпляр Set objWrdApp = CreateObject("Word.Application") 'делаем приложение видимым. По умолчанию открывается в скрытом режиме objWrdApp.Visible = True Else 'приложение открыто - выдаем сообщение MsgBox "Приложение Word уже открыто", vbInformation, "Check_OpenWord" End If End Sub
Для чего вообще это нужно? Ведь можно создавать новый экземпляр. А дело в том, что не всегда правильно создавать новый — куда правильнее зачастую подключиться к ранее открытому, чем плодить новые экземпляры и захламлять диспетчер задач.
Тему обработки ошибок я здесь пока не раскрываю полностью, т.к. это не на один абзац. В одной из следующий статей постараюсь более подробно рассказать как и где их лучше применять и как правильно, а когда лучше вообще воздержаться от их использования.
Конечно, статья не описывает способы устранения ошибок — это просто невозможно. Только известных типов ошибок в VBA более 3 тысяч. Все их упоминать бессмысленно. Целью статьи было помочь начинающим найти строку с ошибкой и рассказать как производить отладку кода при необходимости. А все остальное придет с опытом. Однако на всякий случай я решил выложить файл Excel с описанием большей части ошибок, которые могут возникнуть. В файле указан номер ошибки, описание на английском и описание на русском. Причин ошибки может быть множество, поэтому нет однозначных рекомендаций по устранению каждой из них. Все зависит от данных и от самого кода.

Удачи в программировании!
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
|
Framed Пользователь Сообщений: 223 |
#1 04.03.2019 19:39:20 Коллеги, приветствую, Немного запутался в теме про обработчик ошибок, хотя, скорее всего, я нашёл ответ на вопрос в этой теме , просто не могу его понять до конца. Необходимо, чтобы в случае ошибки, которая возникает в определенный момент в коде, часть кода пропускалась, появлялся MsgBox с определенным текстом, после чего макрос продолжал бы работать в нормальном режиме (если будет какая-нибудь другая ошибка далее — выскочит диалоговое окно). Знаю, что задача простая, ну вот туплю что-то…
На данный момент все как надо, только вот когда даже ошибки нет вылезает MsgBox. Заранее спасибо. P.S. Как-то криво написал название темы, должна была быть VBA: Обработчик ошибок, пропуск кода и продолжение выполнения макроса. Изменено: Framed — 05.03.2019 00:54:10 |
||
|
Anchoret Пользователь Сообщений: 1059 Anchoret |
#2 04.03.2019 19:44:33
|
||
|
Framed Пользователь Сообщений: 223 |
#3 04.03.2019 19:52:06 Anchoret, вот так?
|
||
|
Sanja Пользователь Сообщений: 14838 |
#4 04.03.2019 19:54:37
Обработчик ошибок поместите в самый конец кода, а перед ним должна быть строка Exit Sub
Согласие есть продукт при полном непротивлении сторон. |
||||
|
Framed Пользователь Сообщений: 223 |
#5 04.03.2019 20:03:30 Sanja, спасибо, но разве Exit Sub не остановит выполнение всего макроса, если ошибки не будет? Я уточню, а то мне кажется, я плохо объяснил в шапке.
Выполняется макрос, и вот на 5 строке может выскочить ошибка, например, если файла нет, или его имя неверное. Мне нужно, чтобы в этом случае, часть кода 5-13 строка игнорировалась, не выполнялась и выскочил бы MsgBox c текстом, например, «Нет файла или имя некорректно». Далее код, который идет после ErrorHandler должен выполняться в обычном режиме (обычный режим для меня — это когда дальнейшие ошибки не вернут меня к ErrorHandler, простите за убогое объяснение). В случае же, если ошибки на 5 строке моего примера не возникнет — код работает в штатном режиме. Изменено: Framed — 04.03.2019 20:03:53 |
||
|
Anchoret Пользователь Сообщений: 1059 Anchoret |
#6 04.03.2019 20:06:40 Framed,
перед строкой, в которой вероятна ошибка
после такой строки. Ну и замечание от Sanja, |
||||
|
Framed Пользователь Сообщений: 223 |
Как-то не выходит. Дальнейшие ошибки в коде игнорируются, MsgBox вылезает, даже если ошибки не произошло. |
|
БМВ Модератор Сообщений: 21376 Excel 2013, 2016 |
#8 04.03.2019 20:25:02 только наверно так
По вопросам из тем форума, личку не читаю. |
||
|
Framed Пользователь Сообщений: 223 |
БМВ, спасибо, все отлично, только теперь в случае ошибки ниже End If, VBA продолжит выполнение кода, даже если, к примеру, название листа out of range и так далее. |
|
БМВ Модератор Сообщений: 21376 Excel 2013, 2016 |
Framed, я не зря там написал ‘ или on error goto 0 Изменено: БМВ — 04.03.2019 20:49:50 По вопросам из тем форума, личку не читаю. |
|
Framed Пользователь Сообщений: 223 |
#11 04.03.2019 20:52:16 БМВ, простите, я проглядел. Спасибо большое за помощь, теперь я понял больше, без вас не разобрался бы.
Я где-то читал, что метки не приветствуются в VBA. Да и мне привычнее с операторами условия |
||
|
БМВ Модератор Сообщений: 21376 Excel 2013, 2016 |
По вопросам из тем форума, личку не читаю. |
|
vikttur Пользователь Сообщений: 47199 |
#13 05.03.2019 00:23:09
Метки не беда, если не злоупотреблять и если они не нарушаюют ( не сильно нарушают ) структуру кода |
||
|
Nordheim Пользователь Сообщений: 3154 |
Причина ошибки в данном куске кода в чем заключается? «Все гениальное просто, а все простое гениально!!!» |
|
Framed Пользователь Сообщений: 223 |
Nordheim, потенциально ошибка в том, что файл с таким названием может отсутствовать на рабочем столе у юзера. Этот файл (если он есть) в моем коде открывается, оттуда ВПР-ом подтягивается информация, после чего он закрывается. Если такого файла нет — мне нужно было, чтобы: 1. Выводилось сообщение со специальным текстом, т.е. MsgBox; Вообще, мне помогли и тему можно было закрывать, но раз уж вы спросили БМВ, да, и я даже прочитал это несколько раз перед тем, как создать тему. Просто, откровенно говоря, не доходило до меня, как это правильно использовать; примеры из гугла не добавили ясности. Одним словом, еще учиться и учиться. Изменено: Framed — 05.03.2019 14:33:07 |
|
Nordheim Пользователь Сообщений: 3154 |
#16 05.03.2019 14:45:40
А если так:
Никакого On Error PS:
в отчетах. Изменено: Nordheim — 05.03.2019 14:48:24 «Все гениальное просто, а все простое гениально!!!» |
||||
|
Jack Famous Пользователь Сообщений: 10846 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
#17 05.03.2019 15:02:02 Framed, очень много чего вам посоветовали — лень читать всё)) ссылка на тему с холиваром))) Итак, в чём проблема… Всё просто — код доходит до строки ErrorHandler: MsgBox «Произошла ошибка» и выводит сообщение об ошибке (как и должен). Чтобы этого избежать, я обычно делаю, как в #4 (Sanja), но можно и «в лоб» обойти:
— в таком случае, если мы дошли до GoTo nx, то просто «перепрыгиваем» ErrorHandler на метку nx. Если же произойдёт ошибка, то макрос «перепрыгнет» уже к метке ErrorHandler, минуя GoTo nx. P.S.: скорее всего, в вашем случае никакого On Error GoTo ErrorHandler не нужно — это подтверждает и наличие примеров, где легко без него можно обойтись. Я использую метки в основном, если нужно вернуться «выше по коду» (повтор ввода информации пользователем в случае ошибки) или, как уже сказал, чтобы избежать «ветвления» (многоуровневых вложенных «If—Else—End If»). Изменено: Jack Famous — 05.03.2019 15:34:40 Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
||
|
БМВ Модератор Сообщений: 21376 Excel 2013, 2016 |
#18 05.03.2019 15:21:22 Nordheim,
Короче, при полном пути более 260 символов, файл есть, он виден, но открыть его не возможно, впрочем как и скопировать или удалить, понятно что лучше в этом случае обработать длину пути, но порой проще просто обратится и обработать ошибку. Но в целом я полностью согласен, что обрабатывать ошибку надо там, где избежать её не возможно другими методами. Jack Famous, так как я родом из VBS, а там нет Resume, то перешел на метку по ошибке, обратно не вернешься, что означает не продолжить с того же места. а это означает или куча меток и отдельные обработчики для каждой ошибки или ….. По вопросам из тем форума, личку не читаю. |
||
|
Jack Famous Пользователь Сообщений: 10846 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
#19 05.03.2019 15:32:09
а я, стало быть, из VBA и могу использовать крутые штуки типа возврата наверх))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
|||
|
Nordheim Пользователь Сообщений: 3154 |
#20 05.03.2019 15:32:29 БМВ, На сколько я понимаю в данном случае путь прописывается руками, и визуально видно сколько символов.
Не сталкивался, потому наверное, что c Excel работаю постольку поскольку, это больше для саморазвития (интересные задания иногда встречаются). «Все гениальное просто, а все простое гениально!!!» |
||
|
БМВ Модератор Сообщений: 21376 Excel 2013, 2016 |
#21 05.03.2019 16:15:03
да все верно, ремарка относилась скорее к тому, что бывает, когда невозможно отсечь возможность возникновения ошибки заранее. По вопросам из тем форума, личку не читаю. |
||
|
Казанский Пользователь Сообщений: 8839 |
#22 05.03.2019 16:56:51
Забыл, забыл ты свою родину |
||
|
Framed Пользователь Сообщений: 223 |
Jack Famous, спасибо за разъяснения; Все-таки поясню: планируется, что файл, наличие которого проверяется, я буду высылать юзерам ежемесячно. У него относительно постоянная форма, меняются лишь данные. Соответственно, название файлу задаю тоже я. Файл носит вспомогательный характер. Вряд ли юзеры будут его переименовывать (я обязательно скажу, чтобы этого не делали) — их задача состоит лишь в том, чтобы один раз скопировать этот файл из Аутлука и куда-нибудь его закинуть, а после прописать корректный путь в VBA (а вот это им придется делать в любом случае самим, увы). |
|
БМВ Модератор Сообщений: 21376 Excel 2013, 2016 |
#24 05.03.2019 18:47:08
По вопросам из тем форума, личку не читаю. |
||
|
Nordheim Пользователь Сообщений: 3154 |
#25 05.03.2019 19:11:54
А если написать юзерам что бы сохранили файл с макросом и файл из которого берутся данные, в одну папку, то и прописывать ничего не нужно. Как вариант, можно сделать выбор файла. «Все гениальное просто, а все простое гениально!!!» |
||
|
RAN Пользователь Сообщений: 7091 |
#26 05.03.2019 19:48:22
Еще короче. Для Exsel, кажется, 218 символов. Попадал. |
||
|
БМВ Модератор Сообщений: 21376 Excel 2013, 2016 |
#27 06.03.2019 08:03:50 Off
Это не совсем про файл, а скорее про обращение к нему из самого Excel https://support.microsoft.com/en-us/help/213983/error-message-when-you-open-or-save-a-file-in-microsoft-excel-filename This behavior is based on a 256-character limitation in Excel for creating links to another file. This limit of 218 characters for the path name is based on the following:•Up to 31 characters in a sheet name. •Apostrophes and brackets used to denote the workbook name. •An exclamation point. •A cell reference. For example, the path for a file might resemple the following: ‘c:excelpersonal…[my workbook.xls]up_to_31_char_sheetname’!$A$1 Если перевести кратко, то, для работы с другой книгой, ссылка не может быть больше 256 символов, включая дополнительные символы (скобки,апострофы, восклицательный знак), имя листа и диапазон. если учесть что Адрес может быть $AAA$1000000 (12 сим) +31 на имя листа + 5 на спец символы, то на путь останется менее 218ти По вопросам из тем форума, личку не читаю. |
||
|
Nordheim Пользователь Сообщений: 3154 |
#28 06.03.2019 08:54:26 В дополнении
Вариант файла с макросом при открытии запрашивает папку для сохранения, затем сохраняет текущую книгу в указанную папку, и удаляет модуль с процедурой сохранения. Прикрепленные файлы
«Все гениальное просто, а все простое гениально!!!» |
||
|
Framed Пользователь Сообщений: 223 |
#29 13.03.2019 17:36:49 Коллеги, прошу прощения заранее, что поднимаю старую тему и задаю в ней вопрос, но он связан с тем же макросом и с тем, что мне ответил пользователь Nordheim.
Файлы не с макросом, потому что модуль с ним находится в личной книге макросов.
Вот тут я хотел бы уточнить, если вы не против. Можно ли сделать такой алгоритм (но я точно не знаю, в самом макросе, или сделать отдельный), который поможет юзеру выбрать вспомогательный файл (как с сохранением, с помощью окна), а основной макрос бы ссылался на выбранный файл. Зачем это нужно: планируются, что такие вспомогательные файлы будут отправляться юзерам раз в месяц, соответственно, можно их просто назвать одним именем и заменять один другим (как и реализованно в данный момент), но было бы лучше, если бы они сохранялись в специально созданной для этого папке, а юзеры могли бы просто «переключаться» между файлами, из которых нужно брать инфу. |
||||
|
Jack Famous Пользователь Сообщений: 10846 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
#30 13.03.2019 18:02:32 Framed, если вопрос не связан с темой (Обработчик ошибок, пропуск куска кода), то создавайте новую Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
Типы ошибок в VBA
Смотрите также вероятностью 1/5 If момент возникновения ошибки / 0 j On Error Resume
- . Спасибо.
- = wdSeekCurrentPageHeader Do
- On Error GoTo
будет ошибочным, но этот файл повторится. = Workbooks.Open(«C:Documents and справиться с возникающими
Ошибки компиляции
попытке присвоить переменной расшифрованы на сайте случае при нажатии использовать или обратиться Visual Basic воПри выполнении макросов Excel Cells(i, 1).Value >
в цикле For = «test» If Next For iГрузить файлы запрещено Selection.WholeStory Selection.Copy ActiveWindow.ActivePane.View.NextHeaderFooter err1 ‘включаем первую макрос будет продолжать При желании вместо SettingsData») ‘Присваиваем переменным ошибками, VBA предоставляет значение не соответствующего Microsoft Support (на
на кнопку к переменной, которая введённом коде синтаксической могут возникнуть ошибки, 3 Then On у меня останавливалось Err Then Cells(i, = 1 To в организации, поэтому Loop footercopy: ActiveWindow.ActivePane.View.SeekView обработку ‘создаём исключение выполняться до завершения. попытки открыть нужный Val1 и Val2 разработчику операторы типа – например, английском). Наиболее частоDebug не была объявлена ошибки, будет показано которые в VBA Error GoTo errH2
выполнение кода и 2).Value = Err.Description: 10 If Cells(i, опишу пример. = wdSeekMainDocument Application.Run On Error GoToРедактор Excel VBA предоставляет файл, выполнение процедуры данные из рабочейOn Error объявлена переменная встречающиеся ошибки VBA
(в окне сообщения для текущей области соответствующее сообщение. Если делят на три x = 1 переходило на Next? Err.Clear: End If 1).Value > 3Есть книга со «footercopy» End Sub 0 ‘отключаем её набор инструментов отладки,Sub книги DataWorkbook Val1иi
Ошибки выполнения
перечислены в этой о необходимости отладки) (такая ошибка может же этот режим категории: / 0 EndКазанский Next End SubErr.Description Then If Err значениями на Листе1 Sub footercopy() On On Error GoTo которые помогут найти
может быть прервано = Sheets(«Лист1»).Cells(1, 1)Resumeтипа таблице: будет выделена цветом возникнуть только если выключен, то редактор
Ошибки компиляции If nxt: Next: Да уж наверно, будет выдавать последнюю Then Cells(i, 2).Value [A1:A5]={1;2;3;4;5} и макрос: Error GoTo ExitSub err2 ‘включаем вторую и исправить логические в этом месте Val2 = Sheets(«Лист1»).Cells(1,. Эти операторы отслеживаютInteger5 строка кода, которая
используется VBA продолжит сообщатьОшибки выполнения Exit Sub ‘Если раз не работает ошибку, а не = «Ошибка 1»:
Sub test() Dim ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageFooter обработку ‘создаём исключение ошибки в коде при помощи команды 2) DataWorkbook.Close Exit ошибки и направляют, и происходит попыткаНедопустимый вызов процедуры (Invalid стала причиной ошибкиOption Explicit о синтаксических ошибках,Логические ошибки (баги) ошибка в условииResume первую. Err.Clear: Exit Sub i%, x# [B:B].ClearContents Do Selection.WholeStory Selection.Copy
Exit Sub ‘выход VBA. В даннойExit Sub Sub ErrorHandling: ‘Если выполнение макроса в присвоить ей значение procedure call)
| VBA. | ). просто выделяя их |
| Далее мы поговорим о | цикла, значит Netxнужен для того, |
| А почему в | x = 1 For i = ActiveWindow.ActivePane.View.NextHeaderFooter Loop ExitSub:
из процедуры err1: статье мы не. файл не найден, специальный раздел кода строкового типа.7Получив такое сообщение иОшибки выполнения возникают в красным цветом. Опцию каждом из трёх errH2: ‘If Err.Number чтобы выйти из моём варианте возникает |
| / 0 If | 1 To 10 ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument |
| MsgBox Err.Description ‘обрабатываем | будем рассматривать подробно
Логические ошибки (или баги) предлагаем пользователю разместить VBA, в котором53Недостаточно памяти (Out of видя выделенную строку процессе выполнения кодаAuto Syntax Check типов ошибок VBA > 0 Then состояния обработки ошибки |
| ошибка? | Err Then Cells(i, On Error GoTo
End SubЯ здесь первое исключение Exit эти инструменты. Любознательный |
Перехват ошибок выполнения
возникают в процессе его в ‘нужном происходит обработка ошибки.Файл не найден (File memory) кода, как в и приводят кможно включить/выключить в подробно. ‘проверка не нужна, и перейти вВроде всё верно 2).Value = «Ошибка errH1 If Cells(i, сделал вызов другого Sub ‘выход из пользователь может найти выполнения кода VBA, месте и продолжить
После выполнения кода not found)9 приведённом выше примере, остановке выполнения программы. менюКомпилятор VBA рассматривает ошибки т.к. без ошибки состояние нормальной работы. написано, но обработка 2″: Err.Clear: End 1).Value > 3 макроса, т.к. не процедуры err2: MsgBox обзор инструментов отладки но позволяют ему работу MsgBox «Рабочая обработки ошибки, работаИногда возникает при попыткеИндекс вне заданного диапазона обнаружить причину ошибки Этот тип ошибок
Tools компиляции как недопустимые мы бы сюдаЕсли при работе не срабатывает… If Next End Then On Error знал, как применить Err.Description ‘обрабатываем второе VBA на сайте выполняться до самого книга не найдена! программы может быть открыть не существующий (Subscript out of будет совсем не VBA, как правило,> и выделяет их не попали Cells(i, обработчика ошибок происходитКазанский Sub GoTo errH2 x обработку 2 ошибок, исключениеНо зачем? Microsoft Help & завершения. Правда в » & _ продолжена с того файл. range) сложно. также не сложноOptions в коде ещё
2).Value = «Ошибка ошибка, происходит останов: 1. Нет выходаЕвгений = 1 / которые должны по-любомуМожно и в Support (на английском). результате могут выполняться «Пожалуйста добавьте книгу места, где возниклаНе все ошибки выполненияЭта ошибка возникает приВ случае если код обнаружить и исправить,редактора Visual Basic. до того, как 2″ ‘ Err.Clear (есть правда возможность из обработчика ошибки: Т.е. выполняется условие, 0 End If произойти (это является одной метке обработатьУрок подготовлен для Вас
Логические ошибки
не те действия, Data.xlsx в каталог ошибка, или макрос бывают вызваны недочётами попытке обратиться к сложнее, чем в так как сообщаетсяВ некоторых случаях ошибка дело дойдёт до ‘End If Resume обойти его: — оператор Resume а только потом ‘Если ошибка в функциональностью макроса). несколько ошибок командой сайта office-guru.ru которые ожидалось, и C:Documents and Settings может быть остановлен в коде. Например,
элементу массива за нашем примере, то, информация о характере компиляции может быть запуска макроса. nxt ‘Если ошибкаOn Error Goto -12. Нет обхода
проверяется наличие ошибок, условии цикла, значитЕвгенийOn Error GoToИсточник: http://www.excelfunctions.net/VBA-Error.html может быть получен и нажмите OK.» полностью. Далее это ошибки VBA не пределами заданного размера чтобы получить больше ошибки и место обнаружена при выполненииЕсли при написании кода
перед условием цикла,, но это
обработчиков ошибок при
а не в
Netx errH2: If
office-guru.ru
Обработка ошибок
: Добрый день! errLabel Open «C:имя_файла»Перевел: Антон Андронов неверный результат. Такие
Resume End Sub показано на примере. удастся избежать, если массива – например,
информации о причине в коде, где компиляции кода, непосредственно
допущена синтаксическая ошибка, значит End errH1:
крайний случай), а
нормальном выполнении программы. момент её возникновения? Err.Number > 0Необходимо построить обработку For Input AsАвтор: Антон Андронов ошибки обнаружить иВ этом коде производится’Процедура Sub присваивает для работы макроса если объявлен массив возникновения ошибки VBA, произошла остановка. перед тем, как то редактор VBA ‘If Err.Number >
если ошибка происходитЕвгенийТак работает, спасибо!
Then Cells(i, 2).Value ошибок с двумя 0 Exit SubBusine2009 исправить труднее всего, попытка открыть файл переменным Val1 и необходимо открыть файл с индексами можно проверить значенияПримером такой ошибки может макрос будет выполнен. сигнализирует об этом
0 Then ‘проверка после Resume, то
: 1. Может я Только что делать, = «Ошибка 2″ разными метками выхода errLabel: Select Case: Можно в одной так как компилятор Excel с именем Val2 значения, ‘хранящиеся с данными, аот 1 до 10 используемых переменных. В служить попытка выполнить Обычно ошибку компиляции немедленно: либо при не нужна, т.к. вызывается обработчик ошибок, неправильно представлял работу если будет так: Err.Clear End If (всё в цикле): Err.Number … Case
CyberForum.ru
Обработка ошибок с двумя разными метками (VBA)
процедуре использовать 2 VBA их не
Data в ячейках A1 этого файла не, а мы пытаемся
редакторе VBA для деление на ноль. несложно обнаружить и помощи окна с без ошибки мы
который назначен в обработчика, но зачем Sub test() Dim Next ‘Если ошибка
1. Если возникает 52 MsgBox «Неправильный раза
. Если файл не и B1 рабочей существует. В таких
обратиться к элементу этого достаточно навести В результате будет исправить, потому что сообщением, либо выделяя бы сюда не данный момент. делать Resume, если i%, x#, j% перед условием цикла, ошибка до условия дискриптор файла» CaseOn Error GoToсоответственно может указать на найден, то пользователю книги Data.xlsx расположенной случаях признаком профессионализма этого же массива указатель мыши на показано сообщение « компилятор VBA даёт ошибку красным цветом, попали Cells(i, 2).ValueВаш код может есть GoTo? [B:B].ClearContents On Error значит End errH1: If, то просто 53 MsgBox «Файл
для одной части них так, как
будет предложено поместить в каталоге C:Documents будет перехват ошибок с индексом имя переменной, илиRun-time error ’11’: Division информацию о характере в зависимости от = «Ошибка 1″ выглядеть так: Sub2. Я для Resume Next For If Err.Number > переходим на End не найден» … кода и для это происходит с этот файл в
and Settings Sub и написание кода11 можно открыть окно by zero и причине ошибки.
статуса режима ‘End If End test() Dim i%, этого вставил условие i = 1 0 Then Cells(i, Sub. Case Else MsgBox другой части кода? ошибками компиляции и нужную папку. После Set_Values(Val1 As Double, VBA, который будет. отслеживания локальных переменных«.Например, сообщение «Auto Syntax Check Sub x# [B:B].ClearContents For If Err.Number > To 10 If 2).Value = «Ошибка2. Если возникает
«Другая ошибка» EndЕсли можно, то выполнения.
того, как пользователь Val2 As Double) выполняться при их
11 (в меню редактораВ зависимости от структурыCompile error: Variable not
.Евгений i = 1
0 Then … Cells(i, 1).Value > 1″ End If ошибка в условии Select напишите как. Буду
Например, при создании макроса сделает это и Dim DataWorkbook As возникновении. Таким образом,Деление на ноль (Division
View проекта VBA, может definedПримечание:: Спасибо за подробное To 10 On End If 3 Then If End Sub
If, то переходимBusine2009 очень признательным.
в процедуре случайно нажмёт Workbook On Error вместо неприятных сбоев by zero)>
быть предложено выполнить» при попытке запуститьПри включённом режиме объяснение, всё работает Error GoTo errH1Евгений Err Then Cells(i,KuklP на Netx.: Вот конкретный пример:Abu были просуммированы неОК
GoTo ErrorHandling ‘Открываем будет происходить изящное13Locals Window отладку кода (как выполнение кода VBAAuto Syntax CheckА то у x = 1: Задам немного другой 2).Value = Err.Description:: Так не проще?:Прошу помочь разобратьсяSub HeaderCopy() On: Можно! те переменные, которые, выполнение кода продолжится, рабочую книгу с завершение работы макроса.Несоответствие типа (Type mismatch)). показано на рисунке говорит о том,каждый раз, при Уокенбаха такого не / Int(Rnd * вопрос: как сделать Err.Clear: Exit SubSub test() Dim почему на срабатывает Error GoTo footercopyМожно так требовалось просуммировать. Результат и попытка открыть данными Set DataWorkbookДля того, чтобы помочьЭта ошибка возникает приКоды различных ошибок выполнения ниже). В этом что происходит попытка появлении в редакторе
написано 5) ‘ошибка с так, что в
x = 1 i%, x# [B:B].ClearContents макрос
planetaexcel.ru
Selection.HomeKey Unit:=wdStory ActiveWindow.ActivePane.View.SeekView
При выполнении макросов 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, как правило, также не сложно обнаружить и исправить, так как сообщается информация о характере ошибки и место в коде, где произошла остановка.
Примером такой ошибки может служить попытка выполнить деление на ноль. В результате будет показано сообщение «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 SettingsData")
'Присваиваем переменным 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, но позволяют ему выполняться до самого завершения. Правда в результате могут выполняться не те действия, которые ожидалось, и может быть получен неверный результат. Такие ошибки обнаружить и исправить труднее всего, так как компилятор VBA их не распознаёт и не может указать на них так, как это происходит с ошибками компиляции и выполнения.
Например, при создании макроса в процедуре случайно были просуммированы не те переменные, которые требовалось просуммировать. Результат будет ошибочным, но макрос будет продолжать выполняться до завершения.
Редактор Excel VBA предоставляет набор инструментов отладки, которые помогут найти и исправить логические ошибки в коде VBA. В данной статье мы не будем рассматривать подробно эти инструменты. Любознательный пользователь может найти обзор инструментов отладки VBA на сайте Microsoft Help & Support (на английском).
Оцените качество статьи. Нам важно ваше мнение:
Содержание
- Ошибка макроса
- Как исправить ошибку VBA 400 в Excel
- Что вызывает ошибку VBA 400 в Excel?
- Как исправить ошибку VBA 400 в Excel
- 1]Переместить макросы в новый модуль
- 2]Включить надежный доступ к VBA
- 3]Проверьте свой код
- 4]Восстановить Microsoft Excel
- 5]Удалите, а затем повторно установите Excel.
- 6]Некоторые другие методы
- Ошибка приложения Excel при открытии файла с макросами
- Решение 1: вставка нового листа
- Решение 2: перекомпиляция проекта
- Решение 3: добавление модуля
- Не работают макросы в Excel: кто виноват и что делать?
- Причины
- Что делать
- Включите опцию
- Добавьте нужный модуль в книгу
- Проверьте операционную систему
- Обратите внимание на разработчика
- Проверьте версию Майкрософт Офис
- Убедитесь в наличии пакета VBA
- Активируйте Офис
- Снимите блокировку файла
- Проверьте библиотеки
- Проверьте настройки безопасности
Ошибка макроса
Если в выполняемом макросе произошел сбой, отображается сообщение об ошибке макроса.
В этом случае используемый метод не подходит для указанного объекта по одной из приведенных ниже причин.
Аргумент содержит недопустимое значение. Как правило, причина ошибок такого рода — попытка обратиться к несуществующему объекту, например Книга(5), когда открыты только три книги.
Указанный метод нельзя использовать в данном контексте. Например, некоторые методы объекта Range требуют, чтобы диапазон содержал данные. Если в диапазоне их нет, метод выдает ошибку.
Произошла внешняя ошибка, например не удалось выполнить чтение или запись файла.
(Эта проблема не относится к Mac) Метод или свойство нельзя использовать с текущими параметрами безопасности. Например, свойства и методы объекта VBE для работы с кодом на языке Visual Basic для приложений (VBA), хранящимся в документах Microsoft Office, по умолчанию недоступны.
Чтобы включить доверенный доступ к проектам Visual Basic, выполните указанные ниже действия.
В включить вкладку «Разработчик» на ленте. Дополнительные сведения см. в этой вкладке.
На вкладке Разработчик в группе Код выберите элемент Безопасность макросов.
В разделе Параметры макросов для разработчика установите флажок Доверять доступ к объектной модели проектов VBA.
Чтобы получить дополнительные сведения об использовании метода, выполните поиск по его имени в справке Visual Basic.
Источник
Как исправить ошибку VBA 400 в Excel
В этой статье мы обсудим методы исправления ошибки VBA 400 в Excel. Ошибка 400 в Excel обычно возникает при запуске макроса Microsoft Visual Basic для приложений (VBA). Это вызывает сбой макроса или сбой при запуске и возвращает сообщение об ошибке 400. Причины такой ошибки могут быть разными; давайте обсудим их.
Что вызывает ошибку VBA 400 в Excel?
Вот причины, из-за которых возникает ошибка 400 при запуске макроса в Excel:
- Неправильная установка программного обеспечения Office.
- В коде VBA есть ошибка.
- Недопустимое значение аргумента.
- Запущенный макрос поврежден.
- Файлы, связанные с Excel, заражены каким-либо вредоносным ПО.
- Ошибка чтения / записи из файла.
- Неверные записи в реестре.
Если вы столкнулись с ошибкой 400 в Excel, вы можете использовать перечисленные ниже решения для ее устранения.
Как исправить ошибку VBA 400 в Excel
Программы для Windows, мобильные приложения, игры — ВСЁ БЕСПЛАТНО, в нашем закрытом телеграмм канале — Подписывайтесь:)
Вот способы исправить ошибку 400, возникшую при запуске макроса в Excel:
- Переместите макросы в новый модуль.
- Включите доверенный доступ к VBA.
- Просмотрите свой код VBA.
- Восстановите Microsoft Excel.
- Удалите, а затем повторно установите Excel.
- Некоторые другие методы, такие как сканирование на наличие вредоносных программ и т. Д.
Давайте подробно обсудим эти методы.
1]Переместить макросы в новый модуль
Перенос макросов в новый модуль может решить проблему в случае внешней ошибки. Для этого вы можете использовать следующие шаги:
Перейдите на вкладку «Разработчики» и выберите «Визуальный редактор». Если вы не видите вкладку «Разработчики» на главной ленте в Excel, перейдите в «Файл»> «Параметры» и на вкладке «Настройка лент» установите флажок «Разработчики» в разделе «Основные вкладки».
Теперь в окне Microsoft Visual Basic для приложений щелкните меню «Вставка» и выберите параметр «Модуль».
После этого вставьте код макроса в этот новый модуль и сохраните его, используя специальную опцию в меню «Файл».
Кроме того, вам нужно удалить старый модуль, щелкнув его правой кнопкой мыши и используя Удалять вариант.
Наконец, щелкните Файл> Закрыть и вернуться в Microsoft Excel и посмотрите, устранена ли ошибка 400 в Excel.
2]Включить надежный доступ к VBA
Вы можете включить доверенный доступ к VBA и посмотреть, исчезла ли проблема. Вот шаги, чтобы включить доверенный доступ к VBA:
- Перейдите на вкладку «Разработчики» и нажмите «Безопасность макросов».
- В окне центра управления безопасностью включите параметр Надежный доступ к объектной модели проекта VBA.
- Нажмите кнопку ОК.
3]Проверьте свой код
Ошибка в коде VBA может вызвать ошибку 400 в Excel. Итак, вам необходимо тщательно просмотреть код макроса и исправить ошибку в коде, если таковая имеется. Также проверьте макросы на наличие повреждений.
4]Восстановить Microsoft Excel
Если ничего из вышеперечисленного не работает, проблема может быть в приложении Excel. Возможно, приложение установлено неправильно или что-то нужно исправить. Итак, восстановите Microsoft Excel, используя следующие шаги:
- Запустите приложение «Настройки» и выберите «Приложения»> «Приложения и функции».
- Справа найдите и щелкните Программа Office 365 / Microsoft 365.
- Нажмите на кнопку «Изменить», а затем выберите вариант «Онлайн-ремонт» или «Быстрое восстановление».
- Нажмите кнопку «Восстановить», чтобы восстановить Excel и другие приложения Office.
5]Удалите, а затем повторно установите Excel.
Вы также можете попробовать удалить, а затем переустановить программное обеспечение Office и Excel, чтобы начать заново. Посмотрите, устраняет ли это ошибку.
6]Некоторые другие методы
Кроме того, некоторые другие решения также могут работать, например:
- Вы можете попробовать запустить сканирование SFC, чтобы проверить и восстановить поврежденные системные файлы.
- Некоторые вредоносные программы также могут вызывать эту ошибку. Итак, проверяйте и удаляйте вредоносные программы и подозрительные приложения с помощью Microsoft Defender или сторонней антивирусной или антивредоносной программы.
- Попробуйте удалить поврежденные данные кеша и системные ненужные файлы.
Надеюсь, что приведенные выше решения помогут!
Теперь прочтите: Как исправить ошибку выполнения 1004 в Excel

Программы для Windows, мобильные приложения, игры — ВСЁ БЕСПЛАТНО, в нашем закрытом телеграмм канале — Подписывайтесь:)
Источник
Ошибка приложения Excel при открытии файла с макросами
Не так давно очередной раз столкнулся с ошибками приложения Excel при попытке включения макросов после открытия файлов .xlsm. Вспомнил, что подобные проблемы преследуют пользователей довольно давно, но чаще всего они наблюдались с Excel 2013 и Excel 2016. Характерные особенности этой группы ошибок следующие:
- Приложение Excel закрывается при открытии файла с макросами (при включенном режиме безопасности Включить все макросы );
- Ошибка приложения Excel возникает при попытке включить содержимое (нажатии соответствующей кнопки);
- Ошибка приложения Excel возникает при сохранении файла с макросами;
Ну и по горячим следам очередного инцидента, дабы не откладывать на потом, решил для себя собрать небольшой хаб по ошибкам приложения Excel с последующей модификацией, дабы опять не терять время на поиск информации в Сети и на составление облака причин.
Суть в том, что в процессе открытия файла xlsm, и при отключенных макросах, в верхней части основного окна (над таблицей), высвечивается строка уведомления: ПРЕДУПРЕЖДЕНИЕ СИСТЕМЫ БЕЗОПАСНОСТИ Запуск макросов отключен , с кнопкой включения содержимого (макросов). Как только пользователь её нажимает, Excel попросту аварийно завершается (падает) с ошибкой Программа Microsoft Excel не работает и характерным окном уведомления:
При этом было замечено, что непосредственно перед возникновением ошибки приложения Excel никаких системных обновлений и обновлений пакета Office не устанавливалось. Возможно, каким-то образом задействованы последние обновления на Office, но прямой связи я не заметил, а подробного исследования проблемы не проводил. При этом зависимости от версии операционной системы (мною лично сбои наблюдались на Windows 10 LTSC и Windows 7 Professional) так же выявлено не было. При анализе аварийного дампа приложения ( *.hdmp ) обычно можно увидеть подобную информацию исключения (вывод урезан):
обычно это NTSTATUS с кодом c0000005 — Access violation, доступ запрещен. И чаще всего в дампе можно увидеть такой вот стек потока (вывод оптимизирован для улучшения представления):
из которого единственное что понятно, так это то, что падение Excel происходит в недрах функций библиотеки vbe7.dll (среда исполнения VBA), подгруженной в адресное пространство процесса. Это указывает на проблемы с обработчиком VBA-скриптов, в контексте Excel чаще именуемых макросами.
Так что же такое VBA и для чего он предназначается?
В приложениях, входящих в комплект MS Office, таких как Excel, Word, PowerPoint и Access, VBA используется для автоматизации множества рутинных задач (напр.: повторяющихся однотипных действий), позволяет создавать формы для общения с пользователем и предлагает множество иного богатого функционала. При помощи VBA доступно управление электронной таблицей посредством объектно-ориентированной модели кода/данных, при помощи VBA-кода входные данные таблиц могут быть обработаны и представлены в итоговых (результирующих) таблицах и диаграммах (графиках). Таблица становится интерфейсом кода, позволяя легко работать, изменять его и управлять расчётами. На выходе VBA проект, используемый в структурах описанных выше приложений (электронные таблицы Excel, презентации PowerPoint, базы Access), компилируется в специальный бинарный исполняемый файл, который размещается внутри файла основного формата. Применительно к Excel это файл vbaProject.bin , который располагается внутри *.xslm-файла в директории /xl , представляющий собой бинарный исполняемый файл проекта, содержащий макрос в откомпилированном (готовом к исполнению) виде.
Решение 1: вставка нового листа
Выполните приведенную последовательность действий:
- Открываем [проблемный] .xlsm-файл (файл с макросами).
- Не нажимаем кнопку Включить содержимое .
- Добавляем в книгу Excel новый лист: правая кнопка мыши на ярлыках Лист1/Лист2/Лист3 → Вставить → Лист .
- Сохраняем электронную таблицу. Закрываем Excel.
- Открываем проблемный файл заново и включаем макросы.
Решение 2: перекомпиляция проекта
Выполните последовательность действий:
- Запускаем и открываем новую книгу Excel (не ваш проблемный файл).
- Открываем меню Файл — выбираем Параметры — далее открываем Центр управления безопасностью и заходим в Параметры центра управления безопасностью .
- В разделе Параметры макросов — выставляем чекбокс Отключить все макросы с уведомлением .
- В разделе Надежные расположения — выставляем чекбокс Отключить все надежные расположения .
- В разделе Надежные документы — выставляем чекбокс Отключить надежные документы .
- Жмем везде OK . Закрываем Excel.
- Открываем [проблемный] .xlsm-файл (файл с макросами).
- Не нажимаем кнопку Включить содержимое .
- Открывает редактор Visual Basic при помощи комбинации клавиш Alt + F11 . Либо можно использовать обходной маневр: в настройках включаем меню Разработчик , после этого в появившемся сверху в ленте меню Разработчик выбираем пункт Visual Basic .
- В открывшемся окне редактора Visual Basic (VBA редактор) пересохраняем проект: для этого жмем на панели инструментов кнопку Сохранить (изображение дискетки или комбинация Ctrl + S ).
- Выбираем из меню Debug — выбираем пункт меню Compile VBA Project :
Решение 3: добавление модуля
Дополнительное решение состоит в том, что бы внести изменения в макрос без перекомпиляции.
- Открываем [проблемный] .xlsm-файл (файл с макросами).
- Не нажимаем кнопку Включить содержимое .
- Открывает редактор Visual Basic (при помощи комбинации клавиш Alt + F11 ).
- Открываем меню Tools → пункт Options . В открывшемся окне переходим на вкладку General и деактивируем чекбокс Compile on Demand :
Закрываем окно Опции нажатием клавиши OK .
В левом фрейме окна проекта ( Project ) спускаемся вниз, находим раздел Modules , жмем на нём правую кнопку → пункт Insert → Module :
Источник
Не работают макросы в Excel: кто виноват и что делать?
Не работают макросы в Excel? Включите их выполнение, добавьте специальный модель с кодом, проверьте версию ОС и Эксель, убедитесь в соответствии пакета приложений, активируйте Майкрософт Офис, снимите блокировку файла, проверьте систему безопасности и применяемые библиотеки. Ниже подробно рассмотрим, в чем могут быть причины подобной неисправности, и какие шаги предпринимать для ее устранения.
Причины
Для начала стоит разобраться, почему не работает макрос в Excel, ведь от этого зависят дальнейшие шаги. К основным причинам стоит отнести:
- Функция отключена.
- Отключение отслеживания событий.
- Устаревшая операционная система.
- Несоответствие разработчика пакета офисных приложений.
- Устаревшая версия Майкрософт Офис.
- Неактивированная версия Excel.
- Заблокированный файл.
- Неправильные настройки безопасности.
- Отсутствие необходимой библиотеки и т. д.
Выше рассмотрены основные причины, почему не удается выполнить макрос в Excel. Все они могут быть решены самостоятельно с помощью приведенных ниже рекомендации. Подробнее на решении вопроса остановимся ниже.
Что делать
Многие пользователи теряются в ситуации, когда не включаются или вообще не работают макросы в Excel. Такая проблема не дает нормально пользоваться приложением и заставляет искать альтернативные варианты.
Включите опцию
Первое, что необходимо сделать — включить функцию для обеспечения ее работоспособности. Здесь многое зависит от версии Эксель.
Если не работают макросы в Excel 2003, сделайте следующие шаги:
- Войдите в «Сервис».
- Перейдите в раздел «Безопасность».
- Кликните «Уровень макросов «Низкий».
В случае, когда не работают макросы в Excel 2007, включите их следующим образом:
- Жмите на кнопку «Офис».
- Войдите в параметры Excel.
- Кликните на «Центр управления безопасности».
- Войдите в «Параметры центра управления безопасностью».
- Жмите на «Параметры макросов».
- Кликните на «Разрешить все …».
В ситуации, когда не работают макросы в Excel 2016, сделайте следующие шаги:
- Войдите в раздел «Файл».
- Кликните на кнопку «Параметры».
- Зайдите в «Центр управления безопасностью».
- Войдите в «Параметры центра управления безопасностью».
- Кликните на «Параметры …».
- Жмите на «Разрешить все …».
После внесения изменений параметра безопасности перезапустите приложение Excel, а именно закройте его полностью и откройте снова. Лишь после этого изменения вступают в силу.
Добавьте нужный модуль в книгу
Бывают ситуации, когда макросы включены, но не работают в Excel из-за отключения каким-либо элементом отслеживания событий. В таком случае сделайте следующее:
- Перейдите в редактор VBA с помощью клавиш Alt+F11.
- Вставьте указанный ниже код.
- Для выполнения кода поставьте курсор в любой точке между началом и концом.
- Кликните F5.
Проверьте операционную систему
В ситуации, когда не отображаются макросы в Excel, обратите внимание на тип операционной системы. К примеру, Майкрософт Офис, который подходит для Виндовс, на Мак ОС уже работать не будет. Причина в том, что в приложении используются разные библиотеки. Даже если надстройки и функционируют, могут быть сбои в работе. Вот почему при появлении проблем нужно проверить ОС на соответствие.
Обратите внимание на разработчика
Если в Экселе не работают макросы, причиной может быть другой разработчик. Так, пользователи Excel часто применяют OpenOffice или LibreOffice. Эти пакеты созданы на разных языках программирования, которые имеют индивидуальные особенности. Так, если надстройки написаны на Visual Basic for Application, он может не работать в указанных выше офисных приложениях. Вот почему необходимо уточнять, для какого пакета создан макрос / надстройка.
Проверьте версию Майкрософт Офис
В Макрософт Офис 2003 применяются надстройки xla для Excel. В современных версиях расширение поменялось на xlam. Если ставить макросы старого типа в приложения Офис 2007 и больше, никаких трудностей не происходит. Если же вы попытаетесь поставить новую надстройку на старую версию Excel, она зачастую не работает. Вот почему важно обратить внимание на этот параметр при выборе.
Убедитесь в наличии пакета VBA
Одной из причин, почему не запускается макрос в Excel, может быть отсутствие пакета VBA. Для успешного запуска надстройки необходимо, чтобы этот пакет был установлен. Иногда он уже установлен в Офис, но так происходит не всегда. Для проверки жмите комбинацию на Alt+F11. Если после этого появляется Visual Basic, компонент можно считать установленным. В ином случае его нужно поставить. Для этого:
- Зайдите в «Пуск», а далее «Панель управления / Программы и компоненты».
- Выберите программу Майкрософт Офис.
- Жмите на кнопку «Изменить».
- Запустить файл установки Setup.exe.
- Кликните на «Добавить или удалить компоненты».
- Выберите в списке Visual Basic и установите его.
Активируйте Офис
Если в Excel 2007 не работает кнопка «макросы», причиной может быть отсутствие активации приложения. Для этого жмите на кнопку «Активировать» и следуйте инструкции. В большинстве случаев такая опция является платной.
Снимите блокировку файла
Учтите, что документ, полученный с другого ПК / ноутбука, может заблокироваться. Для разблокировки файла нужно нажать ПКМ и в разделе «Общие» кликнуть на «Разблокировать».
Проверьте библиотеки
В случае, когда параметры макросов не активны в Excel, причиной может быть появление ошибки «Can’t find project or library». При этом, надстройка работает на другом ПК / ноутбуке, а здесь возникают проблемы. Ошибку легко устранить, если в окне, которое идет за сообщением об ошибке, снять отметки в полях Missing. Для вызова окна можно выбрать пункт меню Tools / References.
Проверьте настройки безопасности
В ситуации, когда не работают макросы в Excel, можно добавить надежные расположения или настроить доступ к объектной модели VBA. Для этого в Офис 2007 необходимо сделать следующее:
- Войдите в Меню
- Кликните на пункт «Параметры».
- Жмите на «Центр управления безопасностью».
- Войдите в «Параметры центра управления безопасностью».
- Кликните на «Параметры макросов» и «Доверять доступ к объектной модели проектов».
Зная, почему не работают макросы в Excel, вы можете с легкостью исправить проблему и восстановить работоспособность. Если же сложности в работе возникают, вы всегда можете воспользоваться инструкцией в статье.
В комментариях расскажите, какой из приведенных выше вариантов вам помог, и что еще можно сделать.
Источник
На чтение 25 мин. Просмотров 13.8k.
Эта статья содержит полное руководство по обработке ошибок VBA. Если вы ищете краткое резюме, посмотрите таблицу быстрого руководства в первом разделе.
Если вы ищете конкретную тему по обработке ошибок VBA, ознакомьтесь с приведенным ниже содержанием.
Если вы новичок в VBA, то вы можете прочитать пост от начала до конца, так как он выложен в логическом порядке.
Содержание
- Краткое руководство по обработке ошибок
- Введение
- Ошибки VBA
- Заявление об ошибке
- Err объект
- Логирование
- Другие элементы, связанные с ошибками
- Простая стратегия обработки ошибок
- Полная стратегия обработки ошибок
- Обработка ошибок в двух словах
Краткое руководство по обработке ошибок
| Пункт | Описание |
| On Error Goto 0 | При возникновении ошибки код останавливается и отображает ошибку. |
| On Error Resume Next | Игнорирует ошибку и продолжает. |
| On Error Goto [Label] | Переход к определенной метке при возникновении ошибки. Это позволяет нам справиться с ошибкой. |
| Err Object | При возникновении ошибки информация об ошибке сохраняется здесь. |
| Err.Number | Номер ошибки. (Полезно, только если вам нужно проверить, произошла ли конкретная ошибка.) |
| Err.Description | Содержит текст ошибки. |
| Err.Source | Вы можете заполнить это, когда используете Err.Raise. |
| Err.Raise | Функция, которая позволяет генерировать вашу собственную ошибку. |
| Error Function | Возвращает текст ошибки из номера ошибки. Вышло из употребления. |
| Error Statement | Имитирует ошибку. Вместо этого используйте Err.Raise. |
Введение
Обработка ошибок относится к коду, который написан для обработки ошибок, возникающих во время работы вашего приложения. Эти ошибки обычно вызваны чем-то вне вашего контроля, например отсутствующим файлом, недоступностью базы данных, недействительными данными и т.д.
Если мы считаем, что ошибка может произойти в какой-то
момент, рекомендуется написать специальный код для обработки ошибки, если она
возникнет, и устранить ее.
Для всех остальных ошибок мы используем общий код для их
устранения. Это где оператор обработки ошибок VBA вступает в игру. Они
позволяют нашему приложению корректно обрабатывать любые ошибки, которые мы не
ожидали.
Чтобы понять обработку ошибок, мы должны сначала понять
различные типы ошибок в VBA.
Ошибки VBA
В VBA есть три типа ошибок
- Синтаксис
- Компиляция
- Время выполнения
Мы используем обработку ошибок для устранения ошибок во
время выполнения. Давайте посмотрим на каждый из этих типов ошибок, чтобы было
ясно, что такое ошибка во время выполнения.
Синтаксические ошибки
Если вы использовали VBA в течение какого-то времени, вы
увидите синтаксическую ошибку. Когда вы набираете строку и нажимаете return,
VBA оценивает синтаксис и, если он неверен, выдает сообщение об ошибке.
Например, если вы введете If и забудете ключевое слово Then,
VBA отобразит следующее сообщение об ошибке.
Некоторые примеры синтаксических ошибок
' then отсутствует
If a > b
' не хватает = после i
For i 2 To 7
' отсутствует правая скобка
b = left("АБВГ",1
Синтаксические ошибки относятся только к одной строке. Они
возникают, когда синтаксис одной строки неверен.
Примечание. Диалоговое окно «Ошибка синтаксиса» можно отключить, выбрав «Сервис» -> «Параметры» и отметив «Автосинтаксическая проверка». Строка по-прежнему будет отображаться красным цветом в случае ошибки, но диалоговое окно не появится.
Ошибки компиляции
Ошибки компиляции происходят более чем в одной строке.
Синтаксис в одной строке правильный, но неверный, если учесть весь код проекта.
Примеры ошибок компиляции:
- Оператор If без соответствующего оператора End If
- For без Next
- Select без End Select
- Вызов Sub или Function, которые не существуют
- Вызов Sub или Function с неверными параметрами
- Присвоение Sub или Function того же имени, что и для модуля
- Переменные не объявлены (Option Explicit должен присутствовать в верхней части модуля)
На следующем снимке экрана показана ошибка компиляции,
которая возникает, когда цикл For не имеет соответствующего оператора Next.
Использование Debug-> Compile
Чтобы найти ошибки компиляции, мы используем Debug->
Compile VBA Project из меню Visual Basic.
Когда вы выбираете Debug-> Compile, VBA отображает первую
обнаруженную ошибку.
Когда эта ошибка исправлена, вы можете снова запустить
Compile, и VBA найдет следующую ошибку.
Debug-> Compile также будет включать синтаксические
ошибки в поиск, что очень полезно.
Если ошибок не осталось и вы запускаете Debug-> Compile,
может показаться, что ничего не произошло. Однако «Компиляция» будет недоступна
в меню «Отладка». Это означает, что ваше приложение не имеет ошибок компиляции
в текущий момент.
Debug->Compile Error Summary
Debug-> Compile находит ошибки компиляции (проекта).
Он также найдет синтаксические ошибки.
Он находит одну ошибку каждый раз, когда вы ее используете.
Если нет ошибок компиляции, оставленная опция Компиляция
будет отображаться серым цветом в меню.
Debug-> Compile Usage
Вы должны всегда использовать Debug-> Compile, прежде чем
запускать свой код. Это гарантирует, что ваш код не будет иметь ошибок
компиляции при запуске.
Если вы не запускаете Debug-> Compile, то VBA может
обнаружить ошибки компиляции при запуске. Их не следует путать с ошибками
времени выполнения.
Ошибки во время выполнения
Ошибки во время выполнения возникают, когда ваше приложение
работает. Обычно они находятся вне вашего контроля, но могут быть вызваны
ошибками в вашем коде.
Например, представьте, что ваше приложение читает из внешней
рабочей книги. Если этот файл будет удален, то VBA отобразит ошибку, когда ваш
код попытается открыть его.
Другие примеры ошибок времени выполнения
- база данных недоступна
- пользователь вводит неверные данные
- ячейка, содержащая текст вместо числа
Как мы уже видели, целью обработки ошибок является обработка
ошибок времени выполнения, когда они возникают.
Ожидаемые и неожиданные ошибки
Когда мы думаем, что может произойти ошибка во время
выполнения, мы помещаем код на место для ее обработки. Например, мы обычно
помещаем код на место, чтобы иметь дело с файлом, который не найден.
Следующий код проверяет, существует ли файл, прежде чем он
пытается его открыть. Если файл не существует, отображается сообщение, удобное
для пользователя, и код выходит из подпрограммы.
Sub OtkritFail()
Dim sFile As String
sFile = "C:ДокументыОтчет.xlsx"
' Используйте Dir, чтобы проверить, существует ли файл
If Dir(sFile) = "" Then
' если файл не существует, отобразить сообщение
MsgBox "Файл не найден" & sFile
Exit Sub
End If
' Код достигнет только если файл существует
Workbooks.Open sFile
End Sub
Когда мы думаем, что в какой-то момент может произойти
ошибка, рекомендуется добавить код для обработки ситуации. Мы обычно называем
эти ошибки ожидаемыми.
Если у нас нет специального кода для обработки ошибки, это
считается неожиданной ошибкой. Мы используем операторы обработки ошибок VBA для
обработки непредвиденных ошибок.
Ошибки времени выполнения, которые не являются ошибками VBA
Прежде чем мы рассмотрим VBA Handling, мы должны упомянуть
один тип ошибок. Некоторые ошибки во время выполнения не рассматриваются как
ошибки VBA, а только пользователем.
Позвольте мне объяснить это на примере. Представьте, что у
вас есть приложение, которое требует, чтобы вы добавили значения в переменные a
и b
Допустим, вы по ошибке используете звездочку вместо знака
плюс
Это не ошибка VBA. Ваш синтаксис кода является совершенно
законным. Однако, с вашей точки зрения, это ошибка.
Эти ошибки не могут быть обработаны с помощью обработки ошибок, поскольку они, очевидно, не будут генерировать никаких ошибок. Вы можете справиться с этими ошибками, используя Unit Testing and Assertions.
Заявление об ошибке
Как мы видели, есть два способа обработки ошибок во время
выполнения
- Ожидаемые ошибки — напишите конкретный код для
их обработки. - Неожиданные ошибки — используйте операторы
обработки ошибок VBA для их обработки.
Оператор VBA On Error используется для обработки ошибок.
Этот оператор выполняет некоторые действия при возникновении ошибки во время
выполнения.
Есть четыре различных способа использовать это утверждение
- On Error Goto 0 — код останавливается на строке с ошибкой и отображает сообщение.
- On Error Resume Next — код перемещается на следующую строку. Сообщение об ошибке не отображается.
- On Error Goto [label] — код перемещается на определенную строку или метку. Сообщение об ошибке не отображается. Это тот, который мы используем для обработки ошибок.
- On Error Goto -1 — очищает текущую ошибку.
Давайте посмотрим на каждое из этих утверждений по очереди.
On Error Goto 0
Это поведение по умолчанию VBA. Другими словами, если вы не
используете On Error, это поведение вы увидите.
При возникновении ошибки VBA останавливается на строке с
ошибкой и отображает сообщение об ошибке. Приложение требует вмешательства
пользователя с кодом, прежде чем оно сможет продолжить. Это может быть
исправление ошибки или перезапуск приложения. В этом случае обработка ошибок не
происходит.
Давайте посмотрим на пример. В следующем коде мы не
использовали строку On Error, поэтому VBA будет использовать поведение On Error
Goto 0 по умолчанию.
Sub IspDefault()
Dim x As Long, y As Long
x = 6
y = 6 / 0
x = 7
End Sub
Вторая строка присваивания приводит к ошибке деления на ноль. Когда мы запустим этот код, мы получим сообщение об ошибке, показанное на скриншоте ниже.
Когда появляется ошибка, вы можете выбрать End или Debug
Если вы выберете Конец, то приложение просто остановится.
Если вы выберете Отладить, приложение остановится на строке
ошибки, как показано на скриншоте ниже.
Это нормально, когда вы пишете код VBA, поскольку он
показывает вам точную строку с ошибкой.
Это поведение не подходит для приложения, которое вы
передаете пользователю. Эти ошибки выглядят непрофессионально и делают
приложение нестабильным.
Подобная ошибка, по сути, приводит к сбою приложения.
Пользователь не может продолжить работу без перезапуска приложения. Они могут
вообще не использовать его, пока вы не исправите для них ошибку.
Используя On Error Goto [label], мы можем дать пользователю
более контролируемое сообщение об ошибке. Это также предотвращает остановку
приложения. Мы можем заставить приложение работать предопределенным образом.
On Error Resume Next
Использование On Error Resume Next указывает VBA
игнорировать ошибку и продолжать работу.
Есть конкретные случаи, когда это полезно. Большую часть
времени вы должны избегать его использования.
Если мы добавим Resume Next к нашему примеру Sub, то VBA
проигнорирует ошибку деления на ноль
Sub UsingResumeNext()
On Error Resume Next
Dim x As Long, y As Long
x = 6
y = 6 / 0
x = 7
End Sub
Это не очень хорошая идея, чтобы сделать это. Если вы
игнорируете ошибку, то поведение может быть непредсказуемым. Ошибка может
повлиять на приложение несколькими способами. Вы можете получить неверные
данные. Проблема в том, что вы не знаете, что что-то пошло не так, потому что
вы подавили ошибку.
Приведенный ниже код является примером использования Resume
Next.
Sub OtprSoobsch()
On Error Resume Next
' Требуется ссылка:
' Библиотека объектов Microsoft Outlook 15.0
Dim Outlook As Outlook.Application
Set Outlook = New Outlook.Application
If Outlook Is Nothing Then
MsgBox " Не удается создать сеанс Microsoft Outlook." _
& " Письмо не будет отправлено."
Exit Sub
End If
End Sub
В этом коде мы проверяем, доступен ли Microsoft Outlook на компьютере. Все,
что мы хотим знать — это доступно или нет. Нас не интересует конкретная ошибка.
В приведенном выше коде мы продолжаем, если есть ошибка.
Затем в следующей строке мы проверяем значение переменной Outlook. Если произошла ошибка, тогда
значение этой переменной будет установлено равным Nothing.
Это пример того, когда Резюме может быть полезным. Дело в
том, что, хотя мы используем Resume,
мы все равно проверяем наличие ошибки. Подавляющее большинство времени вам не
нужно будет использовать Resume.
On Error Goto [label]
Вот как мы используем обработку ошибок в VBA. Это эквивалент функциональности Try and Catch, которую вы видите на
таких языках, как C # и
Java.
При возникновении ошибки вы отправляете ошибку на
определенный ярлык. Обычно это внизу саба.
Давайте применим это к подводной лодке, которую мы
использовали
Sub IspGotoLine()
On Error Goto eh
Dim x As Long, y As Long
x = 6
y = 6 / 0
x = 7
Done:
Exit Sub
eh:
MsgBox "Произошла следующая ошибка: " & Err.Description
End Sub
Снимок экрана ниже показывает, что происходит при возникновении ошибки.
VBA переходит на метку eh, потому что мы указали это в
строке «Перейти к ошибке».
Примечание 1: Метка, которую мы используем в операторе On… Goto, должна быть в текущей Sub / Function. Если нет, вы получите ошибку компиляции.
Примечание 2: Когда возникает ошибка при использовании On Error Goto [label], обработка ошибок возвращается к поведению по умолчанию, т.е. код остановится на строке с ошибкой и отобразит сообщение об ошибке. См. Следующий раздел для получения дополнительной информации об этом.
On Error Goto -1
Это утверждение отличается от других трех. Он используется
для очистки текущей ошибки, а не для настройки конкретного поведения.
При возникновении ошибки с помощью функции On Error Goto [label] поведение обработки ошибки возвращается к поведению по умолчанию, т.е. On Error Goto 0 . Это означает, что если произойдет другая ошибка, код остановится на текущей строке.
Это поведение относится только к текущей подпрограмме. Как
только мы выйдем из саба, ошибка будет очищена автоматически.
Посмотрите на код ниже. Первая ошибка приведет к переходу
кода на метку eh. Вторая ошибка остановится на строке с ошибкой 1034.
Sub DveOshibki()
On Error Goto eh
' генерировать ошибку «Несоответствие типов»
Error (13)
Done:
Exit Sub
eh:
' генерировать «определенную приложением» ошибку
Error (1034)
End Sub
Если мы добавим дальнейшую обработку ошибок, она не будет
работать, поскольку ловушка ошибок не была очищена.
В коде ниже мы добавили строку
после того как мы поймаем первую ошибку.
Это не имеет никакого эффекта, так как ошибка не была
очищена. Другими словами, код остановится на строке с ошибкой и отобразит
сообщение.
Sub DveOshibki()
On Error Goto eh
' генерировать ошибку «Несоответствие типов»
Error (13)
Done:
Exit Sub
eh:
On Error Goto eh_other
' генерировать «определенную приложением» ошибку
Error (1034)
Exit Sub
eh_other:
Debug.Print "ehother " & Err.Description
End Sub
Для устранения ошибки мы используем On Error Goto -1.
Думайте об этом как об установке ловушки для мыши. Когда ловушка сработает, вам
нужно установить ее снова.
В приведенном ниже коде мы добавляем эту строку, и вторая
ошибка теперь приведет к переходу кода на метку eh_other.
Sub DveOshibki()
On Error Goto eh
' генерировать ошибку «Несоответствие типов»
Error (13)
Done:
Exit Sub
eh:
' явная ошибка
On Error Goto -1
On Error Goto eh_other
' генерировать «определенную приложением» ошибку
Error (1034)
Exit Sub
eh_other:
Debug.Print "ehother " & Err.Description
End Sub
Примечание 1. Вероятно, в редких случаях полезно использовать On Error Goto -1. Мне лично никогда не приходилось пользоваться этой линией. Помните, что как только вы выйдете из Sub, ошибка все равно будет очищена.
Примечание 2. у объекта Err есть член Clear. Использование Clear очищает текст и цифры в объекте Err, но НЕ сбрасывает ошибку.
Использование On Error
Как мы уже видели, VBA будет делать одну из трех вещей при возникновении ошибки:
- Остановитесь и отобразите ошибку.
- Игнорируйте ошибку и продолжайте.
- Перейти к определенной строке.
VBA всегда будет настроен на одно из этих действий. Когда вы
используете On Error, VBA изменит ваше поведение и забудет о любом предыдущем.
В следующем подпункте VBA изменяет поведение ошибки каждый
раз, когда мы используем оператор On Error
Sub ErrorSostoyaniya()
Dim x As Long
' Перейти на этикетке, если ошибка
On Error Goto eh
' это проигнорирует ошибку в следующей строке
On Error Resume Next
x = 1 / 0
' это отобразит сообщение об ошибке в следующей строке
On Error Goto 0
x = 1 / 0
Done:
Exit Sub
eh:
Debug.Print Err.Description
End Sub
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 [error number], [error source], [error description]
Давайте посмотрим на простой пример. Представьте, что мы
хотим убедиться, что в ячейке есть запись длиной 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 для получения дополнительной информации об очистке фактической ошибки.
Логирование
Ведение журнала означает запись информации из вашего
приложения, когда оно запущено. При возникновении ошибки вы можете записать
детали в текстовый файл, чтобы у вас была запись об ошибке.
Код ниже показывает очень простую процедуру регистрации
Sub Logger(sType As String, sSource As String, sDetails As String)
Dim sFilename As String
sFilename = "C:templogging.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. Эти элементы считаются устаревшими, но я
включил их, поскольку они могут существовать в устаревшем коде.
Функция ошибки
Функция Error используется для печати описания ошибки с
заданным номером ошибки. Он включен в VBA для обеспечения обратной
совместимости и не нужен, поскольку вместо него можно использовать описание
Err.Description.
Ниже приведены некоторые примеры
' Распечатать текст «Деление на ноль» Debug.Print Error(11) ' Распечатать текст "Несоответствие типов" Debug.Print Error(13) ' Распечатать текст "Файл не найден" Debug.Print Error(53)
Заявление об ошибке
Заявление об ошибке позволяет имитировать ошибку. Он включен
в VBA для обратной совместимости. Вместо этого вы должны использовать
Err.Raise.
В следующем коде мы моделируем ошибку «Разделить на ноль».
Sub ZayavlObOshibke()
On Error Goto eh
' Это создаст деление на ноль ошибок
Error 11
Exit Sub
eh:
Debug.Print Err.Number, Err.Description
End Sub
Это утверждение включено в VBA для обратной совместимости.
Вместо этого вы должны использовать Err.Raise.
Простая стратегия обработки ошибок
Со всеми различными опциями вы можете быть озадачены тем,
как использовать обработку ошибок в VBA. В этом разделе я покажу вам, как
реализовать простую стратегию обработки ошибок, которую вы можете использовать
во всех своих приложениях.
Основная реализация
Это простой обзор нашей стратегии
- Поместите строку On Error Goto Label в начале нашего верхнего Sub.
- Поместите Label у обработки ошибок в конце нашего верхнего
Sub. - Если происходит ожидаемая ошибка, обработайте ее и продолжайте.
- Если приложение не может продолжить работу, используйте Err.Raise для перехода к метке обработки ошибок.
- В случае непредвиденной ошибки код автоматически перейдет к метке обработки ошибок.
На следующем рисунке показан обзор того, как это выглядит
Следующий код показывает простую реализацию этой стратегии
Public Const ERROR_NO_ACCOUNTS As Long = vbObjectError + 514
Sub BuildReport()
On Error Goto eh
' Если ошибка в ReadAccounts, то перейти к ошибке
ReadAccounts
' Сделай что-нибудь с кодом
Done:
Exit Sub
eh:
' Все ошибки будут прыгать сюда
MsgBox Err.Source & ": Произошла следующая ошибка " & Err.Description
End Sub
Sub ReadAccounts()
' ОЖИДАЕМАЯ ОШИБКА - Может обрабатываться кодом
' Приложение может обрабатывать A1 равным нулю
If Sheet1.Range("A1") = 0 Then
Sheet1.Range("A1") = 1
End If
' ОЖИДАЕМАЯ ОШИБКА - не может быть обработана кодом
' Приложение не может быть продолжено, если нет учетной записи
If Dir("C:ДокументыОтчет.xlsx") = "" Then
Err.Raise ERROR_NO_ACCOUNTS, "UsingErr" _
, "There are no accounts present for this month."
End If
' НЕОЖИДАННАЯ ОШИБКА - не может быть обработана кодом
' Если ячейка B3 содержит текст, мы получим ошибку несоответствия типов
Dim total As Long
total = Sheet1.Range("B3")
' продолжить и читать счета
End Sub
Это хороший способ реализации обработки ошибок, потому что
- Нам не нужно добавлять код обработки ошибок в
каждую подпрограмму. - Если возникает ошибка, то VBA корректно
завершает работу приложения.
Полная стратегия обработки ошибок
Стратегия выше имеет один недостаток. Он не сообщает вам,
где произошла ошибка. VBA не наполняет Err.Source чем-либо полезным, поэтому мы
должны сделать это сами.
В этом разделе я собираюсь представить более полную
стратегию ошибок. Я написал два сабвуфера, которые выполняют всю тяжелую
работу, поэтому все, что вам нужно сделать, это добавить их в свой проект.
Целью этой стратегии является предоставление вам стека * и
номера строки в случае возникновения ошибки.
* Стек — это список вспомогательных функций, которые
использовались в данный момент при возникновении ошибки.
Это наша стратегия
- Разместите обработку ошибок во всех
подпрограммах. - Когда происходит ошибка, обработчик ошибок
добавляет подробности к ошибке и вызывает ее снова. - Когда ошибка достигает самой верхней
подпрограммы, она отображается.
Мы просто «всплываем» из-за ошибки. Следующая диаграмма
показывает простое визуальное представление о том, что происходит, когда в Sub3
возникает ошибка
Единственная грязная часть этого — правильное форматирование
строк. Я написал две подводные лодки, которые справляются с этим, поэтому он
позаботится о вас.
Это две вспомогательные подводные лодки
Option Explicit
Public Const MARKER As String = "NOT_TOPMOST"
' Вызывает ошибку и добавляет номер строки и имя текущей процедуры
Sub RaiseError(ByVal errorno As Long, ByVal src As String _
, ByVal proc As String, ByVal desc As String, ByVal lineno As Long)
Dim sLineNo As Long, sSource As String
' Если маркера нет, тогда RaiseError вызывается впервые.
If Left(src, Len(MARKER)) <> MARKER Then
' Добавить номер строки ошибки, если она есть
If lineno <> 0 Then
sSource = vbCrLf & "Line no: " & lineno & " "
End If
' Добавить маркер и процедуру к источнику
sSource = MARKER & sSource & vbCrLf & proc
Else
' Если ошибка уже возникла, просто добавьте имя процедуры
sSource = src & vbCrLf & proc
End If
' Если код останавливается здесь, убедитесь, что DisplayError находится в верхней части Sub
Err.Raise errorno, sSource, desc
End Sub
' Отображает ошибку, когда она достигает самого верхнего sub
' Примечание: вы можете добавить вызов для входа из этого подпункта
Sub DisplayError(ByVal src As String, ByVal desc As String _
, ByVal sProcname As String)
' Удалить маркер
src = Replace(src, MARKER, "")
Dim sMsg As String
sMsg = " Произошла следующая ошибка: " & vbCrLf & Err.Description _
& vbCrLf & vbCrLf & " Расположение ошибки: "
sMsg = sMsg + src & vbCrLf & sProcname
' Показать сообщение
MsgBox sMsg, Title:="Ошибка "
End Sub
Пример использования этой стратегии
Вот простое кодирование, которое использует эти Sub. В этой стратегии мы не размещаем какой-либо код в верхнем подпрограмме. Мы только вызываем подводные лодки.
Sub Topmost()
On Error Goto EH
Level1
Done:
Exit Sub
EH:
DisplayError Err.source, Err.Description, "Module1.Topmost"
End Sub
Sub Level1()
On Error Goto EH
Level2
Done:
Exit Sub
EH:
RaiseError Err.Number, Err.source, "Module1.Level1", Err.Description, Erl
End Sub
Sub Level2()
On Error Goto EH
' Ошибка здесь
Dim a As Long
a = "7 / 0"
Done:
Exit Sub
EH:
RaiseError Err.Number, Err.source, "Module1.Level2", Err.Description, Erl
End Sub
Результат выглядит так
Если в вашем проекте есть номера строк, результат будет содержать номер строки ошибки.
Примечание: вы можете получить следующую ошибку при использовании этого кода:
“Programmatic Access to Visual Basic Project is not trusted”
Чтобы решить эту проблему, выполните следующие действия.
- Перейдите в раздел «Разработчик» на ленте и
нажмите «Macro Security», которая находится под кодом. - Нажмите «Настройка макроса» в левом списке.
- Поставьте флажок в поле «Доверительный доступ к
объектной модели проекта VBA». - Нажмите Ok.
Обработка ошибок в двух словах
- Обработка ошибок используется для обработки ошибок, возникающих во время работы приложения.
- Вы пишете определенный код для обработки ожидаемых ошибок. Вы используете оператор обработки ошибок VBA
On Error Goto [label] для отправки VBA на метку при возникновении непредвиденной ошибки. - Вы можете получить подробную информацию об ошибке из Err.Description.
- Вы можете создать свою собственную ошибку, используя Err.Raise.
- Использование одного оператора On Error в самой верхней подпрограмме перехватит все ошибки в подпрограммах, которые вызываются отсюда.
- Если вы хотите записать имя Sub с ошибкой, вы можете обновить ошибку и сбросить ее.
- Вы можете использовать журнал для записи информации о приложении, когда оно запущено.

































вооот , там даже шанса не было 













