Файл: Освой самостоятельно программирование для MS Access 2002 за 24 часа [П.Киммел].pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 21.10.2020
Просмотров: 7910
Скачиваний: 25

Строки 18-26 листинга 18.3 способны обработать любую возникшую ошибку. Если
номер ошибки не 53
(File Not Found —
файл не найден), предпринимается попытка
сгенерировать сообщение об ошибке методом
объекта Err. Если же ошибка
связана именно с отсутствием файла, пользователю будет предложено ввести новое
имя файла, приносимого в жертву. Теперь, если файл с введенным именем существу-
ет, команда Resume, расположенная в строке 24, передаст управление строке 16.
Разумеется, никто не запрещает вам написать нечто, похожее на строку, приведен-
ную ниже:
If
Then Kill
Нетрудно придумать множество других вариаций на заданную тему, и все они с
формальной точки зрения окажутся верными. Вы могли бы, например, добавить
предложение Else, позволяющее пользователю указать новое имя файла, проверить
факт его существования, а затем попробовать удалить этот файл. Все это неплохо -
именно неплохо, но и не очень хорошо. А что случится, если, скажем, и вновь задан-
ный файл не существует? Как быть — создавать цикл, дающий возможность пользова-
телю снова и снова вводить имя файла, а затем пытаться его удалить? Ну, а как спра-
виться с ситуацией, когда файл существует, но он открыт другой программой? Или
файл помечен атрибутом "только для чтения"?
Да, бывают случаи, когда обработчик основывается на наборе условных
выражений — это как раз то, что нужно: например, требуется проверить,
содержит ли выражение правильную дату. Если такое условие решит
проблему — действуйте: достаточно написать If
Then — и вы получите ответ на интересующий вас вопрос.
Примите к сведению такое общее правило: если необходимо решить
некую конкретную проблему, используйте условные выражения; если
же речь идет об обеспечении надежности кода в целом, обращайтесь к
средствам построения обработчиков ошибок.
Существует масса причин, которые могут воспрепятствовать удалению файла. Вот
почему обработчики ошибок, о которых мы говорим, так ценны. Обработчик
пока все в порядке, и вступает в действие, если возникает какая-либо
ошибка. Если проблема устранена, команда Resume позволяет повторно выполнить
соответствующую строку кода.
команды Resume Next
Команда Resume Next может использоваться как в строке заголовка обработчика
ошибок в качестве директивы пассивных действий, так и внутри него. Resume Next
при возникновении ошибки предписывает перейти к очередной строке кода.
Исправим рассмотренный ранее пример с учетом необходимости удаления файла
до начала выполнения операций с ним (скажем, речь идет о файле, содержащем ка-
кой-либо ежедневно обновляемый отчет). В этом случае уместно написать следующее:
On Error Resume Next
Kill FileName
нового
файла и обработка данных
Если файл существует, он удаляется (это как раз то, что нужно), а затем выполня-
ются обычные действия. Команда Resume Next гарантирует, что попытка удаления
старого файла не приведет к остановке программы, если этого файла случайно не
окажется — ведь старый файл не является центральным звеном алгоритма.
320 Часть VI. Работа над ошибками

