|
|
|||||||||||||||||||||||||||||
|
Как эффективно обрабатывать ошибки в приложениях AccessИсточник: sgml Андрей Семенов
Как всем вам хорошо известно, программ без ошибок не бывает. Даже такие монстры, как Microsoft регулярно публикуют списки официальных багов, патчи и.т.д. В приложениях на основе Access, разрабатываемых одним-двумя программистами вероятность появления ошибок (Run-Time errors) на стадии эксплуатации равна 100%. Наша задача таким образом, состоит не только в том, чтобы исключить ошибки на стадии программирования и тестирования, но и эффективно обнаружить и устранить неполадки в процессе работы. Здесь возникает 2 проблемы: 1) Техническая. Как правило, ошибки на стадии эксплуатации возникают при совпадении нескольких факторов, все комбинации которых заранее протестировать невозможно. Для устранения таких ошибок необходимо в первую очередь их воспроизвести и понять причину. Однако как правило это затруднительно: разработчик может быть удалён в пространстве и времени, пользователь может не запомнить при каких условиях произошла ошибка. 2) Психологическая. Этот самый пользователь, не заинтересован в процессе отладки. Он справедливо полагает, что это дело разработчика, и всевозможные сообщения об ошибках, а тем паче остановка и переход в режим отладки вызывают естественное раздражение, которое может на раннем этапе сформировать длительное негативное отношение и недоверие к приложению, что является гораздо большим препятствием для внедрения, чем собственно ошибка. Столкнувшись в процессе работы с этими проблемами, я позволю себе предложить один из вариантов решения. Буду рад его обсудить, улучшить, выслушать альтернативы. Также я буду рад, если мой опыт кому-то поможет Компоненты решенияВсе сказанное здесь и ниже в основном относится к клиент/серверной архитектуре, где Access выполняет роль клиента, однако может быть распространено и на Access базу, используемую в многопользовательском режиме. Суть подхода в том, что все ошибки перехватываются, обрабатываются и пользователю выдаётся сообщение в строке состояния, после чего работа продолжается. Коды ошибок и значения важных параметров пишутся в таблицу на сервере, которая централизованно просматривается админом, анализируется и принимаются соответствующие меры. Итак, для получения полной картины происшествия нам поможет следующая информация: 1) Имя машины, на которой возникла проблема и имя пользователя домена Для того, чтобы определить имя рабочей станции, на которой выполняется Access, достаточно прочитать значение переменной окружения ENVIRON ("COMPUTERNAME"), и имя пользвователя - ENVIRON ("USERNAME"), однако в ряде случаев (например если у вас Win Me рабочие станции с UNIX PDC) это может не сработать. Есть более надёжный способ, основанный на API вызовах - в приложенном файле вы найдёте Class Module SystemInfo в котором реализованы функции. Так или иначе, нам понадобятся функции GetUserName() и GetCompName()
2) Путь к базе и имя пользователя MS Access Легко определяются встроенными функциями:
3) Имя библиотеки, вызвавшей ошибку, номер и описание ошибки Встроенный объект Err при возникновении ошибки заполняется аттрибутами ошибки. Считать их просто:
4) Дата и время возникновения Вставляем текущую дату и время: Now() Однако более полезно вставлять не только текущаю дату / время на машине пользователя, но и то, что в это время на сервере, так как часто ошибка бывает вызвана несогласованностью этих величин. Если вставлять время пользователя и дополнительно время сервера (например иметь поле TimeStamp) то можно проводить дополнительный анализ согласованности часов пользователя с сервером 5) Имя активной формы / отчёта, Имя активного элемента управления, предыдущего элемента управления и его родителя Для этой цели воспользуемся малоизвестным объектом Screen:
Я вынес определение этих величин в отдельную функцию, так как оно само по себе может вызывать ошибки (например, если активный отчёт отсутствует), однако если определять их в функции ReportError, то значения Err.Description, Err.Number и Err.Source в случае ошибки окажутся сброшенными и замененными на ошибку определения активных элементов управления. Поэтому я сперва считываю параметры объекта Err в переменные, а затем запускаю collectActiveControls 6) Имя процедуры VBA, в которой произошла ошибка Это наиболее хлопотная часть, так как в VBA нет средства, позволяющего коду узнать, какая процедура выполняется в данный момент. Единственный способ это сделать, - заранее записать в обработчик ошибки имя процедуры. Ни вам ни мне этого делать, естественно, не хочется. По счастью, эту работу можно автоматизировать. С этим справляется Error Handler, поставляемый с Microsoft Office Developer Edition, однако ODE птица редкая, поэтому я предпочитаю Error Handler Builder от Zada Solutions, благо бесплатное, скачать его можно здесь: http://www.zada.com.au/accessaddins.htm Что же умеет этот софт? Вы можете создать шаблон обработчика ошибок и затем переделать по его образцу выделенную процедуру (или все процедуры). Шаблон выглядит примерно так:
Все, что в квадратных скобках заменяется на конкретные значения. Как это работает? Встречая ошибку мы переходим к метке Whoops, вызываем функцию ReportError, c именем модуля и функции в качестве аргумента. Функция собирает всю информацию, пишет её в прилинкованную серверную табличку, далее в зависимости от режима сообщает об ошибке пользователю и продолжает работу. Здесь возможны два варианта: 1) Работа продолжается со следующей строки (Resume Next) - я предпочитаю именно этот вариант, так как мой опыт подсказывает, что большинство ошибок не фатальны, и можно продолжать работать 2) Вариант, когда в случае ошибки необходимо выйти из функции, не совершая более никаких действий - просто замените Resume Next на Resume Goon Пример функции, обработанной Error Handler:
Наконец функция ReportError:
В принципе всё должно быть понятно - собираем информацию и записываем в таблицу. Интересное здесь в конце: в зависимости от DebugMode
-подавляется сообщение пользователю, либо мигает на секунду в строке состояния, так, чтобы успели заметить вы (если не успеваете, замените pause(1) на pause(x) - количество секунд. Функция pause (параметр hg - отображать ли песочные часы):
Как этим наслаждаться?Здесь можно скачать файл с макетом таблицы и всеми процедурами - их нужно вставить в вашу базу. Если у вас клиент/сервер, таблицу bugs лучше экспортировать на сервер и прилинковать. Если нет - советую сделать отдельную "админскую" базу, закинуть таблицу туда и прилинковать ко всем клиентским. Далее следует скачать и установить Error Handler Builder -http://www.zada.com.au/accessaddins.htm Написать и сохранить макет обработчика ошибок. Прогнать его по всем процедурам и функциям, предварительно удалив те обработчики, что там есть. Обращаю внимание на то, что на сами функции обработки ошибок обработчики вставлять не надо. Готово. Все ошибки сыпятся в табличку. Вам остаётся сидеть и наблюдать. Можно написать форму с таймером, повесить алерты админу , итд. Обратите внимание, что если вы выбрали DebugMode 2 или 3 то пользователь ошибок не заметит, поэтому следите за ними сами. В табличке Bugs предусмотрено поле Solution, куда рекомендую записывать выясненную причину и метод решения, - потом при возникновении аналогичной ошибки (или последовательности) будет легче найти решение. Литература по теме:1) Литвин, Гетц, Гилберт. Access 2000 Руководство разработчика т. 2. Киев, BHV 2001 2) В.И. Король. Visual Basic.Net, Visual Basic 6.0, Visual Basic for Applications 6.0, М.: Кудиц-Образ 2002 3) М.Тэллес, Ю.Хсих. Наука отладки. М.: Кудиц-Образ 2003
Ссылки по теме
|
|