Создание коммерческих приложений на Microsoft Access

Шарифуллин Марат (AKA Marat)

 

В статье рассмотрены способы создания и распространения программ, разработанных в среде Microsoft Access. Статья написана на основании семилетнего опыта разработки на Access VBA (версии 97-2002) автором лично, а также сотрудниками Консультационной группы «Воронов и Максимов».

Введение

У многих разработчиков программного обеспечения (как начинающих, так и опытных) имеется стойкое предубеждение к Microsoft Access как к средству разработки профессиональных программных продуктов.

Попытаюсь описать стандартные причины возникновения этого, с позволения сказать, заблуждения.

1.      Access, как система управления базами данных, позиционируется в качестве средства управления данными конечным пользователем без привлечения программиста. Это безусловно является плюсом Access как программы, но ведет к активному неприятию его IT-профессионалами.

2.      В следствие вышеизложенного, программы на Access/VBA пытаются писать люди, не имеющие достаточного опыта и навыка программирования. Такие разработки даже распространяются на коммерческой основе, а также выкладываются для свободного доступа в интернете. Профессиональный программист приходит в ужас при ознакомлении с кодом таких «программ» и распространяет свое мнение на средство разработки.

3.      Так называемая «литература для чайников» только усиливает впечатление об Access как несерьезной системе. Преподавание разработки баз данных в ВУЗах зачастую также основано на подобных книгах и пособиях.

4.      Столкнувшись в первый раз с необходимостью написания собственной программы на Access, профессионал объектно-ориентированного программирования (C++, Delphi) часто не знает с какой стороны подойти к процессу разработки, так как Visual Basic for Application предлагает своеобразный набор средств работы с классами. Тут необходимо заметить, что программисту, который предварительно глубоко изучил COM-программирование Windows будет гораздо легче понять способы взаимодействия классов, ссылок и т.п.

5.      Access предлагает совершенно нестандартный по отношению к распространенным средствам разработки подход к программированию пользовательского интерфейса (формы, отчеты). Это может вызвать трудность для понимания даже для опытных программистов, и даже разработчиков на родственном языке Visual Basic. Основополагающий момент здесь - это то, что элементы управления (контролы) Access не являются Windows-контролами и не имеют контекста окна (hWnd). Хотя эти контролы и выглядят как стандартные, а также имеют наборы свойства и событий, по существу они являются просто картинки, прорисовываемые приложением на форме. Также нетрадиционный подход реализован для списков и форм с данными. Контролы, а также сама форма, всегда имеет источник данных, который может настраиваться динамически без создания дополнительных компонентов.
Зачастую, не разобравшись в подобных особенностях языка и среды разработки, программисты ссылаются на «неправильность» всей системы.

Также многие обвиняют Access в недостаточной защищенности программ и данных от несанкционированного доступа. Пожалуй, это единственный момент с которым можно согласиться. То есть, правильнее сказать, что для обеспечения защиты данных могут потребоваться дополнительные действия, которые в принципе не требуются при использование других систем разработки. Подробнее на эту тему - см. главу «Ограничения».

С другой стороны, я согласен с тем, что изначально Access предназначался для создания локальных приложений и не являлся в полной мере средством разработки коммерческих программных продуктов. Тот кто работал с Access 2.0, я думаю, подтвердит, что с точки зрения программиста система была очень неудобной. В защиту могу сказать лишь то, что предок современного Delphi, версии 1.0 - мне довелось с ним работать - тоже был далек от идеала. Возможности текущих версий Access (версии 2000 и далее) настолько возросли, что на нем вполне можно создавать очень сложные программы как локального характера, так и тиражируемые системы.

Описание некоторых приводимых в статье решений предполагает наличие специальной версии для разработчика Microsoft Access: для версии Office 97 - это Access Developer’s Toolkit (ADT), для более поздних версий - Office Developer’s Edition (ODE).

Далее в статье описаны необходимые, на мой взгляд, действия по созданию профессионального приложения на Microsoft Access. Хотелось бы только заметить, что данные рекомендации не являются каким-либо стандартом, это скорее набор правил, которым бы хотелось следовать при разработке собственных приложений.

Разработка распространяемого приложения

Разработка базы данных

Тут необходимо решить вопрос с выбором хранилища данных и способом доступа к этим данным. Access предлагает достаточный выбор: Jet/DAO, ODBC, ADO. К сожалению, нет возможности останавливаться подробно на этом важном вопросе в данной статье. Стоит разве что отметить, что стратегия развития Microsoft Access идет по пути вытеснения собственного хранилища (MDB) серверными источниками данных (SQL-сервер).
Главный вопрос, независимо от хранилища - это структура базы данных. Процессы нормализации структуры данных (как, кстати, и обратной денормолизации) безусловно могут проводиться и в процессе разработки программы, но желательно изначально иметь устойчивое ядро базы данных, к которому могут привязываться новые структуры и интерфейсы пользователя.