Использование объектов класса Err
Объект класса Err создается и поддерживается исполняющей системой автомати-
чески. При возникновении ошибки свойствам объекта Err присваиваются соответст-
вующие значения, позволяющие определить, что именно произошло. Объект Err со-
держит два метода, Clear и Raise, и шесть свойств — Description, HelpContext,
HelpFile, Source, Number и LastDLLError. Методы дают возможность изменять со-
стояние объекта, а свойства описывают характер ошибки.
Свойства объекта Err
Свойство Description содержит текстовое описание ошибки. HelpFile и Help-
Context — это, соответственно, имя файла оперативной справки и номер темы в
нем. Такие данные могут быть заданы при вызове метода
для генерации сооб-
щения об ошибке. В этом случае при нажатии клавиши <F1> пользователь получит
возможность вызова приложения оперативной справочной системы с автоматическим
открытием той страницы указанной вами темы, которая, по вашему мнению, должна
содержать более подробную информацию об ошибке и способах дальнейших дейст-
вий.
Свойство Source указывает на имя объекта или приложения, служащего источни-
ком ошибки. Number, номер ошибки, — это число, предопределенное в VBA
на-
пример, 53 — ошибка отсутствия файла, рассмотренная нами в листинге 18.3) либо
заданное программистом.
Свойство LastDLLError содержит описание ошибки, если она возникла в дина-
мической библиотеке, созданной средствами Visual Basic.
Методы объекта Err
Метод Clear позволяет очистить содержимое объекта Err. Формат
к
Clear вызывается автоматически при выполнении программой
команд Resume, Exit или любой инструкции
Формат вызова метода Raise описывается
синтаксическим выражением:
Call
Number [, Source [, Description [, HelpFile [,_
)
(Наименования параметров метода Raise даны на английском языке, поскольку
они совпадают по смыслу со свойствами объекта Err, рассмотренными выше. -
Прим. перев.)
При обращении к процедуре Raise должен быть указан хотя бы один
параметр — Number, номер ошибки. Если вы введете, скажем, число
будет сгене-
рировано соответствующее сообщение об ошибке (номеру 54 отвечает ошибка задания
неверного режима работы с файлом —
Bad File Mode).
Чтобы сгенерировать сообще-
ние по номеру ошибки, определенному пользователем-программистом, необходимо
применить конструкцию Call
(vbObjectError + Number), где
Number — это заданный пользовательский номер ошибки. Акцентируем ваше внима-
ние: Number — обязательный аргумент, все остальные разрешается не указывать. Если
задается параметр Source, он обычно обозначает имя объекта или модуля, в котором
произошла ошибка. Аргумент Description применяется для определения строки
текстового описания ошибки. Параметры HelpFile и HelpContext используются в
тех случаях, если приложение содержит ссылки на файлы оперативной помощи, в ко-
торых находится подробная информация об ошибках и способах устранения их по-
следствий. Процедура RaiseError, приведенная в тексте листинга 18.3, содержит
пример обращения к методу Raise объекта Err.
час. Обработка ошибок во время выполнения программы 321

Существует, по меньшей мере, две ситуации, оправдывающие практическое при-
менение объекта Err: в первом случае полезно исследовать свойства Err после воз-
никновения ошибки, а во втором с помощью метода Raise удобно сгенерировать со-
общение об ошибке, чтобы дать пользователю информацию о характере проблемы. В
листинге 18.3 мы обратились к Raise, чтобы предоставить пользователю данные об
ошибке, для которой специальные средства обработки не предусмотрены (речь идет
обо всех ошибках, кроме ошибки с номером 53).
Применение обработчика ошибок
для проверки данных, вводимых
пользователем
Наиболее распространенный способ использования обработчиков связан с созда-
нием блоков кода, оказывающих помощь в устранении последствий возникающих
ошибок. В ходе этого занятия вы уже ознакомились с рядом примеров такого рода.
Но есть и другие — обработчики иногда удобно использовать с целью проверки пра-
вильности данных, введенных пользователем. Вы можете применить соответствующую
стандартную функцию преобразования типов, а наряду с ней — конструкцию обра-
ботчика, позволяющую избежать ошибок, если информация не поддается преобразо-
ванию. Просмотрите текст листинга 18.4.
Листинг 18.4. Пример использования обработчика в задаче определения признака
високосного года
Sub Test ( )
2:
IsLeapYear( 2001 )
3 : End Sub
4:
5: Function IsLeapYear(
Year As Integer ) As Boolean
6:
7: On Error GoTo EXCEP
IsLeapYear = True
Dim ADate As Date
ADate = CDate(
& Year )
Exit Function
9:
10
11
12
13:
15: IsLeapYear = False
16:
Function
18.4 демонстрирует прием (правда, близкий к трюкачеству) оп-
I ределения того, является ли указанный год високосным. (Строки
со-
держат данные тестовой процедуры.) В строке 7 задается заголовок обра-
ботчика ошибок. Команда строки 8, свидетельствующая о неисчерпаемом
оптимизме программиста, присваивает возвращаемой переменной значе-
ние True. В строке
объявляется вспомогательная переменная типа
Date. Далее из литерала, задающего дату 29 февраля и значения тести-
руемого года, формируется строка, которая передается встроенной функ-
ции CDate. Эта функция предпринимает попытку преобразования значе-
322
Часть VI. Работа над ошибками

ния типа string в Date. Если преобразование осуществляется безоши-
бочно, выполнение функции завершается. В противном случае управле-
ние передается на метку EXCEPT, выполняется инструкция обработчика
ошибки, и функция возвращает значение False.
В числе встроенных функций VBA имеется функция IsDate типа Boo-
lean, выполняющая анализ корректности даты и возвращающая
значение True, если дата верна, и False — в противном случае.
Конечно, помимо продолжительности года, следует проверять корректность значе-
ний месяца и числа. Существует и готовый алгоритм проверки того, является ли год
високосным. Мне удалось ознакомиться с книгой Джека Пэдама (Jack
С
Programmer's Toolkit
1989 года издания и преобразовать функцию с языка С на VBA.
Листинг 18.5 содержит реализацию алгоритма определения признака високосного года
на языке
Листинг 18.5. Функция проверки признака високосного года
1: Function
Year As Integer) As Boolean
2: LeapYear = (Year Mod
And
Mod 100 <> 0)
(Year Mod 400 =
3 : End Function
Or
Високосным считается год, значение которого нацело делится на четыре и четыре-
ста, — за исключением тех, которые делятся на сто. Наверняка аналогичный код при-
сутствует и в недрах функции CDate.
Проблема экономии ресурсов
компьютера
Применяются блоки обработчиков ошибок также с целью защиты ресурсов ком-
пьютера от истощения. Занимаясь программированием, необходимо заботиться об
экономии любых ресурсов, объем которых заведомо ограничен. В вашем распоряже-
нии имеется, например, только определенное количество свободных номеров файлов,
некоторое конечное число ячеек памяти и ограниченный объем свободного дискового
пространства. Если ваша программа не будет предпринимать
мер по их
экономии, то, не исключено, со временем ресурсы
исчерпанными.
Чтобы решить задачу экономии ресурсов, можно воспользоваться механизмом соз-
дания обработчика ошибок — при условии, что его тело, которое должно выполняться
будет содержать необходимые инструкции освобождения занятых ресурсов.
VBA не предлагает специальных средств поддержки подобного подхода, но их легко
построить. Хотя программа, написанная на VBA, способна истощить ресурсы памяти
с меньшей долей вероятности, нежели аналогичное приложение, созданное, скажем,
на языке C++, встречаются ситуации, когда необходимо проявлять особое внимание
относительно корректного закрытия ранее открытых файлов или баз данных.
Блок строк кода, решающих задачу защиты ресурсов компьютера от истощения,
создается как тело обычного обработчика ошибок. Но поскольку он должен выпол-
няться всегда, инструкцию Exit, препятствующую переходу на метку обработчика,
следует исключить. Листинг 18.6 демонстрирует пример обработчика, выполняющего
закрытие файла в любом случае — независимо от того, произошла ошибка или нет.
18-й час. Обработка ошибок во время выполнения программы
323

Листинг 18.6. Пример использования обработчика ошибок,
экономию
ограниченных ресурсов компьютера
1: Sub
)
On Error GoTo
3 : Dim Handle As Double
4: Handle = FreeFile
5: Open
For Input As
6: Dim Line As String
7: Do While
= False)
8: Line Input
Line
Line
10: Loop
12: Close
13: End Sub
Ресурсосберегающие блоки не слишком часто применяются в программах
на Visual Basic. Программисты, работающие с языками
обработки ошибок, используют эту технику чаще. Компания Microsoft
обеспечила структурированную обработку ошибок в Visual Basic.NET,
некоторые элементы этой технологии реализованы и в
Тот факт, что данный простой метод требует поддерживать только один
обработчик ошибок, является следствием разделения задач. Можно
встретить и сложные процедуры, однако это не означает, что они хороши.
Строка 2 задает заголовок обработчика ошибок. В этом примере речь
идет об обеспечении гарантий закрытия файла. В строках 3-4 объявляет-
ся переменная для хранения номера открытого файла и в результате вы-
зова функции FreeFile этот номер резервируется операционной систе-
мой. В строке 5 файл открывается. Строки
содержат ряд инструк-
ций по обработке данных из файла (отдельные строки файла считывают-
ся и выводятся в окне Immediate). Команда строки 12, закрывающая
файл, выполняется всегда (обратите внимание — инструкция Exit Sub
отсутствует), поэтому выделенный файловый ресурс будет обязательно
освобожден и возвращен операционной системе. В данном случае при
именовании метки (FINALLY) мы придерживались иного соглашения —
чтобы легко отличить обработчик ошибки, выполняющий дополнитель-
ную задачу обеспечения экономии ресурсов компьютера, от всех других.
объекта Debug
На страницах нашей книги мы уже неоднократно ссылались на объект Debug. Он
относится к глобальным ресурсам программы и поэтому существует в единственном
экземпляре. Объект Debug особенно полезен на этапе проектирования и отладки при-
ложения. Он содержит два метода — Print и Assert; других атрибутов в его составе
нет. Метод Print позволяет отобразить содержимое элемента данных в окне
Immediate, а верификатор Assert дает возможность приостановить выполнение про-
граммы в том случае, если выражение типа Boolean, переданное ему в качестве пара-
метра, дает в результате вычисления значение False.
324
Часть VI. Работа над ошибками