Файл: Освой самостоятельно программирование для MS Access 2002 за 24 часа [П.Киммел].pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 21.10.2020

Просмотров: 7910

Скачиваний: 25

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Строки 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. Работа над ошибками


background image

Использование объектов класса 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


background image

Существует, по меньшей мере, две ситуации, оправдывающие практическое при-

менение объекта 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. Работа над ошибками


background image

ния типа 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


background image

Листинг 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. Работа над ошибками