Структура данных коммерческого программного продукта в обязательном порядке должна иметь возможность распространения в открытом виде (либо только так и распространяться). Рано или поздно, но это обязательно понадобится для обмена данными с другими программами. Помните об этом и постарайтесь, чтобы не было стыдно за собственную работу, когда придется передавать документацию другим разработчикам.

Разработка концепции интерфейса пользователя

При разработке пользовательского интерфейса настоятельно рекомендуется ограничиться использованием стандартных средств интерфейса Windows (меню, панели инструментов, мастера, сообщения). Собственные «красивости» могут выглядеть привлекательно с вашей точки зрения, но будут интуитивно непонятны конечному пользователю.

Структура форм и отчетов по возможности должна быть единой. Например, все формы для редактирования данных имеют «ленточный» тип и стандартную цветовую палитру, заголовок содержит набор фильтров, кнопки управления располагаются в левом нижнем углу.

Разделение интерфейса и базы данных

Об этом говорится практически в любой книге или статье по программированию в Access для начинающих. Просто добавлю, что полное отделение интерфейса может вызвать некоторые затруднения при работе с MDB/MDE. Безусловно общие данные должны быть перенесены на сервер (файл или SQL). Но все-таки нецелесообразно держать временные таблицы (если таковые используются) в дополнительном локальном MDB-файле. Тем более что это, к сожалению, не приводит к стабилизации размера основного файла интерфейса (все равно требуется регулярное сжатие).

Групповая разработка

Access вполне подходит для разработки приложения несколькими программистами, несмотря на то что рабочий проект (MDB или ADP) представляет собой единый файл. Категорически нельзя использовать совместный доступ к рабочему файлу интерфейса - это приведет к повреждению самого проекта. Но Access содержит специальные методы сохранения и восстановления объектов программы в текстовом виде (Application.LoadFromText, Application.SaveAsText). К сожалению, по непонятным мне причинам разработчики не включили возможности сборки проекта из модулей в среду разработки. Но при наличии некоторого навыка вы можете написать собственную надстройку по выводу проекта в текстовый вид и последующему восстановлению (разработанная в нашей компании надстройка позволяет преобразовывать в текстовые файлы все возможные объекты Access: формы, модули, отчеты, запросы, таблицы с данными, ссылки, панели инструментов). Это нужно для поддержки популярных программ групповой разработки приложений (CVS, SourceSafe, TortoiseSVN). Включаемая в ODE-версию Access программа SourceSafe по идее должна была бы поддерживать такую операцию автоматически, но нам не удалось найти такую опцию (буду рад ошибиться, если она там все-таки есть).

Документация

Пишите по возможности код, который не требует дополнительного пояснения. Это может показаться странным для многих, но одна из современных концепций программирования предполагает практически полное отсутствие комментариев в тексте процедур и функций. Программные идентификаторы должны сами себя описывать - используйте короткие процедуры, «говорящие» имена классов, функций, таблиц, полей, не экономьте на длине идентификаторов. Подробнее о концепции рефакторинга программного кода - см. http://www.refactoring.com/ и http://www.martinfowler.com/.

Что может потребовать дополнительных комментариев и даже отдельной документации, так это структура базы данных. Существует множество систем для моделирования структур данных и бизнес-процессов (ErWin, Power Designer). Минимально необходимые действия по оформлению структуры данных можно проделать при помощи собственных диаграмм данных Access или SQL-сервера.


Специальные средства

Наследование интерфейсов

О невозможности «нормального» наследования в классах Visual Basic может поведать любой программист, воспитанный на классических объектно-ориентированных языках программирования. Не буду никого переубеждать - даже скорее соглашусь с этим утверждением. Судя по направлению развития средств разработки от Microsoft, в следующих версиях Access этот пробел все-таки будет устранен. Тем не менее, даже в текущей версии можно (и нужно) использовать возможности ООП VBA по максимуму. Постарайтесь понять возможности наследования интерфейсов. Эта особенность языка возможно и не добавит ожидаемой функциональности наследования, но сделает код программы более наглядным, понятным, простым для развития и переноса на другую платформу. Подробнее о наследовании интерфейсов - см. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvb600/html/ifacebased.asp.

Шаблоны кода

