Хитрости »
21 Март 2015 94824 просмотров
Очень часто начинающие работать в VBA сталкиваются с различными ошибками, которые выдает код в момент выполнения. Если не знать как поступить в данном случае – то очень сложно будет исправить код быстро, а то и вообще невозможно будет определить причину ошибки без помощи более «продвинутых» пользователей. Новички зачастую делают правки наугад, что может порождать иные ошибки, а это в свою очередь не только затрудняет поиск первоначальной ошибки, но и может привести к невозможности исправить код вообще. Поэтому в этой статье я решил описать как производить отладку кода и определять ошибки.
Чтобы описанное в статье можно было сразу опробовать в практике советую скачать файл пример:
Пример таблицы и кода (35,5 KiB, 2 854 скачиваний)
Что будет рассмотрено:
- Способы отладки кода в момент появления ошибки
- Использование окон 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 с описанием большей части ошибок, которые могут возникнуть. В файле указан номер ошибки, описание на английском и описание на русском. Причин ошибки может быть множество, поэтому нет однозначных рекомендаций по устранению каждой из них. Все зависит от данных и от самого кода.
Ошибки VBA с описанием (152,0 KiB, 5 562 скачиваний)
Удачи в программировании!
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
Вы узнали, что макрос хранится в виде кода VBA в Excel. Вы также узнали, что можете напрямую написать код для создания макроса в редакторе VBA. Однако, как и в случае с любым кодом, даже код макроса может иметь дефекты, и макрос может работать не так, как вы ожидали.
Это требует изучения кода, чтобы найти дефекты и исправить их. Термин, который используется для этого действия в разработке программного обеспечения, является отладкой.
Отладка VBA
Редактор VBA позволяет приостановить выполнение кода и выполнить любую необходимую задачу отладки. Ниже приведены некоторые из задач отладки, которые вы можете выполнить.
- Пошаговое выполнение кода
- Использование точек останова
- Резервное копирование или движение вперед в коде
- Не переступая через каждую строку кода
- Запрашивать что-либо во время пошагового выполнения кода
- Остановка казни
Это лишь некоторые из задач, которые вы можете выполнять в среде отладки VBA.
Пошаговое выполнение кода
Первое, что вам нужно сделать для отладки, это пройти по коду при его выполнении. Если у вас есть представление о том, какая часть кода, вероятно, создает дефект, вы можете перейти к этой строке кода. В противном случае вы можете выполнить код построчно, выполнить резервное копирование или продвинуться вперед в коде.
Вы можете перейти к коду из диалогового окна «Макрос» в рабочей книге или из самого редактора VBA.
Войдя в код из рабочей книги
Чтобы войти в код из рабочей книги, выполните следующие действия:
- Нажмите вкладку VIEW на ленте.
- Нажмите Макросы.
- Выберите View Macros из выпадающего списка.
Откроется диалоговое окно «Макрос».
- Нажмите на имя макроса.
- Нажмите кнопку Шаг в.
Откроется редактор VBA и в окне кода появится код макроса. Первая строка в коде макроса будет выделена желтым цветом.
Шаг в код от редактора VBA
Чтобы войти в код из редактора VBA, выполните следующие действия:
- Нажмите вкладку РАЗРАБОТЧИК на ленте.
- Нажмите Visual Basic. Откроется редактор VBA.
- Нажмите на модуль, который содержит код макроса.
Код макроса появится в окне кода.
-
Перейдите на вкладку «Отладка» на ленте.
-
Выберите Step into из выпадающего списка.
Перейдите на вкладку «Отладка» на ленте.
Выберите Step into из выпадающего списка.
Первая строка в коде макроса будет выделена. Код находится в режиме отладки, и параметры в раскрывающемся списке «Отладка» станут активными.
Резервное копирование или движение вперед в коде
Вы можете двигаться вперед или назад в коде, выбрав Step Over или Step Out.
Не переступая через каждую строку кода
Вы можете избежать пошагового прохождения каждого строкового кода, если вы идентифицируете потенциальную часть кода, которую необходимо обсудить, выбрав Run to Cursor.
Использование точек останова
Кроме того, вы можете установить точки останова в определенных строках кода и выполнить код, наблюдая результаты в каждой точке останова. Вы можете переключать точку останова и очищать все точки останова, если и когда это необходимо.
Использование часов
Вы можете добавить часы во время отладки, чтобы оценить выражение и остановить выполнение, когда переменная достигает определенного значения. Это означает, что вы настраиваете выражение наблюдения, которое будет отслеживаться до тех пор, пока оно не станет истинным, а затем макрос остановится и оставит вас в режиме прерывания. VBA предоставляет вам несколько типов часов на выбор, чтобы выполнить то, что вы ищете.
Остановка казни
Во время отладки, в любой момент, если вы нашли подсказку о том, что идет не так, вы можете остановить выполнение, чтобы расшифровать его дальше.
Если вы опытный разработчик, терминология отладки вам знакома, а опции отладки в редакторе VBA сделают вашу жизнь проще. Даже в противном случае освоение этого навыка не займет много времени, если вы изучите VBA и поймете код.
Li$$@ Пользователь Сообщений: 152 |
А вот такой вопрос возник, если кто знает — пошаговое тестирование кода из модуля листа вообще никак не возможно?.. В полете голова — важнее крыльев |
Hugo Пользователь Сообщений: 23256 |
Поставить точку останова (мышью на левом бордюре окна). Изменено: Hugo — 13.05.2014 18:20:13 |
B.Key Пользователь Сообщений: 633 |
|
Li$$@ Пользователь Сообщений: 152 |
Не работает F8 в коде процедуры листа, там только событие запускать вроде В полете голова — важнее крыльев |
B.Key Пользователь Сообщений: 633 |
А у меня работает. |
B.Key Пользователь Сообщений: 633 |
Hugo, похоже телепат. Я пока нет Изменено: B.Key — 13.05.2014 21:51:18 |
Li$$@ Пользователь Сообщений: 152 |
#7 13.05.2014 18:43:54
Где у вас работает?
В полете голова — важнее крыльев |
||||
Юрий М Модератор Сообщений: 60588 Контакты см. в профиле |
#8 13.05.2014 22:32:34
И в «обычном» (стандартном), и в модуле листа можно запускать по F8, если это не событийная процедура, как в Вашем случае. |
||
Как вариант используйте debug.print и debut.assert Изменено: Все_просто — 13.05.2014 22:36:26 С уважением, |
|
Юрий М Модератор Сообщений: 60588 Контакты см. в профиле |
А чем Debug.Print поможет? Вопрос ведь о ПОШАГОВОМ прогоне кода. |
Alex_ST Пользователь Сообщений: 2746 На лицо ужасный, добрый внутри |
#11 14.05.2014 09:05:31 Если у Вас процедура обработки события, имеющая аргументы запуска, как, например,
имеющая аргументом Target , то она, действительно, по F8 не запустится.
после вызова события (т.е. ввода чего-нибудь в любую ячейку листа) Вы вылетите в режим отладки VBE с остановкой исполнения процедуры в указанном Вами месте. А далее уже сможете идти по шагам с помощью F8 Изменено: Alex_ST — 15.05.2014 17:24:13 С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!) |
||||
Hugo Пользователь Сообщений: 23256 |
#12 14.05.2014 09:15:58 Ещё вариант:
|
||
Johny Пользователь Сообщений: 2737 |
#13 14.05.2014 09:34:51 Если Вы пытаетесь поставть break point на строке объявления переменных, то она ставиться не будет. Изменено: Johny — 14.05.2014 10:04:57 There is no knowledge that is not power |
Skip to content
Как правильно создавать пользовательские функции и где нужно размещать их код, мы подробно рассмотрели ранее в этой статье. Чтобы решить проблемы при создании пользовательской функции, вам скорее всего придется выполнить ее отладку. Тогда вы будете уверены, что функция работает правильно.
Мы рассмотрим несколько способов, как это сделать:
- Что такое отладка функции?
- Способ 1. Использование MsgBox
- Способ 2. Пошаговое выполнение.
- Способ 3. Применение оператора Debug.Print
- Способ 4. Вызов функции из процедуры.
Вы можете выбрать для себя наиболее подходящий метод.
Что такое отладка функции?
Когда вы создаете пользовательскую функцию, всегда существует возможность, что вы допустите ошибку и она не сразу будет работать так, как вам нужно.
Пользовательские функции обычно достаточно сложные. И не всегда они сразу начинают работать правильно. Формула может возвратить неверный результат или ошибку #ЗНАЧ!. В отличие от стандартных функций Excel, никаких других сообщений вы не увидите.
Есть ли способ отследить работу пользовательской функции по шагам, чтобы проверить, как работает каждый оператор, входящий в нее? Да, есть. Для этого и используется отладка.
Я предложу вам несколько способов проверки работы пользовательской функции, чтобы вы могли выбрать наиболее подходящий для себя.
В качестве примера используем пользовательскую функцию GetMaxBetween из нашей предыдущей статьи, которая вычисляет максимальное число в указанном диапазоне значений:
Аргументы функции — это диапазон ячеек, в которых записаны числа, а также верхний и нижний предел значений.
Способ 1. Поместите в важных местах функцию MsgBox.
Для того, чтобы следить за выполнением расчетов, можно в нужных местах выводить на экран значения самых важных переменных. Это можно сделать при помощи всплывающих диалоговых окон.
MsgBox — это диалоговое окно, которое вы можете использовать, чтобы показывать пользователю какое-то сообщение.
MsgBox является функцией и имеет синтаксис, аналогичный другим функциям VBA:
MsgBox( prompt [, buttons ] [, title ] [, helpfile, context ] )
prompt — это обязательный аргумент. Он содержит сообщение, которое вы видите в диалоговом окне. Его также можно использовать для отображения значений отдельных переменных.
Все остальные аргументы являются не обязательными.
[buttons] — определяет, какие кнопки и значки отображаются в MsgBox. Например, если я использую vbOkOnly, то будет отображаться только кнопка OK. Даже если вы пропустили этот аргумент, эта кнопка используется по умолчанию.
[title] — здесь вы можете указать заголовок окна сообщения.
Приступим к отладке. Чтобы показать сообщение, добавим в код пользовательской функции GetMaxBetween перед оператором Case Else следующую строку:
MsgBox vMax, , «Count — » & i
Получим следующий код:
Function GetMaxBetween(rngCells As Range, MinNum, MaxNum)
Dim NumRange As Range
Dim vMax
Dim arrNums()
Dim i As Integer
ReDim arrNums(rngCells.Count)
For Each NumRange In rngCells
vMax = NumRange
Select Case vMax
Case MinNum + 0.01 To MaxNum - 0.01
arrNums(i) = vMax
i = i + 1
MsgBox vMax,, "Count -" & i
Case Else
GetMaxBetween = 0
End Select
Next NumRange
GetMaxBetween = WorksheetFunction.Max(arrNums)
End Function
С помощью переменной vMax в диалоговом окне мы увидим, какие числа соответствуют условиям для отбора, чтобы из них затем выбрать наибольшее. При помощи выражения «Count — » & i в заголовке окна мы указываем, сколько чисел мы уже выбрали, чтобы определить максимальное значение. С каждым новым значением счетчик будет увеличиваться.
В ячейку С1 нашего рабочего листа запишем формулу
=GetMaxBetween(A1:A6;10;50)
После того, как будет нажата клавиша Enter, вы увидите сообщение, как на скриншоте ниже:
Это первое число из диапазона A1:A6, которое соответствует условиям: больше 10, но меньше 50.
После того, как вы нажмете ОК, появится второе сообщение с числом 14. Остальные числа не соответствуют условиям отбора. Поэтому функция завершает работу и возвращает наибольшее из двух значений — 17.
Таким образом, мы шаг за шагом отследили всю работу нашей функции и выяснили, что она работает верно.
Функцию MsgBox можно использовать в самых важных местах кода пользовательской функции, чтобы контролировать изменение значений отдельных переменных. Окна с сообщениями могут оказаться очень полезными, когда у вас большая функция и много вычислений. В этом случае вам будет легко определить, в какой части кода происходит ошибка.
Способ 2. Определите точки остановки и выполните функцию пошагово.
Вы можете добавить в код вашей функции точки останова (Breakpoint), на которых будет останавливаться выполнение вычислений. Так можно пошагово проследить процесс расчёта. При этом вы можете посмотреть, как изменяются значения переменных.
Чтобы добавить точку остановки, поместите курсор в строку с оператором, в котором вы решили приостановить выполнение. Потом нажмите правую кнопку мыши и выберите команду Debug –> Toggle Breakpoint или просто нажмите клавишу F9
. Также можно кликнуть в нужном месте на вертикальной серой области слева от кода функции.
Появится красный кружок, как вы видите на скриншоте ниже. Строка кода, где будет остановлен расчет, выделяется красным цветом.
Теперь при работе функции будет открываться окно редактора VBA. Курсор будет установлен в точке остановки.
Если вы наведете курсор мыши на любую из переменных в коде функции, вы сможете увидеть их текущее значение. Для контроля выполнения вычислений это очень полезно. Вы видите это действие на скриншоте ниже.
Чтобы продолжить вычисления, просто нажмите клавишу F5
.
Примечание. После точки останова вы можете приступить к пошаговому отслеживанию хода вычислений. Если вы нажмете кнопку F8, будет выполнена только одна следующая строка кода VBA. Желтая линия со стрелкой также переместится в позицию последнего выполненного кода.
Поскольку выполнение функции снова приостанавливается, вы можете просматривать текущие значения всех переменных функции с помощью курсора мыши.
Следующее нажатие F8
продвинет нас на шаг вперед. Таким образом, вы можете нажимать F8
до конца расчета. Или нажмите F5
, чтобы продолжить вычисление до следующей точки останова.
В случае возникновения ошибки курсор будет остановлен в той точке кода, где произошла ошибка. И вы также увидите всплывающее сообщение об ошибке. Это позволяет легко определить причину проблемы.
Указанные вами точки останова действуют, пока вы не закрыли файл. При повторном его открытии вам нужно снова их указывать. Согласитесь, что это не всегда удобно.
Эту проблему можно решить. Вставьте в код функции в нужных точках оператор Stop, и вы сможете прервать выполнение программы так же, как при использовании точек останова.
Когда VBA встретит оператор Stop, он остановит расчёты и будет ожидать ваших действий. Проверьте значения переменных, затем нажмите F5
для продолжения.
Оператор Stop является частью программы и поэтому не удаляется при закрытии книги, как это происходит с точкой останова. Когда вы закончите отладку, удалите его сами. Либо превратите в комментарий, поставив перед ним одинарную кавычку (‘).
Способ 3. Отладка при помощи оператора Debug.Print
В коде функции вы можете разместить оператор Debug.Print. Это полезно, чтобы проконтролировать значения переменных, которые циклически изменяются.
Пример такого кода вы видите на скриншоте ниже.
Оператор Debug.Print i, vMax выводит числа, которые были обработаны функцией, и их порядковые номера (начиная с 1).
В окне Immediate вы видите два числа (17 и 14) из выбранного диапазона, которые соответствуют установленным ограничениям и среди которых и будет определено максимальное. Цифры 1 и 2 означают, что функция выполнила 2 цикла, в которых были выбраны числа. Мы видим значения самых важных переменных, как ранее делали при помощи MsgBox. Но при этом не останавливали работу функции.
Способ 4. Вызвать функцию из процедуры
Можно вызвать пользовательскую функцию не из ячейки рабочего листа, а из процедуры. В этом случае все ошибки будут показаны в окне Visual Basic Editor.
Вот как можно вызвать из процедуры пользовательскую функцию GetMaxBerween:
Sub Test()
Dim x
x = GetMaxBetween(Range("A1:A6"), 10, 50)
MsgBox (x)
End Sub
Установите курсор в любое место кода и нажмите F5. Если ошибки в функции нет, вы увидите всплывающее окно с результатом расчетов.
В случае ошибки вы увидите соответствующее сообщение в редакторе VBA. Расчет будет приостановлен, и строка кода, в которой произошла ошибка, будет выделена жёлтым цветом. Вы легко определите, где и почему возникла проблема.
Это все. Теперь вы создали свою надстройку, добавили ее в Excel и можете использовать в ней пользовательскую функцию. Если вы хотите использовать больше функций, просто напишите их код в модуле надстройки в редакторе VBA и сохраните его.
На сегодня все. Мы рассмотрели различные способы отладки пользовательских функций и узнали, как использовать их в своей рабочей книге. Мы очень надеемся, что эти рекомендации будут вам полезны. Если возникнут вопросы, пишите в комментариях к этой статье.
5.1 Понятие макроса
5.2 Создание
5.3 Отладка, использование среды для отладки программ
5.4 Обработка ошибок выполнения
5.1 Понятие макроса
Макрос — процедура на внутреннем языке приложения, в которой записаны действия пользователя приложения. В программах Word, Excel и PowerPoint макрос записывается на VBA. В Access макросы создаются с помощью собственного языка макросов, а не записываются автоматически, и к тому же не являются процедурами VBA.
5.2 Создание
Прежде чем записать макрос, требуется продумать свои действия, то есть составить алгоритм. Особое внимание следует уделить таким положениям:
Какие условия должны выполняться при запуске макроса (какой файл должен быть открыт, где должен находиться курсор, в каком режиме должно работать приложение).
Какие действия должен выполнять макрос.
Какие действия необходимо проделать при завершении работы макроса.
Чтобы начать запись макроса, необходимо:
Активизировать приложение
Открыть документы, используемые при записи макроса
Выбрать команду СервисМакрос
Выбрать команду Начать запись. Выводится диалоговое окно Запись макроса
Ввести имя записываемого макроса в поле Имя макроса
Выбрать в списке Макрос доступен для документ, в который требуется поместить макрос
Нажать ОК, чтобы начать запись
После этого записываются все выполняемые в приложении действия
По завершении выполнения требуемых действий необходимо:
Нажать на панели инструментов Остановка записи кнопку Остановить запись
или выбрать команду СервисМакросОстановить запись
Вновь созданный макрос содержится в документе, который был активным при запуске макроса. При записи документа на диск макрос сохраняется вместе с проектом.
Для выполнения записанного макроса необходимо:
Выбрать команду СервисМакросМакросы. Выводится диалоговое окно Макрос.
Выбрать имя требуемого макроса
Нажать кнопку Выполнить для запуска макроса.
Для редактирования записанного макроса необходимо:
Выбрать команду СервисМакросМакросы. Выводится диалоговое окно Макрос.
Выбрать имя требуемого макроса
Нажать кнопку Изменить. Макрос выводится в окне редактора Visual Basic for Applications..
5.3 Отладка, использование среды для отладки программ
Поскольку идеальных программистов не существует, в большинстве систем разработки программ имеются инструменты, с помощью которых можно решить проблемы, возникающие в процессе программирования. В VBA также есть средства, которые позволяют либо исключить ошибки при разработке, либо задать обработку ошибок при выполнении программ.
Отладка программ — это проверка и внесение исправлений в программу при ее разработке. Отладка позволяет идентифицировать ошибки, допущенные при программировании (синтаксические — ошибки в выражениях и именах, и логические — в логике работы программы).
Обработка ошибок — это задание реакции на ошибки, которые возникают при выполнении программы. Их причиной могут быть как ошибки программиста, так и внешние факторы — отсутствие нужных файлов, отказы аппаратуры, неправильные действия пользователя.
Типы ошибок. Ошибки в программе делятся на три категории:
Ошибки компиляции — возникают, когда компилятор не может интерпретировать введенный текст. Некоторые ошибки компиляции обнаруживаются при вводе, а другие — перед выполнением программы. Такие ошибки легко определить и исправить, поскольку VBA выявляет их автоматически, а сами ошибки очевидны.
Примечание. VBA автоматически компилирует программу каждый раз при запуске на выполнение после внесения изменений. Можно также запустить компиляцию командой ОтладкаКомпилировать.
Ошибки выполнения — возникают при выполнении программы после успешной компиляции. Их причиной обычно является отсутствие данных или неправильная информация, введенная пользователем. Такие ошибки идентифицируются VBA с указанием инструкции, при выполнении которой произошла ошибка. Для исправления таких ошибок обычно приходится выводить значения переменных или другие данные, которые влияют на успешное выполнение программы.
Логические ошибки трудно заметить и устранить. Они не приводят к прекращению компиляции или выполнения, однако являются причиной того, что программа не выдает желаемых результатов. Выявление таких ошибок производят путем тщательной проверки с помощью средств отладки VBA.
Средства отладки. В VBA имеется большое количество средств, предназначенных для отладки программ. К ним относятся: использование оператора Option Explicit, пошаговое выполнение программы, работа в режиме прерывания, использование точек останова, вывод значений переменных.
Использование Option Explicit. Данный оператор описания требует явного задания переменных в программах. При его использовании возникает ошибка компиляции при неправильном написании имени переменной или использовании неописанной переменной. Кроме того, явное описание переменных позволяет обойтись без использования типа данных Variant и связанных с его использованием ошибок при неявном приведении типов данных.
Пошаговое выполнение программы. Этот режим служит для локализации ошибок в теле программы. Для его запуска используются команды меню, клавиатура или панель инструментов Отладка, отображаемая командой ВидПанели инструментовОтладка. В меню и на панели инструментов имеются четыре команды (кнопки) для выполнения программы в пошаговом режиме.
Команда ОтладкаШаг с заходом (клавиша F8) позволяет выполнить одну строку программы и перейти к следующей. Если следующая строка — вызов процедуры, то происходит переход к первому выполняемому оператору этой процедуры.
Команда ОтладкаШаг с обходом (клавиши Shift+F8) также выполняет одну строку программы, но если строкой является вызов процедуры, то она выполняется как одна инструкция. Данная команда используется, если известно, что эта процедура работает правильно.
Команда ОтладкаШаг с выходом (клавиши Ctrl+Shift+F8) заканчивает выполнение текущей процедуры и останавливается на следующей после вызова текущей процедуры инструкции в вызывающей подпрограмме.
Команда ОтладкаВыполнить до текущей позиции (клавиши Ctrl+F8) выполняет программу от текущей до выбранной инструкции. Перед выбором данной команды требуется установить курсор в окне модуля на требуемую позицию.
Работа в режиме прерывания. Переход в данный режим выполняется:
При нажатии кнопки Отладка в окне сообщения об ошибке выполнения.
При прерывании работы программы нажатием клавиш Ctrl+Break. Текущая строка программы выделяется в окне модуля.
По достижении точки останова.
По достижении оператора Stop.
При пошаговом выполнении программы.
В режиме прерывания можно:
Вывести значение переменной.
Вычислить выражение в окне отладки.
Сбросить программу
Выполнить программу в пошаговом режиме.
Продолжить выполнение программы.
Для выхода из режима прерывания используется команда ЗапускСброс.
Использование точек останова. Точка останова — это строка в процедуре, на которой приостанавливается выполнение программы. Все команды, находящиеся выше точки останова, выполняются с обычной скоростью, а по достижении контрольной точки программа переходит в режим прерывания. Затем можно отлаживать процедуру в пошаговом режиме, либо использовать различные способы вывода значений переменных. Кроме того, имеется возможность остановить выполнение или сбросить процедуру командами меню Запуск или кнопками панели инструментов Отладка. В одном проекте можно задать несколько точек останова, причем в различных процедурах.
Чтобы установить или снять точку останова, используется команда ОтладкаТочка останова или клавиша F9, либо кнопка Точка останова панели инструментов Отладка. Можно также установить или снять точку останова, щелкнув левой кнопкой мыши на полосе индикатора против требуемой строки. Точка останова отмечается коричневой жирной точкой на полосе индикатора, а сама строка выделяется коричневым цветом.
Чтобы быстро удалить все точки останова открытого проекта, используется команда ОтладкаСнать все точки останова или комбинация клавиш Ctrl+Shift+F9. Для данной команды не предусмотрена кнопка на панели инструментов Отладка.
Вывод значений переменных. При наличии тестового примера вывод значений переменных позволяет сравнить ожидаемые и полученные значения переменных. Для отображения значений переменных в режиме прерывания необходимо:
При установленном флажке Подсказки значений переменных в окне СервисПараметры достаточно переместить указатель мыши на требуемую переменную для отображения имени и значения переменной во всплывающей подсказке.
Выбрать команду ОтладкаКонтрольное значение (нажать клавиши Shift+F9) для вывода диалогового окна Контрольное значение. При этом курсор должен находиться возле переменной, значение которой надо контролировать. В окне Контрольное значение отображается контекст (имя модуля и процедуры), выделенное выражение (переменная) и кнопки Добавить и Отмена. При нажатии кнопки Добавить откроется окно Контрольные значения, содержащее имена переменных (выражения), их значения, тип данных и контекст.
Для добавления других контрольных значений используется команда ОтладкаДобавить контрольное значение.
Выбрать команду ВидОкно локальных переменных. Откроется окно Локальные переменные, в котором в режиме прерывания отображаются имена, значения и типы всех переменных модуля.
Выбрать команду ВидОкно отладки. В нем немедленно выполняется введенная в него инструкция, обычно операция отображения значения выражения вида Print имя, или операция присваивания значения переменной. Выполняемая программа также может выводить информацию в это окно с помощью выражения Debug.Print имя переменной.
Для отображения значений переменных в режиме нормальной работы необходимо ввести в тело программы вызов функции MsgBox (сообщение, [кнопки, заголовок]). Эта функция отображает диалоговое окно, содержащее сообщение длиной до 1024 символов, в которое с помощью операции конкатенации можно включить значение переменных, а также (необязательно) кнопки для реакции на отображения окна (по умолчанию только кнопка ОК) и заголовок окна (строковое выражение). Пример:
MsgBox «Значение val=» & val
Заметим, что VBA не имеет встроенных функций ввода/вывода в документ. Поэтому для вывода значений выражений и переменных в активный документ приходится создавать пользовательские процедуры. Например, для вывода значения в ячейку рабочего листа «Лист1» активной книги Excel приходится записывать в модуле и вызывать процедуру вида:
Sub out(name As String, val As Variant) Лист1.Range(name).Value = val End Sub
Здесь name — координаты ячейки, записанные в кавычках, а val — имя выводимой переменной.
Для ввода значений переменных в программу применяют функцию InputBox(сообщение[, заголовок] [, значение по умолчанию] [, координата x] [, координата y]). Эта функция отображает диалоговое окно, содержащее окно ввода, кнопки ОК и Отмена, сообщение (подсказку для ввода) и (необязательно) заголовок окна, значение, вводимое по умолчанию, координаты окна по горизонтали и вертикали в твиках. Заметим, что функция InputBox всегда (даже при нажатии кнопки Отмена) возвращает значение строкового типа, поэтому вызов ее должен иметь вид:
name = InputBox(«Введи адрес ячейки», «Ввод», «a1», 100, 200)
Для преобразования введенного значения к нужному типу данных используются функции явного приведения типа, такие как CDbl(выражение), CInt(выражение), CLng(выражение), CSng(выражение), CVar(выражение), CStr(выражение).
Для ввода значений переменных из активного документа приходится создавать пользовательские процедуры. Например, для ввода значения из ячейки рабочего листа «Лист1» активной книги Excel приходится записывать в модуле и вызывать процедуру вида:
Sub read(name As String, val As Variant) val = Лист1.Range(name).Value End Sub
Здесь name — координаты ячейки, записанные в кавычках, а val — имя вводимой переменной.
5.4 Обработка ошибок выполнения
Как уже отмечалось выше, одной из основных проблем являются ошибки выполнения. Эти ошибки возникают при попытке произвести недопустимую операцию, например, при открытии несуществующего файла, делении на ноль, или при обработке неправильно введенных пользователем данных.
Так или иначе, при возникновении ошибки выполнение программы прерывается и выводится сообщение. К сожалению, это сообщение несет мало полезной информации, поскольку в нем указывается только недопустимая операция, а не причина возникновения ошибки. Еще хуже то, что программа не выполняется до конца и не произведены все необходимые действия.
Пользователь может без всякого умысла произвести действия, которые нанесут непоправимый вред данным. Следовательно, необходимо каким-то образом оградить себя от возникновения подобных ситуаций.
При программировании имеются два подхода:
Предотвращение ошибочных ситуаций.
Обработка ошибки с помощью специальной процедуры.
При разработке программ рекомендуется по возможности предотвращать возникновение ошибочных ситуаций. Начиная создание алгоритма макроса, следует ответить на ряд вопросов, например:
Существует ли файл, который требуется открыть?
Находится ли курсор в требуемой для выполнения макроса позиции?
Перехватываемые ошибки.
Перехват используется в том случае, когда предотвратить возникновение ошибочных ситуаций невозможно. Полный список перехватываемых ошибок приводится в разделе системы справочной информации Visual Basic «Перехватываемые ошибки» (Trappable Errors). Ниже описываются только некоторые из них.
КОД СООБЩЕНИЕ
3 Инструкция Return без Gosub 6 Переполнение 7 Не хватает памяти 9 Индекс выходит за пределы допустимого диапазона 11 Деление на 0 18 Произошло прерывание, вызванное пользователем 35 Процедура Sub, Function или Property не определена 53 Файл не найден 61 Переполнение диска 71 Диск не готов 91 Не задана объектная переменная блока With 97 Невозможен вызов процедуры Friend для объекта, не являющегося экземпляром определяющего класса 335 Невозможен доступ к системному реестру 368 Истек срок данного системного файла. Программе требуется файл более новой версии 402 Сначала необходимо закрыть самую верхнюю модальную форму 422 Свойство не найдено 440 Ошибка программирования объектов 448 Именованный аргумент не найден 482 Ошибка принтера 31032 Невозможно создать внедренный объект
Очевидно, что ни одно из показанных сообщений не дает пользователю исчерпывающих сведений о причине возникновения ошибки. Профессионал может точно определить проблему, используя систему справочной информации, а человеку, который захочет, например, написать письмо или ввести данные в отчет с помощью разрабатываемого приложения, такие сообщения непонятны. Предотвращая возникновение ошибок или перехватывая их, можно исключить вывод стандартных сообщений. Вместо них появляется возможность либо отобразить собственную подсказку, либо попытаться исправить положение с помощью макроса. Ниже объясняется, как перехватить ошибку.
Перехват ошибок.
Обработка ошибок выполнения в VBA называется перехватом ошибки. Правильно разработав подпрограмму обработки ошибок, можно задать отклик на многие возможные ошибки. Наиболее важно, чтобы ошибка не остановила выполнение процедуры. При этом пользователь может даже не заметить, что произошла ошибка.
Система перехвата ошибок включает следующие компоненты:
Инструкция On Error устанавливает перехват ошибки. Она сообщает процедуре, что делать, если произошла ошибка, обычно передавая управление подпрограмме обработки ошибки.
Подпрограмма обработки ошибки — это часть выполняемой процедуры, которая используется для обработки ошибок. Обычно в ней определяется тип возникшей ошибки, а затем производятся соответствующие действия. Начало подпрограммы обработки идентифицируется меткой.
Объект Err содержит информацию о возникшей ошибке. Подобно любому объекту он имеет свои свойства, включая номер и описание ошибки.
Инструкция Resume позволяет процедуре продолжить операции после обработки ошибки.
Инструкция Exit позволяет выйти из процедуры, не выполняя оставшийся код. Данная инструкция используется очень часто, поскольку если ошибок не возникло, то не следует исполнять подпрограмму обработки ошибки.
Общие сведения о перехвате ошибок.
Общее правило перехвата ошибок можно пояснить на примере следующей процедуры:
Sub MyProcedure () On Error GoTo MyErrorHandler '… ' Обычные действия, при выполнении каждого из ' которых может произойти ошибка '… Exit Sub ' Выход для обхода подпрограммы обработки ошибки MyErrorHandler: '… ' Подпрограмма обработки ошибки '… Resume End Sub
Инструкция On Error устанавливает перехват ошибки для невыполненной части макроса, указывая на подпрограмму обработки ошибки. В макросе может быть несколько инструкций On Error, каждая из которых определяет разные процедуры обработки. В предыдущем примере при возникновении ошибки управление передается инструкции с меткой MyErrorHandler.
Инструкция On Error имеет три формы:
Инструкция On Error GoTo метка позволяет передать управление подпрограмме обработки ошибки, которая идентифицируется меткой.
Инструкция On Error Resume Next позволяет игнорировать ошибку и продолжить выполнение со следующей инструкции после той, при исполнении которой возникла ошибка. Если ошибка вызывает возникновение других ошибок, то лучше не применять данную форму инструкции On Error.
Для определение типа ошибки и выполнения, соответствующих ей действий имеется возможность получить значение свойства Number объекта Err.
Инструкция On Error GoTo 0 отключает обработку ошибок для данной процедуры. Данная инструкция обычно указывается после первых двух форм инструкции On Error ниже строк, в которых могут возникнуть ошибки. Поскольку подпрограмма обработки уже сыграла свою роль, можно не перехватывать ошибки.
В любом случае инструкция On Error устанавливает обработку ошибок только в той процедуре, в которой она указана.
Инструкцию On Error можно указывать произвольное число раз, изменяя способ обработки ошибок.
Sub MySub () '… On Error GoTo MyHandler '… OnError Resume Next '… On Error GoTo 0 '… MyHandler: '… Resume End Sub
Метка, которая помечает начало подпрограммы обработки ошибок, является параметром инструкции GoTo. Меткой является любое допустимое имя, оно располагается в самом начале строки, а сразу за ней ставится (:).
Обратите внимание, что в инструкции GoTo двоеточие не используется, т.к. оно не является частью имени. Двоеточие только идентифицирует метку.
Инструкция Resume указывается в конце подпрограммы обработки ошибок после выполнения всех требуемых действий. Она возобновляет исполнение процедуры, в которой возникла ошибка.
Совет.
Инструкцию Resume можно использовать только в подпрограмме обработки ошибки. В противном случае возникает ошибка.
Инструкция Resume имеет три формы:
Инструкция Resume Next передает управление инструкции, которая следует за той, в которой возникла ошибка. Предполагается, что подпрограмма обработки устранила последствия ошибки.
Инструкция Resume или Resume 0 передает управление инструкции, в которой возникла ошибка, и VBA производит попытку выполнять эту строку снова. Предполагается, что подпрограмма обработки устранила причины, которые вызвали ошибку, и теперь инструкцию можно выполнить без ошибки.
Инструкция Resume метка передает управление инструкции, идентифицированной указанной меткой.
Инструкция Resume является необязательной. Если требуется завершить выполнение процедуры после обработки ошибки, то можно опустить эту инструкцию.
Обратите внимание на следующее правило: каждая процедура должна иметь только одну точку выхода, чтобы обеспечить выполнение некоторых вспомогательных действий перед своим завершением. Передавая управление хотя бы на метку подпрограммы выхода, можно гарантировать, что требуемые действия производятся всегда. Кроме того, по мере возрастания длины и сложности процедур данное правило приобретает все большее и большее значение.
Инструкция Exit используется для того, чтобы не выполнять подпрограмму обработки ошибки, если ошибка не возникла. Поскольку подпрограмма обработки является частью процедуры, то она будет исполняться если не выйти из макроса.
Инструкция Exit имеет пять форм, указывающих на блок, из которого требуется выйти:
Exit Sub Exit Function Exit Do Exit For Exit Property
В процедурах, в которых имеется подпрограмма обработки ошибки, обычно используются инструкции Exit Sub или Exit Function в зависимости от типа выполняемой процедуры.
Объект Err и подпрограмма обработки ошибки.
Во многих ситуациях имеется большое число потенциальных ошибок, а подпрограмма обработки должна выполнять определенные действия в зависимости от возникшей ошибки. С помощью объекта Err можно во время выполнения процедуры выявить тип ошибки. Обратите внимание, что если подпрограммы обработки не имеется, то выводится стандартное сообщение.
Объект Err — глобальный объект, который содержит информацию о последней возникшей ошибке. Подобно любому другому объекту он имеет свойства и методы. Используя свойства объекта Err и выполняя его методы можно сообщить подпрограмме обработки характер произошедшей ошибки.
Объект Err имеет шесть свойств:
Свойство Number — номер возникшей ошибки.
Свойство Source — имя проекта Visual Basic, в котором произошла ошибка.
Свойство Description — строка, соответствующая номеру ошибки. Некоторые ошибки, включая заданные пользователем ошибки, не имеют описания и тогда строка имеет значение «Ошибка, определяемая приложением» или «Ошибка, определяемая объектом».
Свойство HelpFile — полное имя файла справки Visual Basic, включая диск и путь.
Свойство HelpContext — идентификационный номер в справке Visual Basic, соответствующий возникшей ошибке.
Свойство LastDLLError содержит код системной ошибки для последнего вызова библиотеки динамической компоновки. Используется только в 32-разрядных системах Microsoft Windows и доступно только для чтения.
Обычно, чтобы произвести определенные действия в зависимости от типа возникшей ошибки, требуется просто проверить значение свойства Number. Для этого используется любая логическая инструкция, например, блок If..Else..End If или Select Case..End Select. Блок Select Case..End Select удобнее, т.к. в него проще добавить дополнительное условие.
Заданным по умолчанию свойством объекта Err является свойство Number, поэтому нижеприведенные инструкции эквивалентны:
Select Case Err.Number
Select Case Err
Использование полного синтаксиса упрощает понимание программы. Сокращенный синтаксис совместим только в одну сторону с предыдущими версиями Visual Basic и WordBasic, в которых вместо объекта Err применялась функция Err. Объект Err имеет два метода:
Метод Raise позволяет генерировать ошибку во время выполнения программы. Данный метод используется для проверки подпрограммы обработки ошибки, которую требуется перехватить. Кроме того, с его помощью можно создать для приложения собственные ошибки, указав их номер и описание.
При задании собственных ошибок необходимо сложить номер ошибки с константой vbObjectError. Таким образом, можно гарантировать, что номер не совпадает с номером стандартной ошибки Visual Basic. Приведем пример, в котором создается новая ошибка:
Err.Raise vbObjectError + 1, «MyProject.MyObject», «Служащего с таким именем в данном отделе не имеется»
Метод Clear сбрасывает значения всех свойств объекта Err. Данный метод используется после того, как обработана ошибка и необходимо продолжить выполнение.
Примечание.
В ранних версиях Visual Basic и других языках Basic для создания ошибок использовалась инструкция Error. В целях обеспечения инструкция Error имеется и в новом Visual Basic, однако, во всех вновь создаваемых программах рекомендуется применять объект Err.