Вы находитесь на странице: 1из 331

ACCESS

ТРЮКИ
Оригинальные решения задач по обработке данных

Кен Блюттман

f^nnwp
Москва • Санкт-Петербург • Нижний Новгород • Воронеж
Ростов-на-Дону • Екатеринбург • Самара • Новосибирск
Киев • Харьков • Минск
2006
ББК 32.973.233-018
УДК 004.65
Б71

Блюттман К.
Б71 Access. Трюки. — СПб.: Питер, 2006. — 332 с: ил.
ISBN 5-469-01187-9

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

ББК 32.973.233-018
УДК 004.65

Права на издание получены по соглашению с O'Reilly.


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

© 2005 O'Reilly Media, Inc.


ISBN 0596009240 (англ.) © Перевод на русский язык ЗАО Издательский дом «Питер», 2006
ISBN 5-469-01187-9 © Издание на русском языке, оформление ЗАО Издательский дом «Питер», 2006
Краткое содержание
Введение 11

Глава 1 . Использование ядра Access 17


Трюки № 1 - 12

Глава 2. Таблицы 45
Трюки № 13 - 18

Глава 3. Ввод данных и перемещение по элементам управления 67


Трюки № 19 - 27

Глава 4. Представление данных 93


Трюки № 28 - 39

Глава 5. Запросы и SQL 131


Трюки № 40 - 54

Глава 6. Решение проблем многопользовательской среды 177


Трюки № 55 - 58

Глава 7. Внешние программы и данные 193


Трюки №59-71

Глава 8. Программирование 251


Трюки № 72 - 91

Глава 9. Использование сторонних приложений 297


Трюки № 92 - 95
6 Краткое содержание;

Глава 1 0 . Интернет 31Л


Трюки № 96 - 100

Алфавитный указатель 326

!
Содержание
Введение 11

Глава 1 . Использование ядра Access 17


Трюк № 1. Облегчение поиска нужных объектов 17
Трюк № 2. Индивидуальная настройка приложений Access 20
Трюк № 3. Быстрая работа без опечаток 24
Трюк № 4. Оптимизация процесса изменения данных 27
Трюк № 5. Перенос данных между версиями Access 29
Трюк № 6. Наведение порядка в макросах и придание им большей значимости .. 31
Трюк № 7. Очистка базы данных от ненужного хлама 33
Трюк № 8. Защита ценной информации 36
Трюк № 9. Работа с данными любого объема 37
Трюк № 10. Ускорение поиска объектов базы данных 39
Трюк № 1 1 . Использование связующей таблицы 41
Трюк № 12. Сдерживание базы данных от непомерного разрастания 43

Глава 2. Таблицы 45
Трюк № 13. Создание поля счетчика с произвольным начальным значением 45
Трюк № 14. Копирование данных из одной таблицы в другую без использования
запроса на добавление 48
Трюк № 15. Исключение системных таблиц из обработки 51
Трюк № 16. Прячем информацию от посторонних 54
Трюк № 17. Имитация табличных триггеров 58
Трюк № 18. Ускоренное создание таблиц 63

Глава 3. Ввод данных и перемещение по элементам


управления 67
Трюк № 19. Упрощенное перемещение по длинным формам 67
Трюк № 20. Упрощение ввода дополнительного текста 72
Трюк № 21. Предоставление возможности добавления собственных значений
в существующие списки 76
Трюк № 22. Приемы заполнения и сортировки списков 78
Трюк № 23. Использование в форме дополнительных элементов управления 83
8 Содержание

Тркж № 24. Подтверждение изменений, внесенных в запись перед ее сохранением .. 85


Тркж № 25. Отображение в форме показаний цифровых часов 87
Трюк № 26. Рационализация переходов по элементам 89
Тркж № 27. Выделение активного элемента управления 91

Глава 4. Представление данных 93


Трюк № 28. Деление отсортированных по алфавиту записей на группы по буквам 94
Трюк № 29. Подсчет промежуточных итогов на основе определенных условий 9Э
Трюк № 30. Использование условного форматирования для выделения важных
результатов 10?
Трюк № 31. Создание прямой ссылки на отчет 105
Трюк № 32. Защита интеллектуальной собственности 107
Тркж № 33. Демонстрация слайдов в Access 11?
Тркж № 34. Проигрывание видеоклипов в форме Access 117
Трюк № 35. Просмотр в отчетов в форме 12)
Трюк № 36. Нумерация строк отчета 12}
Тркж № 37. Отчет с чередованием подкрашенных и обычных строк 124
Тркж № 38. Экономия бумаги за счет сокращения количества пустых мест 127
Тркж № 39. Включение в отчет даты, времени и нумерации страниц 12!)

Глава 5. Запросы и SQL 131


Тркж № 40. Получение выборки записей 131
Тркж № 41. Защита от сбоев при проведении операции добавления записей 13-1
Тркж № 42. Поиск записей без подчиненных по нескольким связанным полям . . . 13<>
Трюк № 43. Вставка в запрос итоговой суммы 140
Трюк № 44. Сортировка по любому произвольному символьному фрагменту 14
Тркж № 45. Суммирование сложных данных 14!)
Тркж № 46. Получение всех возможных сочетаний данных 15(1
Тркж № 47. Обезвреживание пустых данных 15Ji
Тркж № 48. Использование в запросе своей собственной функции 160
Трюк № 49. Использование таблиц Access в сценариях SQL Server 161!
Трюк № 50. Использование в запросах символов-заменителей 16!i
Тркж № 51. Упрощение условия отбора, в котором используется оператор Or . . . 167
Трюк № 52. Упрощение условия отбора, в котором используется оператор And . . . 16(1
Трюк № 53. Создание внешнего соединения 170
Тркж № 54. Использование в запросах Access регулярных выражений 173

Глава 6. Решение проблем многопользовательской среды . . . 177'


Трюк № 55. Проверка на наличие дубликатов 177
Тркж № 56. Распространение распределенной базы данных с заранее
установленными ссылками на таблицы 17{1
Содержание 9

Трюк № 57. Создание функции реагирования на простой 183


Трюк № 58. Получение уникальных имен пользователей 191

Глава 7. Внешние программы и данные 193


Трюк № 59. Импорт из Excel разрозненных диапазонов ячеек 193
Трюк № 60. Использование Excel для переориентации данных Access 198
Трюк № 6 1 . Использование функций Excel в базе данных Access 202
Трюк № 62. Использование Word для сравнения данных двух таблиц Access 205
Трюк № 63. Импорт в Access различных XML-данных 208
Трюк № 64. Рациональный способ экспорта данных в формат XML 216
Трюк № 65. Преодоление барьера преобразования при использовании VBA 227
Трюк № 66. Повышение производительности SQL Server за счет вызова
хранимых процедур 229
Трюк № 67. Управление документами Word из Access 232
Трюк № 68. Использование Access в качестве интерфейсной части базы
данных MySQL 235
Трюк № 69. Автоматическая отправка данных Access с помощью Outlook 240
Трюк № 70. Создание таблиц Access из других приложений 246
Трюк № 71. Написание кода VBA при помощи записи макросов в Word и Excel 249

Глава 8. Программирование 251


Трюк № 72. Хранение ранее выбранного значения для его выделения
при последующих вызовах элемента управления 251
Трюк № 73. Отключение синтаксической проверки для ускоренного ввода кода
программы 254
Трюк № 74. Замена агрегатных функций SQL доменными агрегатными
функциями 255
Трюк № 75. Сокращение программного кода за счет использования
подпрограмм 258
Трюк № 76. Сокращение программного кода за счет использования
необязательных аргументов 260
Трюк № 77. Защита программного кода от любопытных пользователей 262
Трюк № 78. Создание в приложении служебного входа для разработчика 264
Трюк № 79. Облегченный доступ к конкретной записи 266
Трюк № 80. Предотвращение игнорирования установленных вами
параметров запуска 270
Трюк № 81. Визуализация длительных процессов 273
Трюк № 82. Предоставление пользователю возможности выбора серверной
базы данных 275
Трюк № 83. Отмена интервала времени ожидания 276
10 Содержанке

Трюк № 84. Хранение значений свободных элементов управления с целью


их повторного использования 277
Трюк № 85. Сортировка записей случайным образом 2£0
Трюк № 86. Пакетное обновление элементов управления формы 2£ 1
Трюк № 87. Обеспечение полного управления данными XML для любых
версий Access 215
Трюк № 88. Использование собственных перечней 2£8
Трюк № 89. Преобразование текста в нужный регистр 2£9
Трюк № 90. Создание программной библиотеки 2£ 1
Трюк № 91. Автоматическое отслеживание обновлений таблиц базы данных 254

Глава 9. Использование сторонних приложений 297


Трюк № 92. Документирование базы данных с помощью программы
Total Access Analyzer 2£i7
Трюк № 93. Создание оболочки приложения при помощи программы
EZ Application Generator 3(2
Трюк № 94. Загрузка в базу проверочных данных 3(6
Трюк № 95. Использование Access в качестве базы данных XML 3(8

Глава 10. Интернет 315


Трюк №
96. Экспортирование отчета в формат HTML 315
Трюк №
97. Использование браузера в приложении Access 318
Трюк №
98. Извлечение исходного HTML-кода из веб-сайта 320
Трюк №
98. Загрузка файлов при помощи элемента управления Обозреватель
веб-страниц (Microsoft) 321
Трюк № 100. Использование смарт-тега для открытия веб-страницы 324

Алфавитный указатель 325


Введение
Система управления базами данных Access — продукт поистине удивительный.
Обладая широкими возможностями, она не требует особых усилий на разработку
и сопровождение приложений. После установки на компьютер система может ис­
пользоваться абсолютно бесплатно. Она подходит и для индивидуального при­
менения, и для работы компьютерных систем целой компании. Имеющаяся
в Access среда ускоренной разработки приложений (rapid application development,
RAD) во многом превосходит подобные средства других систем (например, Visual
Basic), отличается современностью и простотой использования.
Помимо всего прочего, Access — это полноценная прикладная система баз дан­
ных. Она объединяет в себе серверную и интерфейсную составляющие, избавляя
разработчиков от необходимости задействовать два программных продукта. Меж­
ду тем присущая ей гибкость дает возможность использовать файлы базы данных
Access и в роли исключительно программного интерфейса, и в качестве сервера
базы данных. Система Access позволяет также управлять данными внешних баз,
таких как SQL Server и Oracle.
Стоит ли еще о чем-то говорить? Я думаю, чтобы осознать, насколько мощным
продуктом является Access, вам не нужны дополнительные доводы, независимо
от того, пробовали вы с ней работать или только собираетесь это сделать. Есть и
еще одна приятная новость: в данной книге мы собираемся показать несколько
дополнительных способов использования Access: в частности, как запускать за­
просы на объединение, проигрывать в Access видеоклипы, просматривать в ее среде
веб-сайты и даже как управлять Access из других программных продуктов, — в дан­
ной книге есть трюки на любой вкус.
Книга Access. Трюки позволяет отойти от парадигмы всем известных таблиц, форм
и отчетов и по-новому взглянуть на процесс создания более ценных и впечатляю­
щих приложений базы данных. Я с большим удовольствием продемонстрирую
вам новые способы работы с вашей излюбленной базой данных. Итак, вклю­
чайте компьютер, мы приступаем к работе!

Об авторе
Кен Блюттман (Ken Bluttman) занимается разработкой оригинальных решений,
связанных с применением Access, в течение многих лет. Свое мастерство програм­
миста он оттачивает с тех времен, когда в наших домах только начали появляться
первые персональные компьютеры. С появлением ранних версий Access он сумел
по достоинству оценить все удобства этого нового средства управления базами
данных. Кен Блюттман также преуспел и в разработке решений для Excell и дру­
гих продуктов, входящих в Microsoft Office. Ему в равной степени удается разра­
ботка технологий, связанных с SQL Server, Интернетом и языками VB и VB.NET.
12 Введение

Остается только гадать, где он находит время на сон. Он является автором кни г,
посвященных разработкам решений для Microsoft Office, рецептам применения
Excel для начинающих, которые выходили в разных издательствах. Его перу при­
надлежат статьи и публикации об интернет-технологиях. Кроме того, Кен — на­
тура музыкальная, он тонко чувствует природу, любит бродить по лесам с гита­
рой. Он живет в Нью-Йорке вместе с женой, сыном, собакой и некоторыми
представителями отряда земноводных. Если вы желаете познакомиться с ним по­
ближе, посетите его веб-сайт www.bluttman.com.

Сотрудники
Книга во многом появилась благодаря тому, что в ее создании приняли участие
и поделились своими идеями следующие специалисты:
• Стив Конклин (Steve Conklin) — независимый разработчик программного обес­
печения и владелец консультационной фирмы Ultra D.N.T. (разработка, сете­
вые решения и обучение), расположенной в районе Квинс, в Нью-Йорке. Кр\г
его интересов включает разработку приложений на Access, Visual Basic, VB.NET
и MS-SQL Server и их применение в мобильных решениях на базе PocketPC.
Он является автором ряда статей для журнала, посвященного технологиям Access,
VB и SQL, и преподает Microsoft Windows и Office в Нью-Йоркском обще -
ственном колледже. Связаться с ним можно по адресу UltraDNT@Hotmail.com.
• Стив Хаф (Steve Huff) разрабатывает Access-приложения более девяти ле".
Занимаясь на вечерних курсах повышения квалификации разработчика ин­
формационных систем в Северном университете штата Кентукки, он получи п
ученую степень по информатике. В качестве консультанта он более сем л
лет проработал над созданием решений на базе Microsoft Office для организа­
ции SARCOM. Стив и его жена Мелисса живут в штате Кентукки. Связаться
с ними вы можете через веб-сайт www.huffs.us.
• Кирк Ламб (Kirk Lamb) увлеченно занимается Access в течение многих лет.
Являясь специалистом по гребле, он не упускает возможности оценить удач­
ные решения в области управления базами данных. Кирк с женой Дил живег
в штате Вашингтон.
• Андреа Мосс (Andrea Moss) впервые столкнулась с Access, разрабатывая сис­
тему регистрации страховых исков. С того времени она прилагала свой худо­
жественный талант к разработке форматов и цветовых схем различных гра­
фических пользовательских интерфейсов, включая формы Access и веб-сайть:.
Она внедрила в эту работу и ряд собственных трюков Access.
• Майкл Шмальц (Michael Schmalz) работает в банковской системе и являете?
консультантом по организации бизнеса и технологиям в различных промышлен­
ных областях. Он занимался в издательстве O'Reilly технической редактурой кию •,
посвященных Microsoft Office. Майкл имеет ученую степень по финансовым опе­
рациям от штата Пеннсильвания, где он живет вместе с женой и дочерью.
• Симон Сен-Лоран (Simon St. Laurent) живет в Итаке, Нью-Йорк, и являетез
разработчиком интернет-проектов, сетевым администратором, автором ком­
пьютерных книг и крупным специалистом по XML. Его книги посвящены
XML и всему, что связано с этой технологией. Он соредактор веб-сайта
XMLhack.com и время от времени сотрудничает с создателями веб-сайтаХМЬсогг.
Как пользоваться данной книгой 13
• Маргарет Левин Янг (Margaret Levine Young) работает на компьютерах с на­
чала 1970-х годов. Она последовательно переходила от Unix на PDP-11 к Apple
DOS на Apple II, затем работала в DOS, Windows и Unix на различных маши­
нах. Она пропагандировала внедрение компьютерной техники, объясняя лю­
дям, что компьютеры не настолько таинственны и сложны, как это кажется на
первый взгляд, при этом она внедряла компьютерные технологии на студии
Columbia Pictures, обучала ученых и инженеров применению компьютеров,
являлась автором и соавтором компьютерных пособий и книг, включая книги
для начинающих. Маргарет обладает ученой степенью Йельского университе­
та и живет с мужем и двумя детьми в штате Вермонт.

Благодарности
Эта книга является коллективным трудом, поэтому я хочу выразить свою благо­
дарность всем, кто поделился со мной замечательными трюками, и вы, надеюсь,
разделите со мной радость их изучения.
Особую благодарность я хочу выразить своему редактору, Митчу Таллочу (Mitch
Tulloch), прошедшему со мной через все перипетии рождения книги, за прояв­
ленное невероятное терпение и настойчивость. Митч, в свою очередь, благодарит
компанию MTS Communications (www.mts.ca) за предоставление услуг Интер­
нета и места для веб-сайта (www.mtit.com).
Спасибо Майклу Шмальцу (Michael Schmalz) за техническую экспертизу мате­
риала, ускорившую выход книги.
Спасибо Брайану Соеру (Brian Sawyer) и всей замечательной команде издатель­
ства O'Reilly. Спасибо всем.
Спасибо моему агенту, Нилу Салкинду (Neil Salkind), и коллективу Studio В. Од­
нажды в прошлом году именно Нил надоумил меня приступить к написанию «Трю­
ков Access». Благодаря ему я познакомился и с Мичем Таллочем (Mitch Tulloch).
Спасибо персоналу компаний Database Creations (www.databasecreations.com) и FMS
(www.fmsinc.com) за предоставленные копии их замечательной продукции.
И не менее искреннюю благодарность я хочу выразить своей жене Гейле и сы­
ну Мэттью. Во время моей напряженной работы над книгой они старались со­
здать все условия для ее успешного завершения. Забавно было наблюдать, как
семилетний малыш постигает компьютерные премудрости. Мэттью частенько вос­
седал у меня на коленях и следил за тем, что я набираю на компьютере, и теперь
он по праву может считать себя знатоком Access.

Как пользоваться данной книгой


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

Структура книги
Каждая глава концентрируется на определенном аспекте Access. Это позволяет
черпать вдохновение в интересующих вас областях. Если вам нужна помощь г:о
запросам и SQL, обратитесь к главе 5. Если вас интересуют трюки программиро­
вания, изучите главу 8. Ниже приводится содержание каждой из глав.
• Глава 1. «Использование ядра Access». В этой главе изложены основы — от
структуры объектов базы данных до работы с данными. В представленных здесь
трюках рассматриваются способы, призванные помочь обычным пользовате­
лям, добиться преодоления несовместимости версий и даже заставить Access
работать с любыми объемами данных.
• Глава 2. «Таблицы». Таблицы — ключевой объект любой базы данных. В этой
главе вы найдете трюки, позволяющие перемещать данные между таблица­
ми, перезапускать Счетчик для начала отсчета с требуемого числа. Вы также
научитесь различать системные таблицы и убирать их подальше, чтобы они г:е
мешали выполняемым задачам.
• Глава 3. «Ввод данных и перемещение по элементам управления». Эта гла! а
поможет облегчить жизнь пользователей. Система управления базами дан­
ных должна не только хранить информацию, но и улучшать управление дан­
ными. В главе 3 много трюков, улучшающих работу с формами, поскольку
именно с этими объектами базы данных пользователи работают чаще всего.
• Глава 4. «Представление данных». Если данные введены и сохранены, остает­
ся лишь составить отчет. В этой главе показаны новые способы работы с отче­
тами. Вы можете изучить работу с водяными знаками, научиться применять
сложные виды сортировки и обеспечивать вывод условных итогов. Не забудь­
те также ознакомиться с трюками, позволяющими просматривать слайды и ви­
деоклипы!
• Глава 5. «Запросы и SQL». Выполнение запросов — значительная часть рабо­
ты с базами данных. Многие трюки этой главы позволят вам отказаться от ба­
нальных решений при работе с Конструктором запросов. В процессе исследс -
вания запросов на объединение вы сможете окунуться в основы языка SQL,
научится использовать операторы In и Not и изучить способы применения
в запросах собственных функций. Приведен даже трюк, который научит вас
создавать запрос с помощью несвязанных таблиц для получения всех комбр -
наций данных, имеющихся в двух полях.
• Глава 6. «Решение проблем многопользовательской среды». Некоторые про­
блемы присущи только многопользовательской среде. В этой главе вы найдете
трюки, позволяющие обойти наиболее распространенные проблемы, изучить
способы автоматического завершения редактирования и методы безопас­
ного распространения приложений баз данных.
• Глава 7. «Внешние программы и данные». Система Access легко интегрирует­
ся с другими программами и протоколами. В этой главе показано множество спо­
собов использования Access с другими продуктами, включая Excel, Word, MySQL
и SQL Server. Если вы слабо представляете себе работу с данными в формате XML,
вам пригодятся трюки, посвященные этому вопросу. Есть даже трюк, в котором
показано создание таблиц Access без запуска самой системы Access.
Способы оформления, принятые в данной книге 1_5

• Глава 8. «Программирование». Представлены приемы программирования.


Сюда включены трюки, направленные на оптимизацию кода, его ускоренное
создание и защиту. В некоторых трюках представлены краткие решения неко­
торых проблем: например, как добраться до определенной записи или обес­
печить индикацию длительного процесса.
• Глава 9. «Использование сторонних приложений». В этой главе содержится
обзор нескольких продуктов, предоставляемых сторонними разработчиками
и направленных на облегчение работы с базами данных. Вы сможете ознако­
миться со средствами, предназначенными для создания оболочек баз данных,
документирования созданной базы и даже создания данных для проверки ра­
ботоспособности приложения. В заключение представлен обзор законченного
решения по созданию приложения на основе технологии XML.
• Глава 10. «Интернет». Трюки этой главы раскрывают способ создания HTML-
файлов из Access. После проведения небольшой корректировки с использовани­
ем средств обработки HTML-файлов или текстового редактора вы сможете при­
вести отчет, созданный в Access, к нужному формату. В этой главе вы найдете
трюки, позволяющие помещать веб-браузер непосредственно в форму Access. Если
вы хотите проверить, как работают ваши деньги, воспользовавшись информаци­
ей, имеющейся в Интернете, то это можно сделать, не выходя из базы данных.

Способы оформления, принятые


в данной книге
В книге используется следующее оформление:
• Курсив — служит для выделения определений, небольших фрагментов тек­
ста и слов с определенной «интонацией», а также для названий печатных из­
даний и ссылок на другие разделы.
• Шрифт без засечек — применяется для оформления заголовков диалоговых окон,
названий пунктов и команд меню, названий кнопок, флажков, переключате­
лей и т. п., имен файлов и папок, клавиш клавиатуры, адресов электронной
почты и Интернета, имен объектов базы данных.
• Моноширинный шрифт — предназначен для оформления примеров программно­
го кода, инструкций запросов, содержимого файлов, команд, операторов, пе­
ременных и текстов, вводимых с клавиатуры.
• Меню и навигация. В этой книге для обозначения переходов в системах меню
используются символы стрелок. Например, «Файл • Печать» выглядит более ла­
конично, чем пространное описание вида: «Щелкните на надписи Файл Пане­
ли управления в верхней части экрана и выберите пункт Печать в раскрываю­
щемся меню». Тем не менее если инструкцией предписывается щелкнуть на
вкладке, выбрать пункт или щелкнуть на кнопке диалогового окна, то все это
будет описано в явном виде.
• Рядом с заголовком каждого трюка помещены значки гаечных ключей, обознача­
ющие его сложность: для начинающих П, для опытных П и для экспертов |.
16 Введенке

Использование примеров кода


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

От издательства
Ваши замечания, предложения и вопросы отправляйте по адресу электронной пс -
чты comp@piter.com (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
Подробную информацию о наших книгах вы найдете на веб-сайте издательств;.:
http://www. piter. com.
Г Л А В А 1

Использование ядра Access


Трюки № 1 - 1 2

С системой управления базами данных Access работают люди многих специаль­


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

Облегчение поиска нужных объектов


№1 Размещение ярлыков нужных объектов в группе Избранное, избавляющее пользова­
телей от необходимости перебирать всю коллекцию объектов базы данных.
Не каждый способен без особого труда разобраться в содержимом окна базы дан­
ных Access. Поиск нужных объектов среди всех этих таблиц, запросов, форм и от­
четов — задача порой не из легких. Иногда для завершения работы нужно иметь
под рукой всего лишь небольшую подборку объектов, а их приходится выиски­
вать в общей массе.
Решение этой проблемы не составляет труда. Окно базы данных Access позволяет
создавать подборки из ярлыков нужных объектов. Причем ярлыки объектов базы
данных Access по сути ничем не отличаются от ярлыков файлов, папок и прило­
жений, размещаемых на Рабочем столе.
18 Глава 1 . Использование ядра Access

Стандартное окно базы данных


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

j i f f Microsoft Access [Stud


: -Ш &&** Правка Вид Вставка

:.*3 Создать | л-ji


|№ Ш Создание таблицы в режиме конструктора
' =Ш Создание таблицы с помощью мастера
Щ Создание таблицы путем ввода данных
Ш folCalendar
~3 jtbDates!
EH tblIntBr¥iew_Lookup
Ш tblMonthsJ.ookup
Ш tbPeople
Ш fclSchedule
Ш tblStateProv»xe_Lookup
3 iblstudo

::М
Рис. 1 . 1 . Стандартное окно базы данных Access

Конечно, и в этом окне вы можете получить доступ к любому нужному объекту:


после щелчка на вкладке Запросы можно найти запрос, который нужно выпол­
нить, а требуемый отчет найдется во вкладке Отчеты. Но не обязательно выиски­
вать их именно там. Окно базы данных обладает одним весьма ценным свойством:
оно предоставляет вам возможность создавать собственные группы объектов.
Вполне очевидно, что в окне базы данных объекты отделены от групп. На рис. 1.1
в нижней половине левой части окна базы данных вы увидите хорошо различи­
мый раздел групп.

Использование групп
Изначально имеется лишь одна группа Избранное, в которую вы можете поместить
ярлыки любых объектов. Сделать это весьма просто. Надо лишь найти объект
в какой-либо вкладке, подвести к нему указатель мыши и, удерживая нажатой
левую клавишу, перетащить его в группу Избранное. На рис. 1.2 показано, что из
этого может получиться. Группа Избранное заполнена ярлыками, указывающими
на некоторые объекты базы данных. Заметьте, что это всего лишь ярлыки. Сами
объекты остались на прежних местах, соблюдая свою принадлежность к катего­
риям. Вы можете удалить ярлык, размещенный в группе Избранное, но сам объект
при этом сохранится.
Трюк № 1. Облегчение поиска нужных объектов 19
:';•''.::: V: ••':; :/й:;; : ?^ШШ1Ш: : Ш1
{SfudentRoster : йачаданных(фирмзг Access iOoO|]
W^ww;
::;|$|фаЙл ; ; :: Т5заека Вид Вставка Сервис QKHC Справка !**. "К X

' * --> . "> • . Л - ! »'i •


'.СЦкрыть *<£даструктор > -, . 1Й
1
Объекты У Ш frmCalendar &
| 1 Таблицы УЗ FrmSchedule

| # Запросы
Уа rptStudentSchedule
1
3 Формы

1 s :iS : Отчеты £

i *У Стра^цы ] iji

1 ! ^Ц^Щроом |
«t Модули .

|/•••. Группы |i

| м Избранное [ ;!;

1
1
1 •

Готово NUM

Рис. 1.2. Размещение ярлыков в группе Избранное

Очевидно, что использование группы Избранное даст возможность собрать воеди­


но все самое нужное. Но создание новых групп позволит усовершенствовать орга­
низацию объектов. Что, если создать отдельную группу для каждого пользователя
или категории пользователей? Например, операторы ввода данных и диспетчеры

v*3: файл Правка Вил: Вставка Сервис Окно Справка fl х !

и
Объекты I qryDatesSchedulel
:•. Таблицы :;• jj|p qryDatesSchedule2
•j& rptStudentSchedule
•' Запросы i|:

• Формы

: Отчеты

: Страницы

. Макрось*

Модули

:Из6раннте;-:,,,,,.;

Фсриы ввода

От.^ты|.*ратоол

Рис. 1.3. Создание и использование своих собственных групп


20 Глава 1 . Использование ядра Acces;

могли бы пользоваться одним и тем же приложением базы данных, но использо­


вать различные объекты; при этом операторы работали бы с определенными фор­
мами, а диспетчеры и управляющие — с запросами и отчетами, отражающими пол­
ную картину событий.
Добавить новую группу довольно просто. Щелкните правой клавишей мыши НЕ
области Группы, выберите в контекстном меню пункт Новая группа и наберите на­
звание группы. Теперь вы сможете перетащить в новую группу объекты. На рис. 1.3
показаны две новые группы, добавленные к приложению. Каждая из них содер­
жит свой набор ярлыков.
Другое ценное качество групп заключается в том, что ссылки на одни и те же объек­
ты могут присутствовать сразу в нескольких из них. Если нужно поместить яр­
лык, указывающий на один и тот же отчет, в три разные группы, Access не станет
этому препятствовать. На самом деле вы можете даже копировать ярлыки из од­
ной группы в другую.

Н Индивидуальная настройка приложений


Access
Придание приложению персонифицированных свойств методом применения системы ин­
дивидуальных настроек, повышающих эффективность работы конкретного пользователя.
Совсем незачем заставлять всех пользователей придерживаться единого метода
работы с приложением. Способ обойти подобное ограничение не столь очевиден,
поскольку Access в окне Параметры запуска дает возможность указать только одну
форму, открываемую в начале работы приложения, и тут вы ничего не сможете
изменить, пока не воспользуетесь обработкой событий, происходящих при откры­
тии базы данных. Только тогда у вас появится возможность выбирать открывае­
мую в начале работы форму, переопределять ее свойства и т. д. Вы сможете сде­
лать все составляющие приложения уникальными для отдельных пользователей
или их категорий. Приспособить таким образом можно следующие элементы:
• Формы. Можно определить, какая из форм будет открыта, каким способом
она будет отображена и какие функциональные возможности будут в ней за­
действованы.
• Источники данных. Можно определить, какие таблицы персонификации, внут­
ренние или внешние, понадобятся для решения задач каждого пользователя.
• Отчеты. Можно определить отображаемые или игнорируемые элементы.
В этом трюке используется макрос Auto Exec, запускаемый в начале работы прило­
жения и обеспечивающий индивидуальную настройку пользовательского интер­
фейса. Чтобы заставить его работать в этом качестве, вам необходимо сначала со­
здать таблицу базы данных для хранения личных параметров пользователя, а затем,
в начале работы базы данных, у вас должна быть возможность идентифицировать
для нее пользователя. Это можно сделать несколькими способами: например, во
всплывающем окне ввода информации можно запросить имя или инициалы (а за­
одно, возможно, и пароль); также для идентификации пользователя можно при­
менить переключатель командной строки, или, если применяются средства защи-
Трюк № 2. Индивидуальная настройка приложений Access 21

ты Access, идентификатор пользователя может быть получен из свойства текуще­


го пользователя — CurrentUser.

Хранение личных параметров


Личные параметры пользователя хранятся в таблице, которая содержит поле для
каждого из них. Например, поле с типом данных Длинное целое может хранить
желаемый цвет фона, а поле с типом данных Текст может содержать имя формы,
которую пользователь хочет открыть, и т. д. На рис. 1.4 показана такая заполнен­
ная таблица с соответствующим названием Личные параметры. Имена полей отра­
жают предназначения личных параметров, а в самих полях содержатся соответ­
ствующие установки.

ЦввтФонаФормы | РвэмерШрифта| Открк'ичяз-гГирма [ Подр" ;- В


8454143:Мелкий Главная форма ;Нет
т 0\ ZJm
; - ; , ; . . . . . . : . . . . , ; , . ; , . , . . . . , . • :

Рис. 1.4. Таблица, содержащая личные параметры отдельного пользователя

Такая таблица вполне подойдет для баз данных, установленных на отдельных


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

"| Пччние пирометры : тивпши


МыяПйлийователя | ЦеёТФЬнаФармы •'-'} РззмерШрифта ] ОткрываемаяФорма [ ПодраБностиОг^п j
XJJJd

Евгения 8454143 i M ел кий Главная форма Нет

Сюзанна 8454143: Мелкий Распорядок ДА


Admin 12632256; Мелкий Объекты Нет

Р*«* ! QDQQI

6;: ? ® > * ю 6 • • • '
Рис. 1.5. Таблица, содержащая личные параметры нескольких пользователей

ПРИМЕЧАНИЕ
Л
'У/.
Предусмотреть запись для пользователя Admin - весьма здравая мысль. Эта учет­
ная запись используется Access по умолчанию даже в том случае:, когда система
защиты не задействована. Если вход в систему защиты не использовался, то свой­
ство CurrentUser no умолчанию устанавливается в Admin.
22 Глава 1 . Использование ядра Acces;;

Все, что надо для завершения этого трюка, — это предоставить пользователям спо •
соб выбора личных параметров. Вряд ли кому-то захочется вводить абракадабру
числового представления цвета. Значит, для ввода личных параметров нужно вое •
пользоваться формой (ну а чем же еще!). Это будет специальная форма для уста •
новки личных параметров, не имеющая в базе данных никаких других функций.
Внешний вид такой формы показан на рис. 1.6.

Открываемая форма
Цвет фона формы Главная форма
Платежи
Сохранить параметры
Распорядок
Описания
Объекты

, - Детализация отчета

! (*} Подробный

• Размер шрифта •••••— | О Общий

0 Мелкий шрифт

О Крупный шрифт

Рис. 1.6. Форма выбора личных параметров пользователей

После выбора личных параметров их можно будет занести в таблицу, щелкнув ш.


кнопке Сохранить параметры. Для таблицы, рассчитанной на одного пользователя
этот трюк можно реализовать следующей простой командой SQL:
Update Личные_параметры Set ЦветФонаФормы=8454143, РазмерШрифта='Мелкий',
ОткрываемаяФорма='Платежи', ПодробностиОтчета='Нет'
Для многопользовательской конфигурации в команду SQL добавлено еще однс
поле:
Update Личные_параметры Set ЦветФонаФормы=8454143, РазмерШрифта='Мелкий',
ОткрываемаяФорма='Главная форма', ПодробностиОтчета='Да' Where
ИмяПользователя='Сюзанна'
Эти команды SQL составлены с использованием значений элементов управления
формы. Для обновления значений таблицы использована технология доступе
к данным ActiveX Data Objects (ADO). После составления команды SQL обнов­
ление будет проведено методом Execute объекта Connection:
Private Sub cmdSave( )
On Error GoTo err_end
Dim conn As ADODB.Connection
Set conn = CurrentProject.Connection
Dim ssql As String
ssql = "Update Личные_параметры Set " & _
" ЦветФонаФормы=" & _
Трюк № 2. Индивидуальная настройка приложений Access 23

Me.groupFormColor & ", " & _


"РазмерШрифта='" & _
Choose(Me.groupFontSize, "Мелкий", "Крупный") & "', " &
"ОткрываемаяФорма='" & Me.lstForms & "' , " & _
"ПодробностиОтчета='" & _
Choose(Me.groupReportDetai1, "Да", "Нет") &
conn.Execute ssql
conn.Close
Set conn = Nothing
MsgBox "Личные параметры обновлены!"
Exit Sub
err_end:
conn.Close
Set conn = Nothing
MsgBox Err.Description
End Sub

Реализация личных параметров


От проблемы сохранности личных параметров теперь нужно перейти к проблеме
их реализации, поэтому давайте несколько расширим приложение. Один из лич­
ных параметров касается выбора формы, появляющейся при запуске приложе­
ния. Здесь применяется макрос AutoExec, запускающий функцию, в которой ис­
пользуются значения ранее сохраненных личных параметров. Как и раньше, если
дело касается однопользовательской установки, используется упрощенный тип
таблицы, а в многопользовательской конфигурации свою роль сыграет имя пользо­
вателя.
Далее представлены две функции, которые будут вызываться из макроса AutoExec.
Параметром макрокоманды ЗапускПрограммы макроса AutoExec выступает имя
функции. В обоих случаях функция DLookup извлекает значение имени открывае­
мой формы, избранной пользователем, после чего открывается сама эта форма.
Разница заключается в фильтре функции Dlookup, настроенном на имя пользова­
теля. В первой функции, в отличие от второй, этот фильтр отсутствует:
Function open_up_single( )
On Error GoTo err_end
Dim myform As String
myform = ОЬоокирС'ОткрываемаяФорма", "Личные_параметры")
If Not IsNull(myform) Then
DoCmd.OpenForm myform
Else
DoCmd.OpenForm "Объекты"
End If
Exit Function
err_end:
MsgBox Err.Description
End Function

Function open_up_multi_user( )
On Error GoTo err_end
Dim myform As String
Dim username As String
myform =
24 Глава 1 . Использование ядра Access

01.оокир("0ткрываемаяФорма", "Личные_параметры", "ИмяПользователя='" &_


Currentllser & )
If Not IsNull(myform) Then
DoCmd.OpenForm myform
Else
DoCmd.OpenForm "Объекты"
End If
Exit Function
err_end:
MsgBox Err.Description
End Function
Заметьте, что блок If . . . Else в случае возвращения нулевого значения обеспе
чит открытие формы Объекты, которая выступает в роли формы, открываемой по
умолчанию.
Вам нужно обеспечить реализацию и других личных параметров, таких как вы
бор степени детализации отчета или использование различных размеров шрифта,
там, где это уместно. Например, вот так вы сможете изменить цвет фона формы,
воспользовавшись событием формы Открытие:
Private Sub Form_0pen(Cancel As Integer)
Me. Detai I . BackColor = 01_оокир("ЦветФонаФормы", "Личные_параметры")
End Sub

Использование трюка
Все, что теперь остается сделать, — это решить, как открывать форму, предназна
ченную для задания личных параметров. Ее можно открыть через панель инстру
ментов, из меню или с использованием макроса. Неплохим решением станет разме­
щение ярлыка, указывающего на эту форму, в специально созданной группе
часто используемых объектов. Как создать собственную группу объектов, вь
можете узнать, вернувшись к трюку «Облегчение поиска нужных объектов*,
(Трюк № 1).

Т Р Ю К Быстрая работа без опечаток


№3 Экономия времени и избавление от ошибок путем использования простых сочетании
клавиш для ввода даты, времени и других часто используемых данных.
Мышь — вещь хорошая, но ничто так не ускоряет работу с приложением, как кла
виши быстрого вызова. Широко известны сочетания Ctrl+C для копирования, Ctrl+V
для вставки и т. д. А что известно о сочетаниях для ввода даты, времени и других
данных? Использование подобных сочетаний приведет к существенной экономии
времени, особенно в спешке завершающей стадии проекта. Да и когда мы, соб
ственно, не испытывали дефицита времени?

Сочетания клавиш быстрого вызова


В табл. 1.1 собраны сочетания клавиш, используемые в приложениях Access. Это
далеко не исчерпывающий список. Все полезные сочетания можно найти в спра
вочной системе Access. Представленные в таблице сочетания касаются только вво
да данных.
Трюк № 3. Быстрая работа без опечаток 25
Таблица 1 . 1 . Сочетания клавиш быстрого вызова для ввода данных

Действие Комбинация клавиш


Вставка текущего времени Ctrl+:
Вставка текущей даты Ctrl+SHIFT+;
Вставка значения из того же поля предыдущей записи Ctrl+'
Вставка в поле значения по умолчанию Ctrl+Alt+пробел
Вставка новой строки в текст или в поле memo Ctrl+Enter
Вставка новой записи СМ+«плюс»
Вставка содержимого буфера обмена Windows Ctrl+V

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


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

Использование макроса AutoKeys


Макрос AutoKeys позволяет назначить собственные сочетания клавиш для вызова
действий, совершаемых в приложении базы данных. Вы можете назначить дей­
ствия, совершаемые при нажатии функциональных клавиш, сочетаний клавиш,
таких как Ctrl+A, а также при нажатии клавиш Insert и Delete. При этом нужно
строго придерживаться синтаксиса, в котором знак возведения в степень ( л ) пред­
ставляет клавишу Ctrl, а знак плюс (+) представляет клавишу Shift. Обычные кла­
виши вводятся как есть, а функциональные и специальные клавиши (Insert и Delete)
заключаются в фигурные скобки ({}). Вот несколько примеров:
• ЛА — назначает действие сочетанию Ctrl+A.
• {F9} — назначает действие функциональной клавише F9.
• + {F9} — назначает действие сочетанию Shift+F9.
• {INSERT}— назначает действие клавише Insert.
При назначении собственных сочетаний клавиш взамен сочетаний, существовав­
ших по умолчанию, последние будут утрачены. Вы даже можете переназначить
действия, вызываемые общепринятыми сочетаниями клавиш, такими как Ctrl+V
(вставка).
Синтаксические выражения помещаются в столбец Имя макроса, а соответствую­
щие сочетанию клавиш действия — в столбец Макрокоманда. Остается только вы­
полнить еще одно требование — присвоить макросу имя AutoKeys.

Напоминание об установленных сочетаниях клавиш


Чтобы запомнить набор сочетания клавиш, требуется время, поэтому следующим
разумным шагом станет создание сводного списка сочетаний в виде памятки. Надо
сделать так, чтобы список сочетаний клавиш был доступен в виде формы, кото­
рую можно будет вызвать в любой момент при помощи — как вы, наверное, уже
догадались — специально для этого предназначенной клавиши быстрого вызова.
Разумеется, такую форму нужно создать.
26 Глава 1 . Использование ядра Access

На рис. 1.7 показана форма, в которой содержится памятка о сочетаниях клавиш


Источником записей этой формы служит таблица, в которой в двух полях содер­
жатся описания сочетаний клавиш и вызываемых ими действий. Еще одним ре­
шением может стать использование элементов управления формы типа Надпись
содержащих сведения о сочетаниях клавиш и действиях, совершаемых с их по­
мощью.

Сочетания клавиш

Описание Сочетание

Вставка текущего времени Ctrl-

Вставка текущей даты Ctrl-SHIFT- ;

Вставка значения из того же поля предыдущей Ctrl-'


записи
Вставка в поле значения по умолчанию Ctrl-Alt-spacebar

Вставка новой строки в текст или в поле memo Ctrl-Enter

Вставка новой записи Ctrl-+

Вставка содержимого буфера обмена Windows Ctrl-V

Рис. 1.7. Форма быстрой ссылки для сочетаний клавиш

Поскольку проще всего запомнить какую-нибудь функциональную клавишу, то


для вызова этой формы вполне подойдет клавиша F9, которая обычно остается
невостребованной. Не стоит выбирать уже задействованные клавиши, наприме])
клавишу F1, которая обычно используется для вызова справочной системы. Для
установки собственных сочетаний клавиш служит специальный макрос AutoKeys,
который запускается в начале работы приложения, подобно макросу AutoExec.

AutoKeys : макрос
Имя макроса Макрокоманда Примечание ___|л;
WF9} Открытьформу
JHF10} ОткрытьОтчет
1+IDELETE} ЗалускПрограммы
]^Ь ЗалускПрограммы
J ^ Выход

Аргументы макрокоманды
; Имя формы :frn*eyboardShortcuts
. Режим Форма
№ю фильтра
Условие отбора
Режим данных
Столбец для ввода примечаний.
: Режим окна

Рис. 1.8. Использование макроса AutoKeys для назначения собственных сочетаний клавиш
быстрого вызова
Трюк № 4. Оптимизация процесса изменения данных 27
На рис. 1.8 показан процесс создания макроса AutoKeys, в котором задается не­
сколько собственных сочетаний клавиш. Клавиша F9 предназначена для откры­
тия формы frmKeyboardShortcuts, показанной на рис. 1.7.

Н Оптимизация процесса изменения


данных
Избавление от ручной коррекции данных во всех связанных таблицах путем установки
каскадного обновления и удаления.
Предположим, изменяется какая-то учетная единица. Почему бы не предусмот­
реть такую возможность в вашем приложении? Возьмем реальный пример: кли­
ент поменял свое имя. Если вы достаточно давно занимаетесь бизнесом, то такой
случай должен быть предусмотрен при работе с вашей базой данных.
Изменения данных должно осуществляться одним из двух способов. Если дан­
ные не используются в качестве первичного ключа таблицы или внешнего ключа,
вам нужно внести изменения в данные везде, где они встречаются в ваших табли­
цах. Хорошо, если эти данные встречаются только в одном месте. Если схема базы
данных составлена правильно, то определенные данные, такие как имя клиента,
она содержит только в одном месте. Если такие данные содержатся в нескольких
местах, то, вероятно, у вас была для этого веская причина. Приложения со време­
нем разрастаются, а в их разработке в разное время принимают участие разные
специалисты. Такое случается довольно часто.

, Microsoft Ассе»
Файл Правка ; §ид Вставка Формат •Записи Сервис

.11 й
1 <ЫС« stonier» ' T абпиаа
\ CustowerlO j : i Company; Address T : City Щ
.•.• Best Equipment 14 Waller Road jTopeka
JjHCL i Harrison Cranes and Lifts j 2 5 Barrow Road '. Houston :||;
Johnson Machine Parts, Inc .77 Fouth Street |St. Louis
Г*"
1 "•*•• (Ж? < Г~
й
l..(JtJMitij « з
3 .'I : ' . • . - . i . . , . ! . !-••

i Invoice 1С | CustomerlD |ih v o iceNurnber] TnvoiceGate :.RaidlnFull

. • i. 7: BE 1/5/2005-BE 11/5/2005
m
:
t. ; 9iHCL 1/6/2005-HAR 11/5/2005 ia
f .•:: 10: JMP
!
i 1 /15/2005-J M P i 1 /15/2005
i j
{.

Ш
11 JMP 1/18/2005-BE M/18/2005
i
< si
12iBE : 1/18/2005-BE 11/18/2005
m
-' 13HCL 1/22/2005-HAR: 1/22/2005 0

i
•;: 14;JMP 1/24/2005-JMPi 1/24/2005
i
*; 15iBE 2/2/2005-BE i2/2/2005 ii
i щ 16iHCL 2/7/2005-HAR i 2/7/2005
a
\'" Щ 17; HCL 2/12/2005-HAR i 2/12/2005
E
• t:: 18iBE 2/T6/2005-BE Т2/16Д005
и
•i. ••• 19; B E i2/18/2005-BE 12/16/2005 d
i *i 20iHCL 3/1/2005-HAR 13/1/2005
i i
; *; 21;JMP 3/3/2005-JMP 13/3/2005
a
- *i. .22JHCL.. 3/10/2005-HARi3/1O/20O5
J4; ЗЗПИО, Щ j i 1; ..'INI?.*]"» гг

Рис. 1.9. Связанные таблицы


28 Глава 1 . Использование ядра Access

Если в вашем приложении базы данных одни и те же данные можно найти повсю­
ду, схему данных требуется привести в порядок. Что, если поместить данные
в ключевое поле таблицы? Но такое решение будет мешать повсеместному внесе­
нию изменений в том случае, если множество дочерних таблиц используют те же
данные в качестве внешнего ключа. И так будет до тех пор, пока вы не предусмот­
рите в схеме связи таблиц каскадное обновление.
При создании связей между таблицами вы можете, в частности, выбрать установ­
ку каскадного обновления. На рис. 1.9 показаны две таблицы данных. Таблица
tblCustomers, размещенная вверху, содержит сведения о клиентах. Значения клю­
чевого поля, CustomerlD, представляют собой инициалы имен компаний. В ниж­
ней таблице, tbllnvoices, поле CustomerlD служит внешним ключом.
На рис. 1.10 показаны связи между таблицами. Линия соединяет поле CustomerK
таблицы tblCustomers и поле CustomerlD таблицы tbllnvoices. Цифра 1, стоящая на/,
той частью линии, которая примыкает к таблице tblCustomers, свидетельствует
о том, что эта таблица является родительской. Символ бесконечности (°°), кото
рый находится над той частью линии, которая примыкает к таблице tbllnvoices,
свидетельствует о том, что эта таблица является дочерней. Такое отношение меж
ду таблицами называется один-ко-многим. Таблица tbllnvoices имеет к тому же
и другие связи.

Рис. 1.10. Окно схемы данных

Диалоговое окно Изменение связей, показанное на рис. 1.11, позволяет устанавли­


вать связи между таблицами. Чтобы открыть это окно, следует дважды щелкнуть
на линии, соединяющей две таблицы. Обратите внимание на флажок Каскадное
обновление связанных полей. Когда он установлен, то изменения, вносимые в зна­
чение ключевого поля родительской таблицы, влекут за собой автоматические из­
менения связанных полей в дочерней таблице. Просто замечательно! Когда у кли­
ента меняется имя, все, что вам следует сделать, — это изменить имя в ключе. Все
связанные значения, имеющиеся в дочерней таблице, будут скорректированы а з-
томатически.
В примере, показанном на рис. 1.9, если компания «Best Equipment» изменит свое
название на «Best Tools», значение поля CustomerlD должно быть изменено на ВТ.
Трюк № 5. Перенос данных между версиями Access 29

• 1 * в « С««1ей
:
таблица/запрос: Сбдэаннаятаблица/запро

: EblCustomers \Ш tbllnvoices
,г;
) . ———
!£Ц CustomerlD

:':Г^]^§еотачение целостности даииых)

0 каскадное обноемиив ягаанных попей


Ы каскадное удаление связанных записей

Тип отношения: один^ко-многим

Рис. 1 . 1 1 . Выбор каскадного обновления связанных полей и удаления связанных записей

Единственное изменение, внесенное в таблицу tbLCustomers, приведет к автомати­


ческому обновлению всех связанных записей в таблице tbllnvoices.

ПРИМЕЧАНИЕ
В диалоговом окне Изменение связей (рис. 1.11) можно также установить кас­
кадное удаление связанных записей, при котором удаление записи в родительской
таблице приведет к удалению всех связанных записей в дочерней таблице. Когда
этот флажок не установлен, вам придется сначала удалить все записи в дочерней
таблице, и только после этого вы сможете удалить записи в родительской таблице.

Если не установлен флажок каскадного обновления связанных полей, вам при­


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

Т Р Ю К Перенос данных между версиями Access


№5 Прощание с проблемой несовместимости версий.

За многие годы корпорация Microsoft выпустила более шести версий Access. Не­
которые люди и организации приобретают каждое обновление, некоторые дела­
ют это время от времени, но есть и такие, кто упорно держится за ставшую им
дорогой и близкой версию, приобретенную еще в прошлом веке! При работе в пол­
ной изоляции и вам, и вашей организации все равно, с какой именно версией вы
работаете, но когда вы начинаете обмениваться информацией со сторонними орга­
низациями, несовместимость версий может обернуться для вас большой непри­
ятностью.
Скажем, у вас установлена версия Access 2003 и вы отсылаете поставщику базу
данных, заполненную заказами. А у поставщика установлена версия Access 95.
И как бы вы ни сокрушались, но поставщик не сможет открыть вашу базу данных.
В настоящее время в компьютерном мире появились протоколы обмена данными, не
зависящие от применяемых платформ. Одним из них является протокол XML,
30 Глава 1. Использование ядра Access

всерьез претендующий на средство устранения проблемы несовместимости дан­


ных. При всех его преимуществах он доступен только в самых последних версиях
Access.
Есть другой, хорошо зарекомендовавший себя на практике, простой и не требую­
щий применения высоких технологий способ обмена данными: экспортировать
и хранить данные в текстовом виде. Несмотря на то что существуют различия в
подходах к хранению текста, имеющего разделители, выбору символа-раздели­
теля, спецификации текста, фиксации ширины и т. д., — все версии Access способ
ны читать и записывать текстовые файлы. На рис. 1.12 показан мастер Экспор-
текста, позволяющий установить параметры экспортируемого текста. Если вы бу
дете экспортировать таблицу или запрос и при этом укажете текстовый файл »
качестве типа файла, этот мастер будет запущен автоматически.

З Э к с т о р т текста ' _' _ _ _ 1 1 _ 1 _

Мастер позволяет подробно определить экспорт данных Microsoft Office Access. Выберите
нужный формат экспорта.

Q^^te^S^~r^'\mtenMni"i^"^'^ табуляцией "


О фиксированная щирина попей - интервалы заполняются пробелами

Образец формата экспорта:


29:283;"Honda";"Accord";"Bhice";"661-03 4";"PA";"2003";'
3 0 ; 2 5 1 ; " T o y o t a " ; "Carrey"; " B l u e " ; " 3 8 3 - 0 4 7 " ; "PA"; " 2 0 0 3 " ; " '
31;283;"Honda";"Civic";"Silver";"581-260";"NY";"2003";'
4J232; 1 7 6 ; " N i s s a n " ; "Maxima"; " R e d " ; " 8 1 7 - 9 0 0 " ; "NY"; " 1 9 9 9 " ; " '
5 | 2 3 4 ; 2 2 9 ; " f o r d " ; " E s c a p e " ; " R e d " : " 9 5 2 - 5 2 6 " ; "CT"; " 1 9 9 4 " ; " " ; '
35;227;"Honda";"CRV";"Red";"713-947";"PA";"1996";""; ""

I AJ
[ Далее > j | Готово

Рис. 1.12. Пример использования мастера Экспорт текста

Вообще-то экспорт и импорт данных в текстовом формате далеко не идеальны] i


выход из положения, особенно если ведется интенсивный обмен таблицами дан­
ных. Но куда хуже будет ситуация, в которой выгода будет потеряна вами именно
из-за того, что клиент не смог открыть вашу базу данных.
Появлением формата XML была подготовлена почва для облегчения обмена дан­
ными между различными версиями и системами. Этот формат довольно неплохо
поддерживается в Access 2003, в меньшей степени эта поддержка реализована
в Access 2002 и Access 2000. Если работа с текстовыми файлами больше не от­
вечает вашим запросам, вы всегда сможете применить XML, воспользовавшись
отдельным внешним XML-парсером (программой, предназначенной для ана­
лиза содержимого текстового документа, соответствующего спецификация
XML).
См. также « Обеспечение полного управления данными XML для любых версий Access ->
(Трюк № 87) и «Использование Access в качестве базы данныхXML» (Трюк № 95 I.
Трюк № 6. Наведение порядка в макросах и придание им большей значимости 31

Наведение порядка в макросах


№6 и придание им большей значимости
Оптимизация макросов путем сокращения их числа, использования дополнительных
имен и столбцов условий.
Считается, что управлять сложными процессами способна лишь программа, со­
ставленная на VBA, а макросы в основном являются средством решения весьма
простых задач. Пора избавляться от этого мнения. На самом деле макросы вполне
способны справляться с весьма объемными задачами, имеющими развитую логи­
ческую структуру, поскольку у них имеется столбец условий, то есть механизм
проверки, аналогичный структуре If . . .Then, имеющейся в VBA. В этом трюке
показан способ превращения единственного макроса в многоцелевой базовый ком­
понент приложения.

Условные макрокоманды
У макроса имеется единственный обязательный столбец: Макрокоманда. При этом
макрос может состоять из одной и более команд. Но у него есть также и дополни­
тельный столбец Условие, использование которого способно в значительной мере
увеличить эффективность всего процесса выполнения макроса. Для отображения
этого столбца в окне конструктора нужно воспользоваться меню Вид.
Проверяться на соблюдение условия может значение поля, результат, возвращае­
мый функцией, и даже значение, возвращаемое диалоговым окном. В условных
выражениях могут применяться и логические операторы, включая И-ИЛИ.
На рис. 1.13 показан макрос, при выполнении которого происходит ряд различ­
ных действий, часть из которых возможны только при соблюдении сопоставлен-

ЗапускПрограммы Подсчет суммарного значения


ЗапускПрограммы Получение заказов
Day(Now())«l 3-апускПрограммы Конец месяца, итоги
Day(Now())»l ОткрытьОтчет Конец месяца, отчет
ОткрытьОтчет Премии служащим, отчет
ОткрытьОтчет Износ оборудования, отчет
ОткрытьОтчет Финансовый отчет

Аргументы макрокоманды
*alc_earmricjs()

Столбец для задания условных


выражений.

Рис. 1.13. Пример использования условий в макрокоманде


32 Глава 1 . Использование ядра Access

ных с ними условий. Например, функция и отчет с одинаковыми пометками в при -


мечании Конец месяца включаются в процесс выполнения только в первый день ме­
сяца (возможно, для подведения итогов прошедшего месяца). Для определения фак­
та наступления первого дня месяца использованы функции Day и Now.
Отчет с пометкой в примечании Премии служащим будет запущен только в том
случае, если будут соблюдены условия, проверяемые с помощью функции DLookup.
Макрокоманды, не имеющие сопоставленных им условий, выполняются всегдг.
Даже если дойдет черед до такой макрокоманды, чье условие не будет выполненс,
макрос не станет на ней останавливаться, и процесс выполнения продолжится.

Создание группы макросов


Макросы могут быть объединены в группы, известные как группы макросов. Пу­
тем создания таких групп вы сможете сократить общее число макросов и собрат ь
в одном месте однотипные макрокоманды. Коренное отличие обыкновенного мак­
роса от группы макросов состоит в использовании дополнительного столбца Имя
макроса.
Для его появления в окне конструктора макросов вам следует воспользоваться
меню Вид. На рис. 1.14 показана группа макросов под названием ГенерацияОтчет;!.
Эта группа предназначена для выполнения задач по запуску нескольких отдель­
ных отчетов. Важно отметить, что эти отчеты не будут запускаться одновременно. За
каждым именем макроса скрывается отдельный макрос в составе большой группы.

Финансовый_отчвт ОткрытьОтчет
Состоянив^запасов ОткрытьОтчет
ЗапускПрограммы
Сообщение
Запуск 3anpocaSQL
Поетррный_заказ ОткрытьОтчет
ЗапускПрограимы
Продажи ОткрытьОтчет

Аргументы макрокоманды

Инн отчета Отчет об износе


Лросмотр
Имя фильтра
Условие отбора : Выберите имя открываемого отчета.
Режим окна Список содержит все отчеты базы
; даммых. Обязательмый аргумент. Для
справки об аргументе нажт*гте
клавишу F1

Рис. 1.14. Использование столбца Имя макроса

Когда нужно будет выполнить конкретный макрос, следует указать имя группы,
символ точки в качестве спецификатора и имя из столбца Имя макроса:
DoCmd.RunMacro "ГенерацияОтчета.Состояние_зanасов"
Выполнение макроса начнется со строки с его именем. Команды будут выпол­
няться до тех пор, пока не встретится следующее имя макроса. Еще одно преиму­
щество группы макросов состоит в том, что значение в столбце Имя макроса г е
Трюк № 7. Очистка базы данных от ненужного хлама 33
обязательно должно присутствовать во всех строках. В единую конструкцию по­
мещается любое количество небольших наборов макрокоманд. Преимущество
такой реализации макросов состоит в удобстве управления и упорядоченности.

S Очистка базы данных от ненужного хлама


Применение журнала использования объектов с целью очистки непомерно разросшей­
ся базы данных путем анализа действий пользователя и удаления невостребованных
объектов.
Некоторые приложения базы данных порой становятся монстрами. Если вам при­
ходилось когда-нибудь просматривать базу данных, содержащую несметное ко­
личество форм и отчетов, то вы поймете, что я имею в виду. Зачастую базы разра­
стаются в силу утраченной единой политики пользования: формы, созданные для
каждого случая и по любому поводу, отчеты на каждый день недели и множество
подобных вещей.
Ко всему прочему вы еще и не в состоянии сразу определить, какие из этих объек­
тов по-настоящему кем-то используются. Но способ навести порядок в приложе­
нии и избавиться от ненужного хлама все же есть.
Суть задачи сводится к выявлению невостребованных объектов. Пользователи
нередко создают формы и отчеты, о которых после однократного применения боль­
ше и не вспоминают. Обнаружив подобные объекты, вы сможете удалить их из
базы данных. Возможно, от этого приложение станет работать быстрее, а после
того, как вы проведете сжатие базы данных, снизится загруженность оператив­
ной памяти. Для выполнения этого замысла потребуется создать список исполь­
зуемых объектов, а затем удалить объекты, не вошедшие в этот список.

Отслеживание востребованности объектов


У каждой формы или отчета есть событие под названием Открытие. Поместив
в строку обработки этого события вызов несложной функции, вы сможете вести
журнал, содержащий имена открываемых объектов. Вначале нужно создать для
этого журнала таблицу, в которую будут заноситься имена объектов. Сложности
здесь ни к чему, но хотя бы одно поле для размещения имен все же понадобится.
К нему можно добавить поле с отметкой времени открытия, поле с типом объекта
и т. д.
На рис. 1.15 показана структура такой таблицы. Одно ее поле предназначено для
имени объекта, а другое — для его типа. Как только будет открыт какой-нибудь
новый объект, в таблицу будет добавлена запись.
Для того чтобы запись добавлялась в таблицу, объект должен содержать неболь­
шую процедуру обработки события Открытие. Следующий фрагмента кода можно
применить для обработки события открытия формы Клиенты:
Private Sub Form_0pen(Cancel As Integer)
Dim conn As ADODB.Connection
Set conn = CurrentProject.Connection
Dim ssql As String
ssql = "Insert Into ^1Журнал_объектов Values ('Клиенты1, 'Форма')"
34 Глава 1. Использование ядра Access

нал .объектов : габчица


№тполя '" Т Типда—»х
ИмяОбъекта • Текстовый
ТипОбЧекта ;Текстовый

°бщие Постановка
I Размер поля ISO
| Формат поля
щ Маска ввода
1 Подпись
Щ Значение по умолчанию ••". ' : Кео6шатвпьный
:• Условие на значение : параметр, выводится е
СТРОКУ теСТОДММЯпрн
ц Сообщение об ошибке : выбора попя е фдачй, дл!
• Обязательное поле •Нет : справки ПС опксяжиз пел*
щ Пустые строки :Да : нажмите клавишу F i .
|| Индексированное поле •Нет
Щ Сжатие Юникод !Да
:i Режим IME |Нет контроля
'•• Режим предложений IME Нет
: Смарт-теги

Рис. 1.15. Таблица для протоколирования открытий объектов

conn.Execute ssql
conn.Close
Set conn = Nothing
End Sub
В момент открытия формы в журнал будет добавлена запись, содержащая имч
формы и тип объекта. Подобный код нужно поместить в обработчики событи л
открытия всех форм и отчетов. Через некоторое время использования базы дай -
ных посмотрите, как проходит заполнение журнала. По прошествии определен -
ного времени — скажем, недели или месяца, в зависимости от того, какой срок вам
покажется достаточным, — изучите журнальную таблицу. Перед вами откроется
множество записей. Если вы не создавали поле регистрации времени, то вы сто/ -
кнетесь с множеством одинаковых записей. Для просмотра результата, исключа­
ющего дубликаты, вам следует воспользоваться запросом, в котором использует­
ся групповая операция Group By.

Выявление невостребованных объектов


На рис. 1.16 показан выполненный запрос на основе данных таблицы Журнал.,
объектов. В данный список попали только те объекты, которые открывались пользо­
вателями. Вам нужно сравнить этот список с полным перечнем форм и отчето з,
имеющимся в базе данных, после чего можете безо всякой опаски удалить не по­
павшие в этот список объекты, при условии, если вы уверены в том, что по про­
должительности исследованный вами период времени был вполне достаточен для
этого. Да, и не забудьте после удаления сжать базу данных!

Трюк в трюке
Частью данного трюка является добавление кода обработки событий открытг я
всех форм и отчетов. Добавлять код вручную — весьма нудное занятие. Однако
эту работу можно автоматизировать. Следующий пример кода предназначен д;:я
Трюк № 7. Очистка базы данных от ненужного хлама 35
цгуЖурнй1_о6ърктпв итоги : запрос > ,|Гн»рку
ИмяОбъеш . • ] .ТипОБьекта |[
• Администрация Форма
Клиенты Форма
Клиенты по регионам j Форма
1... Главная форма Форма
Стимуляция торговли
:•:;:•;; Форма
Клиенты по продажам Отчет
Уволенные служащие Отчет
Продажи по регионам 1 Отчет
:
Отгрузки Отчет

* •ятшшжжжЛ

Рис. 1.16. Перечень востребованных объектов базы данных

внесения изменений в обработку событий открытия всех отчетов, и м е ю щ и х с я


в базе данных:
Public Sub insert_open_report_event( )
' !! Перед запуском следует закрыть все запущенные отчеты !!
Dim rpt As AccessObject
For Each rpt In CurrentProject.AllReports
DoCmd.OpenReport rpt.Name. acViewDesign
With Reports(O).Module
On Error Resume Next
open_proc_start = .ProcBodyline("Report_Open", vbext_pK_Proc)
If Error <> 0 Then
'Если обработчик отсутствовал, он будет создан
Err.Clear
open_proc_start = .CreateEventProc("Open", "Report")
End If
.InsertLines open_proc_start + 1, _
"Dim conn as ADODB.Connection"
.InsertLines open_proc_start + 2, _
"Set conn =CurrentProject.Connection"
.InsertLines open_proc_start + 3, _
"Dim ssql as String"
.InsertLines open_proc_start + 4, _
"ssql = ""Insert Into ^1Журнал_объектов ValuesC" & _
Reports(G) .Name & "', 'Отчет')
.InsertLines open_proc_start + 5, _
"conn.Execute ssql"
.InsertLines open_proc_start + 6, _
"conn.Close"
.InsertLines open_proc_start + 7, _
"Set conn = Nothing"
End With
DoCmd.Close acReport, Reports(0).Name, acSaveYes
Next
MsgBox "Изменения внесены во все отчеты"
End Sub
Эта процедура работает с программными модулями отчетов. Фактически мы имеем
дело с кодом VBA, который создает такой же код VBA! В процессе работы проце­
дуры каждый отчет открывается в режиме конструктора, после чего в его про­
граммный модуль вставляется новый фрагмент кода. Вы можете создать подоб­
ную процедуру и для форм — для этого нужно будет вместо AllReports обратиться
к коллекции AllForms.
36 Глава 1 . Использование ядра Acce;is

ТРЮК Защита ценной информации


№8 Защита данных с использованием переключателя командной строки «только для чте­
ния», не позволяющим пользователям вносить какие-либо изменения.
Создание на Рабочем столе ярлыка для базы данных открывает новые, малоизвест­
ные возможности. В частности, вы можете скрытно использовать переключатели ко­
мандной строки, и обнаружить факт их использования сможет далеко не каждый.
Используя этот прием, можно легко настроить ярлык на запуск базы данных в ре­
жиме «только для чтения» и защитить таким образом ваши данные и описания
объектов. Осуществляется все это добавлением в свойствах ярлыка в конце стро­
ки поля Объект переключателя /го. Учтите, что полная строка, указывающая на
запускаемый объект, в данном случае содержит не только указание пути к прило­
жению базы данных. Она должна начинаться с указания пути к исполняемому
файлу Access, затем должен следовать путь к приложению базы данных, а у» е
после него должен указываться переключатель командной строки.
Применительно к Access 2003, который по умолчанию обычно находится в ката­
логе Program Files/Microsoft Office/Office 11, полная строка указания на объект будет
выглядеть следующим образом:
"C:\Program F i l e s \ M i c r o s o f t Office\OFFICEU\MSACCESS.EXE"
" C : \ S a l e s Summaries\Sales2005.mdb" / г о
После щелчка на ярлыке Рабочего стола база данных откроется в режиме «только
для чтения». При запуске будет выведено подтверждающее сообщение, представ­
ленное на рис. 1.17. Добавление, удаление или изменение данных в таком режиме
работы будет невозможным.

• / База даннык "Sales'доступна только для чтения.

^f Невозможно сохранение измененных данных или описаний объектов е этом базе дзь

Рис. 1 . 1 7 . Напоминание о работе в режиме только для чтения

Данный способ хорош для распространения информации без опасений за целост­


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

И все же, на всякий случай


Разумеется, некий сообразительный пользователь может просто запустить испол­
няемый файл Access и открыть базу данных, воспользовавшись диалоговым ок­
ном Открытие файла базы данных, проигнорировав, таким образом, созданный ш
Рабочем столе ярлык. После чего база данных будет открыта в режиме работы
безо всяких ограничений, если только на это случай не предусмотрена какая-ни­
будь хитрость.
Справиться с проблемой поможет простая операция вставки данных SQL Insert,
помещенная в процедуру, вызываемую при открытии базы данных. Для обеспе-
Трюк № 9. Работа с данными любого объема 3 7

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

! Microsoft Office Access

&аза данных открывается с помощью ярлыка на Рабочей стопе

Рис. 1 . 1 8 . Предупреждение при попытке обойти использование ярлыка на Рабочем столе

Код процедуры
Процедура, проверяющая возможность вставки данных командой SQL Insert:
Public Function test_mode( )
On Error GoTo err_end
Dim conn As ADODB.Connection
Set conn = CurrentProject.Connection
Dim ssql As String
ssql = "Insert Into tblModeTest Values ('test')"
conn.Execute ssql
conn.Close
Set conn = Nothing
'если выполнение процедуры дошло до этого места,
'база данных не находится в режиме только для чтения
'предупреждаем пользоватепя и выходим из приложения
MsgBox "База данных открывается с помощью ярлыка на Рабочем столе"
DoCmd.Quit
E x i t Function
err_end:
'все в порядке, попытка вставки данных не удалась
End F u n c t i o n
А вот в чем заключается суть этой уловки: предполагается, что база данных долж­
на быть открыта в режиме «только для чтения», поэтому оптимальный результат
будет при неудачной попытке записи. При этом программа перейдет к метке об­
работчика ошибки. Если все так и произойдет, значит, все в порядке и никакие
действия предприняты не будут. Если вставка будет успешной, на экран будет
выведено предупреждение и база данных будет закрыта командой Quit. Эта про­
цедура должна быть вызвана в макросе AutoExec, тогда она будет выполнена сра­
зу же после открытия базы данных.

Т Р Ю К Работа с данными любого объема


№9 Проектирование архитектуры, состоящей из нескольких баз данных и предназначенной
для работы с любым объемом данных, вплоть до гигабайтов и даже терабайтов!
Единственное ограничение на объем информации в Access относится к таблицам,
в которых не может содержаться более 1 Гбайта данных. Даже если это и так, то
все возможности еще далеко не исчерпаны. Разумеется, Access способна справиться
38 Глава 1 . Использование ядра Access

с громадными информационными объемами, но вопрос не в этом. Если в следую­


щем году на вашем рабочем месте не собираются устанавливать SQL Server или
Oracle, то вы можете воспользоваться преимуществами гибкости архитектуры
Access, позволяющими оперировать любыми объемами данных.
Для этого нужно придумать такую структуру данных, в которой они будут рас­
пределены по разным таблицам и файлам базы данных. Не существует правила,
по которому приложение Access должно полностью размещаться только в одном
файле. Оно может быть разделено на интерфейсную и прикладную части. То есть
формы, отчеты и запросы будут находиться в интерфейсной части, а сами данные
будут помещены в отдельный файл прикладной части. Затем таблицы с данными
будут связаны с интерфейсной частью. На рис. 1.19 показан такой стандартный под­
ход, являющийся, по сути, простейшим примером клиент-серверной архитектуры.

Запросы
Формы Данные
Отчеты
Макросы
VBA

Рис. 1.19. Простейшая конфигурация, состоящая из интерфейсной и прикладной частей

Распределение данных
Содержать всю прикладную часть в одном-единственном файле нет никакого
смысла. Как именно разбить данные по частям, подскажет их фактическая струк -
тура. Например, если вы работаете с огромной базой клиентов, то можете разбит],
ее на несколько таблиц по количеству букв алфавита, с которых начинаются фа­
милии клиентов. Подобная конфигурация данных показана на рис. 1.20.
Вы можете также разбить список клиентов по городам, областям и другим гео­
графическим признакам. Опять же, получившиеся слишком большие наборы дан -
ных вы можете разбить на более мелкие наборы (благо букв в алфавите достаточно).
Вся суть данного трюка и состоит в разбиении данных на части. Вам нужно хоро­
шенько проанализировать имеющиеся данные и выработать соответствующий за­
мысел. Возможно, данные будут связаны с календарными датами. Тогда их мож­
но будет разбить по месяцам, дням или по другим имеющим смысл признакам.

Работа с распределенными данными


У распределенных данных есть одна неприятная особенность. Когда данные разби -
ты на несколько таблиц, теряется простота установки их связей с другими табли -
Трюк № 10. Ускорение поиска объектов базы данных 39

Файлы прикладной части

Рис. 1.20. Использование в прикладной части нескольких баз данных

цами. К примеру, у вас главная таблица клиентов связана с таблицей покупок. Вы


разбиваете таблицу клиентов на десять маленьких таблиц. Что тогда станет со
связями? Обойти данную проблему можно двумя способами.
Первый способ предусматривает связь таблицы покупок со всеми десятью табли­
цами клиентов. Второй вообще не предусматривает использования связей, а вза­
мен проводит скрытую обработку данных, каждый раз сопоставляя их в соответ­
ствии с теми условиями, которые задаются в интерфейсной части приложения.
Не так уж все и сложно, как может показаться на первый взгляд. В двух словах,
VBA и ADO работают вместе, выискивая соответствия клиентов и покупок по
заданному в интерфейсной части приложения критерию поиска. Реальный под­
ход к поиску соответствующих товаров заключается в создании на основе таблицы
товаров набора записей или массива записей и в последующем поиске соответ­
ствий ключевым полям во всех десяти таблицах. Конечно, это не самый впечатля­
ющий и далеко не самый эффективный способ обработки данных, но такова цена
успешной работы Access с гигабайтными объемами данных.

ТРЮК Ускорение поиска объектов базы данных


№10 Использование описаний в свойствах форм, запросов и отчетов, избавляющих пользо­
вателей от необходимости разгадывания значений их имен.
Многие придерживаются соглашения, касающегося присвоения имен при созда­
нии объектов базы данных. В сообществе разработчиков выработано соглашение,
в рамках которого считается само собой разумеющимся использование префик­
сов tbl, frm, rpt и им подобных. Это считается неотъемлемой частью работы по
созданию приложений. Например, имя tblStaff принадлежит таблице, frmAdmin —
форме, a rptContacts — отчету.
40 Глава 1 . Использование ядра Access

Однако после того как разработка базы данных, состоящей из ряда объектов, т -
званных в соответствии с существующим соглашением, будет завершена, рядовс -
му пользователю будет нелегко разобраться в именах объектов. На рис. 1.21 покг -
зан типичный пример базы данных, содержащей несколько форм.
Но существует способ выхода из этого затруднительного положения, не затраги­
вающий привычной для разработчиков системы присвоения имен. Каждому объеь •

0Примеры'. базА -;яш'1


- " " • : • : . ; | Создать } >'• '; * £ '„:-• ;".;: ;;!|||.] .

| j Объекты Имя j Описание \ Дата изменения '• Дата с;


j 3, таблицы ЬдУ :Создание формы в режиме конструктора \
1
; j$ Запросы
|У Создание формы с помощью мастера |j
j 5§ f гтАдминистрация 28.10.2005 19:43:05 28.10.Ц
:
Ш ггтЖурналПродаж 28,10,2005 19:43:18 28.10.11
I Ш Отчеты L$ frm3anBKH 28.10.2005 19:43:32 28.10.1
; * > | Страницы •JS тгтИнвестиции 28.10,2005 19:43:45 28.10.|ij
'JJk ггтКлиемты 28.10,2005 19:43:57 28.10.$
1 Ш Макросы
-.Ш ^Контакты 28.10.2005 19:44:09 28.10.1
-ij ^тНовыеКлиенты 28.10.2005 19:44:22 28.10.14
Группы lSi г^глОтчеты 28,10.2005 19:44:32 28.10.||
j jy Избранное •Jag ГгтЛоставщики 28.10.2005 19:44:43 28.10.1
51 ггтТекущиеПродажи 28.10.2005 19:44:54 28.10.3iM
.:& ггтЭкспортныеПоставки 28.10.2005 19:45:05 28.10,1 j
Ш ГгтЮридическиеЛица 28.10.2005 19:45:16 28.10.| 1
1 'Ш 5иЬ*гтОрганизации 28.10.200519:45:28 26.10.2 j
:
SM виЬ^тПостаещикиКонтакты 28.10.2005 19:45:40 28.10.|i
•Ш 5иЬ?гтПродукцияПоставщиков 28.10.2005 19:45:52 28.10.1: |

:;.:.;:::::;;:..< ; > \ 1:

Рис. 1 . 2 1 . Непонятные имена форм способны запутать пользователя

• : - ./;
^ О т к р ы т ь S^!<OMC труктор _^Со>дат Е ! X : лй ",- Н ' : [ Щ ] '

Объекты ! Имя I Описание I Дата изменения Дата с Ч


3 Таблицы : lgj Создание фо УМЫ в режиме конструктора
^J Создание фо Свойства: ПтА.ад+икиетрациа ^
3 Запреты
^8 ггтАдминист 28.10; 1
/Ш Формы | Общие •;'"..

Щ Отчеты Я ^тЗаявки .." т^ i f гтАдминистрация !l0.2005 19:43:32 28.10.; 1


%j| Страницы : ij[ ггтИмеестицч -— ч -.---. - ••--.-- 1 J10.2O05 19:43:45 28.10.; ;i
I '^3 птпКлиенты ; Тип: Форма 26.10.; s
Ш Макросы Описание: j эта форма предназначена для Юлии и Игоря
: ^М frmKoHTaKTb 110.2005 19:44:09 28.10 1}
;
^ frmHoBbieKm J10.2005 19:44:22 28,10,; 5
Группы :& ггтОтчеты 10.2005 19:44:32 28.10! j
:'$% Избранное \ Ш frmTlocTaBim
Создам; 28.10.2005 19:43:05 10.200519:44:43 28.10.; is
: '^3 ^тТекущиеГ . Изменен: 28.10,2005 19:43:05 10,2005 19:44:54 28.10 i si
I uSi ггтЭкспортн j Владелец; Admin
И i Атрибуты: ["} скрытый
10,2005 19:45:05 28,10.; :i
I дЗ« ^тЮридичее 10,2005 19:45:16 28.10.; si

Ч : . J I subfrmOpraH
JJS subfrmTlocTaf
J10.2005 19:45:28
J10.2005 19:45:40
28.10.:
28.io.;:s
jj& ьиЬ^гтПроду Отмена j : При(^енкть j J10.2005 19:45:52 28.10 Л

>
,.„...,.,.....:

Рис. 1.22. Ввод описания


Трюк №11. Использование связующей таблицы 41

ту базы данных может быть дано описание. При этом его можно ввести, не откры­
вая объект в режиме конструктора.
Для этого нужно в окне базы данных щелкнуть правой клавишей на значке объек­
та и в появившемся меню выбрать пункт Свойства. Для ввода описания, состав­
ленного из обычных слов, откроется небольшое диалоговое окно, показанное на
рис. 1.22.
После ввода описаний для всех объектов нужно будет изменить форму представ­
ления списка объектов и перейти от значков к таблице. Тогда в списке появятся
описания. На рис. 1.23 показано, как набор форм, отображенный выше на рис. 1.21,
приобрел вполне понятный вид.

Примеры ft.iw гниньп (форм • Access ЮОО)


• :,
;^Ьт.кры1Ь ^ ^ С Т Р У К Т О Р ЛСОЗДЭ

Объекты
! 'та! Создание формы в режиме конструктора
I ^ Создание формы с помощью мастера
• Ш ^Администрация Эта форма предназначена для Юлии и Игоря 28.10.200:.
j 7Ш ^тЖурналПродаж Просмотр всех продаж 28.10.200j
i 'Ш птпЗаявки Используется для составления заявок 28.10.20о|
! ^ РгтИнвестиции Обзор инвестиций 28.10,200.;
/Щ ггтКлиенты Просмотр и изменение информации о клиентах 28.10.200f:
; ^ ггтКонтакты Используется для контактов, не связанных с продажами 28.10.200;:
:
; 22S ггтНовыеКпиенты Используется для ввода данных о новых клиентах 28.10.200
! Ш ^тОтчеты Выбор отчета 28,10.200 :
• 'Ш "тпПоставщики Просмотр и изменение информации о поставщиках 28.10,200
; ~3 п-тГекущиеПродажи Просмотр продаж текущего квартала 28.10.200
\ 'JMI ^гтЭкспортныеПоставки Обзор экспортных поставок 28.10.200
| Щ ?гтЮридическиеЛица Форма только для офиса организации 28.10.200
; *л!1 5иЬггтОрганизации Не открывать! 28.10.200
.'^Ш виМгтПоставщикиКонтакты Не открывать! 28.10.200;
Не открывать! 28.10.200 !•;

I1&L iiiiiliiailtiii;;— У::Ж«ШШ':

Рис. 1.23. Выбор форм по описаниям

Кроме всего прочего, данный подход дает возможность предупредить пользова­


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

Ш Использование связующей таблицы


Правильное моделирование отношения многие-ко-многим

Впасть в заблуждение, что все связи между таблицами относятся к типу один-ко-
многим, довольно легко. Действительно, многие данные связаны между собой
именно по такому образцу. К примеру, один человек может вообще не иметь ни
одного телефонного номера или иметь множество таких номеров. Однако не все
данные подпадают под эту модель.
42 Глава 1 . Использование ядра Access

Взаимоотношения студентов с преподавателями могут послужить неплохим при­


мером того, как данные, на первый взгляд укладывающиеся в модель отношений
один-ко-многим, на самом деле не соответствуют такой схеме отношений. С од­
ной стороны, у одного преподавателя может быть много студентов, что доказыва­
ет существование отношения один-ко-многим. С другой стороны, и у студента
может быть много преподавателей, что также подпадает под модель отношенг я
один-ко-многим. Казалось бы, в чем тут проблема?
На рис. 1.24 показан один из вариантов схемы отношений преподавателей и сту­
дентов. Таблице Преподаватели принадлежит метка «единица», а таблице Студе •-
ты — метка «бесконечность». Преподаватели и студенты собираются вместе на за­
нятия. При всей состоятельности данной модели из нее следует, что преподавате/ и
и студенты находятся на разных уровнях, что на самом деле не соответствует дей­
ствительности.

СтудентФИО \оо :3амятие10


^ " " СтудентЮ
;ЗанятиеДень
;ЗанятиеЧас

Рис. 1.24. Неподходящее отношение один-ко-многим

На рис. 1.24 таблице Студенты в качестве внешнего ключа требуется поле Пре-
подавательЮ. Это вполне приемлемо, но, судя по связям таблицы Занятия, к заня­
тиям причастны только студенты, а на самом деле к ним имеют отношение и пре­
подаватели.
На рис. 1.25 показано решение этой проблемы. Поскольку к занятиям имеют от­
ношение и преподаватели и студенты, схема должна быть построена именно так.
Таблица Занятия выступает в роли связующего звена между преподавателями
и студентами.
Связующая таблица становится общей для двух или более таблиц. Все ключев ле
поля отдельных таблиц становятся внешними ключами связующей таблицы, ко­
торая может содержать любые другие подходящие по смыслу поля. В данном пр и-
мере у связующей таблицы имеются поля для размещения дней й часов занятий,
на которых будут встречаться преподаватели и студенты. Теперь в таблице Сту­
денты уже нет внешнего ключа ПреподавательЮ, а между студентами и преподава­
телями не существует никакой подчиненности, в соответствии с чем отсутствует
и взаимные связи один-ко-многим.
Трюк № 12, Сдерживание базы данных от непомерного разрастания 43

ма данных

« ; : , •
I
ПреподавательЮ —\ ,'шш
СгудентГО
Преподават ельФИО / :СтудентФИО
^уОО
;ПреподаватепьШ
|СтудеитЮ W
•ЗанятиеДеиь
|ЗанятиеЧас

:.:>
Рис. 1.25. Более удачная схема данных

Сдерживание базы данных


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

тры
Международные Проверка о ш и б с ч с ^ О р ф о г р а ф и я Таблицы и запросы
е . Правка и поиск Клавиатура Режии таблицы Формыиотчеты \ Страницы

• ^аНИЦЫ Л4Ч4ГИ0Г0 Формат года из четыре* цифр

левое поле: f j текущая база данных


f' J всв базы данных
правое поле: 2,54сн
верхнее поле:
нижнее поле:
ш
2,54см
мбГУ^МЙНЗ ИНОМ

[•^отслеживать автозамену имен


"""

Г^;выполмять автозамену имен


gjj Помнить, список файлов: j4 [ 3 журнал изменений автозамвны имен
L.i Звуковое сопровождение событий Порядок сортировки базы данных:
[*^£жимать при закрытии :
Уииверсапьный
р-| У_далять личные сведения из свойств файла при
I—•• сохранении
Рабочий каталог:
•D:\Documents and Settrngs\HnKOflaii\Mon докуменТы\

(Параметры ееб-документа : Параметры служб.

Рис. 1.26. Установите флажок Сжимать при закрытии


44 Глава 1 . Использование ядра Acces:;

и ни к чему, поскольку система Access способна сжимать базу данных в процесс?


завершения своей работы. Такая функция отсутствовала в ранних версиях систе­
мы, но она доступна в Access 2002 и Access 2003.
На рис. 1.26 показано диалоговое окно Параметры (Сервис • Параметры) с откры­
той вкладкой Общие. Обратите внимание на флажок Сжимать при закрытии.
Access отличается от других систем управления базами данных, таких как SQL
Server, тем, что не дает возможности регулировать размер самой базы. Установк \
флажка, позволяющего сжимать базу данных при каждом завершении работы
с ней, устраняет эту извечную проблему Access.
Г Л А В А 2

Таблицы
Трюки № 13-18

Известно, что без таблиц данные хранить было бы негде. Но какие могут быть
трюки с таблицами, если их структура предельно проста? Все, что в них есть, —
это строки и столбцы, или, соответственно, записи и поля.
Тем не менее даже незначительные настройки конструктора таблиц могут сыг­
рать весьма заметную роль.
Изменив значения по умолчанию, установленные для различных типов данных,
и ряд других свойств, вы сможете ускорить разработку приложения. Без вашего
вмешательства длина текстовых полей будет устанавливаться по умолчанию в
50 символов. Хорошо это или плохо — зависит от конкретного проекта.
Может быть, вам хочется использовать триггеры по примеру SQL Server? Пожа­
луйста! При помощи встроенных в формы событий вы добьетесь тех же результа­
тов. Вам нужно скрыть данные? Для этого тоже найдется подходящий трюк!

Ш Создание поля счетчика с произвольным


начальным значением
Полю счетчика совсем не обязательно иметь начальное значение, равное единице.
Вы можете изменить исходную схему автонумерации Access, приспособив ее под
ваши нужды. Поле счетчика — весьма ценный вклад Access в процесс создания
таблиц. В поле этого типа для первой записи устанавливается значение 1, которое
затем автоматически увеличивается на единицу для каждой последующей добав­
ляемой записи. Ничего более сложного или значительного в этом поле не содер­
жится. Его основное предназначение — служить ключевым полем и обеспечивать,
таким образом, уникальность каждой записи.
Вставьте поле в структуру таблицы и определите для него тип данных Счетчик.
Обычно полю этого типа присваивается имя с пометками, отражающими его на­
значение, — ID или Num, скажем, КлиентЮ или 3anncbNum. Учтите, что в таблице
может быть только одно поле счетчика.
46 Глава 2. Таблица

Тем не менее при всех положительных качествах у этого поля есть один недоста­
ток: его начальное значение всегда равно единице. В большинстве случаев про­
блем не возникает, поскольку совсем не важно, какое именно значение имеет это
поле. Главное, что это значение уникально. Ну а если вам нужно иметь возраста­
ющую автонумерацию с произвольным начальным значением, возможно ли та­
кое? Конечно возможно!

Начало автонумерации с числа по выбору


У поля с типом данных Счетчик отсутствует свойство, в котором можно было бы
задать начальное значение. На рис. 2.1 показан конструктор таблиц. Нетрудно
заметить, что первое поле таблицы — это поле счетчика, и присущие ему свойстг а
вводятся в левой нижней части окна конструктора таблиц. Заметьте, что началь­
ное значение счетчика вводить просто некуда.

INSERT INTO Служащие ( СлужащийЮ )


VALUES (100);

Рис. 2.1. Счетчик, поле с автонумерацией

Если быть точнее, то таблица имеет свойство Новые значения, но в нем лишь зада­
ется способ формирования нового значения — либо оно будет приращением пре­
дыдущего, либо будет выбрано случайным образом. В этом свойстве никак не от­
ражается выбор начального значения автонумерации. Поэтому первой записи
будет присвоен номер 1, второй записи — номер 2 и т. д.
Чтобы подавить начальное значение по умолчанию, нужно воспользоваться за­
просом на добавление и вставить другое начальное значение. После создания таб­
лицы в нее нужно поместить начальное значение. На рис. 2.2 показан запрос на
добавление, предназначенный для присвоения значения полю счетчика. В резуль­
тате его выполнения к таблице будет добавлена запись, в которой полю счетчиь а
будет присвоено указанное значение.

INSERT INTO Служащие ( СлужащийЮ )


VALUES (100);

Рис. 2 . 2 . Использование запроса для указания начального значения счетчика

Заметьте, что этот запрос следует открывать в режиме SQL, поскольку непонят­
но, как то же самое можно было бы сделать в режиме конструктора (с использова­
нием сетки построения запроса), в котором обычно составляются запросы на до­
бавление данных одной таблицы к данным другой. Мы же добавляем значение к
полю таблицы, не используя какую-нибудь другую таблицу (в крайнем случге
вы, конечно, можете включить в конструкцию другую таблицу с нужным вам зна­
чением, но вряд ли стоит так делать).
Трюк № 13. Создание поля счетчика с произвольным начальным значением 47

На рис. 2.3 показан результат выполнения запроса на добавление. Пустовавшая


ранее таблица Служащие приобрела свою первую запись со значением счетчика,
равным 100.

Рис. 2.3. Первая запись с указанным начальным значением счетчика

Заметьте, что все остальные поля остались пустыми. Если нужно заполнить зна­
чениями и другие поля, то в запрос следует внести соответствующие указания.
Например, можно изменить запрос и заполнить еще и поля Служащий и Должность:
INSERT INTO Служащие (СлужащийЮ, Служащий, Должность)
VALUES (100, "Кузнецов Иван Иванович", "Контролер");
На рис. 2.4 показан результат выполнения обновленного запроса. На первый взгляд
нам удалось убить сразу двух зайцев — запустить счетчик с требуемого начально­
го значения и не использовать при этом запись-пустышку (изображенную на
рис. 2.3). Тем не менее такой подход не вполне корректен. Вряд ли стоит запол­
нять таким образом первую запись, учитывая, что все последующие записи будут
заполняться либо из формы, либо по результатам обработки данных, либо иным
способом. Дело в том, что не принято заполнять первую запись каким-то спосо­
бом, отличающимся от способа заполнения всех остальных записей.

Рис. 2 . 4 . Использование запроса для заполнения поля счетчика вместе с другими полями

Но как тогда можно инициировать счетчик нужным значением без записи-пус­


тышки в таблице? Выход из положения заключается в таком же заполнении пер­
вой записи с использованием запроса, но с присвоением счетчику значения, на
единицу меньше требуемого. Затем можно будет удалить эту запись, а счетчик
будет увеличен на единицу при добавлении следующей записи. А это значит, что
у первой настоящей записи, введенной предназначенным для этого способом, бу­
дет требуемый номер счетчика. Затем, как и ожидалось, этот номер будет возра­
стать с каждой новой записью.
В нашем примере запрос должен добавить в таблицу единственную запись, в ко­
торой полю счетчика будет присвоено значение 99. Эта запись затем будет удале­
на (неважно, как: вручную или каким-нибудь другим способом). Когда будет до­
бавлена первая по-настоящему нужная запись, значение поля счетчика у нее будет
равно 100.
48 Глава 2 . Таблицы

Трюк в трюке
Вы можете переключить исходное значение счетчика когда угодно. Это не повлс -
чет за собой изменений существующих записей, но нумерация новых начнется
с нового исходного значения. Для этого нужно всего лишь выполнить запрос на
добавление, подобный показанному на рис. 2.2 (настроенный, как это уже объяс -
нялось, на соответствующие значения и поля), но при этом новое исходное значе­
ние счетчика должно быть больше самого большого из имеющихся в таблиц!;.
Например, если у последней введенной записи было значение счетчика 220, нуж­
но переключить значение на какое-нибудь еще большее число. Понятно, что сле­
дующее за ним число будет пропущено, иначе и не стоило бы затевать счет с ново­
го исходного значения.
При этом открывается новая возможность управления данными. Можно придать
группам записей в таблице не вполне очевидный, но все же родственный атрибут.
Например, вы можете переключать исходное значение счетчика в начале каждого
года. Тогда данные будет легко отличить друг от друга по годам. К примеру, все
записи, относящиеся к 2005 году, будут нумероваться в диапазоне 5000-599!),
а записи 2006 года получат номера из диапазона 6000-6999 и т. д.

Копирование данных из одной таблицы


в другую без использования запроса на
добавление
Использование добавления из буфера для упрощенного копирования данных между
таблицами.
Для добавления данных из одной таблицы в другую пользователи Access часто
применяют запрос на добавление. В производственной среде, в условиях посто­
янного обмена данными, использование запросов на добавление становится ру­
тиной. Всякий раз при составлении нового запроса требуется сопрягать поля ис­
ходной и целевой таблиц. Хорошо, когда поля названы одинаково, но если это не
так, приходится выполнять операцию вручную.
Если запрос составлен и сохранен, а исходная и целевая таблицы имеют неизмен­
ную структуру, проблем не возникает. Но если в именах полей случайно будет
какой-нибудь лишний или пропущенный символ, запрос либо не будет выпол­
нен, либо станет требовать ввода значения для каждого неопознанного поля. И в а
ничего не сможете с этим поделать.
Как все же справиться с подобной ситуацией? Хорошо, что существует другой
способ копирования данных между таблицами: с помощью команды Добавить из
буфера.

Добавление записей из одной таблицы в другую


Система Access обладает уникальным методом вставки — команда Добавить из бу­
фера позволяет добавлять содержимое буфера обмена к таблице базы данных.
Данные должны совпадать по структуре, но совпадения имен полей при этом т е
Трюк № 14. Копирование данных без использования запроса на добавление 49

требуется. Согласитесь, такой способ намного лучше, чем утомительный ввод дан­
ных в сетку построения запроса. Надо отдать должное и запросам на добавление:
у них есть одно весомое преимущество — использование условий добавления по­
зволяет добавлять записи из какого-нибудь набора выборочно. В отличие от это­
го добавить из буфера можно только все подряд. Тем не менее, если выборка не
нужна, добавление из буфера имеет явное преимущество.
На рис. 2.5 показаны две таблицы, одна из которых содержит сведения о состояв­
шихся клиентах, а другая — о потенциальных, которые нужно добавить к таблице
состоявшихся. Записи таблицы т.Ы_Потенциальные_клиенты подлежат добавлению
к записям таблицы г.Ы_Клиенты. Назначения и типы полей обеих таблиц, в отли­
чие от имен, совпадают.

•';:• £<зйлV^QpaBKa . £ид Вставка : Форцат • Записи Сервис ^кно : .':£праека. 1Ч-(\«-:т-гг::опр<х »•

Ш :,:МММ,ЛЖ • ,:•: .,! :&Ш}АШШЖ йШММША;Ш Ш

Рис. 2 . 5 . Добавление схожих данных из одной таблицы в другую

Проще всего выбрать все записи в таблице т.Ы_Потенциал ьные клиенты (Ctrl+A), ско­
пировать записи, перейти к таблице 1:Ы_Клиенты и воспользоваться командой
Правка • Добавить из буфера (рис. 2.6).
Заметьте, что при добавлении записей не нужно беспокоиться об именах полей.
Тем не менее есть еще более простой способ, при котором таблицу, содержащую
добавляемые записи (в данном примере это т.Ы._Потенциальные_клиенты), откры­
вать не обязательно! Нужно просто выделить и скопировать закрытую таблицу
прямо в окне базы данных. Затем нужно открыть таблицу, предназначенную для
50 Глава 2. Таблиц DI

добавления записей (в данном примере это г.Ы_Клиенты), и, как и раньше, выбрать


пункт меню Добавить из буфера.

!: Режим таблицы NUM

Рис. 2 . 6 . Использование команды Добавить из буфера

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

Добавление записей из одной базы данных в другую


Прием, рассматриваемый в этом трюке, работает не только в отдельно взятом при­
ложении базы данных, он также позволяет переносить данные из одной базы дан­
ных в другую. То есть вы можете выбрать и скопировать записи из таблицы одной
базы данных, а затем вставить их в таблицу другой базы данных. Разумеется, для
этого обе базы данных должны быть открыты.
На рис. 2.7 показаны две базы данных, расположенные рядом на Рабочем столе.
Таблицу г.Ы_Потенциальные_клиенты из базы данных, отображенной слева, надо
просто перетащить в открытое окно таблицы т.Ы_Клиенты базы данных, отобра­
женной справа. Таблица т,Ы_Потенциальные_клиенты будет скопирована, а не пере­
мещена, при этом ее оригинал в первой базе данных останется нетронутым. Для
завершения операции добавления записей клавишу мыши следует отпустить.
Трюк № 15, Исключение системных таблиц из обработки 51
•. Mir m^Qft Arcen - [1 Ы_К я«е нты ' тав i«t»a] Щ Щ Щ Р
- -ч*
»йл ;-.;ораек:а';. gna.- Вставка CsPfeK '.: 'ZJ''Файл.; • Qpaa<\5 ;:Внд :: Вставка Формат Далией : Сервис • Сжно . Справка . в х:
_ 9 X

С-амияия ; Имя
| :Отчество • j Город :'•' j Адк
ижшмш J ПСЧТОВЫЙ:

^пт/руть < Ь о н г т т к т * „г«деть >< -Л ^ Матвеев jПетрович


Виктор Екатеринбург Техническая 31-18 620090 j
Сухарев :Владимир : Иванович ;Кострома Мира 12-67 1156055 \
:;::;: объекты Чщ Создание таблицы в режиме конструктора | Федотов : Александр ;Николаевич Самара ^Ташкентская 23-41 443122 |
:
|У Создание таблицы с помощью мастера Семенов ;Петр jСергеевич ; Смоленск ; Фрунзе 12-9 :214001 j
ь^У Создание таблицы путем ввода данных Астахов •Николай ;Петрович ;Кемерово Волошина 56-34 6290В1
•-•?£•. Зйпрбсй"•;•
.$ сЫ_Кпиенты • Березкин Андрей '• Викторович : Александров : Энтузиастов 2-35 601600 i
• ; Ж ФЬрны D ф1.Потен«йа*мые^1о»1вит1в1 Дмитриев | Василий ;Михайлович Иваново Громобоя 22-18 153002 ;
Щ Отчеты Петров 1 Алексей j Семенович : Сэров .Юности 11:7 607190

;::';!Щ| Страницы
.'i-:-;*' '*

Группы.:.
j ^ w t ]И 4 jj 6 (>.3i(|S*j»3"8 :<
'
| Режим таблицы '. шн".

Рис. 2.7. Добавление записей из одной базы данных в другую

Исключение системных таблиц


Т Р Ю К

№15 из обработки
Исключение системных таблиц из подсчета общего количества и из обработки про­
граммными процедурами, позволяющее избежать неверных результатов.
Сколько таблиц содержится в вашей базе данных? Вы, наверное, думаете, что для
ответа на этот вопрос нужно просто сосчитать их количество во вкладке Таблицы
окна базы данных. Как бы не так!
Для своих внутренних нужд Access использует системные таблицы. Обычно они
скрыты от обозрения, но, тем не менее, существуют. На рис. 2.8 показана база дан­
ных, содержащая несколько таблиц.
сг
. ЩШШЩШ Р » (форм., Лесе» 20О0) - к
..:; ^ С о з д а т ь ! У-. \ лц tVpfjiiU

Объекты . щ (Создание таблицы в режиме конструктора


1
л •iTafiwtibiv '•-::•.-:! :4i Создание таблицы с поиощью мастера
Создание таблицы путем ввода данных
Запросы
1Ы_Даты
I 3 • Формы
гЫ_Календарь
^•Отчеты
м 1Я г.Ы_Общежитие

"лСтраницы ::! Ш ^.Расписание


г.Ы_Регионы_справки
.^Макросы

и Модули
\ а сЫ_Собеседования_справки
1 3 1Ы_Справки_по_месяцам
\ 2!
\ группы (:Ы_Студенты

I & ^Избранное

I •:; I
Рис. 2.8. Подсчет количества таблиц

Похоже, что в базе данных имеется 8 таблиц, не так ли? Давайте подсчитаем их
количество другим способом. В редакторе VB активизируем окно непосредствен-
52 Глава 2. Таблицы

ного ввода команд — Immediate (Ctrl+G). Затем введем в него следующий кодовый
фрагмент и нажмем клавишу Enter:
?Application.CurrentData.AllTables.Count
На рис. 2.9 показано окно Immediate, содержащее команду и результат ее выпол­
нения. Для базы данных, отображенной на рис. 2.8, результат будет равен 15, то
есть Access сообщает, что в базе данных на данный момент содержится 15 таблиц,
хотя на вкладке Таблицы видны только 8.

Рис. 2.9. Подсчет количества всех таблиц

Команда сообщает правду: эта база данных действительно содержит 15 таблиц


поскольку системные таблицы для вас пока остаются невидимыми. Давайте вклю­
чим их отображение.
Вернемся к самой базе данных (выйдем из редактора VB) и для отображения ди­
алогового окна Параметры выберем команду меню Сервис • Параметры. Теперь вы­
берем вкладку Вид. На рис. 2.10 видно, что в области Отображать имеется флажок
Системные объекты. Установим этот флажок, чтобы включить отображение сис­
темных объектов.
;:-::'•'• :
.. \'УШШЩЩ^ • Щ^:Ш:- '•• • '^-Ш^Ш^ттЩ
, u
•,.,.,mm,,,., i :,а№?ттт$:.,,м. Провеса ошибок ... . ; Орфография..... ;;.: .Таблицы и;;?апррсь|.;-
л^ттЛ.Ре*?нт^ы / ФОР- 1Ы и отчеты Страницы :•
; f Отображать • —
1 \?.\ Строку состояния Щ скрытые объекты
. L 3 область задач при запуске [У|системные объекты^
| |V] новые ярлыки объектов j£] окна в памели задач

LJ столбец имен W\ столбец условий ill


! ;•• Открывать объекты е окне безы домны*
1 О одним щелчком
vV двойным щелчком

[ дк J Отмена ] | Приыемить j ;

Рис. 2.10. Включение отображения системных объектов


Трюк № 15. Исключение системных таблиц из обработки 53
Снова взгляните на вкладку Таблицы, изображенную на рис. 2.11, теперь на ней
можно увидеть и системные таблицы.

^Создание таблицы в режиме конструктора! Ш 1Ы_Расписание

! ~! :;:|Ш!^;:|||;Р l||j Создание таблицы с помощью мастера Ш г.Ы_Регионы_справки


Щ Создание таблицы путем ввода данных Ш 1:Ы_Собеседования_справки
s Запросы
Ш MSysAccessObjects Ш ЬЫ_Справки_по_месяцам
т Формы
"1 MSysAccessXML ;!3 ЬЫ_Студенты
т [ШчвТЬ! .1 MSysACEs
<#•'"•
Страниц^ .' ''• MSysObjects
...' MSysQueries
Макросы
'\ MSysRelationships
;| ^К Модули
3 *Ы_Даты
Группы „3 1Ы_Календарь
.3 (Ы_Общежитие
] :& Избранное


Рис. 2 . 1 1 . Отображение всех таблиц, включая системные

Заметьте, что все имена системных таблиц начинаются с префикса MSys. Этот ат­
рибут, присущий именам всех системных таблиц, облегчит исключение их из под­
счета.

Код
Но зачем это нужно? Дело в том, что в приложении может понадобиться осуще­
ствить перебор всех имеющихся в базе данных таблиц, возможно, для того, чтобы
добавить им какое-то свойство, найти поле или данные, изменить каким-то обра­
зом их структуру и т. д. В таком случае системные таблицы следует исключить из
обработки. Поможет это сделать простая процедура, которая предназначена для
исключения тех таблиц, чьи имена начинаются с префикса MSys:
Sub c o u n t _ t a b l e s ( )
"вывод перечня таблиц базы данных
Dim table_num As I n t e g e r
Dim t b l _ c o u n t As I n t e g e r
With A p p l i c a t i o n . C u r r e n t D a t a
For t b l _ c o u n t = 1 To . A U T a b l e s .Count
I f L e f t ( . A U T a b l e s ( t b l _ c o u n t - D.Name, 4) <> "MSys" Then
D e b u g . P r i n t . A U T a b l e s ( t b l _ c o u n t - l).Name
End I f
Next t b l _ c o u n t
End With
End Sub
Данная процедура перебирает все таблицы базы данных и выводит в окно отлад­
ки (Immediate) имена таблиц, в которых не было префикса MSys. Для использова­
ния процедуры в других целях следует заменить строку вывода имен на любую
другую операцию обработки всех таблиц.
54 Глава 2. Таблицы

Выполнение кода
На рис. 2.12 показан результат работы данной процедуры. Окно Immediate запо/ -
нено именами только тех таблиц, которые имеют непосредственное отношение
к приложению базы данных, что, собственно, и требовалось получить.

Sub c o u n t _ t a b l e s ( )
ПКВ9Л ПСреЧКЯ ТЯЙЛК1; ба.^Ы ЛЯЭТКЫХ
Dim table_num As Integer
Dint tbl count As Integer
With Application.CurrentData
For tbl_count = 1 To .AllTables.Count
If Left{.AllTables(tbl_count - 1).Name, 4) <> "HSys" Then
D e b u g . P r i n t . A l l T a b l e s ( t b l _ c o u n t - 1).Name
End If
Next t b l c o u n t
End t i l t h
End Sub
j
TJ

tbl_flaTbi
t b l Календарь
сЫ_Общежитие
ьы_Расписание
t b l Регионы справки
t b l Собеседования_справки
t b l Справки по месяцам
t b l Студенты

«L
Рис. 2 . 1 2 . Список только тех таблиц, в которых содержатся данные самого приложения

Отделив, таким образом, таблицы данных от системных таблиц, вы сможете де


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

Т Р Ю К Прячем информацию от посторонних


О №16 Придание таблицам свойства невидимости вставкой в их имена префикса Usys.

Этот трюк, скрывающий данные от любопытных глаз, прост и легок в исполне­


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

Сделать это можно вставкой в имена таблиц префикса USys. Для Access это станет
признаком, благодаря которому такие таблицы приобретут смешанные свойства
и станут как бы и системными, и пользовательскими. При этом появится возмож­
ность их скрывать или отображать, используя встроенные механизмы Access.
На рис. 2.13 показан результат использования таких свойств: в открытой фор­
ме явно отображаются данные, а во вкладке Таблицы окна базы данных ника­
ких таблиц нет!

t -*j M i c r o s o f t Access 11Ш1Щ1ШШШШ11Ш'|:11Ш1й


:
Г ф ^ н п ^ Правка 8ид ! : Бстаэка .формат Записи Сервис Окно Справка
?
*•-* i ± < •*.? >>м ' У :
:• •••••;•:••- •:•

•^Открыть ^ К о н с т р у к т о р I j Создать I У \ * а " / • }••• | | Ц

• уОбгекты. *|§£ Создание таблицы в режиме конструктора

Таблицы 'sal Создание таблицы с помощью мастера


^ Создание таблицы путем ввода данных
_j Запросы

3 Форны

Клиенты
Фамилия Имя Отчество Город
• Федотов | Александр : Николаевич .Самара

Семенов ! Петр : Сергеевич Смоленск

Астахов ; Николай \ Петрович .Кемерово

Береэкин : Андрей : -Викторович Александров

1 Дмитриев : Василий ; :Михайлович Иваново Щ

.ишш.»*1 : < • !

Режим формы

Рис. 2 . 1 3 . Форма, имеющая источником записей скрытую таблицу

Форма на рис. 2.13 имеет свойство Источник записей, указывающее на таблицу


Usys_tOiHeHTbi. Флажок, включающий отображение системных объектов, можно
найти на вкладке Вид (команда Сервис • Параметры) (рис. 2.14). При установке
флажка Системные объекты все таблицы с префиксом имени Usys становятся ви­
димыми.
На рис. 2.15 отображены все системные объекты, среди которых присутствуют
как Usys-, так и MSys-таблицы (см. трюк № 15).
56 Глава 2 . Таблицы

Другие ,. , Между^родн^е ^. _. Про&^ка y№QciK ...,,;:,:|,.,.Орфйгр^Фия Телицы и запросы


ВиД
Общие Правка и поиск Кпаеивтура Режим табгмцы Формы и отчеты Страницы

•••Отображать • ••••••• ••. I


Щ\ строку состояния Ю скрытые объекты
[ ^ область задач при запуске ^Системные объекты;
[jTj новые ярлыки объектов Щ\ окна в панели задач

••Конструктор иакросов •

£ j столбец имен О столбец условий

'• Открывать объекты е окне базы данных *•


О одним щелчком
® двойным щелчком

' • . . ' . ' ..•,:•'.'!.. ; Uk ••••] { ,Отмена. [.[Применить]

Рис. 2 . 1 4 . Выбор отображения таблиц с префиксом имен USys

^ОТКРЫТЬ &£КОНСТруКТОр JCOIASTfe ,

:
Объекты ; М '•<

1;йа*й I46waw£;2| ffi Создание таблицы с помощью мастера

: 3
11 ffl Создание таблицы путем ввода данных
MSysAccessObjects

1 V.'^ Ф0рмы: : :
MSysAccessXML

!:Si u Отчеты MSysACEs


- Страницы MSysObjects
J
MSysQueries
з ^Макросы

1 M5ysRelationships
и5у5_Должности

If и&у5_Клиенты

1
иэу^Обслужиеание
Usysjlepeeoflbi
Usys_C4eTa

Рис. 2 . 1 5 . Отображение всех Usys- и MSys-таблиц

Префикс нечувствителен к регистру, поэтому вы можете использовать сочетания


USYS, USys, usys и т. д. — все они будут работать в качестве отличительного призна­
ка таблицы.

Альтернативный вариант
Другой способ скрыть объекты базы данных состоит в том, чтобы щелкнуть на
значке объекта правой клавишей мыши и выбрать в контекстном меню пункт Свой-
Трюк № 17. Имитация табличных триггеров 57

^ О т к р ы т ь |fe£ Конструктор Л Создать ; X

Объекты 'Ш Создание таблицы в режиме конструктора


<щ£ Создание таблицы с помощью мастера
4gjj Создание таблицы путем ввода данных
\'Л Ш^Ктеиуы
Ш ЬЫ_Потенциальные_клиенты

\ Свойства: <Ы..Кпненты IZlIIm


; Общие

-'• Тип: Таблица


: Описание:
j f

! Создан; 29.10,2005 17:27:3?


; Изменен: 30,10.2005 23:36:51
• Владелец: Admin
:
Атрибуты: Раскрытый : • . .

f j отслеживание строк

L™£L~ } [ Отмена j J Применить !

Рис. 2 , 1 6 . Установка атрибута Скрытый

ства, открыв тем самым одноименное окно (рис. 2.16). Установка флажка Атрибу­
ты: скрытый приведет к исчезновению объекта из окна базы данных.
Для включения отображения скрытых объектов надо просто установить флажок
Скрытые объекты в области Отображать вкладки Вид диалогового окна Параметры,
как это ранее было показано на рис. 2.14. Заметьте, что, присвоив именам объек­
тов префикс Usys и установив для них атрибут Скрытый, вы становитесь чуточку
хитрее и опаснее для окружающих. Если объекты не видны, это не означает, что
их вовсе не существует!

Трюк в трюке
Хотя в данном трюке рассматривался способ сокрытия таблиц, позволяющий убе­
речь не предназначенные для всеобщего обозрения данные от пользовательского
доступа, вы можете установить атрибут Скрытый для всех объектов базы данных,
в результате при просмотре вкладок окна базы данных никто абсолютно ничего
не увидит. Присвоив имени стартовой формы префикс Usys, вы сможете получить
полностью работоспособное приложение. Переименовав соответствующим обра­
зом все объекты базы данных, вы можете создать готовое приложение без единого
видимого объекта во вкладках окна базы данных. Безусловно, объекты становят­
ся видимы во время открытия, но при соблюдении определенных мер отстране­
ния пользователей от элементов базы данных вы сможете распространять «неви­
димые» базы данных.
58 Глава 2 . Таблицы

И Имитация табличных триггеров


Включение в приложения Access возможностей, схожих с имеющимися в SQL Server
или Oracle.
Ни Access 2003, ни более ранние версии не поддерживают события в таблица*.
Триггер представляет собой событие в таблице, возникающее при операциях встав -
ки, редактирования или удаления, которое можно обработать с помощью собствен­
ной функции. Примером полезного применения может послужить обработка
события редактирования до сохранения его результатов с целью организации
хранения прежнего состояния данных, то есть для помещения прежней версии
записи в резервную таблицу. Таким образом, сохранится возможность провести
ревизию изменения данных. Если по каким-то причинам возникнут проблемь,
связанные с изменением данных, всегда можно будет вернуться к их первоначаль­
ному варианту.
Та же логика применима и к удалениям. Используя триггеры, вы можете вкли­
ниться в процесс удаления и поместить данные в архив, вместо того чтобы поте­
рять их безвозвратно. В случае вставок (когда в таблицу добавляется новая
запись) вы можете перепроверить данные, прежде чем позволить им попасть
в таблицу.
К сожалению, Access не позволяет совершать подобные действия напрямую, при
работе непосредственно с таблицами. Но вы можете проделывать то же самое,
работая с таблицами из форм. В формах можно обрабатывать множество собы­
тий, получая тот же результат, что и при использовании настоящих триггеров, но
работая при этом вместо таблиц с формами.

Ведение контрольного журнала


Чтобы показать этот механизм в действии, создадим в базе данных еще одну таб­
лицу для зеркального отображения существующей таблицы данных и веденил
контрольного журнала изменений, вносимых в таблицу. Осуществим задуманное,
добавив два дополнительных поля: одного — для хранения типа операции, а дру­
гого — для хранения времени ее проведения. На рис. 2.17 показаны две таблиць :
таблица данных (1Ы_Клиенты) и таблица, предназначенная для хранения записе \
первой таблицы в том состоянии, в котором они находились до внесения измене­
ний или удаления (т.Ы_Клиенты_контрольный_журнал).
Обратите внимание на следующие особенности:
• Таблица журнала содержит два дополнительных поля: Операция и Время_опе-
рации.
• Если для таблицы данных поле КлиентЮ является первичным ключом, то длл
таблицы журнала оно преднамеренно таким ключом не является. Так сделан э
потому, что в таблице журнала может содержаться несколько записей, от­
носящихся к одному и тому же клиенту (и с одним и тем же значением
поля КлиентШ).
Трюк № 17. Имитация табличных триггеров 59
:i:r^:и-;;::::J;:;=::-;;::;^!; ;^;-^-^: ^^Ш1?Ш^Шр^Ш^!Й^ЩЩЩ|
J*| M i c r o s o f t Access
;E;i;^E::^:^=-i]ni-:^;HE^;:i-N:
шш
:
: : ^ я ' ; ^ й й й к а ' ; . : : 8вд • Вставка
:
. Сервис .:: йдао £правк:а:.:-:.:::':::::!. *'!'^"" •
-у;3 ШЖчивнты : та 1ПИЦД

Ж КлиентЮ
Имя попя 1 Тип данных 1 Описание 1 A. i
J t КлиентЮ
'•'; И н я т л я | Тип данных "•
Числовой
• Описание
|;*
Фамилия
ЖИмя^
Текстовьй
Текстовый
Фамилия
: •' ; ИМЯ
Текстовый
Текстовый ж
Текстовьй • ; Отчество Текстовый
-и|| Отчество
Текстовый _ _ Город Текстовый
•:;••.:. Город
Щ Адрес Текстовый
j.-' : Почтовый_индекс Текстовьй _ _ Почтовый _индекс Текстовьй
;: Телефон Текстовый Телефон Текстовый
• Операция Текстовый
fz Время операции Дата./время
v

Свойства поля Свойства поля

Общие П о Д П аиоека : Общие Подстановка


|| Размер поля •Длинное целое Ц Размер поля Длинное целое
Л Новые значения Последовательные В Формат поля •

Ц Формат поля Щ Число десятичных знаков ;АВ.Т.Р.


Щ Подпись Ц Маска ввода
|| Индексированное поле Д а (Совпадения не допускают Щ Подпись
Ы Смарт-теги Ш Щ Значение по умолчанию *зя§
ш Щ Условие на значение
щ Сообщение об ошибке
ш ш ; I Обязательное поле •Нет
Ц Индексированное поле Цет ' '
Щ Смарт-теги

КОНСТОУКТОО.: Р6 «переключениеокон; • Ff*:сгоавка HUM

Рис. 2.17. Использование таблицы контрольного журнала для хранения записей

Отслеживание событий формы


Теперь вы можете воспользоваться стандартной формой для просмотра записей,
их добавления, редактирования и удаления из таблицы данных. На рис. 2.18 по­
казана обычная форма, имеющая в качестве источника записей таблицу tbL
Клиенты.

Жиенш

Клиенты
Фамилия Имя Отчество Город Адрес ' Индекс
{Николаевич } Самара
if {Федотов { Александр {Ташкентская 23-41 j 4 43122

>{ Семенов {Петр |Сергеевич {Смоленск [Фрунзе 12-9 J214001

1 {Астахов

{Березкин
{Николай

{Андрей
{Петрович

^Викторович
| Кемерово

{Александров
>|Волошина 56-34

;.:|Энтузиастов 2-35
{623081

.{601600

^Дмитриев {Василий {Михайлович {Иваново }Громобоя 22-13 Ц53002


i
)Петров {Алексей {Семенович {Саров :]Юности11-7 JG07190

{Матвеев {Виктор {Петрович {Екатеринбург {Техническая 31-18 |620090


• JСухарев {Владимир {Иванович {Кострома |Мира 12-67 |156055

{Антонов .:]Семен ^{Петрович 1 Улан-Удэ {Жукова 10-5 |670040

вались : , И . ] Ш Г : • I>IJ>+ Ю4»

Рис. 2.18. Операции вставки, обновления и удаления могут осуществляться с помощью формы
60 Глава 2 . Таблицы

Разумеется, форма содержит встроенный программный модуль, обрабатывающий


два события: До обновления и Удаление. Обработчиком события До обновления об­
служиваются и вставки, и обновления, а обработчик события Удаление работает
только по прямому предназначению. В частности, при вставке новых данных об­
работчик события До обновления проверяет приемлемость данных (то есть, ска­
жем, наличие фамилии). Если данные не пройдут проверку, свойство Cancel будет
установлено в True, что приведет к отмене события.
В процессе обновления (редактирования) запись, подвергаемая изменениям, сна­
чала копируется в таблицу журнала, то есть сохраняется в нем в своем прежнем
виде. Перед удалением запись также попадает в таблицу журнала.
Код
Этот код должен быть помещен во встроенный программный модуль формы.
Поле Операция таблицы журнала получает одно из двух значений: Обновленке
или Удаление. Оба обработчика событий используют одну общую функцио
(build_sql):
P r i v a t e Sub Form_Beforellpdate(Cancel As I n t e g e r )
On E r r o r GoTo err_end
Dim s s q l As S t r i n g
Dim conn As ADODB.Connection
Set conn = C u r r e n t P r o j e c t .Connection
I f NewRecord = False Then
s s q l = bui l d _ s q l (КлиентЮ, "Обновление")
conn.Execute s s q l
conn.Close
Set conn = Nothing
Else
I f I s N u l l ( C l i e n t L a s t N a m e ) Or ClientLastName = " " Then
MsgBox "Нужно ввести фамилию"
Cancel = True
End I f
End I f
E x i t Sub
err_end:
MsgBox E r r . D e s c r i p t i o n
End Sub

P r i v a t e Sub Form_Delete(Cancel As I n t e g e r )
On E r r o r GoTo err_end
Dim s s q l As S t r i n g
Dim conn As ADODB.Connection
Set conn = C u r r e n t P r o j e c t . C o n n e c t i o n
s s q l = b u i l d _ s q l ( K n n e H T l D , "Удаление")
conn.Execute s s q l
E x i t Sub
err_end:
MsgBox E r r . D e s c r i p t i o n
End Sub

F u n c t i o n b u i l d _ s q l ( c l i e n t _ i d As Long, o p e r a t i o n As String) As String


b u i l d _ s q l • " I n s e r t I n t o 1Ы_Клиенты_контрольный журнал Values ("
b u i l d _ s q l = b u i l d _ s q l & КлиентЮ & " , "
build_sql = build_sql & & _
Т р ю к № 17. Имитация табличных триггеров 61

DLookup("Фамилия" , " 1Ы_Клиенты" , "КлиентЮ=" & _


client_id) & "", "
build_sql = build_sql & & _
DLookup ("Имя " , 'ЧЫ_Клиенты" , "КлиентЮ=" & _
client_id) & "", "
build_sql = build_sql & & _
DLookup ("Отчество", 'ЧЫ_Клиенты", "КлиентЮ=" & _
client_id) & "", "
build_sql = build_sql & """ & _
DLookupC'Aflpec", 'ЧЫ_Клиенты", "КлиентЮ=" & _
client_id) & "", "
build_sql = build_sql & """ & _
DLookup( "Город", " 1Ы._Клиенты", "КлиентЮ=" & _
client_id) & "", "
build_sql = build_sql & & _
DLookup ("Почтовый_индекс", " 1Ы_Клиенты", "КлиентЮ=" &_
client_id) & "", "
build_sql = build_sqi & & _
DLookup ("Телефон", 'ЧЫ_Клиенты", "КлиентЮ=" & _
client_id) & "", "
build_sql = build_sql & & operation & " " , "
b u i l d _ s q l = b u i l d _ s q l & "#" & Now( ) & " # ) "
End F u n c t i o n

Выполнение кода
Код выполняется в том случае, когда в форме совершаются операции вставки,
обновления и удаления. При этом никаких особых дополнительных действий —
скажем, щелчков на кнопке — не требуется. Журнал ведется во время работы
пользователей. В журнальной таблице регистрируются все изменения и даже хра­
нятся многократные изменения, произведенные в записи клиента. Функция
build_sql формирует команду SQL Insert. В эту команду, в зависимости от функ­
ции, осуществившей вызов (и передавшей в виде аргумента слово «Обновление»
или «Уда-ление»), включается в качестве одного из регистрируемых парамет­
ров либо Обновление, либо Удаление. Строка, содержащая команду SQL, воз­
вращается в функцию, осуществившую вызов, а затем эта функция выполняет
команду на вставку данных.
Все это может пригодиться на практике. Например, клиент переехал (изменился
адрес) или вступил в брак (изменилась фамилия), переметнулся к конкуренту (его
запись нужно удалять) и т. д. На рис. 2.19 показана таблица регистрационного
журнала, содержащая несколько записей. В каждой записи отражена операция
и время ее проведения.

Jtb\ К1н»кгы контри иным t y p n a t ! г*Гпм.к< :.: : :.: : :.: : i.r : :.:.: : :.: : i.r.: : :.- : :.: : i : r.- : :.

,.
| Имя [ Oi •• S:'s:s А д р е с i : 1 Операция
• •

9: Матвеев Виктор Петрович


' •Город
Екатеринбург Техническая 31-18 620090 (342) 3554267 ^Обновление
,.
12.10 2005 17 42 00 ;
90: Сухарев Владимир Иванович Кострома Мира 12-67 156055 (0942)245537 ^Обновление 13.10 2005 16 13 00 3
90' Сухарев Владимир Иванович Кострома Мира 12-67 156055 (0942)2*55.17 ^Обновление 14 10 2005 11 32 0 0 ' 18
106: Семенов Петр Сергеевич Смоленск Фрунзе 12-9 214001 (06122)67326 '•• Удаление 10 10.2005 15 23 СО; И
117;Астахов Николай Петрович Кемерово Волошина 56-34 629081 (3642)378219 ]Удаление ...16.10 2005J5 48,00: ;}

::::zr:::i i> : | И : > * ; ^ Ь
ш
- МУ,::„ 6
....... я
Рис. 2 . 1 9 . Каждая запись перед изменением или удалением попадает в таблицу
регистрационного журнала
62 Глава 2. Таблицы

Метод, применяемый в данном трюке, имитирует все то же самое, что предостав­


ляется SQL Server, Oracle и другими системами управления базами данных при
использовании триггеров. Не стоит позволять элите мира баз данных считать, что
Access в чем-то им уступает!
В таблице клиентов и таблице регистрационного журнала содержится множество
записей и благодаря замечательному свойству регистрации времени сохраняете ч
вся последовательность их изменений.

Трюк в трюке
Данный трюк был написан с учетом того, что о структуре таблицы и о типе ег
полей уже все известно. Поэтому я заранее знал, где расставлять одинарные ка­
вычки вокруг текстовых значений в функции build_sql. Адаптируя этот тркк
к собственным нуждам, возможно, вы заранее будете знать, какие типы данны <
следует ожидать, но если это не получится, то для определения типа данных вы
можете обратиться к библиотеке ADOX. Эта библиотека предоставляет способ
сканирования всех полей таблицы и определения их типов (впрочем, как и все <
других свойств). Вот стандартная процедура сканирования отдельной таблицы
и получения имен и типов каждого поля:
Sub get_fields( )
Dim cat As ADOX.Catalog
Set cat = New ADOX.Catalog
Dim fid As ADOX.Column
cat.ActiveConnection = CurrentProject.Connection
For Each fid In cat .Tables ('ЧЫ_Клиенты") .Columns
Debug.Print fid.Name & " " & fid.Type
Next
Set cat = Nothing
End Sub
Учтите, что для использования библиотеки ADOX вы должны установить с ней
связь. Для этого, впрочем, как и для установки любых других связей, необходимо
перейти в редактор VB и воспользоваться командой меню Tools • References, с по-

... ............
ttefereftees - Access 9
Available References:

': Visual Basic For Apphcations


r
i Mcrosoft Access 11.0 Obiect Library
'^Microsoft ОАО 3 6 Obiect Library
5Microsoft ActiveX Data Objects 2.1 Lfcrary
!OLE Automation

I IAS Helper COM Component 1.0 Type Library


.: IAS RADIUS Protocol 1.0 Type Library
J About 1.0 Type Library
I About 2.0 Type Library
"• Acrobat Access 2 0 Type Lfcrary
) AcroIEHelper 1.0 Type Library
.i Active D5 Type Library
• Artivft =Wi in Cnnrrnl I ihrArv

Microsoft ADO Ext. 2.7 for DDL and Security


location: D:\Prooram Mes^Coromon Pte\5ystem\ack>\mMdctx ,dll
Language: Standard

Рис. 2.20. Установка связи с библиотекой ADOX


Трюк № 18. Ускоренное создание таблиц 63

мощью которой вы сможете открыть диалоговое окно References (рис. 2.20). Биб­
лиотека называется Microsoft ADO Ext. 2.7 for DDL and Security. Установите флажок, рас­
положенный напротив этого имени и, чтобы закрыть окно, щелкните на кнопке ОК.
Процедура возвратит для каждого типа поля числовую константу. Например, зна­
чение 202 относится к текстовому полю (хотя на малопонятном жаргоне ADOX
это число сопоставлено с символьным полем переменной длины — adVarWChar).
Чтобы узнать значения этих чисел, нужно просмотреть в Object Browser (браузере
объектов) коллекцию констант DataTypeEnum. Эта коллекция станет доступной
только после установки связи с библиотекой ADOX. На рис. 2.21 показан браузер

• ft Microsoft Visual Basic - Прнмеры2 • [ObjectBrowse г]


• ty He Edit ; View Insert Debug Run Tools Add-Ins Window Help

3 vi.\! !b;-? t i

•Classes.;,,;.;. Members of DataTypeEnurn';


Column Ш adVarBinary
#> ColumnAttfibutesEn ijj adVarChar
Щ Columns Щ adVariant
^ DataTypeEnum Ш adVarNumeric
•S Croup
«5 Groups Ш adWChar

Const adVatWOw = 202(&HCA)


Member of Й^.Х.1)**а.1ш«&пУШ

Рис. 2.21. Обзор констант типов данных

объектов, настроенный на обзор списка констант типов данных. В нижней обла­


сти окна браузера отображается числовое значение выделенной константы.
Используя структуру Select Case или набор операторов If со вставками числовых
кодов ADOX, взятых из этой области, вы сможете написать процедуру, которая
не будет опираться на предварительные сведения о типах полей.

Т Р Ю К Ускоренное создание таблиц


№18 Оптимизация конструктора таблиц путем выбора подходящих параметров по умол­
чанию.
Текстовое поле состоит из 50 символов. Числовому полю по умолчанию присваи­
вается тип Длинное целое со значением 0. Знакомо, не правда ли? Часто ли вам
приходится отвлекаться на изменение этих установок? А вот если вы воспользу­
етесь этим трюком, то больше не придется.
В диалоговом окне Параметры (Сервис • Параметры) на вкладке Таблицы и запросы
вы найдете элементы управления, с помощью которых можно задать такие уста­
новки по умолчанию, как размер текстового поля, размер числового поля (целое,
длинное целое, одинарное с плавающей точкой и т. д.) и даже тип поля по умол­
чанию. На рис. 2.22 показано это диалоговое окно с примерами установок.
64 Глава 2. Таблицы

Монстры
; Вид. £ О',- Пра0К«ИПОИСК ра " Формь L и отчеты. ,.;•::.. Стран); щ ы
Другие Межд,иар«чь* . . I . Проэер* а оавЛж j Таблицы и запросы

I Конструктор таблиц — ~~-* -~- •*" гТТ


г Размеры полей поунолчдшо Тип ПОЛЯ ПО умолчанию:
j текстовое: цоо : Числовой

; числовое; ;Одинарное с плаваю^;; Автоиндекс при импорте и создании;


I шифр; ключ; код; номер

Конструктор запросов —••-—---——•——--— ..............

Щ Вывод имен таблиц г- При запуске предоставляются права ••


f H Вывод всех полей ! ф владельца
ffil Автоматическое объединение • (*)пользователя

•• Шрифт в конструкторе запросе* - ^••Синтаксис ДЛЯ SQfc SepW* (ANSI 92)


Шрифт: Размер: j О текущая база данных
;Tahoma

:•[;. Отмена.. I j Применить

Рис. 2.22. Изменение значений по умолчанию для полей

На рис. 2.22 размер текстового поля по умолчанию был изменен на 100. Значит,
если в конструкторе таблиц будут добавляться новые текстовые поля, их размер
по умолчанию будет устанавливаться в 100 символов. Размерность числового пол я
была также изменена на Одинарное с плавающей точкой. При добавлении нового
числового поля оно по умолчанию будет иметь именно такую размерность. Тип
поля по умолчанию был изменен на Числовой, поэтому при добавлении в конст­
рукторе таблиц нового поля его тип по умолчанию будет установлен в Числовой,
а размерность — в Одинарное с плавающей точкой.
Выбор новых значений по умолчанию может оказаться весьма полезным. К при­
меру, если вы создаете таблицу, которая в основном содержит даты, установите
значение типа поля по умолчанию в Дата/время, и вам не придется постоянно вы -
бирать тип поля. Все вновь вводимые поля будут иметь по умолчанию тип Дата/
время. Вам нужно будет скорректировать свойства только некоторых полей, не
относящихся к данному типу.

Установка значений по умолчанию


В настройках диалогового окна Параметры можно установить типы полей, но нельзя
установить значение по умолчанию. Иначе говоря, вы можете выбрать тип числе -
вого поля Одинарное с плавающей точкой, но не можете назначить ему значение пэ
умолчанию 1,25 (к примеру) для всех новых записей, добавляемых в таблицу.
Тем не менее настроечный параметр, в котором можно указать значение поля пэ
умолчанию, все же существует., На рис. 2.23 для поля, обозначенного в третьей
строчке создаваемой таблицы, вручную было установлено значение 1,25, и имен­
но оно станет его значением по умолчанию.
Трюк № 18. Ускоренное создание таблиц 65
1 нояНомяТабпииа : ««лиц» -Т@© :
• • • . ' - ИМЯ'П0П»''>'::'' f Тип данных [ '•'•• •Описаняе ]:*•
Ц Поле1 Текстовый
Ш Поле2. i Текстовый
^ЩПолеЗ :ЧИСЛОВОЙ
щ Поле4 .. J Числовой
Поле5 'Числовой
Ш Полеб [Числовой \
Ш Поле? .[Числовой
'i~u.
iж Прлвв •Числовой
^ Поле9 : ЧИСЛОВОЙ
| £ ПолеЩ ;Числовой
jj: ] £ ПолеП Дата/время ;,.....
1 "Щ1 Поле 12 : Текстовый Шъ \
Свойства поля

\ Общие утрдстаноека;
1 Размер поля Юдинарное с плавающей точкой
1 Формат поля
I Число десятичных знакоЕ |Авто _ _j р:
1 Маска ввода
| Подпись
: Значение по умолчанию
- Условие на значение SIMZZZZIZZZZIZ §
: Сообщение об ошибке
; Обязательное поле ;Нет LZZZZZZZZZZZZZZZj| II
j Индексированное поле Йет
! Смарт-теги I I:
i
1
i
i ~rTZr^Z~~Z~i~S~S—^SiSSg"
Рис. 2 . 2 3 . Установка для поля значения по умолчанию

Код
А что, если сотня других полей нуждается в установке такого же значения по умол­
чанию? Мои пальцы начинают болеть только при мысли о предстоящем ручном
вводе! Автоматизация этой задачи позволит спасти жизнь или, по крайней мере,
пальцы. Спасение заключается в небольшом кодовом фрагменте:
Sub c h a n g e _ f i e l d _ d e f a u l t s ( )
Dim c a t As ADOX.Catalog
Set c a t = New ADOX.Catalog
Dim f i d As ADOX.Column
cat.ActiveConnection = CurrentProject.Connection
For Each f i d I n cat.Tables("мояНоваяТаблица").Columns
I f f i d . T y p e = adSingle Then
f i d . P r o p e r t i e s ( " D e f a u l t " ) . V a l u e = 1.25
End I f
Next
Set c a t = N o t h i n g
End Sub
В этом фрагменте для работы с полями указанной таблицы использована библио­
тека ADOX (см. трюк № 17). В данном примере имя таблицы указано внутри про­
цедуры, но оно, конечно же, может быть передано и в виде аргумента. В данном
программном примере сканируются все поля, и если встречается поле с число­
вым типом Одинарное с плавающей точкой (выявляемое с помощью константы
adSingle), его значение по умолчанию устанавливается в 1,25.
66 Глава 2. Таблицы

Вы можете дополнить эту процедуру фрагментами установки значений по умол­


чанию для всех возможных типов полей. Более того, вы можете установить значе­
ния по умолчанию для комбинаций типов полей и имен полей. Например, noj:e
с именем local_rate может иметь числовой тип Одинарное с плавающей точкой, и в л
сможете установить для него значение по умолчанию 0.25; точно так же вы може­
те установить значение по умолчанию равным 0,5 для поля с именем nationaLrate
и таким же числовым типом данных.
Г Л А В А 3

Ввод данных и перемещение по


элементам управления
Трюки № 19-27

Успех приложения зависит от признания пользователей. Осознав эту истину, стоит


подумать, как сделать интерфейсную часть приложения приятнее на вид и удоб­
нее в работе.
Порой на впечатления пользователя от работы с приложением не обращается
никакого внимания. Разработчики тратят уйму времени, создавая поля и табли­
цы, устанавливая связи, придумывая хитрые SQL-команды и т. д. Думаете, для
рядового пользователя все это что-нибудь значит? Ровным счетом ничего!
Давайте посмотрим правде в глаза. Access — это больше, чем просто база данных.
Эта система, ко всему прочему, обладает встроенными средствами разработки
интерфейса. Конечно, таблицы являются ядром базы данных, но создание форм
и отчетов — основное предназначение инструментального комплекса. У системы
Access имеются обе составляющие, поэтому нужно постараться успешно разрабо­
тать каждую из них.
Трюки этой главы подбирались в расчете на обычного пользователя, основным
занятием которого считается ввод данных, и предназначены для того, чтобы сде­
лать это нудную и утомительную работу хоть чуточку приятнее.

Упрощенное перемещение по длинным


формам
Использование элемента управления Разрыв страницы и кнопок управления, избав­
ляющих пользователя от прокрутки длинных форм ввода данных.
Информация — вещь замечательная. Чем больше вы знаете, тем больше сможете
сделать и спланировать, если только вы не застряли на этапе ввода данных. Тогда
все, что вы можете спланировать, — это постучать по клавишам и поводить указа­
телем мыши по экрану.
68 Глава 3 . Ввод данных и перемещение по элементам управления

На рис. 3.1 показана очень длинная форма ввода информации. Эта форма содер
жит столько полей ввода, что они не помещаются на одном экране, о чем свиде­
тельствует полоса прокрутки справа. При работе с такой формой до нижних по­
лей приходится добираться с помощью полос прокрутки или клавиш перехода.

Э ! г т _ К * и е н т ы : фор*и
ЩЙЙЩЩЙЩЩЩ
г -г о*
i Фамилия:' Федотов ! , Поиск
•! Имя: ;Александр.
Отчество: -Николаевич 1 . Выкрд^
'; Место работы ;;::-
•• Организация: ОАО "Полет"

Гагарина 12
А
Адрес 1:

Адрес 2:
- : :•:•:•
...........:.......,,,.,,,:...-
- • Город: Самара

Регион: Самарская обл,

Почтовый индекс: №43102 <<^шшшш


Телефон: 62-54-12

•" Факс; .62-54-18

Л и ^ ы е данные 1 • !
Дата рождения: 12.10.1965

Супруг(а); Наталья Ивановна


. . . . : : . . : . : • ;

Адрес К Ташкентская 23-41

Адрес 2:

;
Город:

Регион;
Почтовый индекс:
Самара

443122
1 i1
Т«п«Ьпк: 7Д-5Л-79
,,„,; ,„.,,„, .™Jj

Рис. 3 . 1 . Форма, перегруженная полями ввода

СОВЕТ
Если форма содержит большое количество элементов управления, лучше всего при­
менить вкладки. Но данный трюк продиктован реальной жизненной ситуацией. Од­
нажды я работал над проектом, где операторы должны были вводить данные со
стандартных форм, и экран ввода информации должен был структурно соответство
вать именно этим формам.

Клавиши Page Up и Page Down помогают прокручивать форму, но задать количе


ство прокручиваемых строк вы не можете. Шансы на то, что при использование
клавиши Page Up или Page Down форма будет устанавливаться в нужном положе
нии, крайне малы.
Но способ останавливать форму в нужном положении все же есть. Для этого тре­
буется всего лишь вставить в форму элементы управления Разрыв страницы. Вы не
знаете, что это такое? На рис. 3.2 отображена панель инструментов с указателем
установленным на элемент управления Разрыв страницы. Размещая в соответствие
с общим замыслом разрывы страниц в конструкторе форм, вы получите управля­
емую прокрутку при использовании клавиш Page Up и Page Down.
Трюк № 19. Упрощенное перемещение подлинным формам 69

Рис. 3.2. Элемент Разрыв страницы на панели инструментов

На рис. 3.3 форма изображена в режиме конструирования. Элемент управления


Разрыв страницы был помещен прямо над группой элементов Личные данные. Вы­
глядит этот элемент в режиме конструирования весьма скромно, в виде ряда то­
чек. В режиме просмотра он и вовсе становиться невидимым.

У Заголовок формы
етиЛдау Фамилия
I vm& vn*
Ш.КШЯЙ;] <Э!.честео
• Обметь данных
;Место рабого. •
Г ; Организация:; С'рг анимация

Адрес l:j Адрес организации 1


Адрес 2: Адрес организации 2
Город:- Город организации

Регион; Регион организации

|Почто»ый индекс; Лочтоеый индекс организации \

П" Телефон: Телефон рабочий

Факс: Факс рабочий

-Личные данные:
! Дата рождения:; Дата рождения
Cynpvr(a);: ;Супруг(а)
Адрес!:; ;Адрес домашний 1
у . . . : - ^ . - . - . • • • • • ' - • - • - • • •

Адрес 2:; Адрес домашний 2

Город:; Город

Рис. 3.3. Добавление элементов Разрыв страницы

Теперь, при использовании клавиши Page Down, прокрутка будет останавливаться


в том месте, где находится Разрыв страницы. На рис. 3.4 показано, как при прокрут­
ке форма остановилась в начале группы элементов Личные данные.

Управляемый переход
Использование клавиш Page Up и Page Down — неплохой способ прокрутки формы,
но можно сделать кое-что получше. Представьте, что форма содержит несколько
разделов и вам нужно иметь к ним произвольный доступ. Многократно нажимать
клавишу Page Up или Page Down для того, чтобы добраться до нужного раздела, —
крайне нерациональное занятие. Для решения этой задачи вы можете разместить
ряд кнопок управления в заголовке или в примечании формы. И заголовок, и при­
мечание всегда на виду, поскольку прокрутка их не касается. На рис. 3.5 показана
форма в режиме конструирования. В ее заголовке размещены кнопки управле­
ния для мгновенного перехода к нужным разделам.
70 Глава 3. Ввод данных и перемещение по элементам управлени я

Фамилия; Федотов
Имя: Александр
От чество: Николаев* ч.
Личные данные
2.101965
Дата рождения;
••з'апья Ивановна
СупрУФ);
ешкентская 23-41*
Адрес I:
Адрес 2:
Город:
Регион;
: «43122
. Почтовый индекс.
23-56-79
Телефон:
Мобильный; ;8-913-345-67-89'

Заметки: I Проявляет интерес к домашнему и


:садовому инструменту

Сведения о контактах

Дата контакта; 10.09.2005


Способ контакта: По рабочему телефону
Суть контакта: Запрос каталогов. Высланы каталоги
по домашнему, садовому и
водительскону инструменту.

Рис. 3.4. Управляемая прокрутка

• Заголовок формы
'•*••-•-••:-.-~г~~;

.Фамилия;; фамилия v

.Отчеств^;; Отчество.

# Область данных
;-{Место работы]
' " ' Оргвнизация;] Организация
Адрес J 0 Адрес организации 1
Адрес 2: j Адрес организации 2
Город: 1 Город организации
Регион:} Регион организации
: ; Почтовый индекс:] Почтовый индекс организации
ТелефонТ] Телефон рабочий
Факс; Факс рабочий

;• (Личные данные |
: | Й«та рождения: Дата рождения

С*Ш® Супруг(а)
Адрес); !Адрес домашний 1
Адрес 2:| АДР«с домашний 2

Рис. 3.5. Кнопки, облегчающие переход к разделам формы

Код
Трюк состоит в том, что обработка события щелчка на каждой кнопке генерирует
имитацию нажатия клавиш Page Up и Page Down. Достигается это использованием
Трюк № 19. Упрощенное перемещение по длинным формам 71
оператора Send Keys. Каждая из четырех новых кнопок, размещенных в форме, ини­
циирует работу серии операторов SendKeys:
Private Sub стй_Место_работы_СПск( )
' 4 раза вверх, 1 вниз

переходы 4, 1
End Sub

Private Sub сп^_Личные_данные_С1лск( )

' 4 раза вверх, 2 вниз

переходы 4, 2
End Sub

P r i v a t e Sub стй_Подробности_общения_СИ с к ( )

' 4 раза вверх, 3 вниз

переходы 4, 3
End Sub

Private Sub cmd Заказы_СИск( )

' 4 раза вверх, 4 вниз

переходы 4, 4
End Sub

Sub переходы(и As Integer, d As Integer)


For вверх = 1 To u
SendKeys "{PGUP}"
Next вверх
For вниз = 1 To d
SendKeys "{PGDN}"
Next вниз
End Sub
Процедура обработки каждого щелчка генерирует определенное количество мни­
мых нажатий клавиш Page Up и Раде Down, которое требуется для прокрутки фор­
мы к нужному разделу. Эта имитация нажатия клавиш приводит к переходам на
элементы Разрыв страницы, ранее расставленные в форме. По щелчку на кнопке
программа сразу же посылает четыре имитации нажатия клавиши Page Up. Это
число обусловлено количеством разделов в данном примере. Тем самым обеспе­
чивается переход в начало формы. Конечно, четыре имитации нажатия клавиши
Page Up на самом деле требуются только в том случае, если форма находится на
последней метке Разрыв страницы, но зато это число приводит к нужному резуль­
тату независимо от текущего положения формы.
Затем код имитирует уже конкретное число нажатий клавиши Page Down. Это число
для всех кнопок разное и зависит от расположения раздела, к которому нужно
перейти. Иными словами, кнопка Место работы имитирует одно нажатие клавиши
Page Down, кнопка Личные данные — два, и т. д.
Использование данного приема позволяет перейти к любому разделу длинной
формы одним щелчком, избавляя пользователя от прокрутки всей формы.
72 Глава 3. Ввод данных и перемещение по элементам управления

Упрощение ввода дополнительного


i текста
Установка текстового курсора в конце текста, имеющегося в поле, в целях немедленно­
го ввода дополнительной информации.
Этот прием часто и незаслуженно игнорируется. Вы когда-нибудь, работая с дан­
ными формы, замечали, что при переходе к любому полю в нем выделяется вес:>
текст? А ведь это обстоятельство может привести к случайной перезаписи дан -
ных. На рис. 3.6 показано полностью выделенное поле адреса. Теперь предполо -
жим, что вам нужно дополнить поле данными (а не переписать его содержимое),
для этого потребуется переместить указатель мыши в конец текста и щелкнуть
клавишей, чтобы снять выделение.

Фамилия: Федотов, . w,„

Имя: ОПРНГЧНДС)

Отчество: .•Николаевич

( Место работы \ I гичные данные


в м е с т о работы
; Организация: "Полет"
Адрес 1:
Адрес 2:
Город:

Регион:

Почтовьй индекс: 1443102

Телефон: 62-54-12

Факс: 162-54-18

^Личные данные
-Дата рождения:
Супруг(а): • Наталья Ивановна
Адрес*: Ташкентская 23^41
Адрес 2:

Город:

Регион:

Рис. 3 . 6 . Автоматическое выделение данных создает угрозу их случайного удаления или


перезаписи

Не плохо было бы обойтись без этого щелчка, снимающего выделение, тем более
что есть подходящий способ, не требующий глубоких познаний в программиро­
вании.
Многие элементы управления, включая поля, имеют событие Вход, которое воз­
никает при щелчке на элементе управления или при переходе к этому элементу.
В процедуру обработки события можно поместить код, устанавливающий курсор
в конец строки еще до того, как появится доступ к вводу данных. Следующий
фрагмент кода относится к элементу управления Адрес_организации1:
Private Sub Адрес_организации1_Еп1ег( )
Dim длина_текста As Integer
Трюк № 20. Упрощение ввода дополнительного текста 73
длина_текста = 1_еп(Ме. Адрес_организации1)
Me. Адрес_организации1.SelStart = длина_текста
End Sub
Функция Len определяет длину текста, которая затем передается свойству SelStart.
Все предельно просто.
При необходимости подобную процедуру можно добавить в программные моду­
ли всех полей формы. Решение, куда именно поместить такой код, остается за
вами, поскольку только вы можете определить, где в приложении данные чаще
всего переписываются и где в поля не вводится дополнительный текст. В данном
примере дополнение было внесено в первое адресное поле (рис. 3.7).
: ;Й;;:Й:;; : ;;К : :Й:ЙКЙ:«;К;:

frm К тенты : форма ~ ^И


Фамилия; : Федотов ГТдаск.
:
"• -Имя;:;;-- .;Алексэндр :

Отчество: [Николаевич

[ Место работы ![ Личные да


:':'МвСТОрЙ&0ТЫ .
Организация:- i;:;iOAO "Полет"
' Адресе; ^Гагарина 12, второй этаж
. Адрес 2;
Город;
Регион;
.Почтовый индекс;

Телефон:

|| :•• Личные данные


is : Дата рождения; 12.10.1965
|| .: Супруг(а): :Наталья Ивановна
Адрес U Ташкентская 23-41
if i Адрес 2;
:
if : Город; Самара
регион;

1.„:
Рис. 3.7. Дополнительная информация, не предназначенная для замены существовавшего текста

Свойство SelStart не одиноко в своем семействе, существуют еще два свойства:


SelLength и SelText. Все три свойства, касающиеся выделенного текста, вместе или
порознь, предоставляют неплохую возможность для обработки текста, содержа­
щегося в полях и полях со списком.
Мы уже показывали, как использовать свойство SelStart для установки текстово­
го курсора на место ввода текста. Но однажды мне нужно было предоставить
пользователю простой способ менять местами в наборе записей имена и фами­
лии. Там порой попадались и инициалы, и отчества, в общем, вариантов было до­
статочно. Если вам приходилось когда-нибудь создавать процедуру обработки
имен, то вы поймете, что все предусмотреть совсем не просто.
Но в данном случае перестановку требовалось проводить только время от време­
ни, поэтому создавать сложную, универсальную процедуру не имело смысла. Вме­
сто этого я воспользовался свойствами выделенного текста, а часть работы оста­
вил за пользователем. Вот как все это работало.
74 Глава 3. Ввод данных и перемещение по элементам управление

Я поместил фамилии и имена деловых партнеров, требующие перестановки,


в форму, представленную на рис. 3.8.

;Д;ОД'рОДемий":форма
обратив шегос 1111
Федотов Александр Николаевич
Семенов Петр
Астахов Николай Петрович
Березкин АндрейВикторович
Дмитриев Василий
Петров Алексей Семенович
Матвеев Виктор Петрович
Сухарев Владимир Иванович
Антонов Семен Петрович
Симонов А.П.
Фиников Николай
Самохин Александр Иванович
Дунаев Юрий
Перов Саша
Александров Владимир Сергеевич \
Дорошенко А.В.
Лазарев Алексей
Харитонов К.К
Заварзин Роман Дмитриевич
Бурлаков Антон
Терентьев П.А.
.-*«... 14| • | П > |>Jl£*J

Рис. 3.8. Фамилии и имена, требующие перестановки

Пользователь выделял имя, инициалы или имя и отчество и т. п., а затем нажима;:
клавишу Tab или Enter (рис. 3.9).

Федотов Александр Николаевич Ц


Семенов Петр
Астахов Николай Петрович
Березкин АндрейВикторович
Дмитриев И Я И И
Петров Алексей Семенович
Матвеев Виктор Петрович
Сухарев Владимир Иванович
Антонов Семен Петрович
Симонов А П .
Фиников Николай
Самохин Александр Иванович
Дунаев Юрий
Перов Саша
Александров Владимир Сергеевич | |
Дорошенко А В
Лазарев Алексей
Харитонов К Н
Заварзин Роман Дмитриевич
Бурлаков Антон
_Терентьев П.А

Рис. 3.9. Выделенное имя

Вот и все, что от него требовалось! Все остальное приводилось в действие за счет
свойств выделенного текста при обработке события Выход, относящегося к тек-
Трюк № 20, Упрощение ввода дополнительного текста 75

стовому полю. В примере использовано поле под названием Имя_обратившегося.


Рассмотренная ранее процедура обработки события Вход также нашла свое при­
менение в этом примере:
Private Sub Имя_обратившегося_ЕгПег ( )
'Снятие выделения
'и установка тектового курсора в конец текста

Dim длина_текста As I n t e g e r
дпина_текста = 1_еп(Имя_обратившегося)
Имя_обратившегося.SelStart = длина_текста
End Sub

P r i v a t e Sub Имя_обратившегося_Ех11 (Cancel As I n t e g e r )

Если есть выделенный текст и он


короче, чем весь т е к с т , то
если выделение начинается не с первого символа, то
переместить выделенную часть текста в начало

Dim новый_текст As S t r i n g
I f Имя_обратившегося.SelLength > 0 And _
Имя_обратившегося . SelLength < 1_еп(Имя_обратившегося) Then
I f Имя_обратившегося.SelStart > 1 Then
новый_текст = Имя_обратившегося.SelText & " " & _
Lef t (Имя_обратившегося , 1_еп(Имя_обратившегося) - _
Имя_обратившегося.SelLength)
Имя_обратившегося.Text = Т м т ( н о в ы й _ т е к с т )
End I f
End I f
End Sub
Процедура обработки события Вход снимает для удобства дальнейшей работы
первоначальное выделение текста. Пользователь выделяет имя, или имя и отче­
ство, или инициалы, если они есть, а затем выходит из поля по клавише Tab или

ЗОвращенх» -форма
Имя обратившегося-
Александр Николаевич Федотов
Петр Семенов
Николай Петрович Астахов
АндрейВикторович Березкин
Василий Дмитриев
Алексей Семенович Петров
Виктор Петрович Матвеев
Владимир Иванович Сухарев
Семен Петрович Антонов
А П Симонов
Николай Фиников
Александр Иванович Сэмохин
Юрий Дунаев
Саша Пвров
Владимир Сергеевич Александров
А В Дорошенко
Алексей Лазарев
К.Н Харитонов
Роман Дмитриевич Заварэин
Антон Бурлаков
П А Терентьее

Рис. 3 . 1 0 . Все имена и фамилии переставлены местами


76 Глава 3. Ввод данных и перемещение по элементам управления

нажимает клавишу Enter. В результате возникает событие Выход, при обработке


которого текст проверяется на наличие выделения, на то, что оно не совпадает
с длиной всего текста, и на то, что оно начинается не с первого символа.
Затем процедура меняет местами выделенную и невыделенную части текста (фа­
милию и имя) и возвращает их текстовому полю. Результат показан на рис. 3.10.
В процедуре использованы все три свойства выделенного текста: SeLStart, SelLeng1:h
и SelText. Эти свойства дают все необходимое для работы с выделенными фраг­
ментами текста. Но если сравнивать их с родственными свойствами и метода­
ми обработки простого текста — Text, Len, Left, Right, Mid и т. д., то можно заметить,
что предоставляемые ими возможности по обработке текста весьма скромны.

Предоставление возможности
добавления собственных значений
Т Р Ю К
в существующие списки
№21 Снятие ограничений на выбор значения только из предопределенных элементов спис­
ка путем добавления процедуры обработки новых значений.
При работе с формами пользователям нередко приходится выбирать одно из пре -
допределенных значений из поля со списком. Но иногда может возникнуть по­
требность ввести в это поле отсутствовавшее ранее значение. К примеру, во вре -
мя работы с данными нового клиента, еще не занесенного в соответствующую
таблицу, или при исправлении значения, внесенного в список с ошибками.
Свойство Ограничиться списком управляет разрешением на ввод в поле со списком
нового значения. Если свойство имеет значение Нет, пользователь может ввести
в это поле новое значение. Все бы хорошо, но есть одно «но»: если нужно допол­
нить список новым значением, то простой ввод его в поле не приведет к желаемо­
му результату. Если нужно дать возможность пользователям приложения до­
полнять источник данных поля со списком, следует воспользоваться другой
технологией. Сначала установите значение свойства Ограничиться списком в Да.
(Тогда ввод нового значения будет запрещен, но оно будет считываться!) Суть
данного трюка заключается во включении нового элемента в процессе обработки
события Отсутствие в списке, а это событие возникает только при включенном со­
стоянии свойства Ограничиться списком.
На рис. 3.11 показана форма в режиме конструирования. Эта форма содержит пол<!
со списком, а рядом с ней изображена таблица с перечнем свойств этого поля,
в которой значение свойства Ограничиться списком установлено в Да.
При попытке пользователя добавить новое значение в поле со списком возникает
событие Отсутствие в списке. А новое значение добавляется к списку в процессе
обработки этого события.

Код
Код процедуры не отличается сложностью. В процедуру обработки события пе­
редаются два аргумента: NewData и Response. Аргументы вам создавать не нужно
это делается автоматически:
Трюк № 21. Добавление собственных значений в существующие списки 77

Рис. 3 . 1 1 . Свойство «Ограничиться списком», установленное в «Да»

Private Sub cmb_KnMeHTbi_NotInList (NewData As String, _


Response As Integer)
Dim ctl As Control
Set ctl = Me.стЬ_Клиенты
Response = acDataErrAdded
ctl.RowSource = ctl.RowSource & ";" & NewData
End Sub
Значение, присваиваемое переменной Response, определяет для Access характер
последующих действий. В данном случае введенное значение будет добавлено
к списку. Это достигается присвоением переменной Response значения констан­
ты acDataErrAdded. После этого новое значение (содержащееся в аргументе NewData)
будет добавлено к источнику строк.

Трюк в трюке
Пока в данном трюке был использован источник строк типа Список значений. Но
если в этом качестве выступает Таблица или запрос, то вам следует дополнить про­
цедуру командой на добавление нового значения к основному источнику данных.
Тогда процедура обработки события Отсутствие в списке дополнит новым значени­
ем исходную таблицу.
В коде измененной процедуры предполагается, что исходная таблица называется
1Ы_Способы_доставки, а поле этой таблицы — СпособДоставки:
P r i v a t e Sub cmb_Cnoco6_flocTaBKM_NotInList(NewData As S t r i n g , _
Response As I n t e g e r )
Dim новые_данные As S t r i n g
Dim conn As ADODB.Connection
Set conn = C u r r e n t P r o j e c t . C o n n e c t i o n
'удвоение всех апострофов перед операцией I n s e r t
новые_данные = Replace(NewData, , ' )
Response = acDataErrAdded
conn.Execute " I n s e r t I n t o " & _
78 Глава 3. Ввод данных и перемещение по элементам управления

'ЧЫ._Способы_доставки(СпособДоставки) ValuesC" & _


новые_данные & " ' ) "
End Sub

Ш Приемы заполнения и сортировки


списков
Использование трех необычных методов для заполнения и сортировки списков.
Списки являются штатным элементом конструктора форм. Правда, не всем фор­
мам они подходят, но там, где их можно применить, выбор значения из списка
упрощает работу, избавляя от ручного ввода данных. К тому же их использовани з
позволяет избежать опечаток.
В данном трюке представлены три способа заполнения и сортировки списков.
В каждом примере ключевыми элементами являются исходные таблицы и структу­
ра. В примерах демонстрируются способы сортировки данных из двух источни­
ков в алфавитном порядке, сортировка на основе ключевого элемента, сортировка
с применением операторов команды SQL и даже сортировка на основе от­
слеживания востребованности самих элементов списка. Ключевым звеном
в реализации большинства способов служит SQL-оператор Union.

Форма
На рис. 3.12 изображена форма с тремя списками, условно названными Список 1,
Список 2 и Список 3.

Рис. 3 . 1 2 . Ферма, содержащая три элемента Список

Источником заполнения списков служат две таблицы: гЫ._Фрукты и г.Ы_0вощи


(рис. 3.13). Обратите внимание, что у них два одинаковых поля: Сортировочный-
Номер и Наименование. Такая общая структура выбрана неспроста, в чем вы скоро
убедитесь сами.
Трюк № 2 2 , Приемы заполнения и сортировки списков 79

Рис. 3 . 1 3 . Две таблицы, используемые для заполнения списков

Заполнение списка в алфавитном порядке


из двух источников
Список 1 содержит значения, взятые из двух таблиц и отсортированные по алфа­
виту уже после объединения. Суть трюка заключается в управлении списком, ис­
пользующем записи двух таблиц в свойстве Источник строк. Записи объединены за
счет выполнения запроса, содержащего оператор Union. На рис. 3.14 показана фор­
ма в режиме конструирования с раскрытым списком свойств, относящихся
к элементу Список 1.

Рис. 3 . 1 4 . Список 1: свойство «Источник строк»

Команда SQL в свойстве Источник строк выглядит следующим образом:


Select Наименование from 1Ы_Фрукты UNION Select Наименование from
tbl_0Bouin;
Оператор Union объединяет значения двух таблиц в том случае, если структура
и тип данных в них совпадают. Другими словами, в команде SQL используются
поля Наименование каждой из таблиц. При использовании оператора Union нуж­
но, чтобы каждый оператор Select запрашивал одно и то же количество полей. За­
прос не сможет работать, если количество полей, к которым открывается доступ
в каждой таблице, будет разным.
80 Глава 3. Ввод данных и перемещение по элементам управления

В результате объединенные записи проходят сортировку, как будто они принад -


лежали единому источнику (что технически так и есть — благодаря запросу, ис -
пользующему команду Union). Поэтому различия между фруктами и овощам i
искусственно стерты и спаржа следует за персиком, брокколи — за бананом и т. д.
Такая технология может пригодиться в тех случаях, когда требуется предоста­
вить элементы списка, составленного из нескольких источников. В следующем
фрагменте будет рассмотрена возможность собирать воедино данные из любого
необходимого количества источников с помощью нескольких операторов Union.

Управление сортировкой списка, составленного


из нескольких источников
На рис. 3.12 в элементе Список 2 отображается результат раздельной сортировки
фруктов и овощей. Список включает также разделительные строки и значения,
которых нет в исходных таблицах: Все, Все фрукты и Все овощи. Как же все это мог­
ло попасть в список?
Запрос, содержащий оператор Union, осуществляет заполнение списка. Исполь­
зуются два источника данных —г.Ы_Фрукты и т_Ы_0вощи, но теперь их данные не
перемешиваются и не сортируются в алфавитном порядке, вместо этого сорти­
ровка осуществляется по содержимому поля СортировочныйНомер.
Здесь ключевым моментом служит различие диапазонов числовых значений поля
СортировочныйНомер в Ш_Фрукты и в 1:Ы_0вощи. Операция Union фактически при­
водит к объединению данных из обоих источников в единый, отсортированный
список, но разница в диапазонах числовых значений поля СортировочныйНомер
приводит к разделению общего списка на две части.
На рис. 3.15 показана форма в режиме конструирования с перечнем свойств, при
надлежащих элементу Список 2. Команда SQL, определяющая содержимое свой
ства Источник строк, показана в окне Область ввода.

• Область данных

Щ , •--*
Список!: ^Гписок ?. • ^Список 3 : ;
-Свободны Свободный

Свободны

Select "Все"
т *asв a, -2 as СортировочныйНомер from (Ы_Фрукты union Select
вода
as a, -1 as СортировочныйНомер from tblJTJpyxTbi Union Select "Все
фрукты" as a, 0 as СортировочныйНомер from (Ы_Фрук:ть1 Union Select
Наименование, СортировочныйНомер From 1Ы_Фрукты Union Select"—" as
а, 99 as СортировочныйНомер from (Ь1_Овощи Union Select "Все овощи" as
100 as СортировочныйНомер from сЫ_Овощи Union Select
Наименование, СортировочныйНомер From tbl^OeoiuH Order 6
Cop тироеочиыйномер

«•i,.:

Рис. 3 . 1 5 . Содержимое свойства «Источник строк» для элемента «Список 2»


Трюк № 22. П р и е м ы заполнения и сортировки списков 81
Вот содержимое этой команды S Q L :
Select "Все" as a, -2 as СортировочныйНомер from tbl_<t>pyKTbi
Union Select " — " as a, -1 as СортировочныйНомер from tbl_1>pyKTbi
Union Select "Все фрукты" as a, 0 as СортировочныйНомер from tbl_<t>pyKTbi
Union Select Наименование, СортировочныйНомер From tbl_OpyKTbi
Union Select " — " as a, 99 as СортировочныйНомер from tbl_0BOiun
Union Select "Все овощи" as a,
100 as СортировочныйНомер from tbl_0BOHM
Union Select Наименование, СортировочныйНомер From tbl_0Boiwi
Order By СортировочныйНомер
Ничего сложного для понимания здесь не происходит. В общем, команда SQL
объединяет в список строки, полученные из исходных таблиц, со строками, полу­
чаемыми из самой команды SQL. Все строки связаны воедино значением поля
СортировочныйНомер. Команда SQL использует оператор Union несколько раз, и вы
можете убедиться, что все операторы Select указывают на одинаковое количество
полей. В данном примере это количество равно двум.
Команда SQL начинается с размещения слова «Все» в начале списка при помощи
следующего фрагмента кода:
Select "Все" as a, -2 as СортировочныйНомер
В этом кодовом фрагменте желаемое достигается за счет сопоставления со сло­
вом «Все» наименьшего значения поля СортировочныйНомер (-2). Здесь следует
пояснить, что ни само слово «Все», ни значение -2 не являются данными исход­
ной таблицы. Тем не менее структура их размещения в команде SQL совпадает со
структурой других операторов Select, встречающихся в команде, что позволяет
им объединяться с другими значениями, получаемыми этой командой.
Команда SQL использует оператор Union для объединения значений, полученных
из таблиц со значениями, созданными в процессе работы самой команды. В ко­
манде SQL представлены следующие значения, создаваемые в процессе выполне­
ния команды:
Select "Все as a, -2 as СортировочныйНомер from tbl_<t>pyKTbi
Select as a, -1 as СортировочныйНомер from tbl_<t>pyKTt>i
Select "Все фрукты ' as a , 0 as СортировочныйНомер from tbl_<t>pyKTt>i
Select as a, 99 as СортировочныйНомер from tbl_Oeonn
Select "Все овощи" as a, 100 as СортировочныйНомер from tbl_0eoiun
Каждый из этих фрагментов команды SQL внедряет в список какое-нибудь из
значений: Все, Все фрукты, Все овощи или —. Ни одно из этих значений из таблиц
не берется. Тем не менее всем им сопоставлен сортировочный номер, согласно
которому они занимают свое место в последовательности элементов списка.
С элементами, создаваемыми в процессе работы команды, должны сопоставлять­
ся сортировочные номера с учетом сортировочных номеров элементов, получае­
мых из таблиц (см. рис. 3.13). Сортировочные номера для овощей начинаются со
значения 101. Поэтому словосочетанию «Все овощи» сопоставлен номер 100. Это
обстоятельство приводит к его появлению в списке перед перечнем овощей.
Имейте в виду, что такой список, как этот, с рядом доступных для пользователь­
ского выбора элементов, требует соответствующего функционального обеспече­
ния, предназначенного для обработки выбранного элемента. Если выбор пользо­
вателя падет на отдельный фрукт или овощ, то приложение, скорее всего, про­
должит нормальную работу. А что, если он выберет «Все фрукты»? Функции
82 Глава 3. Ввод данных и перемещение по элементам управлен!- я

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


цу Ш_Фрукты.
Следует также заметить, что в список внесены разделительные знаки (—), разби­
вающие длинный список значений на отдельные части. Эта группа символов по­
могает ориентироваться при прокрутке длинных списков, но ведь пользователь
может остановить свой выбор и на ней! Поэтому нужно предусмотреть проверку
правильности пользовательского выбора и соответствующую реакцию систем .л
на неподходящий выбор. Обычно если пользователь выбирает разделительные
знаки, он должен быть предупрежден, что следует выбрать другой элемент.

Сортировка списка элементов по степени


их востребованности
Бывает довольно трудно предположить заранее, какие из элементов окажутся
наиболее востребованными. Вы можете воспользоваться полем с сортировочны­
ми номерами и выстроить элементы списка в нужной последовательности, но эт/
задачу все же лучше решить по-другому.
Почему бы не дать возможность самому пользователю влиять на процесс сорти­
ровки списка? Памятуя о том, что легче всего отсортировать список, используя
поле с числовыми значениями, можно прийти к выводу, что значение числового
поля должно отражать востребованность того или иного элемента списка.
Проще всего этого сделать путем обновления того поля, по значениям которого
ведется сортировка, при каждом выборе соответствующего элемента. На рис. 3.1(5
показана форма в режиме конструирования с перечнем свойств, относящихся
к элементу Список_3.

: : ^'::^::'-: : . ; : -№К

• I - . | . 2 - 1 -J • I • • • • 12 • ' • !3 • l • И ' i • 15 ' i • № '

D • Область данны*

Щ. .
:Слисок 1: i ^ГписокЭ;^ .
Свп6одиьиЗ„ Ш Щ
С п и с о к _Э

Имя . . ..Список 3
Данные
Тип источника строк . . . . Таблица или запрос
•Таблица w j __ Щ
Источник строк SELECT Востребованность, Наименование FROM ^ ф р у к т ы ORDER BY Востребованность DESC; i Y ^ s i
Число столбцов .2'г •
Заглавия столбцов ,;нет
Ширина столбцов .:6см; 2см
Присоединенный столбец . •Ж^.."'""'"""
Значение по умолчанию . .
Сохранение режима IME . . •$T1ZZZ.'"'".''..
Режим IME . Нет контроля
Режим предложений IME . . .[Нет

Рис. 3 . 1 6 . Список_3: Свойство «Источник строк»


Трюк № 23, Использование в форме дополнительных элементов управления 83

В качестве источника строк для элемента Список_3 послужит следующая команда


SQL:
SELECT Востребованность, Наименование FROM tbljDpyKTbi ORDER BY
Востребованность DESC;
В данном списке используется только таблица т.Ы_Фрукты. В ней имеется допол­
нительное поле Востребованность, определяющее характер сортировки записей
в списке. Обратите внимание на свойство Источник строк: записи попадают в список
на основании значений поля Востребованность, будучи выстроенными по убыванию.
Чтобы все это приобрело какой-то смысл, нужно найти способ обновления значе­
ний поля Востребованность. Обновление этого поля должно происходить при об­
работке выбранного из списка значения в соответствии с избранным в приложе­
нии способом. В учебных целях, для достижения наглядности, в форму помещена
специальная кнопка. Вот процедура обработки события щелчка на этой кнопке:
P r i v a t e Sub сп^_0бновление_счетчика_С1ick( )
'получение текущего состояния счетчика для указанного элемента
Dim счетчик_текущего_элемента As I n t e g e r
I f Not IsNull(Me.CnncoK_3) Then
счетчик_текущего_элемента = _
ОЬоокирС'Востребованность", 'ЧЫ._Фрукты", "Наименование1^' " &_
Me.Список_3 & )
'увеличение показания счетчика на единицу и внесение изменений в таблицу
счетчик_текущего_элемента = счетчик_текущего_элемента + 1
DoCmd.SetWarnings False
DoCmd.RunSQL ("Update tbI_<t>pyKTbi Set Востребованность^' & _
счетчик_текущего_элемента & " Where Наименование^" & _
Ме.Список_3 & )
Me,Список_3.Requery
End If
End Sub
В двух словах, функция DLookup находит текущее значение поля Востребованность,
относящееся к выбранному элементу, и присваивает его переменной счетчик_те-
кущего_элемента. Значение переменной увеличивается на единицу, а SQL-команда
Update записывает измененное значение на место ранее извлеченного из таблицы.
Затем список обновляется, что приводит к перестраиванию порядка следования
его элементов.
В результате всех этих операций, когда выбирается один из элементов списка, он
«всплывает» ближе к началу этого списка. Вы сможете это заметить, сравнивая
расположение элементов в Списке_3 на рис. 3.12 со значениями поля Востребован­
ность в таблице на рис. 3.13. Например, Малина стоит первой в Списке_3 потому,
что у нее наивысшее значение в поле Востребованность.

Ш
Использование в форме дополнительных
элементов управления
Забудем об обычных формах управления Access и откроем новые возможности разработки.
Если у вас уже имеется достаточный опыт разработки приложений Access, зна­
чит, освоено и содержимое Панели элементов, и знакомы не только сами элементы,
но и методика их применения. При этом вы не могли не заметить, что на панели
84 Глава 3. Ввод данных и перемещение по элементам управления

есть еще одна кнопка, открывающая доступ к дополнительным элементам. Расп( i


ложение этой кнопки показано на рис. 3.17.

Фпрма2 : фор»«
;
j . . ; 3 • ! •• ч • • • v « 5

Заголовок- -формы''

JQ

!
At abl L l г '

\ 1 Л ~>> J U £

Другие элементы |

^Примечание Формы::

Рис. 3 . 1 7 . Дополнительные элементы управления

Выбрать новый элемент можно из списка, который открывается по щелчку на


кнопке Другие элементы. Я не предлагаю перепробовать все элементы из этого спис­
ка, поскольку не все из них пригодятся в Access. Тем не менее, если прокрутить
список до элементов Microsoft, можно будет найти несколько интересных экземп­
ляров, которые следует попробовать применить в форме. Давайте рассмотрим, ка <
можно будет воспользоваться некоторыми из этих дополнительных элементов.

Добавление дополнительного элемента к элементам формы


Список дополнительных элементов на разных компьютерах может быть разный,
но элементы управления Microsoft Forms должны в нем присутствовать обяза­
тельно, поскольку они устанавливаются вместе с Microsoft Office.

. 2 . , . 3 . , . 4 .

.JDS33E553I

i >

Рис. 3 . 1 8 . Элемент SpinButton, установленный в форме


Трюк № 24. Подтверждение изменений перед сохранением записи 85

В качестве примера я поместил в форму элемент Microsoft Forms 2.0 SpinButton


(рис. 3.18). Делается это очень просто: элемент выбирается из списка, а затем его
границы прорисовываются на форме с помощью мыши.
Этот элемент управления имеет настраиваемое свойство минимального и макси­
мального значения счетчика, поэтому его можно использовать для циклического
изменения значений в диапазоне 1-100 или 128-133 либо в любом другом под­
ходящем по смыслу диапазоне. Доступ к значению счетчика можно получить
в программном модуле, воспользовавшись тем же способом, который применял­
ся при работе с другими управляющими элементами.
Затем я поместил в форму элемент Microsoft Date and Time Picker Control 6.0
(рис. 3.19). Этот эффектный элемент управления находится в свернутом состоя­
нии до тех пор, пока на нем не щелкнуть кнопкой мыши, после чего он раскрыва­
ется в календарь с прокруткой. Его использование облегчает работу, избавляя
пользователя от ручного ввода даты. Преимущество этого элемента управления
в том, что он в неактивном состоянии занимает совсем мало места.

j j Ноябрь 2005 •А
- 1 2 3 4 5 6
7
14
8 9 10
15 16 17
11 12 13
<Т2)19 20
<!•
21 22 23 24 25 26 27
28 29 30 I 2 :••

H^Toda»: 18.11.2005

Запись: ПЙГ] « f " SD»


Рис. 3 . 1 9 . Упрощение выбора даты

Вам будет полезно ознакомиться с некоторыми новыми элементами управления


и включить их в свой арсенал. Тем самым вы расширите горизонты конструиро­
вания форм и обогатите свой личный опыт.
См. также: «Проигрывание видеоклипов в форме Access» (Трюк № 34), «Использо­
вание браузера в приложении Access» (Трюк № 97).

Подтверждение изменений, внесенных


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

ные утрачиваются, если только не предусмотрены какие-нибудь меры наподобие


резервного копирования.
И тут нам на помощь может прийти одно из средств управления процессом — ее -
бытие До обновления. Используя обработку этого события, можно запросить у полг -
зователя разрешение на окончательное обновление данных. Если будет получе i
отрицательный ответ, изменения будут отменены.
Пользователи могут выбирать, где именно получать запрос на подтверждение
внесенных изменений, поскольку излишние запросы могут изрядно надоесть. Н а
рис. 3.20 показана форма с флажком в правом верхнем углу, позволяющим уста­
новить запрос на внесение изменений.

J j l W - n l i ! : форме
:...!*.
. :: Фа«
Фамилия: :федотое
1%я: ^Александр : : Ifj :3enpdiiJtiL'.i'Tt. гюдтрер*дениу на внесение изменении! •
lv НовкнКчет j
ОтчвСтВО!': £ :; :: :И ИК ° ЛйвВИЧ
Д д р « : ^Ташкентская 23-41 ГсфДО Самара !• /Регйдй:;:.;

Почтовый индекс: ^43122 \. Телефон рабочий: ;б2-54-\г "


Телефон мобнпьный: Р-913-345-67-Ё ; -Электроиньй адрес;'\

Номер корпуса •Изготовитель '• М:депь 1 . . Ц в е т . [;: Год выпуска


33544J19HY Тойота Rav4 ;Серебристый ;2000
^4pU75SA, ' •Тойота Королла Синий

За™ U U *• '• 1 Г1ШУШ«2 ш • * •

\ Счета:
:|: : | Дата счета.::] Статус | :Номер . : Изготовитель: , - И ; Модель::; _[06щая стоимость

Щшишшшиш!
:
:У::: : • :: ' : :
Ш1
} Загмсь \\*_ •'• \ i - .JML, т 1 ш >

Рис. 3.20. Флажок, предназначенный для установки запроса на внесение изменений

Событие До обновления наступает при условии, если в данные действительно вно


сились изменения. При обработке этого события проверяется состояние флажка
и, если он установлен, выводится запрос на подтверждение (рис. 3.21).
Если пользователь щелкнет на кнопке Да, изменения будут записаны, а если он
выберет кнопку Нет, будет выполнена команда отмены изменений. В процедуру
обработки события следует ввести следующий код:
P r i v a t e Sub Form_BeforeUpdate(Cancel As I n t e g e r )
I f Me.спк_Подтверждение = True Then
продолжение = MsgBox("XoTme сохранить внесенные изменения?", vbYesNo,
"Запись изменений")
I f продолжение = vbNo Then
DoCmd.RunCommand acCmdUndo
End I f
End I f
End Sub
В данном трюке важно то, что пользователь сам решает, получать запрос или нет
Постоянные запросы на подтверждение изменений могут вызвать нервное рас­
стройство. Поэтому лучше дать возможность пользователю самому включать запрос
при внесении изменений в поля, содержащие важную информацию, например
в поля имен и адресов, и выключать его, когда изменения вносятся во второсте­
пенные поля.
Трюк № 25. Отображение в форме показаний цифровых часов 87

Фамилия: '.' Федотов


Имя: •'••^Александр Запрашивать подтверждение ма внесение изменени
'":••::• о т ч е с т в о ^ - : Н и К 0 Л й ^ и ' - <

i : Адрес;: -[Ташкентская 23-41

[ Почтовый индекс^[J443122
; i • Телефон «обильный:; $3-913-345-67-89
||::3аиетки1 :
: Телефон; [23-56-79
:
;. Город; ;Самара

Факс; $52-54-18
[[.; [Регион:.:

Телефон рабочий:- ;62-54-12 "

••-•'- Эл^ктр0ннь1Й адрес;;: [


Печать истории
сделок[

А^ТО>10биЛИ! ' . • • . •

Записи и » « и е н
Номер корпус а •• Изготовителе Год выпуска
• 33544J19HY : Тойота Хотите сохранить внесенньге: изменения? :|ый 2000
99940U75SA !Тойота 72000"

*! __ .'...;. I Да Нет |
Запись; ( M J « Г
Счета;
I"•".'!'•')•*> .
rr^i
Дата счета | : :!:Статус ; Номер Изготовитель | Модель | Общая стоимость

| ?»пись' ;ТТ) \ Т и и; 1

Рис. 3.21. Запрос на сохранение изменений

Отображение в форме показаний


Т Р Ю К

О №25 цифровых часов


Отображение даты и времени для нескольких часовых поясов.
Используя события Таймер и Интервал таймера, а также системные часы, вы може­
те отобразить показания электронных часов в форме.
На рис. 3.22 показаны часы, помещенные в заголовок формы. Они неспроста раз­
мещены в заголовке, а не в области данных, поскольку это делает их независимы­
ми от особенностей каждой записи.

13:45:59

Федотов Александр Николаевич

Ташкентская 23-41
Самара

Запись; jJjQ i j T ^ Z " С О Ш > * 1 «" I __'

Рис. 3.22. Форма с изображением текущего времени

Вы можете заниматься своими делами, перелистывать записи, вносить в них из­


менения и т. д., а показания времени будут изменяться своим чередом.
88 Глава 3. Ввод данных и перемещение по элементам управления

Создание часов
Создать часы не составит труда. Сначала нужно поместить в форму элемент уп­
равления Надпись. Затем установить в свойствах значение элемента Интервал вре­
мени в 1000 (что соответствует одной секунде). И наконец, поместить кодову»
строчку в процедуру обработки события формы под названием Таймер:
Me.1Ы_Часы.Caption « Format(Now( ), "hh:mm:ss")
В данном случае предполагается, что элемент Надпись получил имя 1Ы_Часы. Функ­
ция Now возвращает системное время, а функция Format придает отображени»
времени желаемый вид. Применять функцию форматирования не обязательно.
Без нее будет возвращено полное значение даты и времени. А в предложенном
варианте функция форматирования возвращает только показания времени; фор­
мат hh:rnm:ss относится к часа (hh), минутам (mm) и секундам (ss).

Трюк в трюке
Вы можете значительно расширить привлекательность и функциональные воз­
можности цифровых часов. Вот первая идея: вы можете демонстрировать теку­
щее время для городов, находящихся в разных часовых поясах. На рис. 3.23 пока­
зана форма с двумя циферблатами. На одном из них отображается время для
Москвы, а на другом — для Нижнего Новгорода.

"
••

Москва- Нижний Новгород

14:00:19 15:00:19
§

Федотов Александр Николаевич
Ташкентская 23-М
Самара

•-. з

Заг»*ъ; UU * 1 1 (JL;iyJ**J из !

Рис. 3.23. Двойное отображение времени в форме

Нижний Новгород отстоит от Москвы на один часовой пояс. Эту разницу в покг -
заниях часов можно высчитать с помощью функции DateAdd. Дополненный ко а
процедуры обработки события Таймер должен выглядеть следующим образом:
Me.1Ы_Часы_Москва.Caption = Format(Now( ), "hh:mm:ss")
Me.1Ы_Часы_Нижний_Новгород.Caption = Format(DateAdd("h", 1, Now( )),
"hh:mm:ss")
Функция DateAdd способна прибавлять или вычитать значения времени. В дан­
ном случае значение 1 приводит к прибавлению одного часа.
А вот вторая идея: предоставить пользователю способ самостоятельно изменять
формат отображения. Реализовать ее поможет глобальная переменная и проце­
дура обработки двойного щелчка на элементе типа Надпись. При открытии формы
Трюк № 26. Рационализация переходов по элементам 89

глобальная переменная тип_формата получает значение 1. При каждом двойном


щелчке на циферблате значение этой переменной возрастает на единицу. Когда
оно достигнет четырех, происходит сброс и значение возвращается к единице.
Процедура обработки события Таймер проверяет значение переменной вариант_
формата и устанавливает формат, соответствующий этому значению. Далее пред­
ставлен программный модуль формы, реализующий данный замысел, в его пол­
ном варианте:
Option Compare Database
P u b l i c вариант_формата As S t r i n g

P r i v a t e Sub Form_0pen(Cancel As I n t e g e r )
вариант_формата = 1
End Sub

P r i v a t e Sub Form_Timer( )
S e l e c t Case вариант_формата
Case 1
Me. 1Ы_Часы.Caption = Format(Now( ), "hh:mm:ss")
Case 2
Me. 1Ы_Часы. Caption = Format(Now( ), "hh:mm ")
Case Else
Me. 1Ы_Часы.Caption = Format(Now( ), "dd/mm hh:mm ")
End S e l e c t
End Sub

P r i v a t e Sub l b l _ 4 a c b i _ D b l C l i c k ( C a n c e l As I n t e g e r )
вариант_формата = вариант_формата + 1
I f вариант_формата = 4 Then вариант_формата = 1
End Sub
Теперь у пользователя будет возможность двойным щелчком на циферблате под­
бирать формат отображения даты и времени по собственному усмотрению. Разу­
меется, увеличить количество доступных форматов особого труда не составит.

Н Рационализация переходов
по элементам
Совершенствование последовательности переходов, позволяющее сразу попадать
в нужные поля.
Конструируя форму, вы вряд ли обращаете особое внимание на порядок переме­
щения по элементам, поскольку для его определения не требуется ни особых раз­
думий, ни глубокого анализа. Обычно этот порядок определяется в самом конце
работы, когда все элементы управления уже расставлены по местам. Честно гово­
ря, я порой даже забывал об установке последовательности переходов по элемен­
там в созданных мною формах. Конечно, коллектив пользователей тут же указы­
вал мне на это упущение.
Тогда я задумался: если последовательность перехода в форме так уж важна для
пользователей, то почему бы не подойти к решению этого вопроса более рацио­
нально? В некоторых формах данные вводятся только в часть имеющихся полей.
90 Глава 3. Ввод данных и перемещение по элементам управления

Разумно было бы в таком случае настроить переходы в форме с учетом тех поле 9,
которые могут быть пропущены.
Смысл в этом появится при возникновении определенных условий или при под­
чинении содержимого текстовых полей определенной логике. Например, при вво, [е
сведений о новом клиенте вы обычно заполняете каждое поле. Но если вы вводи­
те какую-то информацию, касающуюся ранее зарегистрированного клиента, то,
скорее всего, ряд полей вы пройдете вхолостую.
На рис. 3.24 показана форма, в которой осуществляется выбор значения для поля
со списком, названного Статус и имеющего четыре варианта значения: Зарегистри­
рованный, Без направления, Телефоны и Обновление.

3 *гт_Студенты_2 : фор;*»
Выбор студентаine фамилии:
r
Федотов v ] |1^ОРЫЙ студент

Статус: 2 у Источник направления;


Зарегис трированный]
Без направления
Имя; Александр Отчество: Николаевич
Телефоны
Адрес 1 Обновление Телефон домашний: 23-56-79
Адрес 1 Телефон рабочий: 162-5Ч-12
Город: Самара Факс; £2-54-18
РВГИОн; Электронный адрес:

День рождения:
Очередная годовщина:

Рис. 3.24. Выбор варианта перехода из поля со списком

В процедуре обработки события Выход программного модуля поля со спискем


используется структура Select Case, с помощью которой, в зависимости от выбора,
сделанного в этом поле, фокус устанавливается на различные управляющие элг-
менты формы. Например, статус Без направления предназначен для людей, не пр >
шедших регистрацию и прибывших без предписания. Их нужно как-то класси­
фицировать, поэтому следует перейти к полю ввода Источник_направления. Ес/:и
будет выбран статус Зарегистрированный, то программа осуществит переход к полю
Заметки. Вот код процедуры обработки события Выход:
Private Sub CTaTyc_Exit(Cancel As Integer)
Select Case статус
Case "Зарегистрированный"
Me. txt_3aiweTKH. Set Focus
Case "Без направления"
Me.txt_Иcтoчник_нaпpaвлeния.SetFoeus
Case "Обновление"
Me . 1х^Фамилия_студента . SetFocus
End Select
End Sub
Суть данного подхода состоит в том, что вы можете адаптировать правила пере­
хода к любой конкретной ситуации. К примеру, если вы работаете с базой данных
фирменного автосалона и к вам обратился клиент, уже купивший машину, то раз-
Трюк № 27. Выделение активного элемента управления 91

дел, в котором зафиксированы желания клиента в отношении марки и комплек­


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

И Выделение активного элемента


управления
Предоставление визуального ориентира в заполненной форме за счет выделения ак­
тивного элемента
Если вы, переходя от элемента к элементу, вводите данные, то порой бывает труд­
но сориентироваться, какой из элементов в данный момент активен. Чем больше
в форме элементов, тем проще в них заблудиться. В этом трюке демонстрируется
способ выделения активного поля.
В трюке № 26 «Рационализация переходов по элементам» показан способ перехо­
да к определенным элементам формы в зависимости от обстоятельств и в нем
применялась процедура обработки события Выход. Данный трюк использует
обработку не только события Выход, но и события Вход. Все элементы управле­
ния, предназначенные для ввода информации, имеют процедуры обработки
обоих событий.
На рис. 3.25 показана форма, предназначенная для ввода информации, имеющая
обрамление поля Фамилия. По мере переходов пользователя к следующим элемен­
там формы или щелчков на этих элементах активный элемент неизменно получа­
ет обрамление, которое есть в любой момент времени только у него.

Статус: Обновление *• Источник направления:

Фамилий: (Федотов | Иня: Александр Отчество; Николаевич

Адрес 1: ^Ташкентская 23-41 Телефон домашний: 23-56-79


Адрес 1: Телефон рабочий: 62-54-12
ф
Город: Санара ««; 62-54-18
Регион: Электронный адрес:

День рождения:
Очередная годовщина:

Заметки:

Рис. 3.25. Обрамление, возникающее вокруг активного элемента


92 Глава 3. Ввод данных и перемещение по элементам управления

Чтобы осуществить данный замысел, нужно установить во всех элементах формы


свойство Оформление в состояние обычное. Вы можете использовать и другие ус -
тановки, позволяющие иметь обрамление, например, с тенью, но оптимальным яг -
ляется обычный вариант оформления. При использовании варианта с тенью во: -
никает нежелательный эффект: когда обрамление исчезает, его тень все равно
остается.
На рис. 3.26 показан принадлежащий форме программный модуль. В его верхней
части помещаются две процедуры: Вход_в_активный_элемент и Выход_из_активнс-
го_элемента, которые работают по вызову из процедур обработки событий Вход и
Выход, принадлежащих элементам управления формы. Процедура Вход_в_актиЕ-
ный_элемент предписывает активному элементу независимо от его предыдущего
состояния включить тонкое красное обрамление. Стиль границы имеет значение ,
соответствующее сплошной линии. Ширина границы имеет значение 2, соответ­
ствующее тонкой линии. Затем устанавливается красный цвет границы.

O p t i o n Compare D a t a b a s e Щ
P r i v a t e Sub вход_в_активный_злемент()
With H e . A c t i v e C o n t r o l
.Properties("BorderStyle") - 1
.Properties("BorderUidth") = 2
. P r o p e r t i e s ( " B o r d e r C o l o r " ) = vbRed
End U i t h
End Sub
P r i v a t e Sub выход_из_активнопо_элемента{)
He.ActiveControl.Properties("BorderStyle") = 0
End Sub
Private Sub Фамилия_Епсег(J
вход_в активный_элемент
End Sub __ _
P r i v a t e Sub Фамилия_Ехit(Cancel As I n t e g e r )
вых од_из_активного_э леме нта
End Sub •
P r i v a t e Sub MMn_Enter()
вход в активный_элемент
End Sub Щ i
P r i v a t e Sub Имя E x i t ( C a n c e l As I n t e g e r ]
вых од__из_активно го_э леме нта
End Sub щ
P r i v a t e Sub Адрес_домашний_1_Епгег О ;|S:i :
вход в активный элемент
End Sub Sf

Рис. 3 . 2 6 . Программный код для включения и отключения обрамления

Процедура Выход_из_активного_элемента содержит одну-единственную строку


кода, которая переводит обрамление в прозрачное состояние.
Каждый вход в элемент управления означает, что произошел выход из другого
элемента. Поэтому две процедуры выполняются в паре. Процедура выхода отклк -
чает обрамление одного элемента, процедура входа включает обрамление другого.
Использование технологии, рассмотренной в данном трюке, дает возможность
пользователю ясно различать активный элемент на фоне неактивных.
Г Л А В А 4

Представление данных
Трюки № 28-39

При всей сложности приложения базы данных, в котором содержится множество


специально созданных функций, искусно составленных запросов и прочих изо­
щренных решений, в конечном итоге от него требуется обеспечить извлечение
сведений, выстраиваемых на основе имеющейся в базе информации. И тут на пер­
вый план выступают формы и отчеты. Чтобы построить наше взаимодействие с -
базой данных, требуется разработать эффективный интерфейс приложения. Сис­
тема Access предоставляет для решения этой задачи массу возможностей.
Конструктор отчетов Access представляет собой средство разработки с богатым
функциональным набором. В него включены инструменты форматирования, груп­
пировка и сортировка записей, обширная палитра управляющих элементов, а так­
же возможность перехвата событий и разработки необычных решений с исполь­
зованием VBA. Формы также способны реагировать на события, имеют варианты
форматирования и массу различных свойств. Использование всего этого арсена­
ла невозможно охватить в одной главе. Поэтому здесь будут освещены лишь не­
которые стимулирующие фантазию способы работы с формами и отчетами.
Методы использования форм для просмотра записей базы данных уже были рас­
смотрены. А что, если их использовать и для просмотра фотографий или видео­
клипов? Как это делается, показано в разделах -«Демонстрация слайдов в Access»
(Трюк № 33) и «Проигрывание видеоклипов в форме Access» (Трюк № 34).
Обычно наилучшими бывают первые впечатления. Поэтому создаваемые вами
отчеты должны радовать глаз. Часть трюков этой главы посвящена рациональной
группировке и форматированию данных в отчетах. В разделе «Создание прямой
ссылки на отчет» (Трюк № 31) показан прием, позволяющий слишком занятым
пользователям щелчком на ярлыке распечатать отчет, не связываясь с самой ба­
зой данных. В разделе «Просмотр отчетов в форме» (Трюк № 35) объясняется
способ просмотра образов отчетов в форме.
94 Глава 4. Представление даннь х

Ш Деление отсортированных по алфавиту


записей на группы по буквам
Новые возможности представления данных, появляющиеся при установке свой­
ства группировки в состояние По первым знакам.
В сортировке по алфавиту нет ничего нового, она на самом деле настолько при­
вычна, что воспринимается как нечто само собой разумеющееся. Но просмат­
ривать десятки и сотни распечатанных страниц в поисках одной-единствен-
ной записи — крайне утомительное занятие, даже если данные отчета следуют
в алфавитном порядке.
Становится понятным, что записи в отчете нужно еще и разбить по алфавиту. На
рис. 4.1 показана страница отчета, в которой список отсортированных записей пред­
ставлен единым блоком, без выделений или разбиений. Хотя записи и отсортирова­
ны, но они представлены в таком виде, что найти что-либо нужное крайне сложно.

Рис. 4 . 1 . Отчет, представленный в однообразном виде

Сама конструкция отчета проста и понятна. В области данных содержатся пол л,


которые превращаются в строки отчета. В представленном варианте отчета груп­
пировка не используется, что, собственно, и придает ему такой однообразный вид.
На рис. 4.2 показан отчет в режиме конструирования.

Разбиение по буквам
Использование группировки в структуре отчета позволяет разбить непрерывны й
список, состоящий из однообразных строк. На рис. 4.3 показано, как нужно изме­
нить конструкцию отчета, чтобы добавить в него группировку.
Трюк № 28. Деление отсортированных по алфавиту записей по буквам 95

* j Сортироека по фамипии : отчет

Рис. 4 . 2 . Отчет, в котором не используются сортировка и группировка

Is Сортировка по фамилии : отчет


16 • . • ;

• Еврхнхи колонтитул

^Клиенты
Фамилия Имя: О т ч е с т в о ; Адрес: J [Город; • -:ШШ-
• Заголовок группы'Фамилия'
!=1.еЛ([Фамипия|;1)

# Область данных
;Фамипия i Имя \ ^Отчество I ;Адрес \ Город
•* Нижний колонтитул

:="Страмица " 3 [Page] & " из" & [Pages]


Гкэл^выра кемме ПОРЯДОК СОРТИР' 1
Щ Фамилия По возрастанию
...: Цш

Заголовок группы .Да


Г^**течанив группы :Нет
Группировка . .'Ло первым знакам
Интервал::;..: 1
Не разрывать: Нет

Рис. 4 . 3 . Отчет, использующий сортировку и группировку

Группировка и сортировка проводятся по содержимому поля Фамилия. Группи­


ровка имеет следующие ключевые особенности:
• Используется заголовок, и не используется примечание. Заголовок группы и При­
мечание группы установлены в диалоговом окне Сортировка и группировка соот­
ветственно в Да и Нет.
• Свойство Группировка в диалоговом окне Сортировка и группировка установлено
в состояние По первым знакам, а свойство Интервал установлено в 1.
• В заголовок группы вставлено свободное текстовое поле, а его свойство Дан­
ные содержит выражение.
При создании отчета выражение, помещенное в свободное текстовое поле, приве­
дет к тому, что создание группы будет зависеть не от появления каждой новой
96 Глава 4. Представление данньх

фамилии, а от появления в начале фамилии новой буквы алфавита. В результате


будут собраны в группы все фамилии, начинающиеся на А, на Б и т. д. Достигается
это использованием функции Left, возвращающей первую букву:
=l_ef t ( [Фамилия] ; 1)
На рис. 4.4 показан отчет, разбитый на группы по буквам.

{• • •''^Г^К-Ч"-
ртмровка па фамилии
Захаре* Виктор Петрович Техническая 31-18 Екатеринбург л
И

Нсшя Сергей Петрович П а к о в а л 34-81 Перта

И|чехко Полина Миуайловяа Ш и я е р с к д я 34-112 Кемерово

Нпн ояммш HiuciK4 Алтуфьевское шоссе 1 1 2 - 2 Москва

HIUOI ИМЯРПОЮ В асшпешич Индустриальная 128-32 Ноюсибирск


К

Кулигах Георгий С те] и н о е н ч Степная 3 Белгород

Копмясш Николай Васильевич М о е кок скал 26-9 Новгород

Крикса Олег Николаевич Авиаторов 1 8 Клин

К о ю rate i Алексей Анатольевич Овражная 23 Суздаль

Куямана М*рим Петровна Советская 15-104 Тверь

Кумнмм Виктор Леонидович Купе о в с к н й пр. 3 4 - 5 6 Москва

Кшш Александр Викторович Лазо 23-56 Владивосток

1
Капустин Виктор Иваювнч П р и м о р с к а я 40-31 Находка

Киселев Владимир Валерьевич Судаков» 23-15 Москва

Колобов Нияш Викторович Смоленская 12-56 Липецк

Комаров* Светлана Федоре» к» Советская 9 7 - 3 в о л седа


Л

Лиутин Федор Алексее! и ч Ж е л е з н о д о р о ж н а я 15-1 Чех он

Ямш Андрей Семенович К о л х о з н а я 18-45 Ставрополь

Лебедев* Ирин* В аенльевна В е с е н н я я 10-34 Moan a

Лысенко АНАТОЛИЙ Сергеевич Заводская 1 9 - 4 3 Архангельск

С т р а * ц э 0 и)
и V

|Стр* ««» UijCiil •) ULL*.U < {>••

Рис. 4.4. Список клиентов, разбитый на группы по первым буквам фамилий

Более крупный и жирный шрифт букв, а также подчеркивание позволяют четко


различать группы при просмотре отчета.

Трюк в трюке
Обратите внимание, что на странице отчета, показанной на рис. 4.4, отсутствуют
фамилии клиентов, начинающиеся на букву «Й». Отсутствие записей на эту бук­
ву может для кого-то тоже иметь значение. Я однажды слышал, как возмущается
начальник, который вопреки своим ожиданиям не нашел того, чего и не могло быть
в списке: «А где запись о клиенте по фамилии Йонсон?» В таких случаях можно
только указать, что записей, отвечающих определенным условиям, не найдено,
тогда станет понятным, что «потерявшихся» записей просто не существовало.
В частности, было бы полезно указать в отчете, что записей, начинающихся с бук­
вы «Й», не найдено. Нам нужен способ, при котором в отчете будет отображена
эта буква алфавита, но при существующей конструкции отчета она появиться не
сможет. Любые фигурирующие в отчете буквы связаны с существующими запи­
сями о клиентах, чьи фамилии начинаются на эти буквы.
Чтобы в отчете появились все буквы, независимо от наличия соответствующих
записей, в конструкцию отчета нужно включить список букв алфавита, который
Трюк № 28. Деление отсортированных по алфавиту записей по буквам 97

будет сравниваться с данными имеющихся записей. Используемый при этом под­


ход заключается в том, чтобы связать таблицу клиентов с таблицей символов,
вместо того чтобы создавать отчет только на основе таблицы клиентов.
К базе данных добавляется таблица, состоящая из единственного поля Буква.
В таблице содержится 30 записей, но количеству букв алфавита от А до Я, с кото­
рых могут начинаться фамилии. На рис. 4.5 показана таблица, названная т.Ы_Буквы.

Рис. 4 . 5 . Таблица, заполненная буквами алфавита

Неплохо было бы включить в таблицу еще и цифры от 0 до 9, особенно если рабо­


та ведется с названиями компаний.
Раньше свойство отчета Источник записей содержало ссылку на таблицу клиентов
(т,Ы_Клиенты). Теперь же источником записей для отчета послужит запрос. Вот
команда SQL, по которой он будет создан:
SELECT tbl_K/ineHTbi.Фамилия , tbl_KnneHTbi. Имя , 1:Ы_Клиенты.Отчество,
1:Ы._Клиенты. Адрес, 1Ы_Клиенты. Город, 1Ы_Буквы. Буква
FROM tblJOineHTbi RIGHT JOIN т.Ы_Буквы ON
left(tbl_KnneHTbi.Фамилия ; 1) = tbl_ByKBbi. Буква ;
Особенностью этой команды является присутствие оператора RIGHT JOIN, исполь­
зованного для установки связи между таблицами. Тем самым гарантируется при­
сутствие всех записей из таблицы с буквами (т.Ы_Буквы). Иными словами, отчету
станет доступна каждая буква, даже если и не будет начинающихся с нее фа­
милий.
98 Глава 4. Представление данных

Конструкцию отчета также следует подвергнуть незначительным изменения к.


Теперь основанием для группировки уже не служит содержимое поля Фамилия,
вместо этого группировка базируется на содержимом поля Буква. А в свободном
текстовом поле используется новое выражение. Все внесенные изменения ото­
бражены на рис. 4.6.

Г
• Ю • I • 11 • I • |2 • i • 13 •

Р ^,8ер%ний колонтитул

|]&{^ент^!_
Фамилиц; ИМИ: gmw^cmef) Адрес] Гор^>д;
U •4 Заголовок группы *БухваУ
НЩСоип1([Фамилия])>0;[Буква];"Записи на букву " & [Буква] & " отсутствуют')

* Область данных •• •

;Фамипия ii;HMH |Адре Г^род


• Примечание группы 'Буква'
* Нижнийкопонтитул :

Страница '['$. [Раиз] <• и • [Fagesj j

|!« Сортировга и i руппирогеа Щ

;По возрастанию -jr^

Свойства rpynnbt;

j ; Заголовок группы • ;да


| | Тфимечение группы 'iДа
|j;Группировка :По nepei
Интервал:- т '
I ;Ме разрывать гНет

Рис. 4.6. Группировка на основе букв алфавита

1 Сартирома по ф*1ипни : игчвт - ч _


Завьялова Евгения Александровна Фругое 12-9 Смоленск >;
Зеленцова Наталья Ивановна Мира 12-67 Кострома
Зорина Надежда В асипь евна Автогенная87-4.5 Чита
Зимин Александр Николаевич Ташкентская 23-41 Самара
Зябликов Василий Сергеевич Прибрендаая 23-41 Красноярск
Зах аров Виктор П етрович Техническая 31-18 Екатеринбург
Зопин Сергей Иванович 2-й Сетуньский пр. 2-35 Москва
И

Исаков Сергей Петрович Парковая 34-81 Пермь


Ивченко Полина Михайловна Шахтерская 34-112 Кемерово
Ивин Валерий Иванович Алтуфьевское шоссе 112-2 Москва
Иванов Владимир В асиль евич Индустриальная 128-32 Новосибирск
Записи на букву И отсутствуют

К
Киселев Владимир Валерьевич Судак ова 23-15 Москва
Колобов Михаил Викторович Смоленская 12-56 Липецк
Капустин Виктор Иванович Приморская 40-31 Находка
.'v;
Q
Страница ЩлЖ 1 Ч и] < \:К

Рис. 4.7. Включение в отчет сообщения об отсутствии записей на определенную букву


Трюк № 29. Подсчет промежуточных итогов на основе определенных условий 99

Выражение, помещенное в текстовое поле, возвращает одно из двух возможных


значений. Если хотя бы одна запись содержит фамилию, начинающуюся с задан­
ной буквы, то выводится эта самая буква, а если таких записей нет, выводится
сообщение, что на заданную букву записи отсутствуют. Для выполнения данной
задачи задействованы функции IIF и Count:
=IIf(Count([Фамилия])>0,[Буква],"No records for " & [Буква])
В результате отчет получает в качестве заголовков групп все буквы алфавита, не­
зависимо от того, существуют ли соответствующие им записи (см. рис. 4.7).
Вы можете по-разному приспособить этот трюк под собственные нужды. Напри­
мер, можно скрыть область данных и изменить выражение в заголовке, чтобы при
отсутствии записей выводился прочерк. Тогда в отчете будут отображены только
сообщения об исключениях.

Ш Подсчет промежуточных итогов на основе


определенных условий
Деление общего итога на имеющие смысл составляющие с использованием сумм с на­
коплением и выражений.
Общий замысел состоит в создании двух наборов итоговых данных, подлежащих
сравнению. При создании отчетов эта задача входит в число типовых. Можно
сгруппировать данные на основе различий в значениях одного из полей. Непло­
хим примером могут послужить данные за определенный год. Если в отчет вклю­
чено поле Год, вы можете включить подсчет промежуточных итогов в примечание
группы. То есть вы можете получить итоговое значение (для содержимого любых
других полей) за каждый год.
Но когда появляется потребность вывести итоговые значения с учетом несколь­
ких условий, возникает неразбериха. Вы можете создать две группы, но тогда при­
дется решать, какая из них будет размещаться внутри другой. Такое решение не
всегда бывает достаточно очевидным. Сюда добавляются еще и различные вари­
анты размещения данных. Если вы хотите расположить промежуточные итоги
в произвольном порядке, выйдя за рамки каскадной расстановки, то вам не уда­
стся добиться этого до тех пор, пока вы не задействуете свойства суммы с накоп­
лением и вычисляемые элементы управления.
На рис. 4.8 показан отчет, отображающий общий итог за каждый год, под кото­
рым размещены годовые итоги по отдельным регионам.
Разумеется, отчет, подобный тому, что изображен на рис. 4.8, можно создать с ис­
пользованием других методов: например, воспользоваться подчиненным отчетом.
Использование суммы с накоплением как основной идеи данного трюка — всего
лишь один из возможных вариантов решения проблемы включения в отчет ито­
говых значений, зависящих от нескольких условий.
В данном трюке используется пример из ветеринарной практики, в нем анализи­
руются данные о визитах к врачу за два года и о клиентах, приезжавших из пяти
разных штатов. Источником записей для отчета служит запрос на объединение,
составленный из двух идентичных запросов на выборку, различающихся лишь
100 Глава 4. Представление данн ых

)мты_2003.

Сравнительные сведения
о визитах клиентов по штатам в 2003 и 2004 годах

2003 2004

Всего визитов: 707 Всего визитов: 890

Всего визиюв вСТ: 127 Всего визитов в СТ: 153

Всего визитов в МА: ВО Всего визитов в МА: 93

Всего визитов BNJC 169 Всего визитов в N J 231


Всего визитов в NY 196 Всего визитов в NY 246
Всего визитов в РА: 136 Всего визитов в РА: 167

Рис. 4 . 8 . Общий итог, разбитый на промежуточные итоги

годами, к которым относятся записи: в одном используются записи за 2003, а в дру­


гом — за 2004 год. Итак, источником записей служит следующая команда:
SELECT * FROM ргу_Визиты_2003
Union SELECT * FROM дгу_Визиты_2004
На рис. 4.9 показан запрос qry_Bn3HTbi_2003. У каждого клиента может быть от ну;:я
до нескольких животных, и каждое животное может быть на приеме у врача от
нуля до нескольких раз. Следует иметь в виду, что в отчете отражаются только
состоявшиеся визиты к врачу. Вид животного не имеет значения, но в схеме дан­
ных затребовано обращения к таблице, содержащей сведения о животных (tb ._
Животные).

КлментГО
Фамилия ;ЖивотноеШ
Имя
Второе имя
—' |КлиемтГО
Кличка
;*ВититШ
Адрес :Вид ЖиВОТНОеЮ
г
Город ;Дата_рождения :
Да а_ви' ,ита
Штат
Почтоеый_индекс
Телефон

*.к
••;•-

Поле: Фамилия Штат Вид Дата визита


Имя таблицы: Cbl Клиенты (Ы Клиенты сЬОКивотные tbl Визиты ш
Сортировка; У
Вывод из экран; Й Р1 И
условие отбора: И
или;

< : •

Рис. 4 . 9 . Запрос сведений о визитах к ветеринарному врачу


Трюк № 29. Подсчет промежуточных итогов на основе определенных условий 1 0 1

Использование суммы с накоплением


В этом отчете обрабатываются сотни записей, но поскольку свойство Вывод на
экран раздела Область данных установлено в Нет, на экране появляются только ито­
говые данные. Несмотря на это, раздел Область данных играет существенную роль:
в нем размещается набор текстовых полей, использующих суммирование с накоп­
лением. На рис. 4.10 показан отчет в режиме конструирования.

п •^ Верхний копоититуп •

Сравнительные сведения
о визитах клиентов по штатам в 2003 и 2004 годах

Штат , 'Штат'" | (Дата_визит9:] [Дата визита


1-ИЦШТ1ТКСТ* And УягЩ1ата_Виаитар-20пз,1 ;0)
•ЩШ^а^'^^Х^М?^^У'1'\>^^ЛЙ} Й([Штат].мМА" A n d ' еагГ[Цата_Вюитз|)-2004.1:01
h*5UjTaTJ."N.l And \'eai{(fiwrijimna^2^iWj »ИдШтат]-Т1 J And УеагГЩата в>вита]1-2004.1.0)
•il(jtijTai|= H: And геа.ЦДата_Еи"и о /«2003.1.0) .И(|Штат1- «-'" And Уеаг(1Да1а_Виаита])»2004,1;0)'|
>11([Штат].ТА-And У«аг(1Дата,Визита])«2003 1 0) ; -.||(|Штат|.1>А- And Уеаг(|Даг«_Втито|).2004.1.0)

< Нижний колонтитул

5003...

[Всегр.визи.Т.ов; J -ItxtCT2003|»|txtMA3: iBcerp.визитов;

Всего визитов в CT:j HJS<tCT2d03J jBcero визитов в СТ: ytxtCT20041


Всего визитов в MA: HJtxtMA2003J"" Всего визитов в МД: -|txtMA2l)04|
.Всего визитов в NJ: i -I1xtNJ20031' iBcero визитов в NJ: [-jtitNJ2604J
Всего визитов в NY: -|txtNY2003J ;Всего визитов в NY: -|txtNY20(J4J

Рис. 4 . 1 0 . Свойство «Сумма с накоплением», установленное в состояние «Для всего»

Помимо полей, связанных с существующими данными, раздел Область данных содер­


жит 10 свободных текстовых полей, для каждого из которых свойство Сумма с накоп­
лением установлено в состояние Для всего (см. таблицу свойств на рис. 4.10).
В 10 текстовых полях фигурируют 10 возможных условий. Данные обобщаются
по двум годам и пяти штатам, для получения общего итога с 10 возможными про­
межуточными итогами. В каждом свободном текстовом поле ведется подсчет по
отслеживаемому в нем источнику. Например, текстовое поле txtCT2004 содержит
следующее выражение:
=1If([Штат]="СТ" And У е а г ( [ Д а т а _ В и з и т а ] ) = 2 0 0 4 ; 1 ; 0 )

В соответствии с ним накопление суммы возникает только в том случае, если поле
Штат имеет значение «СТ», а год, извлеченный из данных поля ДатаПриема, равен
2004. Каждое текстовое поле устроено таким же образом и допускает накопление
суммы при появлении определенного сочетания штата и года приема.
Имена, присвоенные этим текстовым полям, играют существенную роль, посколь­
ку на них ссылаются другие элементы управления, расположенные в нижнем ко­
лонтитуле отчета. Выглядят эти имена следующим образом: txtCT2003, txtCT2004,
txtMA2003, txtMA2004 и т. д. В общем, в них используются буквенные индексы пяти
штатов: СТ, MA, NY, NJ и РА.
102 Глава 4. Представление даннь ix

Нижний колонтитул отчета разбит на две области, в одной из которых содержится


итоговое значение за каждый год. Эти области разделены для наглядности н з-
сколькими элементами Линия. На самом деле никаких установок на разбиение
нижнего колонтитула на части не существует. Все текстовые поля нижнего ко­
лонтитула являются свободными и содержат ссылки на текстовые поля из разда­
ла Область данных. Например, в текстовом поле нижнего колонтитула, отображаю­
щем итоговое значение для штата СТ за 2003 год, содержится простая ссылка на
текстовое поле txtCT2003, в котором формируется сумма с накоплением:
=[txtCT2003]
Точно так же устроены все десять полей нижнего колонтитула, отображающее
итоговые данные для разных штатов за разные годы. Каждое из них содержит ссыл­
ку на конкретное текстовое поле из раздела Область данных. В двух общих итога*,
помещенных в нижний колонтитул, каждый из которых основан на показаниях
за отдельный год, просто суммируются значения имеющих к ним отношение пяти
текстовых полей из раздела Область данных. Например, в текстовом поле, отобра­
жающем общий итог за 2004 год, содержится следующее выражение, вобравшс е
в себя значения элементов управления, имеющих к нему отношение:
=[txtCT2O04]+[txtMA2004]+[txtNY2004]+[txtNJ2004]+[txtPA2004]
Осуществляя подсчет итогов в разделе Область данных и ссылаясь затем на текстовые
поля, в которых формируется сумма с накоплением, вы получаете возможность раз­
мещать выходные данные отчета произвольным образом, по своему усмотрению.

Трюк в трюке
Схема данных, показанная в этом трюке (см. рис. 4.9), включает таблицу живот -
ных. А что, если пользователь захочет получить отчет по годам, штатам и живот -
ным? Предположим, что в данных встречаются 10 видов животных (коты, соба­
ки, птицы и т. д.), тогда у вас будет сто вариантов условий: данные за два года, пэ
пяти штатам на десять видов животных. Вы можете, конечно, создать отчет п э
методике, рассмотренной в этом трюке, но это будет слишком утомительным за­
нятием. При таком большом наборе условий лучше воспользоваться отчетом на
основе перекрестного запроса. В примере из раздела «Суммирование сложных дан­
ных» (Трюк № 45) для демонстрации работы запроса такого типа используете.!
модель данных, взятая из этого трюка.
См. также «Суммирование сложных, данных» (Трюк № 45) и «Использование ус­
ловного форматирования для выделения важных результатов» (Трюк № 30).

И Использование условного
форматирования для выделения важных
результатов
Использование функции условного форматирования и собственной функции, выполня •
ющей ту же задачу, созданной без особых усилий в среде VBA.
Результаты и выводы, имеющие особо важное значение, должны быть преподне
сены с особой выразительностью. Вместо того чтобы выводить результаты отчета
Трюк № 30. Использование условного форматирования 103
в виде простого текста, нужно использовать возможности условного форматиро­
вания, позволяющие привлечь внимание читателей к важным новостям. Если это
хорошие новости, нужно их умело преподнести и обозначить тем самым свои при­
тязания на возможное повышение по службе. Если новости плохие, нужно подо­
брать такой стиль отображения, который сдерживал бы желание расправиться
с тем, кто о них сообщит.
В разделе «Подсчет промежуточных итогов на основе определенных условий»
(Трюк № 29) рассмотрено создание отчета на основе данных за два года с исполь­
зованием промежуточных итоговых значений. Этот прием хорош для проведения
анализа путем сравнения результатов одного прошедшего года с результатами
следующего и оценки наступивших изменений (включая определение положи­
тельных или отрицательных тенденций).
В некоторых отчетах выводится еще и третий столбец, показывающий процент­
ное изменение на основе сравнения двух величин. Хотя такой вариант нами не
разбирался, вы можете применить условное форматирование, рассматриваемое
в данном трюке, для текстовых полей, отражающих процентные изменения, если
сочтете нужным включить их в отчет.

Стандартное условное форматирование


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

Угхлэчме форматирование ЩЩ

Формат, используемый при


АаВЬБбЯя
невыполнении условий:

Условие 1
Выражение V. ;C[txtCT2004)-[txtCT2003])/[UtCT2003>0.2
фориет, используемый при
выполнении условия: АаВЫзбЯя жк ч

Выражение VI ([txtCT2004]-[txtCI2003MtxtCI20031<-0.2 And [txtCt2004]-[txtCI2003])/[txtCT2003]--'


Формат, используеиьй при Ж К Н
выполнении условия. АаВЬБбЯя

выражение v. ([txtCT2001J-[txtCT20O3MtxtCT2n03]<.0.15 And ([txtCT2OO4]-[txtCT2OO3]W[txtCI2O03.


Формат, используемьй при •->!*,:"*:. Ж К Ч
выполнении условия:

| Удалить...\ \ O K ~ ] J

Рис. 4 . 1 1 . Цвета шрифта, изменяющиеся в зависимости от условий

Окно Условное форматирование открывается по команде меню Формат •Условное


форматирование. Оно позволяет одновременно форматировать только один эле­
мент, поэтому перед тем, как получить доступ к команде меню, следует выбрать
этот элемент управления. Пункт меню остается недоступным и в том случае, если
элемент управления не может быть подвергнут условному форматированию.
104 Глава 4. Представление данных

На рис. 4.11 показано условное форматирование, установленное для текстово/о


поля txtCT2004_llTor. В частности, для этого элемента установлены три условия
форматирования, в которых рассматривается процентная разница итогов 20(13
и 2004 годов:
Больше 20 %:
([txtCT2004]-[txtCT2003])/[txtCT20O3]>0.2
Больше или равна 15 % и равна или меньше 20 %:
([txtCT2004]-[txtCT2003])/[txtCT2003]<=0.2 And _
([txtCT2004]-[txtCT2003])/[txtCT2003]>0.15
Больше 10 % и равна или меньше 15 %:
([txtCT2004]-[txtCT2003])/[txtCT2003]<=0.15 And _
([txtCT2004]-[txtCT2003])/ [txtCT2003]>0.1
Наступление каждого из условий вызывает форматирование поля в соответствии
с установками, сделанными в диалоговом окне Условное форматирование. Все б л
хорошо, да вот количество условий ограничено всего тремя, из-за чего могут по­
требоваться иные подходы к решению этой задачи.

Способ условного форматирования с применением VBA


Используя процедуры обработки событий отчета, вы можете задать форматы, недс -
ступные стандартной функции условного форматирования. У стандартной
функции есть два основных ограничения: проверка не более трех условий и недс -
ступность некоторых приемов форматирования.
Эти ограничения можно обойти, создав собственное условное форматирование
с помощью VBA. На рис. 4.12 показан отчет, в котором ясно выделяется итоговое
количество визитов за 2004 год, оформленное с использованием обрамления.

Сравнительные сведения
о визитах клиентов по штатам в 2 0 0 3 и 2004 годах

2003 2004

Всего визитов: 707 Всего в и ш н е : |>90 |

Всего визитов в СТ: 127 Всего ей гигов в СТ: 153


Всего B W игов в МЛ 80 Всего низшие вМА: 93
Всего визитовв MJt 169 Всего виштов BNJ: 231
Всего визитов в NY 195 Всего визитов в MY 246
ВсеГО ВИЗИТОВ В Р А 136 Всего визитов в РА: 167

Страница:

Рис. 4 . 1 2 . Условное форматирование, осуществленное с помощью кода VBA


Трюк № 3 1 . Создание прямой ссылки на отчет 105
Такое оформление стало следствием совпадения условий, проверяемых при вы­
полнении программного кода, помещенного в процедуру обработки события Пе­
чать, относящегося к нижнему колонтитулу:
P r i v a t e Sub НижнийКолонтитул_Рп'гП (Cancel As I n t e g e r , P r i n t C o u n t As _
Integer)
Dim визиты_изменения As S i n g l e
визиты_изменения = ([txt2004_MTOr] - [txt20O3_MTor]) / [txt2003_MTor]
S e l e c t Case визиты_изменения
Case I s > 0.25
Me. txt2004_MTor . P r o p e r t i e s C ' F o r e C o l o r " ) = vbBlue
Me.txt2004_HTor. P r o p e r t i e s C ' B o r d e r s t y l e " ) = 1
M e . t x t 2 0 0 4 _ M T o r . P r o p e r t i e s ( " B o r d e r C o l o r " ) = vbBlack
Me.txt2004_HTor. P r o p e r t i e s C F o n t l t a l i c " ) = i
Case I s <= 0 . 2 5 , Is > 0.2
Me. txt2004_HTor. P r o p e r t i e s C ' F o r e C o l o r " ) = vbBlue
Case I s <= 0 . 2 , I s > 0.15
Me. txt2004_MTor. P r o p e r t i e s C ' F o r e C o l o r " ) = vbGreen
Case I s <= 0 . 1 5 , I s > 0 . 1
Me. txt2004_MTor. P r o p e r t i e s C ' F o r e C o l o r " ) = vbMagenta
Case I s <= 0 . 1 , Is > 0
Me. txt2004_MTor . P r o p e r t i e s C ' F o r e C o l o r " ) = vbBlack
Case I s <= 0
Me. t x t 2 0 0 4 _ M T o r . P r o p e r t i e s C ' B o r d e r s t y l e " ) = 1
M e . t x t 2 0 0 4 _ M T o r . P r o p e r t i e s ( " B o r d e r C o l o r " ) = vbRed
End S e l e c t
End Sub
В процессе выполнения процедуры отслеживаются процентные изменения, а за­
тем операторы группы Select Case обеспечивают реализацию различных устано­
вок форматирования в зависимости от степени наступивших изменений. В при­
мере обеспечивается проверка шести условий, но на самом деле их количество
ничем не ограничено и должно отвечать задачам приложения. Способы формати­
рования определяются возможностями VBA и практически также ничем не огра­
ничены.

Т Р Ю К Создание прямой ссылки на отчет


№31 Создание на Рабочем столе ярлыка для работы с отчетом, независимо от работы с са­
мой базой данных.
Избавление от процесса открытия базы данных может существенно облегчить
работу менеджера или сотрудника, испытывающего сложности в работе с базой.
Вы можете без особых усилий облегчить им работу, создав ярлык, указывающий
непосредственно на отчет, и поместив его на Рабочий стол.

Создание ярлыка
Для создания такого ярлыка нужно сначала открыть окно базы данных, а затем
щелкнуть правой клавишей на значке избранного отчета. Появившееся контекст­
ное меню будет содержать пункт Создать ярлык (рис. 4.13).
После выбора пункта Создать ярлык появится диалоговое окно, в котором нужно
выбрать место для ярлыка. По умолчанию будет предложено сохранить его на
Рабочем столе текущего пользователя (рис. 4.14).
106 Глава 4 . Представление данных

Прич-ры л 1 • бамдахиы» |форм»тАссе« ХЮО)

^ Просмотр |£крнстру»; о р . : J С о с а т ь ' >! »_ Ц Я

объекты 4J Создание отчета в режиме конструктора

3 Таблицы ffl Создание отчета с помощью мастера

33* Запросы ^ Предварительный просмотр


г}гу_Ви'
Ш Формы
• а qry_OT |цЦ конструктор
s3 Отчеты | дгу_От и
•^ Страницы £Щ
ВО Печать
Вырезать

£2 Макросы йУ» Копировать

>;$£ Модули 1 Сохранить как,..

1 Экспорт...
Группы
1 Отправить •
М Избранное
f Добавить в группу • !

Создать ярлык;..'; ::;|


Х | Удалить [^ ;
1
| Переименовать
! | ЩЯ Свойства

| Зависимости объектов...
• -:8 1

Рис. 4.13, Создание ярлыка для отчета

Ярлык 'пгу_Внзиты_гООЗ_2004" (Примеры 4_2)

Тип объекта: Отчет Access


Имя объекта: пгу_Виэиты_2003_2004
: База данных: Примеры 4_2.rn.Jb
Путь: Н:\1р*оки Ахсесс

'• Размещение:
D:\Docurrients cjnd Зе^пд^НиколайДРабочий стол\Ярл.

[ 3 Сетевая база данных

CZEZJC^
Рис. 4.14. Выбор места для ярлыка

После щелчка на кнопке О К требуемый ярлык будет создан. Теперь по щелчку на


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

Распечатка отчета и закрытие базы данных одним щелчком


Лучше было бы дать возможность одним щелчком на ярлыке автоматически рас­
печатать отчет и закрыть после этого базу данных. Похоже, что без макроса здес з
не обойтись!
На рис. 4.15 показана простая макрокоманда, распечатывающая отчет, а затем за­
крывающая базу данных.
Главная задача — открыть отчет. Важно также выбрать для свойства Режим значе -
ние Печать, а не Просмотр или Конструктор. Тогда отчет вместо вывода на экран бу •
Трюк № 32. Защита интеллектуальной собственности 107
'). Распечатка отчета : макрос
Макрокоманда
ОткрытьОтчет
Выход

Apr /менты макрокоманды

Имя отчета дгу_Ви5иты _200Э .2004


Режим Печать
Имя фильтра
Ус повив отбора Открытие ответа в режиме
Р е ж т окна Обычное кожтруктора или просмотра или
непосредственная печать отчета.
Дня сгрэвки мажгмте клавишу Н .

Рис. 4 . 1 5 . Использование макрокоманды для запуска отчета и закрытия базы данных

дет сразу же отослан на принтер. Следующее действие — Выход — приведет к за­


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

Н Защита интеллектуальной собственности


Защита конфиденциальных и авторских материалов путем включения в отчет «водяных
знаков».
Если кто-то покушается на вашу интеллектуальную собственность, то вы вряд ли
найдете от этого стопроцентные меры защиты. Но здравый смысл подсказывает,
что нужно предпринять все возможное, чтобы отстоять свою интеллектуальную
собственность. Часто в этих целях на страницу, в верхний или нижний колонти­
тул отчета, помещают какую-нибудь фразу, свидетельствующую о конфиденци­
альности материала. Но такой способ не дает гарантий, что сообщение будет сра­
зу бросаться в глаза.
В качестве дополнительной меры можно поместить в отчет водяные знаки, кото­
рые пройдут прямо по тексту отчета на всех страницах. Сообщение, выбранное
в качестве водяных знаков, следует сделать прозрачным, не затеняющим текст,
и поместить прямо под ним. Для заметности оно должно быть набрано большими
буквами и следовать по всему листу.
На рис. 4.16 показан отчет, в котором водяные знаки занимают пространство дан­
ных. Слово «Конфиденциально» следует по диагонали с нижнего левого в верх­
ний правый угол. Текст отчета выглядит напечатанным поверх водяных знаков.

Создание водяных знаков


Водяные знаки создаются при помощи изображения, помещаемого в отчет,
в свойство Рисунок. Для его создания вам понадобится программа работы с гра-
108 Глава 4. Представление данных

1 Отчет1 • и

Рис. 4 . 1 6 . Использование водяных знаков в виде диагонального сообщения

фикой. Среди имеющихся программ, работающих с изображениями, я предпочк -


таю хорошую и вполне доступную программу Paint Shop Pro компании Corel Corp
(www.jasc.com). Любая используемая в наших целях программа должна выпол­
нять следующее:
• работать с текстом в графическом режиме;
• растягивать и разворачивать изображения;
• регулировать прозрачность изображения.
В готовом рисунке прозрачность изображения должна достигать 75 %, Наилуч­
шего результата можно добиться методом проб и ошибок.

Подбор размера изображения


Создавая изображение, нужно растянуть его почти на весь лист бумаги. Каким
будет по размеру созданное изображение, таким оно и появится в отчете (в зави­
симости от состояния свойств, рассматриваемых далее в этом трюке).
Сохранять изображение следует в файле с расширением .jpg, .bmp и т. д.
Трюк № 32. Защита интеллектуальной собственности 109
ПРИМЕЧАНИЕ
Вы можете использовать для файла любой формат, подходящий для вставки изо­
бражений в свойство отчета Рисунок.

Процесс создания изображения в данном трюке не рассматривается, но к вашему


сведению, изображение на рис. 4.16 имеет 70 % прозрачности и было сохранено
в формате .jpg. Размер картинки может быть 10-18 см. Внешний вид созданного
изображения показан на рис. 4.17.

___, .__^

Ф Ф •','.& Q /: г si it \ X т Ы ш \ >Ф

Рис. 4.17. Водяные знаки в графическом файле

Использование водяных знаков


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

Тип рисунка
Можно выбрать одно из двух значений: Внедренный и Связанный. Правильно будет
выбрать внедренный тип рисунка. Если выбрать связанный тип, то при гене­
рации отчета будет предприниматься попытка открыть внешний графический
файл.
110 Глава 4. Представление данных

Рис. 4.18. Установка в отчете свойства Рисунок

Размеры рисунка
Можно выбрать один из трех вариантов: Фрагмент, Вписать в рамку и По размеру
рамки. Каждый из них представляет собой различные способы размещения график л
в отчете. Понять суть каждого варианта можно экспериментальным путем. Теп
не менее, как уже было отмечено ранее, если размер создаваемого рисунка был
выбран правильно, следует выбрать вариант Фрагмент. Правильный подход к созда­
нию рисунка избавит вас от необходимости подбирать способ размещения его в отчет*:.

Выравнивание рисунка
Вы можете выбрать один из пяти вариантов: Сверху слева, Сверху справа, По центру,
Снизу слева, Снизу справа. Большинство предпочитают выбирать установку По цен •
тру, но вашим нуждам может лучше соответствовать и другой вариант.

Мозаичное заполнение
Вы можете выбрать либо Да, либо Нет. Если установить Нет, рисунок будет поме •
щен на страницу один раз. Если Да — его копии заполнят все пространство стра
ницы наподобие мозаики. Вы можете попробовать оба варианта и выбрать
наиболее подходящий. Если выбрать Да, водяные знаки станут выглядеть бо
лее насыщенно. Возможно, именно это и будет отвечать вашим вкусам.

Страницы с рисунком
Это свойство позволяет определить, на каких страницах будут появляться водя­
ные знаки. Есть три варианта: Все страницы, Первая страница и Отсутствует.
Трюк № 32. Защита интеллектуальной собственности 111

ВНИМАНИЕ
Если выбрать последний вариант, водяных знаков вы просто не увидите!

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

Клиент: Количество

CvaptE т л и м IBBHOWN

Матвеев ш п ( п етро.

ЛетрседлепзЯСе,

О.чриее 1киливш«ааАпееич

Eipftnn «щр.Я iHETcpcC

.ясттксе НнювЯ пвтрое*ы

М М не* ПвтрСергвее

Лнтомес-Свмппе'

рышемирей iHiraie-e*.

i V m c e ГвсопЛ С те гвк»«*

«г*»>» M s a u ) Вплрпоемч

Страница: 1 CDS <


Рис. 4 . 1 9 . Текстовые поля, перекрывающие водяные знаки

Чтобы устранить этот эффект, нужно войти в режим конструирования отчета. Для
всех текстовых полей, проецирующихся на водяные знаки, следует изменить со­
стояние свойства Тип фона с Обычного на Прозрачный. Тогда в текстовых полях бу­
дет пропечатываться только текст, к чему мы, собственно, и стремились. На
рис. 4.20 показан внешний вид отчета после установки прозрачности фона тек­
стовых полей.
112 Глава 4 . Представление данных

Рис. 4.20. Водяные знаки, проступающие через текстовые поля

Ш Демонстрация слайдов в Access


Использование изображений и события Таймер для создания управляемой демонст­
рации слайдов.
Встраивание в Access изображений приводит к весьма впечатляющим результа •
там. Появляется возможность поместить в приложение изображения товаров,
фотографии сотрудников и заменить любые текстовые описания наглядными
иллюстрациями. Обычно полные имена графических файлов хранятся в поле таб
лицы. Таким образом изображения связаны с данными, хранящимися в таблице
При отображении записи в форме управляющий элемент Рисунок может быть за­
полнен изображением, найденным в указанном месте.
В данном трюке не используется сценарий, основанный на хранении данных
Вместо этого в нем применяется свободная форма, в которой отображается про­
извольный набор изображений. Решение, в котором задействованы сохраненные
данные, может быть скомбинировано с той технологией, которая здесь рассмат­
ривается. Например, в форме могут отображаться записи базы данных, а произ­
вольные изображения могут помещаться в заголовок или примечание формы.
В данном трюке для вывода на экран изображения и демонстрации способа егс
автоматической замены на другое с периодичностью в несколько секунд использу-
Трюк № 33. Демонстрация слайдов в Access 113
ется элемент управления Рисунок. Кроме этого, в трюке применяется ручной спо­
соб замены изображения.

Графика
В примере, иллюстрирующем суть данного трюка, все изображения собраны в од­
ном каталоге, путь к которому жестко задан в программе. Но небольшое дополне­
ние программного кода даст возможность использовать множество каталогов, зада­
вать нужный каталог в диалоговом режиме и т. д. А теперь предположим, что подборка
файлов с расширением .jpg размещается в каталоге, показанном на рис. 4.21.

Файп Ораека Вид Избранное Сервис ^правка 1* ^


&. J j назад * ' ;-; , £ , •• Поиск &• . Папки Ш-
v
A,VK"'.L ; 0 СЛОбраяхы товаров фото
Размер Тип
fl"^вход |;
;Размеры
R
Задач* д«м файлов и магкж щ образец А 144 КБ Рисунок JPEG 768x511
1 фПэмН9»«**тьДО .^Образец Б 123 КБ Рисунок JPEG 1024 х 768
;*3 Образец е 22 КБ Рисунок JPEG 460 х 231
• , v Переместить-йаил ': к » „ , _
Щ :™••• . • ^Образец Г 28 КБ Рисунок JPEG 470 х 256
: Л Кятирсеат» файл - ^образец Д 21КБ Рисунок JPEG 535 X 250
^ Опубликовать файл й еебв «^ Образец Е 166 КБ Рисунок JPEG 746 х 494
III £ $ O-npasviTbэтот фййлпо ^ОбразецЖ 181КБ Рисунок JPEG 745 х 499
электронной почте Щ Образец 3 181КБ Рисунок JPEG 745 х 499
Ш ^ Печатать эаип *£ Образец и 144 КБ Рисунок JPEG 768x511
X >'Дв"итьфайл ^Образец К 123 КБ Рисунок JPEG 1024 х 768
*^ Образец Л 22 КБ Рисунок JPEG 460 X 231
• ^Образец М 28 КБ Рисунок JPEG 470 х 256
; Другие места ^ Образец Н 21КБ Рисунок JPEG 535 х 250
Ш * - ,~ \ *%Образец 0 166 КБ Рисунок JPEG 746 х 494
Щ %& П0К4ЯЬИМйДЧ0((О) '^
:
||| •&& ,№зи документы
£ 3 Общие документы
j ^ М>:+|компьютер.
|Щ *s^ Сетевое окружение

Подробно ' vi<;

Размеоь» /68 х 511 Тип: рисунок JOES Размер: 143 КБ . 143№:: . $ Мой юмпьк тер
1
Рис. 4 . 2 1 . Каталог, содержащий файлы изображений

Не обязательно выбирать файлы формата J PG. Вы можете использовать и другие


форматы, например BMP и TIF (указав их расширения в коде программы).

Конструкция формы
На рис. 4.22 показана форма в режиме конструирования. Она содержит ряд эле­
ментов управления: несколько элементов Кнопка, элементы Флажок и Рисунок.
В элементе Рисунок содержится начальное изображение, которое будет заменять­
ся другими в процессе демонстрации слайдов.
Нетрудно заметить, что пользователю доступен как автоматический, так и руч­
ной режим просмотра слайдов. Кнопки Следующее и Предыдущее при отключен­
ном режиме автоматического просмотра позволяют передвигаться вперед и назад
по коллекции изображений. Щелчки на этих кнопках вызывают циклический
114 Глава 4. Представление данньх

PtHi

Т.... I
Непрерывный просмотр

dtoptw

' Lfe™
Ошибка
Фильтрация
Применение фильтра. .
Таймер {Процедура
Интервал таймера . . . . . 2000
До экранной подскажи
Включение команды . .
Проверка команды . . .

Рис. 4.22. Конструкция формы для демонстрации слайдов

перебор коллекции, созданной средствами VBA, и замену ссылки на изображе­


ние в свойстве управляющего элемента Рисунок.
Элемент управления Флажок используется для задания режима просмотра. При
установке этого флажка начинается непрерывный показ. Независимо от состоя •
ния флажка, для начала демонстрации необходимо щелкнуть на кнопке Пуск. Тем
самым пользователь имеет возможность запускать процесс просмотра.
Поскольку имеется кнопка Пуск, то должна быть и кнопка Стоп. С ее помощьк»
всего-навсего изменяется значение логической глобальной переменной стоп_по-
каз с false на true.

Код
Для работы приложения необходимо воспользоваться событием Таймер. В следу
ющем далее программном фрагменте интервалу таймера присваивается значение
2000, чем вызывается наступление события Таймер каждые две секунды. Изменяв
это значение, вы можете подобрать другой временной интервал:
Option Compare Database
Public стоп_показ As Boolean
Public рисунки As Collection
Public номер As Integer

Private Sub Form_Open(Cancel As Integer)

'Установка начальных свойств

Me.спк_НепрерывныйПросмотр = False
Me. с последующее. Enabled = False
Me . стс!_Предыдущее. Enabled = False
End Sub
Трюк № 33, Д е м о н с т р а ц и я слайдов в Access 115

P r i v a t e Sub cmd_riycK_Click( )

'считывание путей графических файлов в коллекцию


'отображение первого изображения

Me.Timer-Interval = 2000
стоп_показ = False
If Me. сг|к_НепрерывныйПросмотр = False Then
Me.стс!_Следующее. Enabled = True
Me .сп^_Предыдущее. Enabled = True
End If
в следующей строке нужно указать собственный путь!!
рис_путь = "СЛОбразцы товаров фото"
Set рисунки = New Collection
Set fs = Application.FileSearch
With fs
.Lookln = рис_путь
.FileName = "*.jpg"
If .Execute( ) > 0 Then
For i = 1 To . foundfiles.Count
рисунки.Add Item : = .foundfiles(i)
Next i
Else
MsgBox "Файлы не найдены!"
End If
End With
'загрузка первого изображения
Me.img_PncyHOKl.Picture = рисунки(1)
номер = 1
End Sub

P r i v a t e Sub cmd_Cneflyioii4ee_Click( )

'переход к следующему изображению


'коллекции

If номер = рисунки.Count Then


номер = 1
Else
номер = номер + 1
End If
Me.img_PncyHOKl.Picture = рисунки(номер)
End Sub

Private Sub сгт^_Предыдущее_С11'ск( )

'переход к предыдущему изображению


'коллекции

If номер = 1 Then
номер = рисунки.Count
Else
номер = номер - 1
End If
Me.img_PncyHOKl.Picture = рисунки(номер)
End Sub
116 Глава 4 . Представление данных

P r i v a t e Sub cmd_CTon_Click( )

'установка глобальной переменной в True


'отключение действия кнопок Следующее и Предыдущее

стоп_показ = True
Me . стй_Следующее. Enabled = False
Me.сп^_Предыдущее.Enabled = False
End Sub

P r i v a t e Sub Form_Timer( )
'При включенном непрерывном просмотре и если не было щелчка на кнопке
'Стоп продолжить циклический показ изображений
I f Me.спк_НепрерывныйПросмотр = True _
And стоп_показ = False Then сп^_Следующее_С11ск
End Sub
Данный фрагмент состоит из нескольких процедур. В процедуре обработки собы -
тия Открытие (в тексте программы — Open) формируется коллекция ссылок на
изображения, обнаруженные в указанном каталоге. При этом в программе жестк э
задаются как тип файлов с изображениями, так и имя каталога. Объект FiteSearci
использует эти значения для поиска файлов с изображениями. Вы можете расши -
рить сферу поиска на несколько каталогов и (или) несколько типов файлов. Ка <
это сделать, можно узнать в описании объекта FileSearch, помещенном в справоч­
ной системе, или в Интернете.
Характер работы приложения после его запуска определяет состояние флажкл
спк_НепрерывныйПоказ. Если он сброшен, то для перехода от одного изображения
к другому служат кнопки Следующее и Предыдущее. При щелчке на любой из ни:с
индекс коллекции увеличивается или уменьшается на единицу, а свойству Рису­
нок (фигурирующему в коде программы как Picture) присваивается значение кон -
кретного элемента коллекции.
Если флажок спк_НепрерывныйПоказ установлен, кнопки Следующее и Предыдуще(!
становятся недоступными и показ слайдов будет происходить автоматически.
Периодичность смены изображений зависит от значения интервала таймера. По •
каз будет идти до тех пор, пока не последует щелчок на кнопке Стоп. После этого
щелчка переменной стоп_показ будет присвоено значение true. Процедура обра
ботки события Таймер (в тексте программы — Timer) при таком значении пере
менной прекратит циклический показ изображений, поскольку он возможен толь
ко при значении false.

Трюк в трюке
Вы можете усовершенствовать это приложение несколькими способами. Заметь­
те, изображение не имеет сопроводительного текста. Если по-прежнему придер­
живаться произвольного подхода к выбору изображений, то одним из варианте!
решения этой проблемы станет вывод сведений об изображении по щелчку нг
самом рисунке. Управляющий элемент Рисунок имеет обрабатываемое событие
Нажатие кнопки, которым можно воспользоваться для вывода значения свойства
Рисунок (рис. 4.23).
Трюк № 34. Проигрывание видеоклипов в форме Access 117

Чапись |_М_ - j 1 > ({Г,- • и» i 'Si.:. ::..,:....,.: .: >:

Рис. 4 . 2 3 . Использование события «Нажатие кнопки», относящегося к элементу управления


«Рисунок»

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


вы можете воспользоваться событием Нажатие кнопки для поиска и отображения
любой информации, касающейся этого изображения. Например, если можно вы­
делить имя файла изображения, то можно и собрать дополнительные сведения о
нем из текстового файла или из других источников.
Сам собой напрашивается еще один подход к решению рассматриваемой задачи:
связать элемент управления Рисунок с полными именами файлов, размещенными
в таблице. Тогда соседние поля каждой записи могли бы содержать комментарии
к рисунку. На самом деле такой подход считается более естественным. Ранее я не
заострял на нем внимание из-за трудоемкости его реализации: обновление пол­
ных имен файлов в записях таблицы преподнести сложнее, чем просто задать один-
единственный путь непосредственно в коде программы. К тому же если вы будете
приспосабливать программу для работы с файлами, путь к которым определяется
самим пользователем, то независимый подход будет предпочтительнее, посколь­
ку не потребует предварительного ввода в базу данных полных имен файлов.

Е Проигрывание видеоклипов в форме


Access
Внедрение мультимедийного способа подачи информации с использованием Проиг­
рывателя Windows Media.
Внести разнообразие в приложения базы данных можно весьма эффектным спо­
собом — придать им способность воспроизведения видеоклипов. Хотя может по­
казаться, что в «серьезном» деле развлечения неуместны, демонстрация видео­
клипов — один из самых наглядных способов подачи информации. Существует
118 Глава 4 . Представление данных

несколько способов встраивания видеотехнологий в базу данных. Можно связать


видеоклипы с записями и проигрывать их параллельно с выводом на экран со­
ответствующих данных. А можно проигрывать видеоклипы независимо от работ з!
остальных компонентов приложения, по мере необходимости (для чего потребуется
использование кнопки или других способов управления началом воспроизведения).
Чтобы воспроизводить видеоклипы, потребуется включить в форму специально
предназначенный для этого элемент управления. Существует несколько подоб­
ных элементов, наиболее известным из которых является Проигрыватель Windows
Media, используемый в данном трюке.

Включение в форму проигрывателя


Сначала нужно добавить в форму Проигрыватель Windows Media. Поскольку он
не входит в перечень стандартных элементов управления, доступ к нему нужно пол) -
чить через кнопку Другие элементы, расположенную на Панели элементов (рис. 4.24).

Форма,! 4прм»
• г • i • з • i • 4 • t •• в *: • ? ' * : ' 8 • i ' Э • I • Ю ' ' • 11 ' i - 12 • • 14 • I • S - I
шш
• 16 '

4У Область Данные;;

B B E S M

ШШВжШ
Рис. 4.24. Поиск дополнительных элементов

После щелчка на кнопке Дополнительные элементы появится длинный перечень


элементов управления и библиотек. Прокрутите список вниз и найдите Window:;
Media Player (рис. 4.25).
Щ TSHOOTCtrl Class
4 » о р > я 2 • форна
1 VCommand Class
Ц voct Class
• Область данных
1 VideoRenderQJ Class
:i :
i|
-.; * *fiSi¥Wt -ff'lH 1 WebCommand Control

. > 4. ,Ы и , gg J <;. WebViewFolderlcon Class

'• г :: 1 WebViewFolderlcon Class

'У WIA Video Preview Class


з l
1 1 1 " ' •••••••':•:•"••:.•
Windows Media Player •.•'.:.'. .

* '•
\ Обозреватель веб-страниц (Microsoft)
IS
! - " I Оболочка - маршрутизатор просмотра папок

^•••':-¥t-# -Ш-ч | Объект Migration Wisard OOBE Automation


'- i Панель ссылок

Рис. 4.25. Выбор Проигрывателя Windows Media


Трюк № 34. Проигрывание видеоклипов в форме Access 119

После щелчка на элементе управления прорисуйте указателем мыши его конту­


ры на форме. На рис. 4.26 показана форма, содержащая Проигрыватель Windows
Media, список и кнопку. В данной конфигурации в списке отображается перечень
доступных видеоклипов. После щелчка на кнопке Воспроизвести начнется воспро­
изведение выбранного видеоклипа.

; Фймп ; Главка : §ид Вставка Формат -Сервис QKHO Слравка

| Режим <fccpww

Рис. 4 . 2 6 . Конструирование формы, содержащей Проигрыватель Windows Media

На рис. 4.26 список заполнен именами файлов видеоклипов с расширениями .mpg.


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

Воспроизведение видеоклипа
Как же воспроизвести видеоклип? На самом деле весьма просто: передать свой­
ству URL Проигрывателя Windows Media полное имя файла с видеоклипом, и вос­
произведение начнется автоматически. В следующей процедуре обработки собы­
тия Нажатие кнопки полный путь к файлу с видеоклипом берется из элемента
Список_клипов и передается элементу Проигрыватель:
120 Глава 4 . Представление данных

З Ф о р м а 1 : фчргы

Рис. 4.27. Выбор видеоклипа

P r i v a t e Sub стй_Воспроизведение_С11ск( )
I f Not IsNull(Me.CnMcoK_KnMnoB) Then
Me.Проигрыватель.URL = Me.СПИСОК_КЛИПОВ
Else
MsgBox "Сначала нужно выбрать видеоклип!"
End I f
End Sub
Функции воспроизведения, остановки, перемотки и паузы являются встроенны­
ми и доступны через кнопки на самом проигрывателе. Благодаря им пользова­
тель может управлять воспроизведением видеоклипа.
Проигрыватель Windows Media имеет множество обрабатываемых событий. Не­
много фантазии и смекалки откроют широкие возможности по внедрению видео •
клипов в ваши приложения. В этом трюке представлены лишь основы техноло •
гии воспроизведения видеоклипов, но вы можете поэкспериментировать с программ •
ным кодом и найти множество новых способов работы с проигрывателем.
См. также Windows Media Support Center (http://support.microsoft.com/default.asp>:
?scid=fh;en-us;wmp).

И Просмотр в отчетов в форме


Просмотр текущих или ранее созданных отчетов непосредственно в рабочей форме.

Система Access считается одним из наиболее развитых инструментальных средстЕ


составления отчетов из всех имеющихся на рынке программных продуктов
Начиная с Access 97 корпорация Microsoft декларировала возможность создавать
Трюк № 35. Просмотр в отчетов в форме 121
образы отчетов с целью их просмотра в свободно распространяемом средстве
Snapshot Viewer, которое можно загрузить с веб-сайта Microsoft (http://www.
microsoft.com/downloads).
Разработчики приложений базы данных Access могут повысить качество создава­
емых программных продуктов за счет использования средства ActiveX Snapshot
Viewer для просмотра отчетов в рабочей форме.

Создание формы
В состав формы включены поле со списком и ActiveX Snapshot Viewer. В поле со
списком содержится перечень отчетов, имеющихся в базе данных. Это поле за­
полняется при открытии формы, во время работы процедуры обработки события
Загрузка:
Private Sub Form_Load( )
Dim obj As AccessObject, dbs As Object
Dim strList As String
Set dbs = Application.CurrentProject
For Each obj In dbs. AUReports
strList = strList & obj.Name & ";"
Next obj
cboReports.RowSourceType = "Value List"
cboReports.RowSource = strList
End Sub
Для вставки в форму управляющего элемента ActiveX Snapshot Viewer следует щелк­
нуть на значке Другие элементы, расположенном на Панели элементов (рис. 4.28), про­
крутить вниз появившийся список и выбрать Snapshot Viewer Control 11.0. Учти­
те, что в зависимости от установленной у вас версии Access это средство может
быть более ранней версии, чем И.О.

Рис. 4 . 2 8 . Добавление в форму элемента ActiveX Snapshot Viewer

Размер рамки для элемента управления Snapshot Viewer следует выбрать при­
близительно равным по ширине размеру бумаги, используемой для распечатки
отчетов, тогда при просмотре отчета не придется пользоваться горизонтальной
122 Глава 4 . Представление данньIX

прокруткой. На рис. 4.29 показана форма в режиме конструирования с размещен­


ным в ней средством просмотра отчетов Snapshot Viewer.

II rm П11111 м о 1 р _ о т ч » т о 1 : ф о р м а -
• i-i • I • 2 • ( • 3 ' i • 4 • r • 5 • ) • 6 ' I • 7 • I ' t • I • Э • « • 10 • i • 11 • '• 13 • i • 14 • ' ' В I • 16 • i • 17 • i ' 18 •
^:;

1
I
:
• Обпясть д-эммь"

Свободный
".

'"^'-
••;"

т
••'.-1 •

::
1
ШШ ••л;fl§| <Й,Л;'
з •

*;
Ш
• Щ • ''':
. ||| : ||1|
||| . и 1
; ; •:.:s : , (is
5 i
liplii •Ш ш&Швт • • "
M • . • . • • • • • . . • :

1'
: •р
. . • . . • • . . . •• •

6 i
•••«••"•^IPW""^
••• v ••

< • : > • .' •

Рис. 4.29. Подбор размера для элемента Snapshot Viewer

После того как элемент Snapshot Viewer будет вставлен в форму, в процедуру об­
работки события Изменение (в программном коде — Change), относящуюся к пол о
со списком, нужно поместить следующий код, при этом название элемента фор­
мы Snapshot Viewer должно соответствовать названию, использованному в про­
граммном коде:
P r i v a t e Sub cboReports_Change( )
DoCmd.OutputTo acOutputReport, cboReports, acFormatSNP, _
Application.CurrentProject.path & "\temp.snp"
SnapshotViewerl.SnapshotPath = _
A p p l i c a t i o n . C u r r e n t P r o j e c t . p a t h & "\temp.snp"
End Sub
В приведенном примере создается временный образ отчета, названный temp.sn э,
который помещается в рабочий каталог базы данных. Затем отчет temp.snp загру­
жается в Snapshot Viewer. Файл temp.snp при выборе для просмотра нового отче­
та переписывается. Если вы работаете с удаленного места с общей базой данных,

а
р~~~"
Выб%1Т|!>;от4втдляг^оснотг>а: : .-:•.-:;
Счет ;v.

J%h БОРЕЙ СЧЕТ


^ЩШ^ Т0РГ0&АЯКОД8ШШЯ
""Щг
Мосх*а 108156. Еорвйасаяул. 13-13 Дата: 28-ИОЯ-2О05
Г*мА?» 7-095-155-1417 Фоме 7-095-155-5933

»Ь1 >.Ш*1
(
!:Ш л>
Рис. 4.30. Отображение отчета
Трюк № 36. Нумерация строк отчета 123

то хранить временный файл, во избежание проблем, связанных с многопользова­


тельской средой, следует не на сетевой машине, а на локальном компьютере.
В готовой форме на рис. 4.30 отображается выбранный в поле со списком отчет
под названием Счет.
Данный трюк позволяет иметь в приложении единое средство для просмотра вы­
бранного отчета перед его выводом на печать. Обратите внимание на то, что уп­
равляющий элемент ActiveX Snapshot Viewer имеет кнопку Печать, расположен­
ную рядом с кнопками навигации.

Трюк в трюке
Образы отчетов, в отличие от настоящих отчетов, относящихся к динамичным
объектами Access, являются статичньщи объектами, что позволяет сохранять их
в папках, а затем просматривать как архивные документы в Snapshot Viewer.
Вы можете внести изменения в программный код, позволяющие просматривать
в Snapshot Viewer архивные отчеты из заданной папки, поместив в поле со спис­
ком имена файлов, в которых хранятся образы отчетов.

Нумерация строк отчета


©• Использование свойства суммы с накоплением для включения в отчет счетчика.

Когда-нибудь у вас может возникнуть потребность в нумерации строк отчета.


Делается это очень просто. Весь трюк состоит в том, чтобы включить в отчет сво-

;;г.Л_Нумерация *:.:; Arid .^j: : 8 ,.».,|,.|(5.,,Д Л .Д„!,,Ц=,.||

: файл : Правка £ил Вставка фораат Сервис QKHO Справка

:.г
| ф Верхний колр^Итул; ;

Клиент:
* Область данных.

• Нижний котент*!^....
- П » * 1 ^Нумерация.:трок
:j:j схг_НумерацияСтрок • у-;
Все
,,,М<ж?т,...;:. Данные События Другие ..
• Имя itxt „НумерацияСтр:
Данные |=1
Формат поля [
Число десятичных 5наков iAj?.Tp
Маска ввода |
Вывод на экран ;Да
По вертикали :Нет
Не выводить повторы И*Т.

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

Рис. 4 . 3 1 . Текстовое поле, предназначенное для нумерации строк


124 Глава 4 . Представление даннь IX

бодное текстовое поле, выбрать значение Для группы или Для всего в его свойстве
Сумма с накоплением и присвоить его свойству Данные стартовое значение.
На рис. 4.31 показан отчет в режиме конструирования. Текстовое поле, размещен­
ное слева, является свободным и в нем, в процессе генерации отчета, будет ото­
бражаться номер строки. В диалоговом окне свойств этого поля показано, что свой­
ству Данные присвоено начальное значение =1.
На рис. 4.32 показано, как выглядит сгенерированный отчет.

Ш ffrietl : отчет

.;.:L-:i:K;fi
ш

Клиенты:
1 Салон Видео-Аудио

2 Магазин Акцент

3 Салон Видео гурман

4 Магазин Союз

5 Магазин CD-DW3

6 Салон Студия-фильм

7 Магазин Радуга

в Магазин Медиа
страница: '••< • V I 1

Рис. 4.32. Отчет с пронумерованными строками

Значение, присвоенное свойству Данные, является не только исходным, но и зад \-


ет шаг приращения нумерации. Если используется значение 1, счет начинается с
единицы и ведется с единичным приращением. Но вы можете использовать и дру­
гие значения, например 10. Тогда счет начнется с десяти и будет вестись через
десяток (рис. 4.33).

Отчет с чередованием подкрашенных


и обычных строк
Улучшение внешнего вида отчета за счет использования подкраски каждой второй
строки.
Простым способом улучшить читаемость отчета считается чередование подкра­
шенных и обычных строк. Хотя специальных функций или свойств для решения
этой задачи не существует, вы можете улучшить внешний вид отчета без особых
усилий. Для выполнения задуманного следует воспользоваться свободным тек­
стовым полем, в котором содержится сумма с накоплением. По мере вывода строк
Трюк № 37. Отчет с чередованием подкрашенных и обычных строк 1 25

j Отчет1 : отчет

Клиенты:
10 Салон Видео^удио

20 Магазин Аоаент

30 Салон Видеогурман

40 Магазин Союз

50 Магазин CD-DW

60 Салон Студия-фильм

70 Магазин Радуй

80 МагазинМедиа V .

| Страница: : 1 > •<


Ш:::::'::;::::::::::::: >ш.
Рис. 4 . 3 3 . Сроки, пронумерованные через десяток

значение этого поля будет поочередно представлять собой четное и нечетное чис­
ло, и этим обстоятельством можно воспользоваться.
Свойство Цвет фона раздела Область данных можно изменять в зависимости от зна­
чения суммы с накоплением. Изменение этого значения с нечетного на четный
повлечет за собой и изменение применяемого цвета фона.
Для реализации этого замысла нужно выполнить несколько настроек:
• в раздел отчета Область данных следует включить свободное текстовое поле и
установить его свойство Данные в =1, свойство Вывод на экран в Нет, а для свой­
ства Имя набрать 1хг._ВозрастающаяСумма;
• установить свойство Тип фона всех текстовых полей и надписей, находящихся
в разделе Область данных, в Прозрачный.

Код
В разделе Область данных в процедуру обработки события Форматирование нужно
поместить следующий код:
Dim чет_нечет As I n t e g e r
Me.ОбластьДанных.BackColor = vbWhite
чет_нечет = Me. 1х1:_Возрастаю1цаяСумма Mod 2
I f чет_нечет = 0 Then
Me.ОбластьДанных.BackColor = vbYellow
End I f
Для определения четности или нечетности значения суммы с накоплением ис­
пользуется оператор Mod, возвращающий остаток от операции деления. Когда чет­
ное число делится на два, остаток равен нулю. Результат операции Mod присваи­
вается переменной чет_нечет.
126 Глава 4 . Представление данных

Результаты
В начале выполнения процедуры устанавливается белый цвет фона. Если значе­
ние переменной чет_нечет не равно нулю, то цвет фона изменяется на желтый. На
рис. 4.34 показан внешний вид сгенерированного отчета.
•:• :•.•• : ••••

1)щи|1 имей ' fc&gSaw! Wftiff" ••

Клиенты:
Салон Видео-Аудио 0 Доставка заказа

Магазин Ацент О Доставка заказа

Салон Видеегрман И Достаека заказа

Магазин Союз Е Достаека заказа

Магазин CD-D\© О Дсставка заказа

Сапон С тудия^мльм П Достаека заказа

Магазин Радуга 0 Достаека заказа

Магазин Медиа О Достаека заказа

| Страница: i<

Рис. 4.34. Отчет с чередующейся подкраской строк

Трюк в трюке
Вы можете слегка переделать этот трюк. К примеру, если вам необходимо подкра­
сить каждую третью строку, можно проверить условие деления суммы с накопле­
нием на три. Если сумма будет кратной трем, то на три она будет делиться без
остатка.
Также для задания цвета вы можете воспользоваться функцией RGB, название
которой составлено из первых букв слов красный (red), зеленый (green) и синий
(blue). Работа функции основана на смешении трех цветов, насыщенность кажде -
го из которых имеет значение от 0 до 255. С функцией RGB стоит познакомиться
поближе, обратившись к справочной системе Access. Для использования ее в этом
трюке нужно изменить строку, в которой задается свойство Цвет фона:
Me.Detail.BackColor = RGB(200, 200, 200)
Вы можете поэкспериментировать с различными установками аргументов этой
функции, но при этом нужно иметь в виду следующее:
• при установке всех трех аргументов функции RGB в 0 она возвращает черны л
цвет;
• при установке всех трех аргументов функции RGB в 255 она возвращает белы л
цвет.
Трюк № 38. Экономия бумаги за счет сокращения количества пустых мест 1 27

Все остальные цвета можно получить, устанавливая различные сочетания значе­


ний аргументов функции.

Экономия бумаги за счет сокращения


Т Р Ю К

№38 количества пустых мест


Использование свойства Сжатие для уплотнения отчетов.
Наличие пустых полей при распечатке объемных отчетов может привести к серь­
езным проблемам. Представьте себе список из 1000 обращений, поступивших от
потенциальных клиентов, в котором только половина записей имеет зарегистри­
рованные телефонные номера, внесенные в соответствующее поле. Если это поле
попало в отчет, то в распечатке вы увидите 500 пустых мест, отведенных под несу­
ществующие телефонные номера. Если пустыми окажутся и другие поля, то си­
туация усугубится.
Пустые места могут занять в отчете, в зависимости от его компоновки, в общей
сложности до 50 и более лишних страниц. На рис. 4.35 показан отчет, имеющий
подобный недостаток. Хотя часть контактной информации отсутствует, под нее
все равно отводится место.
•*:WrW:-:№*::W;::W>::: . . . • • . , , , . - . : • , . : , • , : •
;>:!:;:v:>::;:::-::-::V::;-:S:>;:::-Sr:::>:iW:;r>^:::-:::^:>:^::"::S:::::-;:^:-:

отчет
А
Казаков Александр Викторович

Лазо 23-56
Владивосток

354-56-73
fa
Зимин Александр Николаевич

Ташкентская 23-41
Самара
443122
Щ>

Лозовой Александр Владимирович

Маш иностроителей 1
Курган

Коноппев Алексей Анатольевич

| Страница:
< :..« :.| i \±JW\ < > ;
Рис. 4 . 3 5 . Отчет, неэкономно расходующий бумагу

На рис. 4.36 показан отчет в режиме конструирования, у которого в разделе Об­


ласть данных имеется группа полей. Как показано на рис. 4.35, некоторые из этих
полей остаются пустыми.
В перечне свойств следует придать свойству Сжатие значение Да. Это касается не
только свойств всех полей в разделе Область данных, но и свойств самого раздела.
128 Глава 4 . Представление данных

|=[Фамилия] а " & [Имя] S " 3 [Отчеств

.й ОбластьДаннь

: Макет
Имя
!; Данные.;.:. События
1 .:ОбластьД"«- * I;
Конец страницы .Отсутствует i
Новая строка или столбец Отсутствует I
Не разрывать
Вывод на экран
Расширение
•1т
.!Нет
Сжатие
Высота
Цвет фона
•\KZ zzzi
. 12,899см
;;;-:;ёЕ;Е-Ву:Жй:;;::;:...
* " • • "

Л6777215

Рис. 4.36. Настройка свойства Сжатие

ВНИМАНИЕ
При использовании свойств Расширение и Сжатие настраивать следует как связг н-
ные элементы управления, так и сам раздел Область данных.
У
При включенном свойстве Сжатие незаполненные поля данных уже не будут за­
нимать место в отчете. На рис. 4.37 показан улучшенный вариант отчета.

Зимин Але<сэндр Ниюлэем

Taiu I «wo; ая 23-41


Самара
443121

Л<вй*ой Александр Владимире »ич

Маш wo строит ел ей
Кдоган

Коноплеi А ш м й йн arc льпич

Пыоенио Аятояий Сергее ми

Зэюдса* 19-43
Архангельск

Лине» Андрей Семенов

Ксладзная 18-46
Ста •сопеть

Зъкси Андрей Вин of ci

Энтугиасто! 2-35
Александре»

И»ин Валерий Иннами

,хиий';:-: И •
I ГСВн] <
Рис. 4.37. Более компактный вариант отчета

На этом рисунке можно заметить ряд записей без номеров телефонов и даже во­
обще без дополнительных сведений. Во всех случаях пропуски подверглись еж *•
тию. При сравнении отчета на рис. 4.37 с отчетом на рис. 4.35 можно отметить, что
даже на первой странице уместилось большее количество записей. Как только бь л
Трюк № 39, Включение в отчет даты, времени и нумерации страниц 1 29

прекращен неэкономный расход рабочего пространства, число страниц отчета


значительно сократилось.
Свойство Расширение отвечает за обратный эффект. При конструировании отчета
следует рационально размещать элементы управления. Но при этом не исключе­
ны случаи, когда длина выводимых строк может превысить длину связанных
с ними полей. Устанавливая свойство Расширение в Да, вы позволите полю увели­
чить установленные для него размеры и вместить в себя все выводимые на печать
данные.

Ш Включение в отчет даты, времени


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

: Файл Праек Щрдат Сервис


т
~--у.'--'"г-'г::^ П о с т р п нт чь в м ра чга'й и и

1 . ' ' . ' . . * • : : • • :

• Верхнийко4:Г"Страница &LPa9eJ& из &


LK^gesj^
. . . . . " . ' . ; . . . . . . . . . . . . . . . . . .

! • 1
:••• Отмена |
• Область дек; :

!=[Фамилия] &S ••"•; :.., 1


±:::::::::::=Ы-М'!а Справка I
[Алрес
рР 0 * . : ЙбтЗ-тГ" | Номер страницы "Страница " 8. Ради Ь" MS " & Pat
1Чиспостраниц
'Почтовый,.*- 1 s g j Таблицы
ГГелефон : Щ запросы I Текущая дата
Й ] Forms 1 Текущая дата и время
J • Нижний коле; S3 Reports |Текущий пользователь
1 ЕЙ Функции
I £ 3 Константы
| СЗ Операторы

Ш;Поле7

, ДзнньД
Имя .Поле?
Данные . |="Страница" &. [Page] Ek" из
Формат поля
Число десятичных знаков .
Маска ввода
Вывод на экран • IAS
По вертикали Нет
Не выводить повторы . Йёт
Расширение

•::;КОнструктор -

Рис. 4 . 3 8 . Использование Построителя выражений для вставки в поле общего выражения


130 Глава 4. Представление данных

окне Построитель выражений. Лучший способ вызвать это окно при конструирова­
нии отчета — вставить свободное текстовое поле в верхний или нижний колонти­
тул (туда, где в этом есть смысл), а затем щелкнуть на многоточии (...), которое
следует за описанием свойства Данные, принадлежащего этому свободному поли.
Открывающееся после этого окно Построитель выражений показано на рис. 4.38.
В перечень доступных общих выражений входят нумерация страниц, вставка дат ы
и времени и вставка сведений о текущем пользователе. Самое практичное —вы­
ражение нумерации страниц Страница N из М, при использовании которого страни­
цы не просто нумеруются, а содержат сообщение вида: «Страница 15 из 40». Пос­
ле выбора нужного выражения его можно вставить в свободное текстовое пол г,
щелкнув на кнопке ОК. При генерации в отчете появится нумерация страниц (или
результат работы другого общего выражения).
Г Л А В А 5

Запросы и SQL
Трюки № 40-54

Используя стандартный Конструктор запросов, можно получить неплохие резуль­


таты, но создавая запросы непосредственно в окне ввода инструкций SQL, можно
добиться гораздо большего. Запросы делятся на две категории: запросы на вы­
борку (пассивные) и запросы на изменение. Запросы на выборку используются
для извлечения данных из таблиц, а запросы на изменение используются для опе­
раций над данными. Вы можете создавать запросы обеих категорий в стандарт­
ном Конструкторе запросов, но есть и исключения. Например, создание запросов
на объединение возможно только с помощью инструкций SQL. Эти же инструк­
ции служат для создания сложных запросов на изменение.
В данной главе рассматриваются все варианты использования SQL, как в стан­
дартном Конструкторе запросов, так и без его применения. Например, в разделе
«Получение выборки записей» (Трюк № 40) рассмотрен способ извлечения неболь­
шого набора записей с использованием Конструктора запросов, а задача «Встав­
ка в запрос итоговой суммы» (Трюк № 43) решена исключительно с помощью SQL.
В конечном итоге все рассмотренные в данной главе трюки посвящены неорди­
нарным и, порой, вполне реальным задачам, над решением которых вы, возмож­
но, уже давно ломаете голову. При разработке собственных проектов освоение
языка SQL воздастся сторицей. Конструктор запросов поначалу удерживает от
изучения SQL, но по прошествии времени в этом возникает объективная необхо­
димость, вызванная функциональной неполноценностью стандартного средства.
Будем надеяться, что трюки этой главы активизируют ваше мышление и послу­
жат своеобразным трамплином для более углубленного подхода к разработке баз
данных.

Т Р Ю К Получение выборки записей


№40 Использование свойства Набор значений для получения независимой выборки записей.

Чаще всего запрос на выборку используется для получения всех записей, отвеча­
ющих определенным критериям. Как правило, возвращаемый набор записей мень-
132 Глава 5. Запросы и SOL

ше по объему, чем таблица или таблицы, послужившие источником данных, п >


скольку не все записи отвечают заданным критериям и подходящих записей все­
гда меньше их общего числа в исходной таблице.
В некоторых случаях вам может понадобиться всего лишь выборка записей, для
которой не имеет смысла определять какой-либо критерий отбора. Эта выборка
совсем не похожа на отбор некоторых записей, отвечающих вполне определенно­
му критерию. Например, в целях статистических исследований может понадобит Ьг
ся выборка, на основе которой можно составить общее представление обо всем
наборе данных. Неважно, где находятся исходные данные, в простой таблице ил и
в наборе записей, полученном в результате фильтрации по определенному крит г-
рию, здесь ключевым пунктом является то, что на следующей стадии производит­
ся выборка без каких-нибудь предварительных условий. Вот тут-то и пригодится
свойство Набор значений, или, на языке SQL, — предикат Тор.
Набор значений работает по одному из двух вариантов:
• возвращает определенное количество записей;
• возвращает указанный процент записей.

Использование свойства Набор значений


Набор значений извлекает выборку из числа первых записей набора данных. Если
вы хотите получить выборку из числа последних записей набора данных, то сна­
чала следует отсортировать набор в порядке убывания, а не возрастания значе­
ний. В любом случае, при каждом выполнении запроса вы будете получать одну
и ту же выборку записей. Чуть позже мы рассмотрим способ получения выборки,
состоящей из случайных записей.
На рис. 5.1 показан запрос в режиме Конструктора, в котором число возвращае­
мых записей указывается в списке свойств. Свойство Набор значений предлагает
на выбор несколько значений. Вы можете воспользоваться одним из этих предлс -
жений или ввести свое собственное значение.
Если будет выбрано значение 25, то из начала набора запрос извлечет, как и ожи­
далось, 25 записей (рис. 5.2).

1 •? - -
1 ;f Свойства запроса
j Общие
• - - • • '
Г л

; Считывание
1 Описание . ;Л :|
:| Режим по умолчанию Режим таблицы
| Вывод всех полей Нет
| Набор значений 25 "'v
5
п<>
—*—$ <1ри запуске предоставляются права . 100 ^ U >
Попе: Считывание 5% "% Щ1
1Фчя таблицы; По*азания ;| г 25%
Все
Сортировка: Динамический набор
Вывод на экран:

t
Условие отбора: b if Фильтр
60

ИЛИ: j | Порядок сортировки :


< \:- -у-

Рис. 5 . 1 . Выбор значения для свойства «Набор значений»


Трюк № 40. Получение выборки записей 133
ра. значений : запрос на выборку

0,277
0,51
"6,943
llillili-'../'
1,312
0.847 11
Тдв
0,718
0,984
ililiil
1,481
0.375
1111111
1,513
0,916
0.568
ill
" 6.744
1,189
;
1,417 . ШШ
0,76
"6,718
' 1.266
0.327
0,093
"6,723
"6,578
Ъ,Э7
0
Запись: Г Щ * | " ~

Рис. 5.2. Возвращение заданного числа записей

Интересно посмотреть, какую инструкцию SQL сгенерирует стандартный Конст­


руктор запросов Access. Переключив Вид в режим SQL, мы увидим следующее:
SELECT TOP 25 Показания.Считывание
FROM Показания;
Предикат Тор помещен сразу же после инструкции Select и указывает на количе­
ство возвращаемых записей. Чтобы возвратить определенный процент записей,
нужно просто добавить слово Percent к инструкции SQL после указания числа:
SELECT TOP 25 PERCENT Показания.Считывание
FROM Показания;
Если используется Конструктор запросов, то к числу, которое присвоено свой­
ству Набор записей, нужно добавить знак процента (%) (рис. 5.3).

Свойства запроса
Общие ;
Описание
тРежим таблицы
Режим по умолчанию
Вывод всех полей !нет
"•"'!
Набор значений
Уникальные значения т Л
Уникальные записи
При запуске предоставляются права , ж &....
База данных-источник |Нет J3
Поле;
Строка подключения-ист очник Пользователя
Иия таблицы:
Блокировка записей |(текущая)
Сортировка: Тип набора записей ^Отсутствует
Вывод не экран Время ожидания ODBC Динамический иабос
Условие отбора; Фильтр
: Порядок сортировки

Рис. 5.3. Задание на возврат определенного процента записей


134 Глава 5. Запросы и SOL

Трюк в трюке
Свойство Набор записей или предикат Тор хорошо справляются с извлечением не­
большой выборки записей, но эта выборка всегда будет одной и той же. Если даже
к исходным записям не применялась сортировка, то они располагаются в порядке
их занесения в таблицу.
Для возвращения случайного набора записей требуется при сортировке записей
применить функцию Rnd. Обычно сортировка сама по себе не способна вернуть
случайный набор записей. Но сортировка на основе случайного значения позво­
ляет оспорить это утверждение. Для проведения именно такой сортировки в ин­
струкцию SQL следует внести следующие изменения:
SELECT TOP 25 Показания.Считывание
FROM Показания
ORDER BY RND([Считывание]);
В качестве аргумента функции Rnd используется имя поля. При каждом выпол­
нении запроса возвращается случайная выборка записей.

Ш
Защита от сбоев при проведении
операции добавления записей
Предупреждения отказов, возникающих при добавлении записей, и обеспечение зане­
сения в таблицу всех предназначенных данных.
SQL-инструкция Insert используется для добавления записей к таблице. Чаи,»,1
всего она неплохо справляется со своей работой, но склонность к сбоям все же
имеет. В данном трюке рассматриваются два метода проверки данных на пригод­
ность к использованию в инструкции Insert. Перед разбором этих методов созда­
дим простую таблицу, показанную на рис. 5.4.

Тип данных Г
Пациент Текстовый
Возраст Числовой

Свойства поля

Поде
Размер поля
Формат поля
Маска ввода
] Подпись
I Значение по умолчанию Иия поля может
• Условие на значение ; состоять из 64 знаков с
; учеточ пробелов. ДЛЯ
I Сообщение об ошибке
справки по именам
I Обязательное поле :нет полей нажмите
| Пустые строки
| Индексированное поле iAtl ~Z клавишу?!.
| Сжатие Юникод Мет
I Режим IME ifel
| Режим предложений IME ;Нет контроля
I С март-те г и :Нет.

Рис. 5 . 4 . Таблица для хранения сведений об именах и возрасте пациентов


Трюк № 41. Защита от сбоев при проведении операции добавления записей 135

Таблица состоит из двух полей:


• Пациент — хранит имена пациентов; размер поля установлен в 10 символов;
• Возраст — хранит возраст пациентов.

Решение проблемы превышения размеров поля


Попытка разместить в текстовом поле данные, превышающие его длину, приве­
дет к сбою в работе инструкции Insert. Следующая инструкция Insert будет рабо­
тать без сбоя:
"Insert Into Пациенты (Пациент, Возраст) Values ('Петр', 22)"
Имя Петр легко помещается в текстовом поле Пациент. А теперь рассмотрим та­
кую инструкцию:
"Insert Into Пациенты (Пациент, Возраст) Values ('Пантелеймон', 22)"
Выполнение этой инструкции приведет к сбою, поскольку имя Пантелеймон со­
стоит из одиннадцати букв, а поле Пациент способно вместить максимум десять.
Исправить подобные инструкции проще всего вставкой функции Left, урезающей
текст до десяти символов.
К примеру, в следующей процедуре записи из таблицы НовыеПациенты добавля­
ются в таблицу Пациенты. Функция Left, укорачивающая имена до десяти симво­
лов, помещена в середину инструкции Insert:
Dim myDB As ADODB.Connection
Set myDB = CurrentProject.Connection
Dim г5_НовыеПациенты As ADODB.Recordset
Set г5_НовыеПациенты = New ADODB.Recordset
г5_НовыеПациенты.0реп ("Select * from НовыеПациенты " ) , myDB
Do Until г5_НовыеПациенты.EOF
myDB.Execute ("Insert Into Пациенты Values ('" & _
Left(г5_НовыеПациенты.Fields("nauneHT"), 10) & _
"', " & г5_НовыеПациенты.Fields("Возраст") & ")")
г5_НовыеПациенты.MoveNext
Loop
г5_НовыеПациенты.Close
myDB.Close
Set myDB = Nothing
Другим вариантом решения этой проблемы может стать увеличение размера поля
таблицы.

Отслеживание появления апострофов в исходных данных


Ничто так не вредит работе инструкции Insert, как непарный апостроф или оди­
нарная кавычка. Полностью исключить их появление в данных невозможно, но
для инструкции SQL, содержащей Insert, одиночная кавычка означает границу
текстовой строки. Поэтому без небольшого исправления следующая инструкция
вставки работать не сможет:
"Insert Into Patients (Patient, Age) Values (Left('O'Reilly'. 16), 22)"
Проблема заключается в том, что при выполнении инструкции одинарная кавыч­
ка, размещенная перед буквой «О», откроет текстовую строку, а одинарная ка­
вычка после буквы «О» эту текстовую строку закроет. В результате этого остав­
шаяся часть имени — Reilly — останется нераспознанной.
136 Глава 5. Запросы и SQL

Удвоение одиночной кавычки приведет к устранению проблемы, а помочь в этом


сможет функция Replace, которая заменит каждую одинарную кавычку двойной.
Следующая процедура представляет собой модифицированную версию ранее рас -
смотренной процедуры:
Dim myDB As ADODB.Connection
Set myDB = CurrentProject.Connection
Dim г5_НовыеПациенты As ADODB.Recordset
Set г5_НовыеПациенты = New ADODB.Recordset
Г5_НовыеПациенты.0реп ("Select * from НовыеПациенты " ) , myDB
Do Until г5_НовыеПациенты.EOF
myDB.Execute ("Insert Into Patients Values ('" & _
Replace(rs_HoBbienauMeHTbi. Fi eldsC'flaLiMeHT") , "'", ) &_
"', " & г5_НовыеПациенты.Fields("Bo3pacT") & ")")
rs_HoBbienauMeHTbi.MoveNext
Loop
г5_НовыеПациенты.Close
myDB.Close
Set myDB = Nothing
А вот пример использования функции Replace:
Replace(rs_HoBbienauneHTbi. F i e l d s ( " P a t i e n t " ) , , "''")
Эта функция проверяет наличие в текстовой строке одного или нескольких сим­
волов. Если искомая подстрока будет найдена, то ее заменит другая подстрока,
состоящая из одного или нескольких символов. Функции передаются три аргу­
мента:
• строка, в которой производится поиск;
• искомые символы;
• символы, предназначенные для замены найденных символов.
Все данные, получаемые из поля Пациент таблицы НовыеПациенты, проверяются
на наличие одинарной кавычки, которая заменяется двойной кавычкой. В резуль­
тате получается работоспособная инструкция SQL, осуществляющая вставку.

Сочетание двух проверок на приемлемость


Все хорошее я приберег напоследок. Вам ведь нужно проверять данные и на пре­
вышение длины, и на наличие одинарных апострофов. А нельзя ли сделать это
одновременно? Ну конечно же можно! Нужно только разместить одну функцию
внутри другой, как это сделано в следующем примере:
myDB.Execute ("Insert Into Пациенты Values ('" & _
Lef t(Replace(rs_HoBbieIlauMeHTbi. Fields("riauMeHT") , " ' " , ' ) , 10) & _
& г5_НовыеПациенты.Fields("B03pacT") & " ) " )

Поиск записей без подчиненных


Т Р Ю К

№42 по нескольким связанным полям


В мастере запросов на выборку записей без подчиненных в другой таблице задается
только одно связанное поле. Вы можете приспособить этот вид запроса для работы
с несколькими связанными полями.
Если нужно выбрать из одной таблицы записи, у которых нет связанных записей
в другой таблице, то проще всего воспользоваться встроенным в Access мастерои
Трюк № 42. Поиск записей без подчиненных по нескольким связанным полям 137

запросов Записи без подчиненных. На рис. 5.5 показано диалоговое окно Новый за­
прос, из которого вызывается мастер.

Новый ззпрчс

Простой запрос
Перекрестный запрос
Повторяющиеся записи
Записи без подчиненных
Самостоятельное создание
нового запроса ъ

DDC
Рис. 5.5. Запуск мастера запросов «Записи без подчиненных»

Запрос составляется поэтапно, в нескольких окнах, выводимых мастером. Вам


нужно выбрать две таблицы и метод работы запроса. Например, вам нужно знать,
какие записи Таблицы А не имеют связанных с ними записей в Таблице Б или,
наоборот, какие записи Таблицы Б не имеют связанных с ними записей в Табли­
це А. В любом случае, непременным условием для выполнения задачи должна
быть установленная связь между таблицами.
Точнее говоря, отобранные в этот запрос таблицы не обязательно должны иметь
формальную связь, установленную в диалоговом окне Схема данных. Достаточно
того, чтобы анализируемые на соответствие поля содержали одинаковые данные,
иначе все без исключения записи будут возвращены в качестве записей без под­
чиненных.
Таблицы могут быть связаны по одному или нескольким полям. К сожалению,
мастер дает возможность установить связь между таблицами только по одному
полю (рис. 5.6).

имеющих подчиненных
Какие данные содержатся в обеих таблицах?
Например, и таблица "Клиенты", и таблица "Заказы" содержат поле
"Клиент". Соответствующие поля иогут иметь и различные имена.

Выберите подходящее попе в каждой таблице и нажните кнопку к « ? .

Поля в сЫ_ПокупателиЗ': Поля a tbtJloKynKH? :

Рис. 5 . 6 . Выбор единственного поля для включения в поиски соответствия

Для этого следует выбрать по одному полю из каждой таблицы, справа и слева,
а затем щелкнуть на кнопке между таблицами и установить соответствие, исполь-
138 Глава 5 . Запросы и SCI.

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

Разбор запроса
В используемом примере производится поиск покупателей, не имеющих подчи­
ненных записей в таблице покупок. Использование мастера Записи без подчинен­
ных позволяет выявлять таких покупателей на основе их фамилий. На рис. 5 7
показан запрос, созданный в режиме Конструктора.

Рис. 5.7. Создание запроса для поиска записей без подчиненных

Для извлечения всех записей о покупателях, чья фамилия отсутствует в таблице


покупок, используется ключевое слово LEFT JOIN. В режиме SQL запрос имеет сле­
дующий вид:
SELECT 1Ы_ПокупателиЗ .Фамилия , 1Ы_ПокупателиЗ .Имя
FROM 1Ы_ПокупателиЗ LEFT JOIN 1:Ы_ПокупкиЗ ON
ТЫ_ПокупателиЗ.Фамилия = tbl_noKynKn3.Фамилия
WHERE (((tblJloKynKH3.Фамилия) I s N u l l ) ) ;
Но здесь может возникнуть проблема однофамильцев. Стоит только одному п >
купателю иметь запись в таблице покупок, как все остальные с такой же фамил \-
ей будут исключены из данных, возвращаемых запросом, даже если должны были
в них попасть.
На рис. 5.8 проиллюстрирована эта ситуация. Слева направо расположены таб­
лица покупателей, таблица покупок и результат выполнения запроса, осуществ­
лявшего поиск покупателей, не совершавших покупок. В левой таблице есть д за
однофамильца: Алексей Петров и Виктор Петров. В расположенной посреди зе
таблице покупок фигурирует Виктор Петров. В списке, полученном в результате
выполнения запроса, Алексей Петров в качестве покупателя без покупок не появ­
ляется, хотя на самом деле должен там быть.
Поскольку проверка ведется только по фамилиям, все клиенты-однофамильцы,
в том случае, если хотя бы один из них совершил покупку, в итоговом списке яе
фигурируют. Результат выполнения запроса не отвечает поставленной задаче.
Трюк № 42. Поиск записей без подчиненных по нескольким связанным полям 139

., MfcWl tec.» - ' '.


B«ato;S::!^^s:::s:::|iai:::::Bcj^K«:^;:*op>»T Записи Cgpmc Окно Jnpaetca

tbl Покупате i » 3 т ~
/мц
!;;;__ Фамилий | Имя Дата •Сумма Щ '•• Фамилия
L\ Александр
1i
!•:' • Асташков Александр
Волков
Климов
Григорий
.Кирилл
С Петров
Степанов
Романов
| Виктор
Александр
:Александр
12.05.2005;
09.03.2005
02.04.20051
1 200,00р.
2 345 Л0р.
234,00р.
: • Асташков
Волков
Климов
iГригорий
[Кирилл
Курмазов Александр 23.12.2004] 654,00р. Боярский Владимир
Петров Виктор Завьялов :Александр 26.07.2005! 975.00р". Сухов 1 Виталий
Боярский -Владимир Чельцов [Алексей 12.06.2005: f324,00р. Матвеев Николай
i _ _ Андреев ; Сергей
Петров Алексей
Соловьев ; Виктор
Сухов Виталий Г Тарасов ; Андрей
Матвеев Николай | Быков j Анатолий
Андреев Сергей тСлавин :Леонид
| Дорохов [Владимир
Курмазов Александр
л Казаков : Игорь
Соловьев Виктор | Евсеев :Андрей
Тарасов Андрей
Быков Анатолий
Запись; [HJ •» [~
Славин Леонид
Кириллов Алексей
Дорохов Владимир :: \ запись- [ и ) : 1 LUHLfeiJ »>7
Казаков Игорь

Запись; [ M ] : ; i . ; Г

Рис. 5.8. Просмотр таблиц и результата выполнения запроса на отсутствие подчиненных записей

Внесение изменений в запрос


Все, что нужно изменить в запросе, — это устроить проверку записей не только по
фамилиям, но и по именам. Сделать это можно как в режиме Конструктора запро­
сов, так и в режиме SQL. На рис. 5.9 показана измененная конструкция запроса.

I'
<
*
Фамилия
Имя
Отчество
Город

Поле:
Имя таблицы:
Сортировка;
1ыесд на экран:
'словив отбора:
Фамилия
; •

гЫ ПокупателиЗ
• ,

щ
шчщврв : wnpoc на »ыбарку


• тЬ^.ТЬкуЬййЗ

* ;Фамилия

Имя
fc::z;r:j
^Отчество
!дата

:Ы ПокупателиЗ

т
v;

Фамилия
tbl Покупки3

Is Null
п
Имя
tbl ПО''упкиЗ

Is Mull
п
l —
«
3

1 пли:
< : •
Ф
1
_ „.
Рис. 5 . 9 . Теперь в запросе на поиск записей без подчиненных проверка будет вестись
по двум полям
140 Глава 5. Запросы и SGL

При этом важно соблюсти следующие требования:


• нужно добавить Is N u U в условие отбора, чтобы обозначить отсутствие в табл!
це имени покупателя;
• между таблицами нужно установить еще одну, вторую, связь по новому, вклк »-
ченному в запрос полю; присмотритесь к различиям в связях таблиц, исполь­
зуемых в запросе, сравнивая конструкцию на рис. 5.7 с конструкцией на рис. 5.9;
• нужно сбросить флажки Вывод на экран в столбцах полей, представляющгх
подчиненную таблицу (в данном случае — таблицу покупок), поскольку эти
поля не должны отображаться на экране.
На рис. 5.10 показано, что теперь в результате работы запроса покупатель Алек­
сей Петров попал в список не совершавших покупок, а с ним заодно туда попали
еще несколько ранее пропущенных покупателей.

; tbUTonynaren>i3' без гюдчи нв нньгх » Ч bV ПохупкиЗ*:ranрос на вы бирж у


Фамилия J Имя •
Асташков Александр
i Волков Григорий
. . . . • ' .
• •

• . :• . ' • . :•::•:••:
:

• : :

Климов Кирилл :. ' V . | К . . . ' . • • " • • . ' • • ' . : ' . " . ' . . • ' " '

Боярский Владимир ' . ' . • ' ' . . . : • ' . " . ': ' .'

Петров Алексей ' . • • :


' • • . : • . • • : ' • • • . • / • : :•.•• • . • • - - : • : • • • '•• . • . ; • • • • • • • • • . . . . . . . . . . . . . . . • • . .. ..

:
• я .. ..:•: : •
Сухов Виталий
Матвеев Николай
•ИР"
_ „ _
Андреев

Тарасов
Быков
Сергей
Соловьев Виктор
Андрей
Анатолий
•«llilillilllili!::
• . :
: ' • ' • ' ' • • ' ' ' " ' ' ' ' " " ' " • • • • • • . . . . . . . . . . . . . . • • . . . • • .

Славин Леонид
1JJ

Владимир
Игорь
— Андрей
Щеглов Михаил
Вороное Семен
Фурсин Василий
1 Я 1 | 1 1 ^ ; - " : : ^ ' " ; • ' . ••';-';-:;:-; '
Эапи;о ' | < _ | Г т [ Б Ш > - "'>8
Рис. 5 . 1 0 . Исправленный список записей без подчиненных

Т Р Ю К Вставка в запрос итоговой суммы


№43 Использование запроса на объединение для вывода записей, содержащих некотор >ie
данные, и их итоговой суммы.
Вам предлагается простой способ вывода списка записей таблицы, в конце котэ-
рого помещается итоговая сумма всех значений. Для этого сначала нужно при
помощи инструкции Select создать запрос на выборку и извлечь записи из табл и-
цы, а затем, используя инструкцию Union, объединить эти записи с итоговой сум­
мой значений. Итоговое значение возвращается функцией Sum. Естественно,
подразумевается, что данные, с которыми ведется работа, имеют числовой или
денежный формат.
Трюк № 44. Сортировка по любому произвольному символьному фрагменту 141

Поскольку Конструктору запросов не под силу справиться с запросом на объеди­


нение, его нужно ввести в режиме SQL. В следующем примере инструкция SQL
объединяет записи о продажах с суммой продаж:
SELECT 1Ы_Продажи. Сумма
FROM 1:Ы_Продажи
UNION ALL SELECT Sum(1:Ы_Продажи .Сумма) AS СуммаПродаж
FROM ИЫ_Продажи;
На рис. 5.11 показана нижняя часть списка возвращенных запросом записей. Оче­
видно, что в последней строке выведена итоговая сумма.

Рис. 5 . 1 1 . Включение в данные итоговой суммы

Трюк в трюке
Этот запрос нетрудно изменить для вывода других совокупных значений, напри­
мер каких-нибудь вычислений или средней величины:
SELECT 1Ы_Продажи .Сумма
FROM 1Ы_Продажи
UNION ALL SELECT Ау§(1:Ы_Продажи .Сумма) AS СредняяСумма
FROM 1Ы_Продажи;

Ш Сортировка по любому произвольному


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

Мне нравится работать с Конструктором запросов. С его помощью можно зада­


вать все виды сортировки. Но, наверное, вы замечали, что текстовые данные он
всегда сортирует по всему содержимому поля. Такой подход вполне логичен и
отвечает обычным требованиям к сортировке. Но если нужно применить необыч­
ный способ сортировки, скажем, по первым пять символам или по последним трем,
тут уже возникнет проблема.
142 Глава 5. Запросы и SQL

Подобная задача становится особенно актуальной, если Access использует дан­


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

Сортировка по символам внутри строки


На рис. 5.12 показана таблица, заполненная записями о продажах. Все записи
имеют фиксированный формат. Два первых символа содержат код продавца, шесть
следующих — дату, а последние символы — сумму покупки, причем последние;
два символа являются десятичной частью числа. Поэтому первая запись поля
Продажи (СТ2310044595) означает следующее:
• код продавца — СТ;
• дата покупки — 23 октября 2004 года (в поле формат даты представлен в виде
мм-дд-гг);
• сумма покупки — 45 рублей 95 копеек.

СТ2Э10044595
ВС2307041281Э
ШД15120410375
ставзотз&Г
ШД2701041706В
ВС13100413546
СТ2912048504
МР2210044682
Ав75Т2044373
ШД01040417368
МР24080418517
ВС12080448Б1
AB2S050410578
МР240204156Т8
СТ21050414354
ШД180Е0414418
МР2807049141
ШД21030410344
ШД1909048653'
BClT090470178
Запись;
(Ш '< Г
Рис. 5.12. Код продавца, дата и сумма покупки, собранные в одном поле

Предположим, вам нужно отсортировать записи по дате. В каждой записи дага


покупки начинается с третьей позиции и занимает шесть символов (рис. 5.12).
Вам когда-нибудь приходилось работать с такими данными? Без знания структу­
ры разобраться в них невозможно. Попробуй догадайся, из каких именно чисел
складывается дата.
Для решения нашей задачи лучше всего подойдет функция Mid, одна из функций
обработки текстовых данных. Она возвращает часть текстовой строки, но для этого
Трюк № 44. Сортировка по любому произвольному символьному фрагменту 143

ей необходимо передать три параметра: строку данных, стартовую позицию и число


извлекаемых символов. А вот так выглядит ее синтаксис:
ШсЦстрока, начальная позиция, длина)
Хотя по замыслу в данном примере работа ведется с датой, информация, храня­
щаяся в таблице, представлена в текстовом виде. Поэтому с работой легко справ­
ляются стандартные строковые функции.
На рис. 5.13 показан запрос в режиме Конструктора, в котором используется функ­
ция Mid. В первом столбце расположено поле Продажи само по себе, а во втором —
вычисляемое поле, использующее функцию Mid. Внутри строки вызова функции
название поля Продажи взято в скобки. Это стандартный прием размещения име­
ни поля в функции. Аргументы функции Mid указывают на извлечение шести сим­
волов, начиная с третьей позиции (то есть даты).
г™:*:*»:***:*:*:***:
' Чгу_П(ияп*н : мпрос »» •ыГюриу

- л
Попе: Продажи М1сХ[Продажи];Э;б) |;у
Имя таблицы: Продажи
Сортировке: по возрастанию
Вывод не ж р а н : И п п
Условие отбора:
ИЛИ:
:
ММ

Рис. 5 . 1 3 . Использование функции Mid для извлечения даты, по которой происходит сортировка

При выполнении запроса второй столбец содержит именно дату, поскольку функ­
ция Mid извлекает символы, размещенные с третьей по восьмую позицию. Во вто­
ром столбце к тому же должна быть включена сортировка, поскольку в итоге, нам
нужно отсортировать данные по дате. Поэтому на пересечении строки Сортировка
и второго столбца следует установить сортировку по возрастанию, выбрав соот­
ветствующий пункт из раскрывающегося меню.
Обратите внимание, что на рис. 5.13 флажок Вывод на экран для вычисляемого
поля не установлен. При выполнении запроса этот столбец не нужно выводить на
экран. Он используется только для осуществления сортировки, поэтому его по­
явление на экране не обязательно.
На рис. 5.14 показан результат выполнения запроса. Теперь записи о продажах
отсортированы по дате. В первой возвращенной записи (МР0104047011) содер­
жится фрагмент 010404, соответствующий 4 января 2004 года.

Сортировка по нескольким фрагментам поля


А что, если нужно будет отсортировать данные и по дате, и по сумме покупки?
Причем сортировать по дате в возрастающем порядке, а по сумме покупки —
в убывающем. Обычно требуется отсортировать суммы покупок именно по убы­
ванию. Можно ли вообще такое сделать?
144 Глава 5 . Запросы и S Q .

Рис. 5.14. Записи, отсортированные по дате

Конечно можно! Для этого следует поместить выражения в два столбца, для даты
и для суммы. На рис. 5.15 показано, как это сделать, если сумма начинается с де­
вятой позиции. Параметр длины, передаваемый функции Mid, обрабатывающей
сумму, равен 5. Учитывая, что точная длина известна не всегда, в данном примере
суммы в записях могут состоять из четырех или из пяти цифр, поэтому установка
длины в пять символов будет работать для всех записей.

• Чгу_Прода*м? : юпрос 11л «ыборку '?-Ж

Продажи
Порядок

<
Поли; Продажи
№(я таблицы; Продажи
М1с1([Продажи1;3;6 Уа1(М1с)([Продажи Ь9;5»
,дЧ
Сортировка; по возрастанию по убыванию
8ывад не экран:
Условие отбора; п о F1 г
или:
<щ >У

Рис. 5.15. Запрос, созданный для сортировки по двум фрагментам поля

В данном примере, как и раньше, при выполнении запроса на экран выводится


только само поле Продажи. Поэтому для второго и третьего столбцов флажки Вн-
вод на экран не установлены. В обоих столбцах используется функция Mid, извле­
кающая фрагменты из одной и той же строки, содержащейся в поле Продажи.
Но теперь результат несколько отличается от предыдущего. На рис. 5.16 показа­
ны возвращенные запросом данные. Сравнивая этот результат с тем, что изобра-
Трюк № 44. Сортировка по любому произвольному символьному фрагменту 145

жен на рис. 5.14, вы можете заметить, что записи с 6 по 8 подверглись перестанов­


ке. У этих записей одинаковые даты — 16 января 2004 года (011604), но теперь
суммы, содержащиеся в них, следуют в порядке, определенном условиями запроса.
. : • . . : . . . . : . : . : . . . ' . •

)^гу_Прода'*:и2 : Mnpote на выборку

МР01040471


ШД010904765
СТ0112049883
AB011204198; 111
ВС011304135^ ЯШ
MP011304551
МР011604138
МР011604966
СТО11604733: V
| ж
АВ012104636 •: • . - . • • • • • • •:•-. : • • •••. • : . : . • . • . • • • • • • • • • • •

. - . • • .
: :
ШД012204454- . • ' • • ШшЩ
• •

МР012304158 •

ШД0123043
СТ0124042111
ШД01270417068 J
AB0128046699
BC0201041377
MP0206041435
•ill
AB0212041047

Запись: [Ц j; i P ' • |">Г]Щ Ю 200

Рис. 5 . 1 6 . Сортировка по дате и сумме, изменившая порядок записей

Сортировка по фрагменту с неизвестной начальной позицией


Нередко данные, импортированные из внешних систем, должны подвергаться
обработке перед их использованием в вашем приложении. Подобные проблемы
часто связаны с именами и фамилиями. В вашей базе данных для имени и фами­
лии могут быть предусмотрены отдельные поля, поэтому сортировка по фамили­
ям не вызовет затруднений. Но представьте, насколько все усложнится, если вам
представлены данные, в которых полные имена помещены в одно поле. А что, если
сначала идет имя, а потом фамилия? В отличие от предыдущего примера о прода­
жах вы не можете заранее знать, с какой позиции каждой записи начинается фа­
милия.
Вся хитрость сортировки по фамилии заключается в предварительном вычисле­
нии позиции пробела. Для этого наряду с функцией Mid используется и функция
InStr. Теперь изменяющаяся позиция пробела возвращается функцией InStr.
Эта функция обнаруживает начальную позицию первого появления отдельного
фрагмента в строке. В данном примере строкой, в которой ведется поиск, служит
содержимое поля Клиент, а искомым фрагментом является пробел. Строка вызова
функции InStr имеет следующий вид:
InSti-ЦКлиент] ;" ")
Функция InStr служит для передачи функции Mid той позиции, с которой она долж­
на начать извлечение фрагмента. При этом вызов функции InStr расположен внут­
ри вызова функции Mid. Это сочетание имеет следующий вид:
Mid([Клиент];InStr([Клиент];" ")+1;10)
146 Глава 5 . Запросы и SCI.

Следует заметить, что функция InStr возвращает позицию пробела, а нас интере­
сует начальная позиция фамилии, отстоящая от пробела на один символ вправо,
поэтому к значению, возвращаемому функцией InStr, добавлена единица, после
чего эта сумма используется в качестве параметра начальной позиции для функ­
ции Mid.
На рис. 5.17 показано, как создать запрос, используя эти вложенные друг в друга
функции. В качестве длины фамилии выбрано произвольное значение 10. Фами­
лии отличаются по длине, но использования для сортировки первых 10 символе в
вполне достаточно для получения приемлемого результата.

3 1 Клиенты сортиров.,, Пнтоос «а .«6 0( жу ..,..,.,...,,.,. 2НЙЁ


j ,«,„.» 'л

1 :Клиент

'У :
щш
Попе: Клив„, МкЙКяивнт1;1паг([г<лиент1;" >1;Ю) Щ
ИНЙ таблицы: Клиент.
Сортировка: по возрастанию
Вывод на экран; • ]
Условие отбора; И п
или;

1 •

ж
<м • > •

^^^^•Х^ЪХЗ&ХЖХЖ&ЖЗЯЪ ^.™«^^.w~w~-^ - izsx^i^z^iSit^zs&ifix&^z^vX&x*к Й й т е к

Рис. 5 . 1 7 . Использование вложенных функций для сортировки

На рис. 5.18 показан результат выполнения запроса. Клиенты отсортированы пэ


фамилиям внутри единственного поля, в котором содержатся имена и фамилии
Что, собственно, и требовалось сделать.

К 1ИИШЫ П1,1ГН|
Клиент-
- е Adams

Ш Travis Adams
Emily Alandale
Henry Albrecht
SethAlpaugh
Sal Antelman 'Л
Dana Armstrong
Alex Avakian
Randal Balan
Riaz Baldwin
Alan Barandes
Evan Barbee
Г" Rosie Baucom
Ruben Baylis
Rusty Bearman
Betty Bearman
Jannice Beasley
Запись: [iij

Рис. 5 . 1 8 . Список клиентов, отсортированный по фамилиям


Трюк № 44. Сортировка по любому произвольному символьному фрагменту 147

Трюк в трюке
Сортировка по именам и фамилиям не вызывает затруднений, когда приходится
работать исключительно с ними. А как быть со вторыми именами, формами обра­
щения и примечаниями? Как в таком случае можно справиться с задачей? Давай­
те поднимем планку сложности данного трюка и включим в состав запроса соб­
ственную функцию.
Нам нужна функция, которая для определения позиции пробела исследует име­
на, хранящиеся в поле Клиент. Вся загвоздка в том, что теперь в именах может
быть несколько пробелов. Например, имя Ken S. Bluttman содержит два пробе­
ла — по одному с каждой стороны от инициала. Некоторые имена содержат три,
четыре или даже пять пробелов. Предназначением функции будет вычисление
нужного пробела, определение его позиции и передача результата функции Mid.
Сначала нужно поместить код функции в программный модуль VBA. Для этого
в окне базы данных нужно выбрать вкладку Модули, выбрать создание нового мо­
дуля и ввести в него следующий код:
Function поиск_пробела(имя_клиента As String)
Dim длина_имени As Integer
Dim цикл_пробелов As Integer
Dim счетчик_пробелов As Integer
Dim фрагмент_имени As String
Dim позиция_первого_пробела As Integer
'подсчет пробелов в полном имени
счетчик_пробелов = 0
длина_имени • 1_еп(имя_клиента)
For цикл_пробелов = 1 То длина_имени
If г^(имя_клиента, цикл_пробелов, 1) = " " Then
счетчик_пробелов = счетчик_пробелов + 1
End If
Next цикл_пробелов
'разбор полного имени, с предположением в каждом ветвлении Case
Select Case счетчик_пробелов
Case 0
'пробелы не обнаружены!
'возврат 1 в качестве начальной позиции
поиск_пробела = 1
Case 1
'имя и фамилия,
'разбиение по первому пробелу
поиск_пробела = InStr(имя_клиента, " ")
Case 2, 3
'предполагается наличие имени, второго имени и фамилии (2 пробела)
'или имени, втрого имени, фамилии и примечания (3 пробела),
'разбиение по второму пробелу
поиск_пробела = InStr(имя_кпиента, " ")
позиция_первого_пробела = поиск_пробела
фрагмент_имени = _
Млс1(имя_клиента, поиск_пробела, длина_имени - поиск_пробела)
поиск_пробела = InStr(фрагмент_имени, " ") + позиция_первого_пробела - 1
Case Else
'структура имени не поддается разбору
'разбиение по первому пробелу
Поиск_пробела = InStr(имя_клиента, " ")
End Select
End Function
148 Глава 5. Запросы и SGL

В двух словах, функция анализирует имя клиента, подсчитывая, сколько в не л


пробелов, а затем определяет наиболее подходящий пробел, возвращая его пози­
цию, как и раньше, функции Mid.
В режиме Конструктора вызов функции поиск_пробела встроен в вызов функции Mid:
Mid([Клиент];поиск_пробела([Клиент])+1;10)
Как создать запрос, показано на рис. 5.19.

Рис. 5.19. Функция Mid, использующая функцию поискпробела

При выполнении запроса имя каждого клиента анализируется функцией поискпро­


бела, которая возвращает позицию наиболее подходящего пробела, после чего проис­
ходит сортировка по фамилиям. На рис. 5.20 показан результат работы запроса.

i
шшшш—'
Клиент •: |
• Travis Adams i
Emily Alandale
Henry Albrecht
Sal Antelman, Jr j
Dana Armstrong i
Alex Avakian III
Seth B. Alpaugh i
Riaz Baldwin
Alan Barandes
Evan Barbee
Rosie Baucom
Ruben Baylis
Betty Bearman 'llllllllllllll
Rusty Bearman Jr
Jannice Beasley
Clay Beeken
Laureen Bennet
Knstie Bennet
Matti Bennett
Kirk Bever
Tammie Jill Adams
Lahring Judd
- Joyce К Garonzic
Terry Kantola
Patnca Kapuiska
*
3«пись ГТГ; < | : • H > t j из

Рис. 5.20. Сортировка по фамилии при наличии в полном имени второго имени
и дополнительных пометок
Трюк № 45. Суммирование сложных данных 149
Приглядевшись к результату, вы сможете заметить, что проблем при сортировке
избежать не удалось. Функция создавалась из расчета, что если в полном имени
имеется два пробела, значит, оно состоит из имени, фамилии и дополнения. Та­
кое предположение работает с именами вида Alex Avakian III. Работа функции
строится на предположении, что фамилия начинается после первого пробела.
К сожалению, имя вида Tammy Jill Adams не попадает в категорию фамилий, на­
чинающихся на букву «А». В функции строится предположение, что наилучшим
будет первый пробел, и полное имя подвергается сортировке, как будто фамилия
начинается на букву «J». А у Tammy фамилия начинается со второго пробела,
поэтому перед ним стоит извиниться.
Разбиение имен на части всегда было трудной задачей. Некоторые имена упорно
не поддаются даже самым лучшим программам по разбору имен на составные ча­
сти. Может, именно поэтому я продолжаю получать каталоги, адресованные не­
кой личности, именуемой Mr. Ken.
См. также «Использование в запросе своей собственной функции» (Трюк № 48).

ТРЮК Суммирование сложных данных


№45 Использование преимуществ перекрестных запросов для просмотра разнообразных
данных.
Если вам нужно собрать воедино данные, структура которых не поддается про­
стой группировке, то лучшим средством послужат перекрестные запросы. В раз­
деле «Подсчет промежуточных итогов на основе определенных условий»
(Трюк № 29) показан способ условного суммирования, примененный в отчете. Он
работоспособен до тех пор, пока количество условий не превышает возможности
этой технологии.
В примере этого трюка при формировании промежуточных итогов фигурируют
пять штатов и два года. Но в схеме данных есть еще и таблица Животные (схема
моделирует пример из ветеринарной практики), привлечение которой создает
множество вариантов: например, сколько котов было принято врачом в штате Нью-
Йорк в 2003 году или сколько собак было принято в Пенсильвании в 2004 году,
и т. д. На рис. 5.21 показана дополненная схема данных, приспособленная для дан­
ного трюка.
В схеме данных присутствуют семь видов животных (птицы, коты, собаки, хорь­
ки, лошади, обезьяны и змеи), пять штатов (СТ, MA, NJ, NY и РА), и два года, за
которые собирались сведения (2003 и 2004). Из этого количества данных можно
составить 70 комбинаций. Лучшим способом подсчета количества визитов при
различных сочетаниях и комбинациях условий будет применение перекрестного
запроса.
Для начала нужно создать запрос на выборку, чтобы объединить различные таб­
лицы и получить поля, необходимые для перекрестного запроса. Обратите вни­
мание, что запрос на выборку содержит вычисляемое поле, извлекающее год
из поля Дата_визита. На рис. 5.22 показан запрос на выборку в режиме Конст­
руктора.
150 Глава 5. Запросы и SCL

;
*Ы>'л**Н;?>;
КлиентЮ
Фамилия ЖивотноеЛ)
Имя КпиентЮ
Второе имя Кличка
Адрес Вид
Город Дата_рождения
Штат
Почтовый индекс
Телефон

Рис. 5 . 2 1 . Схема данных, включающая таблицу Животные

- • „ . , „ . . . - , , , - ->.-.• • ',,••:', ••- •• -

; дгу^ШтатыЖихггныеДатм : запрос на *ь'Йор*У ... г-гж^т)


?Ы Кянамт ?И *vWf*:fc«(

КлиентЮ ЖмвотноеЮ Визит©


Фамилия КлиентЮ ЖиеотноеЮ
Имя Кличка Дата_визита
Второе имя Вид
Адрес Дат а .рождения
Город
Штат
Почтовый_индеке
Телефон

Поле: Ыэт Щ Вид Год: Уезг([Дата еиэита]) Дата визита


Имя таблицы: tbl Клиенты tbl Животные tbl Визиты
Сортировка:
Вывод 4S экран: I71 В
Условие отбора: i и
или:
jfefe

Рис. 5 . 2 2 . Запрос на выборку, на основе которого будет выполняться перекрестный запрос

Введение в перекрестный запрос


В Access имеется мастер создания перекрестных запросов, который проведет ы.с
по всем этапам этой работы. На рис. 5.23 показано диалоговое окно Новый запрос,
с которого начинается создание перекрестного запроса.
В данном примере в первом окне мастера нужно выбрать запрос ^гу_ШтатыЖи-
вотныеДаты (рис. 5.24).
В следующем окне нужно выбрать два поля для строк. В перекрестном запросе
строки играют роль групп. Обратите внимание, что после выбора двух полей для
строк должно оставаться по крайней мере еще два поля. В качестве заголовке в
строк нужно выбрать поля Штат и Вид.
Трюк № 45. Суммирование сложных данных 151
Мовмй запрос"

\
: Создание запроса,
; выводящего данные в
:
компактном формате,
; подобном формату
: зпектроммой таблицы.

Рис. 5.23. Создание перекрестного запроса

нме перекрестных таблиц


=j Выберите
Выбер таблицу или запрос, поля ;Запрос в/у .Визит ы_200Э
которых необходимо вывести а ;Запрос о\ _Визиты_2004
перекрестком запросе. Запрос crv _Визит ы_в_рктябре_2003
;Запрос c.'V _Пос ле днии _прием_к а ж д ого животного
CTV .Продажи
:Запрос _Продажи_2
:] Дня включения полей из
;• нескольких таблиц сначала
| создайте обычный запрос,
|| содержащий все необходимые п
Показать
О Таблицы 0 Запросы

Рис. 5.24. Выбор запроса на выборку

»1ие пеиекоРиныхтабчии
выберите пол?! для использования^:
шп
:их значений в качестве загопопков '•••'•':• Дата_визита
.столбцов! ;.::;.•'

Например, чтобы использовать имя


каждого сотрудника в (Сачестее
jar с ловка столбца, выберите поле
МмяСотрудника. ;, : :

Штат j ^ A ^ ,г«л» |год? (годЗ j


Штат1 Вид1 1ИТОГИ
ШШштат'г Вид2
•2 Штат 1 ВидЗ 1
В
^Нштвтч Вид*

< Назад .. |1 -.Далее >.• .,.р

Рис. 5.25. Выбор поля Год в качестве заголовка столбца

Следующее окно позволяет выбрать поле, значения которого будут использоваться


в качестве заголовков столбцов. В перекрестном запросе требуется выбрать для
столбца хотя бы одно поле. Здесь нужно выбрать поле Год, как показано на рис. 5.25
(заметьте, что на рисунке изображено третье, а не второе, по счету окно мастера).
152 Глава 5. Запросы и SQL

В последнем окне остается одно поле. Здесь нужно выбрать тип составного вы­
числения, в данном случае должна быть выбрана сумма (рис. 5.26), поскольку на л
нужно вычислить суммарное количество визитов. Также нужно сбросить флажок
Да под вопросом «Вычислить итоговое значение для каждой строки?». Если фла­
жок оставить, сумма будет подсчитываться только для сочетания штата и вида

есткых габтнц

Какие счисления необходимо


провести для каждой ячейки на
пересечений строк и Столетов? V

Например, можно вычислить сумм>;


заказов для каждого сотрудника
(столбец) пезстранаи и регионам
(строка).;:

Рис. 5.26. Выбор возвращаемой суммы

3 •iry ШтатыЖиютиывАвтм.лерекрестнмй . исрикрвгтмыи Шпрос ^ "1 \£р


Штат Вид "2003 2004 j
• СТ Птица 29 34:: ::
СТ Кот 37 49
СТ Собака 38 44
тшшшятш
СТ Хорек 8 9 . . • . н > . ' . Ь . ' . У » 7 & ; ; •••.;:
СТ Лошадь 6 6
СТ Обезьяна 4 6 : . . : : : : . : • . • . • . . . • • . . . .

СТ Змея 5 5 ШШШШжШШШШ: •
МА Птица 19 22
МА Кот 23 25
МА .Собака j 23 30
МА Хорек 2 2 1мшг'•••";
МА Лошадь 1 2 ^::aIi:|^:':::;:Й^:•fe^:,<;.::V.Й

МА Змея 7 7
NJ Птица 30 38 '• ''•':• - г - ' . ' : • • • ' • ' ' . • • ' " : :
• • • :

NJ Кот 60: 77
NJ Собака 54 69

NJ Лошадь 9 10 " ":- ШШШ'-ЯЩ


NJ Обезьяна 14 17 1№лтшмжшш1тшж
NJ Змея 12 17 :111111
NY Птица 17 22 : : :' ' : : ; : : >ШШ
NY Кот 58 7В 1
NY
NY
Собака
Хорек
62
9
8з"
13
1
запись L!±JM •! 1 LLAiUt*) * *

Рис. 5.27. Результат выполнения перекрестного запроса


Трюк № 46. Получение всех возможных сочетаний данных 153
животного (для полей, являющихся заголовками строк), но наша задача состоит
в другом: подсчитать сумму для сочетания штата, вида животного и года.
Когда запрос будет создан, станут доступны все суммарные значения. На рис. 5.27
показан результат выполнения запроса, в котором представлены суммы для всех
комбинаций штатов, видов животных и лет.
В результате получается 35 записей, поскольку в качестве заголовков строк вы­
ступают штаты и виды животных, а в качестве заголовков столбцов — годы. В со­
вокупности представлены все 70 уникальных сочетаний, поскольку и 2003,
и 2004 год имеют собственные столбцы.
См. также «Подсчет промежуточных итогов на основе определенных условий»
(Трюк № 29).

Ш Получение всех возможных сочетаний


данных
Удаление ключевого слова Join из инструкции SQL с целью возврата декартова произ­
ведения (возврата всех возможных комбинаций).
Если убрать ключевое слово Join из инструкции SQL, то количество возвращенных
записей будет равно произведению количества всех записей в таблицах. К примеру,
если взять две таблицы и назначить для вывода на экран по одному полю из каж-

^Microsoft Access

Прикладное искусство |
п
.....игия
Кулинария
" ™ * --'Дмитрии Туризм
•н Данила
Григорий
Константин
Музицирование
Занятия спортом
Пересказ историй
Леонид Плавание
Плетение

6
ИШ1^:«
• •

Рис. 5.28. Две несвязанные таблицы


154 Глава 5. Запросы и SCI.

дой, то количество записей, возвращенных запросом на выборку, будет равно прс i-


изведению количества записей двух таблиц.
Получается, что запрос соответствует всем комбинациям данных. Если в каждой
таблице содержатся сотни или тысячи записей, то счет возвращенным записям
может идти на миллионы. Если подобный результат не соответствовал замысг у
запроса, он может навредить работе приложения. Тогда для чего же нужны по­
добные запросы? Они создаются для получения всех возможных комбинации.
Если требуется получить именно такие всеобъемлющие данные, то не стоит во­
зиться с программированием на VBA, достаточно создать запрос, который все сд з-
лает за вас. На рис. 5.28 показаны две таблицы: одна — с именами двенадцати ч г-
ловек, а другая — с восемью возможными занятиями.
Нужно создать запрос на выборку, содержащий две таблицы, и выбрать из ках-
дой по одному полю для вывода на экран. На рис. 5.29 показан запрос в режиме
Конструктора. Обратите внимание, что между таблицами намеренно не устано в-
лено никакой связи.

3 Возврат декартова произведения : запрос на «ыоорку

Поле: Имя Занятие l*«s


Имя таблицы; Люди Занятия
Сортировке:
Вывод на ж р а н : PI
Условие отбора: и п п п
или: | У '" ''у

Рис. 5.29. Запрос на выборку из несвязанных таблиц

Несложный подсчет на калькуляторе даст в результате 96 комбинаций людей и за­


нятий. В результате выполнения запрос вернет 96 записей (см. рис. 5.30).
Результаты выполнения запроса могут быть скопированы, экспортированы и т д.
Это быстрый и простой способ получения всех комбинаций данных. Следуя даль­
ше, нужно добавить к запросу третью таблицу, в которой в двух полях будут со­
держаться части дня: утро и после обеда. В результате работы запроса (рис. 5.; 1)
будет возвращено 192 записи, это количество получается после перемножения
чисел 12, 8 и 2.
Хотя обработка несвязанных данных считается нерациональной, по крайней ме ре
при работе с базами данных, подобный набор возможных комбинаций примез [я-
ется в обзорах, контрольных перечнях и т. д.
Трюк № 47, Обезвреживание пустых данных 1 55

£Воз§рвт декартом проимадеим... J ^


врат декартова произведении:
Имя •Занятие;;-
Имя Занятие Часть_дня А
Андрей Прикладное искусство
Андрей ; Прикладное искусство [Утро
Андрей Кулинария
Андрей Прикладное искусство После обеда
Андрей Туризм Андрей ;Кулинария Утро
|Андрей Музицирование Андрей : Кулинария :
После обеда
Андрей Занятия спортом Андрей Туризм Утро
Андрей Пересказ историй Андрей Туризм После обеда
Андрей Плавание Андрей ; Музицирование Утро
Андрей Плетение Андрей Музицирование После обеда
Борис Прикладное искусство Андрей Занятия спортом ;Утро
Борис Кулинария Андрей : Занятия спортом После обеда
Борис ТУР"3." Андрей Пересказ историй Утро
Борис Музицирование | Андрей : Пересказ историй После обеда
Борис Занятия спортом Андрей \Плавание Утро ^.Z
I Борис Пересказ историй Андрей Плавание После обеда
Борис Плавание Андрей Плетение ;Утро
I Борис Плетение Андрей j Плетение После обеда
Дмитрий Прикладное искусство Борис Прикладное искусство Утро
Дмитрий Кулинария Борис Прикладное искусство После обеда
Дмитрий Туризм JZ Борис Кулинария Утро
Дмитрий Музицирование Борис Кулинария После обеда
Дмитрий Занятия спортом Борис Туризм Утро
Дмитрий Пересказ истории Борис Туризм После обеда
Дмитрий Плавание Борис Музицирование Утро
Дмитрий Плетение Щ Борис Музицирование После обеда
Данила Прикладное искусство Щ Борис ! Занятия спортом Утро
Данила Кулинария Борис Занятия спортом После обеда
Запись; О * j Г ( 1 р 7 1 ] * ' / "* * Запись: JH ] 192

Рис. 5 . 3 0 . Возврат комбинированных Рис. 5 . 3 1 . Возврат комбинаций записей трех


записей несвязанных таблиц

Т Р Ю К Обезвреживание пустых данных


№47 Смешивание пустых и реально существующих данных иногда приводит к неверным
результатам. Здесь рассматривается ряд рекомендаций по предотвращению по­
добных ситуаций.
При работе с данными Access можно подумать, что пустые поля совершенно без­
вредны. Между тем пустое поле, содержащее пустое строковое значение, суще­
ственно отличается от пустого поля со значением null. To же самое относится и к
числовым полям, в которых поле, содержащее 0, следует отличать от поля, содер­
жащего значение nulL Данный трюк поможет в работе со значениями null.
Первые неприятности со значением null возникнут при использовании следую­
щей программной строки, возвращающей Заполнено, даже если значение поля рав­
но null:
I I F ( [ С у м м а ] = N u 1 1 , " П у с т о " , "Заполнено")
Так получается из-за того, что в логическом выражении присутствие данных лю­
бой категории, чьи значения сопоставимы со значением Null, приводит к возврату
значения False.
156 Глава 5 . Запросы и SCL

Эту ситуацию легко исправить, применив имеющуюся в Access функцию ISNUL..


Она возвращает логическое значение и позволяет успешно провести эту провер­
ку. Предыдущий пример нужно переделать следующим образом:
I IF(ISNULL([Сумма]),"Пусто" , "Заполнено")
Проблема решена, и каждое встреченное значение null теперь будет преобразова­
но в Пусто.

Значение null в числовых полях


Предположим, существует таблица, содержащая поле под название Сумма. Вы пы­
таетесь вычислить среднеарифметическое значение содержимого этого поля (пред­
положим также, что эта средняя величина не должна быть взвешенной). В запрос,
осуществляющий попытку вычислить среднеарифметическое значение, нужго
вставить следующую инструкцию SQL:
SELECT Avg(tbl_CyMMa.Сумма) AS СредняяСумма
FROM tbl_CyMMa;
В результате ее работы будет возвращено среднеарифметическая величина зна­
чений, содержащихся в этом поле. Но если какие-нибудь значения будут равны
null, то запрос их проигнорирует. Итак, если значения поля последовательно рав­
ны 8, null, 8, null, 8, null, среднеарифметическое значение будет равно 8. A ecj;n
значения поля последовательно равны 8,0,8,0,8,0, среднеарифметическое значе­
ние будет равно 4. В соответствии с назначением запроса вам в любом случае хэ-
телось бы получить четыре, а не восемь.
При желании заменить значение null значением 0 следует воспользоваться функ­
цией ISNULL, включив ее в следующую программную строку:
I IF(I SNULL([Сумма]),0,[Сумма])
Но есть еще более простой способ. В Access существует функция NZ, использую­
щая два параметра: в одном содержится значение, а во втором — то, во что оно
превратится в случае, если будет пустым (null). Эту функцию можно использо­
вать внутри числовых и строковых функций. Программная строка, использую­
щая функцию NZ, приобретет следующий вид:
SELECT Avg(NZ([Сумма],0)) AS СредняяСумма
FROM 1:Ы_Сумма;
Нетрудно заметить, что строка получается короче, чем при использовании в тех
же целях структуры IIF.
Теперь давайте взглянем на пример, использующий строковую функцию. Пред­
положим, вы живете в таком месте, где растут сосны, и занимаетесь исследовани­
ем, для которого тип дерева вводится только в том случае, если это не сосна;
в противном случае вводится только количество деревьев (плохо составленная
программа, но я видел и похуже), а поле Порода_дерева остается пустым (null).
Теперь предположим, что вы продолжаете использовать это приложение и наме­
рены работать с ним в других частях страны. Поэтому вам захотелось обновг ть
все пустые значения поля Порода_дерева и поместить в них значение Сосна. Функ­
ция NZ поможет вам справиться с этой задачей. Вот как будет выглядеть соответ­
ствующая инструкция SQL:
Трюк № 47. Обезвреживание пустых данных 157
UPDATE 1;Ы_ПородыДеревьев SET 1Ы_ПородыДеревьев.Порода_дерева =
nz([Порода_дерева],"Сосна");
Эта инструкция вполне работоспособна, но нам ведь нужно обновить каждую
запись. Если использование выражения Порода_дерева = Null не имеет смысла,
возникает вопрос, а нельзя ли использовать null в качестве условия отбора в за­
просе. Вы можете воспользоваться одним из двух способов, но проще применить
тот, в котором в качестве условия отбора используется специальный оператор IS
NULL. Предыдущий запрос при использовании IS NULL будет выглядеть следую­
щим образом:
UPDATE t b l _ ПородыДеревьев SET t b l _ ПородыДеревьев.Tree_Type = "Pine Tree"
WHERE ( ( ( t b l _ ПородыДеревьев.TreeJType) Is N u l l ) ) ;

Предотвращение появления значений Null


Иногда подавление появления значений null или строк нулевой длины в вашей
базе данных может стать приоритетной задачей. В качестве примера можно при­
вести поле имени или почтового индекса. Добиться поставленной цели можно
как при создании таблиц, так и при создании форм ввода данных.
Конструкция таблицы, в которой невозможно появление
значения null и строк нулевой длины
При конструировании таблицы вы можете установить несколько свойств, помо­
гающих справиться с появлением пустых полей (рис. 5.32).

Свойства поля

Подстановка
Размер поля И
Формат поля
Маска ввода
Подпись
Значение по умолчанию
Условие на значение
Сообщение об ошибке
Обязательное поле
Пустые строки
Индексированное поле
Сжатие Юникод
Режим IME
Режим предложений IME
Смарт-теги

Рис. 5.32. Установка свойств поля, подавляющих появление пустых значений и строк
нулевой длины

Сначала рассмотрим свойство Обязательное поле. Если его значение установлено


в Да, то Access не сможет сохранить значение поля до тех пор, пока в него не будут
введены какие-нибудь данные. Но это не спасет от заполнения поля строкой ну­
левой длины. Установка значения свойства Пустые строки в Нет заставит вводить
158 Глава 5. Запросы и SC L

в поле ненулевую строку. Если установить значение в Да, желая избавиться лишь
от значений null (и осуществлять проверку на незаполненные поля с помощь о
выражения вида [Поле]= ""), то можно установить значение свойства Значение г о
умолчанию в "".
При правильной установке значений этих двух свойств вы обеспечите заполне­
ние всех полей и избавитесь от необходимости обрабатывать в приложении пу>
тые значения. Такой же подход применим и к числовым полям: значение свой­
ства Обязательное поле должно быть установлено в Да, а кроме этого, можко
воспользоваться свойством Значение по умолчанию, которое обычно в числовых
полях устанавливается в 0. Но если вам нужно убедиться в том, что пользователь
не проигнорировал поле, а ввел в него значение, вам нужно удалить 0 из свойства
Значение по умолчанию и установить значение свойства Обязательное поле в Да. Та­
кой прием гарантирует запрет на сохранение записи до тех пор, пока пользова­
тель не введет в поле какое-нибудь значение (может быть введен и 0, если только
вами не установлены правила проверки, исключающие такую возможность).
Управление null-значениями с помощью свойств формы
Если вы не установили контроль над появлением пустых значений в таблице, но
хотите все же получить гарантии того, что значения были введены, то это можно
сделать и в формах Access. При создании формы становятся доступны несколы со
свойств текстовых полей, с помощью которых можно гарантировать наполнен­
ность данных (см. рис. 5.33).

r w породив.» :Щ
Ж Порода ^дерева '• у

N.. Макет : Данные ^ Ш ь ш я | Другие ,Д Все


I Данные Лорода^ерева } 1
i Маска ввода [ \.
\ Значение по умолчанию ! >
| Условие на значение jls Not Null К \
I Сообщение об ошибке l/_ h$ l
:
* Доступ |Да | I
Блокировка ;Нет

! Применение автофильтра ^Параметр базы данных ji

1
"" Смарт-теги { __ \

I
Рис. 5.33. Подавление появления пустых значений с помощью свойств элементов формы
Если вам нужно всего лишь избежать появления значений null, вы можете уста­
новить значение свойства Значение по умолчанию, разрешающее появление стро ш
нулевой длины.
Кроме этого, можно ввести программный код в процедуру обработки события По­
теря фокуса, поскольку событие До обновления может возникнуть и при холост>м
проходе поля, а событие После обновления возникает после реального внесения
в поле каких-нибудь изменений. Вот как должен выглядеть программный код для
поля с именем Поле1:
Private Sub nonel_LostFocus( )
If IsNull(Me.nonel.Value) Then
MsgBox "В данное поле требуется ввести значение", vbOKOnly, "Внимание!"
Трюк № 47. Обезвреживание пустых данных 159

Me.Поле2 .SetFocus
Me.Поле1.SetFocus
End I f
End Sub
Вас может удивить двойной вызов события Получение фокуса (в тексте процеду­
ры — SetFocus). Это связано с необходимостью убрать фокус с текстового поля,
а затем вернуть его обратно, иначе фокус не будет установлен на поле. Также мо­
жет вызвать удивление, что здесь не использовано свойство Условие на значение.
Дело в том, что это свойство задействуется только при внесении изменений, по­
этому при холостом проходе поля оно не сработает.
Существуют ограничения и на использование события Потеря фокуса в том слу­
чае, если пользователь использует мышь и не щелкает на каждом поле. Это огра­
ничение можно обойти, установив значение Текущая запись для свойства Цикл та­
буляции вкладки Другие диалогового окна свойств формы (рис. 5.34), а затем
установив значение Нет для свойства Кнопки перехода во вкладке Макет того же
диалогового окна (рис. 5.35).

Форма
ШШ ШЩ ;'";;: ;••••;• ;•;;;;•. ;;

всплывающее окно Мет..


Модальное окно [Нет
Цикл табуляции .Текущая запись
Строка меню
Панель инструментов
щk
Контекстные меню 'М...
Контекстное меню
Для лазерного принтера . . . Да..,
Файл справки
Идентификатор справки . , .
Дополнительные сведения . .
Наличие нодуля .Нет
Разрешить изменения макета , Все режимы

Рис. 5 . 3 4 . Установка значения «Текущая запись» для свойства «Цикл табуляции»

-Форм и
|Форма v
:;
Макет Данные L.Q&WW (.Другие . Все. J • . :'

Подпись
Режим по умолчанию . . . Одиночная форма
:<*>:;
; ' • &

Режим формы • • • -А* i


Режим таблицы • • • Ш
Режим сводной таблицы • • • • А '
Режим сводной диаграммы , . . • • • А *
Полосы прокрутки . . . . Все
Область выделения •••Ш _
Кнопки перехода . . . Нет i:V:
Разделительные линии
Автоматический размер
. . . Да
• • • \ЙЛ
k'\ ,
Выравнивание по центру . , . . . , , Нет
Тип границы , . . Изменяемая
Кнопка оконного меню • • • • ' А * ..
Кнопки размеров окна . . . Все
Кнопка закрытия • •••Si ,
Кнопка контекстной справки . . . . Нет
Ширина ,9,998см
Рисунок . . . . (отсутствует)
Тип рисунка . . . .Внедренный
Масштабы рисунка . . . ..Фрагмент
выравнивание рисунка По центру
Мозаичное заполнение Нет
-
Рис. 5 . 3 5 . Установка значения «Нет» для свойства «Кнопки перехода»
160 Глава 5. Запросы и SClL

Проделав все это, вы можете создать собственные кнопки, позволяющие пользо­


вателю переходить к следующей записи, и поместить в обработку событий, возни­
кающих при щелчке на этих кнопках, программный код, проверяющий приемл э-
мость заполнен