VBA не поддерживает специальной функциональности шаблонов классов или что-либо подобного. Под шаблоном кода, я здесь подразумеваю, стандартный набор описаний, процедур и функций, требующихся в нескольких модулях программы. Это может быть набор стандартных обработчиков событий для рабочих форм, либо, например, код по организации форм-мастеров. Такие шаблоны могут быть разработаны как предварительно, так и в процессе разработки. Не бойтесь повторять такой одинаковый код в нескольких местах программы - такой код выглядит нагляднее, понятнее и проще для тестирования и внесения специальных изменений, чем вызовы глобальные функций и процедур. Обновление шаблона также не является трудоемкой операцией. Во многих случаях шаблоны кода имеет смысл сочетать с наследованием интерфейсов.

Экземпляры форм

Access позволяет работать с несколькими экземплярами одной и той же формы или отчета. По непонятным мне причинам в документации и примерах Microsoft рекомендует использовать традиционный способ открытия форм (через команду DoCmd.OpenForm). По опыту работы мы не нашли каких-либо скрытых ошибок при использовании экземпляров форм, при том что это добавляет значительно больше возможностей по программированию интерфейса и делает его более современным и удобным конечному пользователю.

Подробнее о работе с экземплярами форм - см.

http://www.sql.ru/faq/faq_topic.aspx?fid=240

Временные таблицы и запросы

Этот пункт включен в перечень только для того, чтобы обратить внимание на особенности работы с временными таблицами и запросами при использовании экземпляров форм и отчетов. Если какие-либо форма основана на временной таблицы, то потребуется создавать отдельную копию такой таблицы для использования в экземплярах формы. В этом случае имеет смысл разработать генератор временных таблиц и запросов.

Обработка собственных событий

Ориентация на события является большим шагом вперед в развитии программных систем. Программы Access также можно заставить обрабатывать ваши собственные события, причем без привлечения функциональности сабклассинга и Windows API. События в этом случае представляют собой объект класса и обрабатываются специальными скрытыми формами (процессорами), загружаемыми при старте программы. Через события можно передавать результаты из модальных окон, контекстно обновлять списки на всех открытых рабочих формах, запускать серверные процедуры в асинхронном режиме и т.п. Таким образом, можно практически избавиться от использование глобальных переменных.

Кроме того, VBA предоставляет специальную функциональность для взаимодействия классов через события (см. справку по WithEvents и RaiseEvent).

Подробнее о создании событий для классов - см.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/modcore/html/deovrCreatingEventsEventProcedures.asp

Условная компиляция

Это мощное средство, позволяющее тиражировать программные модули в различные проекты при незначительном изменении функциональности (см. справку по #If). Хотелось бы только обратить внимание, что условная компиляция имеет смысл только при добавлении условия непосредственно в свойства проекта VBA (меню Tools\<projectname> Properties). При использовании ключевого слова #Const большинство полезных свойств условной компиляции теряется, так как такая константа имеет область видимости только на уровне модуля.

Надстройки

Может оказаться полезным вынести некоторую функциональность приложения в отдельный файл надстройки. Access поддерживает три типа надстроек: отдельный файл, инсталлируемые надстройки (требующие USysRegTable) и COM-надстройки.

Надстройка в виде отдельного файла должна быть установлена в тот же каталог, что и файл msaccess.exe. В этом случае не потребуется устанавливать связь с эти файлом на уровне коллекции References.

Очень полезно при программировании надстроек использовать описание Friend для свойств и методов классов - в обычном проекте Access это описание не отличается от Public.

Инсталлируемые и COM-надстройки в основном предназначаются для облегчения процесса разработки и могут быть бесполезны конечному пользователю программы (пользователь может вообще не иметь стандартной версии Access).

Подробнее об инсталлируемых надстройках Access - см. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/modcore/html/deovrcreatinginstallableaddinsforaccess.asp

Подробнее о разработке COM-надстроек - см. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dno2kta/html/comaddins.asp

Сабклассинг

Старайтесь обойтись без использования сабклассинга (переопределения главной функции окна). Особенно это касается главного окна приложения. При возникновении любой необработанной ошибки приложение закроется с системным сообщением Access (возможно после этого будет произведена попытка восстановления базы данных), что выглядит для пользователя пугающе. Вообще хорошим стилем является возможность восстановления значений глобальных переменных и перезагрузка скрытых форм при возникновении любой критической ошибки в программе.

Создание runtime приложения

Преобразование интерфейса в MDE (ADE)

Для распространения программы с закрытым программным кодом используется преобразование файла проекта в формат MDE или ADE. Соответственно не используйте в коде программ операции недопустимые в MDE-файле.

Очень аккуратно используйте ссылки (References), в MDE-файле установить их программным способом не удастся. Кроме того, по собственному опыту работы, Access не всегда корректно восстанавливает ссылки на библиотечные файлы различных версий. В частности из-за проблем с работой под различными версиями Microsoft Office, в разработках нашей компании не используется ссылка на библиотеку Microsoft Excel Object Library. Вместо этого во всех операциях обмена данными с Excel используется тип Object и позднее связывание (CreateObject("Excel.Application")).

Будьте уверены, что программа установки вашего приложения разместит библиотечные файлы (ActiveX, DLL, надстройки) именно в тех папках (по типам: системная, программная, Office\Library и т.п.), куда ссылался основной файл проекта перед преобразованием в MDE/ADE.

Access Run-time

ODE версия включает в себя программу для подготовки установочного пакета (Package Wizard), в который может быть включена run-time версия Microsoft Access. Эта программа распространяется вместе с конечным приложением Access по лицензии ODE и позволяет запускать файлы пользователям, не имеющим предустановленного пакета Microsoft Office Professional. Run-time версия Access - это набор исполняемых и библиотечных файлов, причем некоторые абсолютно идентичны обычной версии Access (например, msaccess.exe), другие отличаются и по содержанию, и по названиями (msoX.dll и msoXrt.dll). Установить Run-time версию вручную достаточно сложно. Начиная с версии 2002 Package Wizard формирует отдельный msi файл Access Run-time для установки с помощью WindowsInstaller’a. Для предыдущих версий run-time версия также была доступна в виде обычного setup-файла.

Run-time версия несколько отличается от стандартной: в частности отсутствует окно базы данных, не доступны никакие средства редактирования проектов, нет стандартных панелей инструментов.

Я никогда также не слышал о локализованных run-time версиях Access (ODE не распространяется с русской локализацией). Будьте готовы к тому, что все системные сообщения надо либо заменять, либо смириться с тем что они будут выводиться на английском языке (например, текст в строке состояния).

Тестирование приложений в Run-time

Тестирование готовых приложений необходимо производить именно в run-time версии. Для этого скорее всего понадобится отдельный компьютер без предустановленных офисных программ.

Командная строка Access предлагает использование опции «/runtime» для тестирования приложений. Не пользуйтесь этой возможностью, так как поведение приложения и результаты работы в настоящей run-time версии могут отличаться!

Дополнительная информация по ODE для Access 97 доступна по адресу http://faqs.org.ru/progr/database/ode.htm

Стандарты для клиентских приложений

Здесь перечислены стандартные интерфейсные средства, делающее клиентское приложение дружественным пользователю.

Заставка

Приложение должно иметь заставку с названием программы, авторский копирайт и год (дату) выпуска , номер версии. Если программа имеет систему регистрации, то должна быть выведена информация о зарегистрированном пользователе и типе лицензии. Информация об авторах должна быть также доступна через меню и справочную систему.

Иконка для окон

Чтобы максимально скрыть происхождение программы и средство ее разработки, имеет смысл заменить иконки для форм и отчетов приложения. Для этого можно воспользоваться свойствами запуска в меню Access, либо настраивать иконку через вызов API-функций при открытии окна.

Меню, панели инструментов

Используйте все возможности (не очень, кстати, богатые) для разработки дружественного интерфейса пользователя. Замените стандартное меню на собственное, разработайте панели инструментов и контекстные меню.

Справочная система

Разработка справочной системы и комплекта пользовательской документации дело безусловно непростое, но обязательное. Контекстный вызов справки можно настроить через вызовы функций библиотеки "hhctrl.ocx" (HTMLHelpStdCall).

Компилятор help-файлов входит в состав ODE.

Средства администрирования базы данных

Включите в состав пакета программы средства обслуживания базы данных и интерфейсного файла. Это могут быть простейшие программы по резервному копированию, восстановлению, сжатию базы данных и интерфейсного файла.

Создание программы установки для законченных приложений

Программа установки

Программа создания установочных пакетов Package Wizard, входящая в состав ODE, способна сделать setup-файл для вашего приложения. Но по всем отзывам и по собственному опыту возможности и результат работы этой программы совершенно не те, что хотелось бы увидеть. Эта программа (версии ODE2002) не поддерживает русских настроек Windows, не позволяет настроить алгоритм установки, и даже отказывается создавать архив на диске с файловой системой NTFS!

Таким образом, настоятельно не рекомендуется использовать эту программу для распространения собственных приложений. Главное что можно взять после работы Package Wizard, это msi-файлы для Access Run-time и Microsoft Desktop Engine.

Разработать программу установки можно в любой инсталляционной системе, например, InstallShield, Wise. В этом случае потребуется настроить эти программы для вызова msi-архивов из командной строки. Иностранные разработчики очень рекомендуют программу SageKey, специально настроенную для работы с приложениями Access.

Наша компания использует свободно распространяемую программу InnoSetup (http://www.jrsoftware.org/).

Создание ярлыка для запуска приложения

Используя любую программу установки не забывайте указывать полный путь запуска в ярлыке приложения, например: ‘C:\Program Files\Microsoft Office\Office\msaccess.exe’ ‘C:\MyProgram\MyProgram.mde’ /wrkgrp ‘C:\MyProgram\MySystem.mdw’.

Обновления

При поставке многопользовательской версии приложения имеет смысл подумать о методе установки обновлений с единого сервера. Программа (и возможно база данных) должна хранить номер текущей версии (в собственном коде или во внешнем файле на компьютере пользователя) и проверять при запуске наличие обновления на сервере.

Аналогичным образом можно организовать процедуру сжатия интерфейса, автоматически проверяя размера исполняемого файла.

Ограничения

Здесь описаны причины, которые могут послужить для отказа от Access при выборе средства разработки.

Несанкционированный доступ

К сожалению, приложение Access практически невозможно защитить от несанкционированного доступа к данным «хакерскими» методами. В интернете получили широкое распространение программы для взламывания паролей файлов рабочих групп и баз данных.

Кардинальным выходом остается шифрование данных, но при этом надо менять всю систему управления и отказываться от реляционной модели. Что, по-моему, совершенно недопустимо. Кстати, от возможных потерь информации (например, преднамеренного удаления) шифрование также не может защитить.

В связи с вышеизложенным конечно же не стоит разрабатывать на Access приложения, обрабатывающие конфиденциальные данные (банковские, бухгалтерские, биллинговые и т.п.).

По собственному опыту в 9 случаях из 10 не требуется глобальная система защиты приложений от «хакерских» атак. Кроме того, убытки от неверных действий пользователей с санкционированным доступом могут быть даже выше, так как приводят к скрытым ошибкам. Тем не менее обеспечить минимально необходимый уровень защиты данных безусловно необходимо. Далее приведен перечень действий для обеспечения такого уровня безопасности:

1.      Настройка опций запуска («защита от Shift»).

2.      Настройка прав на объекты на уровне сервера и/или файла рабочих групп.

3.      Обеспечение входа в приложение только с указанием пароля.

4.      Подключение при входе и отключение при выходе линкованных таблиц в проектах MDB/MDE.

5.      Настройка автоматических процедур резервного копирования данных на сервере.

6.      Ведение журналов изменения критических данных.

Рекомендуется создавать отдельный файл рабочей группы (первоначально скопировав system.mdw), затем запускать приложение через использование опции командой строки «/wrkgrp».

Вообще-то в разработках нашей компании не используется разграничение доступа через стандартные функции рабочей группы Access. По многим причинам пришлось разработать собственный модуль настройки пользователей и групп. Поэтому оценить работу со стандартной системой разграничения доступа к объектам и данным я, к сожалению, не могу.

Подробнее о безопасности и разграничении доступа - см. http://am.rusimport.ru/MSAccess/topic.aspx?ID=469

Скрытые ошибки Access

Как и любая система разработки, Access, содержит ошибки в собственной программной реализации. Их количество возрастает или сокращается в связи с выпуском различных версий и сервис-паков. Несмотря на наличие таких ошибок и недоработок, в целом Access при корректном использовании достаточно устойчивая система. А количество неустранимых или необъяснимых ошибок вообще чрезвычайно мало. В 99% так называемые «ошибки» Access на самом деле связаны с неправильным алгоритмом или программным кодом.

В наших разработках возникали следующие сложные для устранения проблемы:

1.      Полное разрушение mdb-проекта без возможности восстановления при импорте объектов без последующей компиляции. Решается резервным копированием и хранением объектов в текстовом виде.

2.      Потеря ссылок при использовании библиотек различных версий. Решается через использование типа Object и позднее связывание.

3.      Ошибки при работе с ActiveX. Например, неверные данные иерархии листьев TreeView, если дерево не отображается в данный момент на форме. Здесь в каждом случае надо разбираться отдельно.

4.      Потеря пункта пользовательского меню. Решается через программное создание меню и панелей инструментов.


Страница сайта http://www.interface.ru
Оригинал находится по адресу http://www.interface.ru/home.asp?artId=7075