Стоит ли использовать временные таблицы для отчетов
Здравствуйте, уважаемые читатели.
Сегодня прочитал спорное мнение на форуме, что использовать временные таблицы при формировании отчетов это кривое решение. С этим мнением я в корне не согласен.
Мои доводы ЗА:
1. Модульность. Временные таблицы позволяют разделить между собой отчет и код расчета данных. В последующем это повышает сопровождаемость (см. п.3).
2. Удобство отладки. Если отчет перестал работать или работает как-то не правильно, то гораздо легче проверить расчет данных для него.
3. Сопровождаемость. В любой момент может возникнуть необходимость переделать либо расчет данных, либо переделать отчет, например, печатать его в word. Это все можно модифицировать по отдельности. Также пользователь может захотеть хранить рассчитанные данные, этого тоже будет просто добиться.
4. Документирование. Если разработчик укажет комментарии к полям для временной таблицы, то это можно считать документацией.
Мои доводы ПРОТИВ:
1. Увеличивается время разработки. Это происходит в том случае, если для отчета можно использовать простой запрос в качестве источника данных. Если же расчет данных не вписывается в простейшие запросы, то будет проще и надежней реализовать расчет отчета в коде.
Больше против я не вспомнил. Выбор очевиден
. Увлекаться данным способом естественно не стоит, каждой проблеме лучше подбирать свое решение. Этот метод подходит для отчетов со “сложными” расчетами данных.
До встречи!
(с) Скоков Сергей
Подписаться на: RSS или e-mail рассылку или добавить в ЖЖ друзья.
3 вида меню в MS Access
Здравствуйте, уважаемые читатели.

То, что первым видит пользователь в программе – это меню. От него зависит (и не только) на сколько удобно будет работать с программой. С течением времени определенные подходы, которые я видел, классифицировались в следующие виды меню:
- формы с кнопками,
- кнопочная форма (на основе мастера),
- строка меню.
Я заметил, что «новички» начинают с форм с кнопками, затем открывают для себя кнопочные формы, а если встает задача сделать, как классическом текстовом редакторе, то переходят к строке меню или используют вместо нее панель инструментов. Конечно, бывают исключения и это только мои наблюдения.
Очень долгое время я думал, что самое лучшее и удобное меню – это строка меню. Но как показала жизнь, для каждого класса задач подходит свое меню.
1 Формы с кнопками
При этом подходе создается множество однотипных форм с кнопками или группой переключателей. Этот метод очень активно использовался в старых ДОСовских программах.
Это очень удобно использовать, когда пользователю при работе с одной из функций не нужна другая функция, которая вызывается из меню. Примером таких программ могут служить любые, в которых происходит потоковая регистрация и пользователю некогда переключаться между клавиатурой и мышкой.
К минусам такого способа можно отнести большое количество форм и муторность в изменении этого меню. Для пользователя может быть не удобно закрывать или сворачивать текущие формы, чтобы увидеть меню и открыть необходимую форму.
Очень не рекомендую использовать группы переключателей в качестве кнопок, переходить клавишами по такому меню не удастся.
2 Кнопочная форма (на основе мастера)
В этом варианте существует только одна форма и мастер редактирования пунктов. Из недостатков – при открытии любая формы, форма меню будет не видна.
При ближайшем рассмотрении оказалось, что это обыкновенная форма с х кнопками и надписями и с системной таблицей в качестве источника данных.
Не знаю почему, но мне этот вариант мне не нравится. Я лучше сам его реализую при необходимости.
3 Строка меню
Это мой самый любимый способ, т.к. очень просто изменять и все время на виду. Да и очень редко мне доводится разрабатывать программы для людей, не пользующихся мышкой.

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

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

Тут я выбираю свою строку меню и убираю отображение окна базы данных. В таком режиме я и работаю.
Как вы заметили можно и свое контекстное меню сделать. Или убрать панели инструментов по умолчанию. Не рекомендую этим увлекаться. Например, панель инструментов отчетов ой как нужна, чтобы напечатать. А на панели инструментов для форм есть такая полезная штуковина как сортировка.
После того, как вы перезапустите свою БД, то всегда будет отображаться ваше меню. А стандартного не будет. Чтобы его отобразить/скрыть достаточно нажать Ctrl+F11. Очень удобно.
До встречи!
(с) Скоков Сергей
Как показать первое значение в поле со списком
Здравствуйте, уважаемые читатели.
Поделюсь с вами еще одной удобной функцией. У меня часто возникает ситуация, когда при открытии формы в поле со списком необходимо показать первое значение.
Например, на форме списка пользотваль хочет видеть данные за текущий год. Для этого я добавил на форму поле со списком “Год” (Имя элемента управления P_GOD). В нем выводятся года, за которые есть данные в обратном порядке. А при открытии формы вызвал специальную фукнцию:
Call CM_ListSelectFirst( Me.P_GOD_FLT ) '-- мега функция '-- увы при программном изменении значения поля события не происходят, '-- то придется еще вызвать фукнцию соотвествующую фукнцию Call SetFilter()
А вот код той самой функции CM_ListSelectFirst():
Public Sub CM_ListSelectFirst(ByRef ctl As Control)
' Скоков С.А. 2009-02-25
' Выбрать первое значение в поле со списком или списке
With ctl
If Not (.ControlType = acListBox Or .ControlType = acComboBox) Then
Exit Sub
End If
If .ListCount > 0 Then
.Value = Nz(.ItemData(0))
End If
End With
End Sub
P.S. Эта же функция будет работать для списков
.
До встречи!
(с) Скоков Сергей
Хитрость печати отчетов
Здравствуйте, уважаемые читатели.

В одной из программ реализована функциональность печати адресов клиентов на конверты, в результате пользователь получает готовенький документ MS Word. Клиент попросил добавить свой логотип на каждый конверт. Существующая реализация формирования документа в Word не позволяет дублировать картинку для каждой страницы. Переделывать полностью не хотелось. Поэтому я искал как обойтись меньшей кровью.
Идея пришла из ниоткуда. Я мониторил меню Word 2007 в поисках пункта записи макросов (может они и могли мне помочь, но увы
) и наткнулся на создание подложки – “Разметка страницы – Подложка – Настраиваемая подложка” (“Формат – Фон – Подложка” для Word 2003).
Как оказалось это отличная идея. Рисунок располагается на странице за текстом, размер и положение можно изменить в режиме изменения колонтитулов.
Супер. Просто и со вкусом. Пример можно посмотреть тут.
До встречи!
(с) Скоков Сергей
Округления
Здравствуйте, уважаемые читатели.

До Access 2002 (или 2000) встроенной функции округления не было. Поэтому все пользовались самописными. Потом появилась функция Round(). Тут можно было вдохнуть с облегчением и избавится от собственной.
Как-то заказчик прислал мне скриншот с неправильными расчетами. Анализ кода показал, что функция Round() дала сбой и округляла следующим образом (проверял в окне отладки):
9.5 =10
8.5 = 8
7.5 = 8
6.5 = 6
5.5 = 6
4.5 = 4
3.5 = 4
2.5 = 2
1.5 = 2
0.5 = 0
Разбираться было лень. В результате заменил на собственное творение, т.к. это деньги:
Public Function CM_Okrugl(ByVal dbl As Double) As Long
' округляет число dbl до целого
Dim lng As Long
lng = Fix(dbl)
If (dbl - lng) < 0.5 Then
CM_Okrugl = lng
Else
CM_Okrugl = lng + 1
End If
End Function
До встречи!
(с) Скоков Сергей
Ошибка в MS Access
Всем привет.
Как-то у меня возникла необходимость поработать на другом компьютере. Я давно использую VSS и не хотел от этого отказываться. Но тут меня подстерегал подводный камень.
При импорте базы данных из репозитория я получил кучу ошибок, когда очередь дошла до форм. Ладно, думаю так поработаю. И не тут то было. При попытке открыть форму я увидел надпись:
“There isn’t enough memory to perform this operation. Close unneeded programs and try the operation again.”
Мне помог вот этот hostfix: http://support.microsoft.com/kb/945674/en-us. Качаем и наслаждаемся.
(с) Скоков Сергей
Импорт базы MS Access в MS Visio
Здравствуйте.
В любом проекте настает момент, когда количество таблиц увеличилось на столько, что все в голове не удержишь. И появляется желание посмотреть на схему таблиц. Это желание возникает, как правило, при пожелании пользователя чего-нибудь этакого. Что коренным образом затрагивает существующие отношения между таблицами. Или вы решили задокументировать БД и положить проект в архив до лучших времен.
Первым делом все лезут в «Сервис»->«Схема данных». Если не заполнена, то заполняют. Тут то и встает проблема. Как ее достать? Первый простейший способ это «Prt Scr» и вставить в текстовый редактор. Если же таблиц больше, чем помещается на экран, то тут можно взять “бубен” побольше – графический редактор, чтобы в нем составить картинки.
Для экстренного случая предыдущий способ подойдет. Но вот делать этот танец регулярно навряд ли кто-то захочет. Есть отличное решение – MS Visio. Оно конечно не единственное. О других средствах позже.
MS Visio умеет:
• Импортировать информацию из mdb.
• Обновлять схему из mdb.
MS Visio не умеет (в стандартной поставке):
• Создавать mdb на основании схемы.
Последний пункт немного омрачает. Но и без него хорошо живется.
Импорт информации из mdb
Для начала нам нужно создать документ типа Database Model Diagram (он находится в категории Database). Потом выбрать пункт «Database->Reverse Engineer…» и немного покликать:
1. Выбираем драйвер MS Access 97 Database (или другой необходимый)

2. Не заполняем имя пользователя и пароль (по умолчанию это так). Иначе придется заполнить.

3. Выбираем файл БД

4. Отмечаем какая информация нас интересует

5. Выбираем таблицы (обычно все)

6. Сейчас выбрано «Добавлять таблицы на страницу»

7. Финиш!

В результате мы получим документ с нашими таблицами. Если «схема таблиц» была заполнена, то Visio подтянет и связи. Руками их тоже не проблема нарисовать.
Чтобы нарисовать связь, необходимо «кинуть» на документ линию Relations. Основание линии перетаскиваем на таблицу с FK (Foreging Key или внешний ключ), а стрелку линии перетягиваем на таблицу с PK (Primary Key или первичный ключ). Если имена совпали, то связь установится автоматически. В противном случае, в таблицу с FK будет добавлено поле с именем PK. Не беда, в свойствах связи меняем поля, а лишнее поле можно удалить.
После связей останется только навести «гламурный» вид, чтобы стрелки как можно меньше пересекались, и распределить таблицы в группы по смыслу.
Обновлять схему из mdb
Это делать еще проще. Я полагаю, что документ со схемой БД уже открыт. Остается только выбрать пункт меню Database->Refresh Model и немножечко покликать как и в предыдущем пункте. В результате откроется окно найденных отличий с ними остается только согласиться. После этого придется немного подравнять схему.
Создавать mdb на основании схемы
Возможно вы подумаете, что отсутствие этой функции важный недостаток. «Нет», – скажу я вам, – «Все намного проще».
Практика показала. Разработка базы начинается методом листика, карандаша и стирки. Потом делается набросок в mdb файле. И начинает кипеть работа с логикой.
Когда же необходимо сделать реинжиниринг, то схема печатается, а дальше вступают в работу карандаш и стирка. Эти изменения вносятся в mdb и, если необходимо, схема обновляется.
До скорых встреч!
(с) Скоков Сергей
События
Здравствуйте, уважаемые читатели.
Поговорим в этом выпуске об очень интересной штуке – события. Я очень мало где видел их использование в MS Access. Но они очень сильно облегчают жизнь при работе, особенно с формами. У событий есть маленькое ограничение. Их могут использовать только объекты. Это означает, что их можно объявлять и получать только в модулях пользовательских классов, формах и отчетах.
Чтобы объявить событие необходимо в начале модуля класса (формы, отчета или пользовательского) написать:
Event ИмяСобытия( СписокАргументов )
Для использовании события необходимо объявить в начале модуля ссылку на объект и в списке (левый список, который расположен в редакторе кода) выбрать обявленный атрибут, в правом списке можно выбрать событие, если их несколько. В результате получим следующее:
Dim WithEvents Имя As Тип
Вызвать событие можно так:
RaiseEvent ИмяСобытия( Параметры )
Где это можно применить? Рассмотрим пример из жизни. На форме заказа есть поле клиента. В этом поле отображается, допустим, УНН и название клиента. Рядом с полем кнопка. По нажатию на кнопке отображается еще одна форма – список клиентов. Задача – выбрать клиента.
Одним из решений будет открыть модальное окно и тут возникает куча разных вариантов: записать напрямую с формы списка клиентов в поле формы заказов (очень плохая идея!!!), скрыть форму при нажатии пользователем кнопки “Ок” (Выбрать) и т.д.
При помощи событий получается простое и элегантное решение. Всего-то объявить на форме списка клиентов событие:
Event OnClientSelect(ByVal lId As Long)
На форме заказа это событие обработать:
Dim WithEvents m_frmKlientSepis As Form_frmKlientSpis
'--
Private Sub Kn_KlientSelect_Click()
'-- выбор клиента
'-- можно и так
'-- DoCmd.OpenForm "frmKlientSpis"
'-- Set m_frmKlientSepis = Forms("frmKlientSpis")
'-- но мне нравится этот вариант
Set m_frmKlientSepis = New Form_frmKlientSpis
m_frmKlientSepis.Visible = True
End Sub
Private Sub m_frmKlientSepis_OnClientSelect(ByVal lK_KLIENT As Long)
'-- клиент выбран пользователем
Me.K_KLIENT = lK_KLIENT
Set m_frmKlientSepis = Nothing '-- уничтожаем форму
End Sub
Подробности можете увидеть в примере. Чуть позже я расмотрю еще один пример – связные списки.
До скорых встреч!
(с) Скоков Сергей
1000 и 1 способ разработки коммерческого ПО на MS Access
Здравствуйте.
На самом деле способов больше тысячи. Проще будет сказать, что он не умеет. Но так и быть я скажу, что он умеет, это даже очень просто:
Самое главное предназначение MS Access – быть средством разработки клиентов баз данных и их хранения.
Но ведь и на С++, и на Java, и на C#.NET тоже можно сделать клиента БД, скажите вы. Да, можно. Но на MS Access для этого не нужно программировать. Например, повторяющиеся, рутинные действия по реализации интерфейса можно выполнить в редакторе. После чего ваше окошко уже готово для ввода данных. Попробуйте сделать такое в более гибких средствах.
Возникает вопрос: Зачем же в MS Access встроен язык VBA? Ответ весьма прост – для того, чтобы писать бизнес логику. Без этого ну совсем никак. VBA значительно расширяет возможности – COM (читай Word и Excel) и WinAPI становятся вашими союзниками. Если вы научитесь программировать, то вы еще больше расширите границы применения MS Access. Это именно то средство, в котором манипулировать данными легко и просто.
Как писать коммерческие приложения? Коммерческим оно станет тогда, когда будет максимально автономным, т.е. пользовать запустил, и оно работает, и ему вовсе не надо задумываться о том, что программа запущена в среде MS Access. Для этого нужно обзавестись некоторым багажом знаний и немного (чуть больше, чем вы подумали) попрограммировать. Всего один раз. Дальше дело за малым: использовать готовые решения и реализовывать только отличия.
Чуть не забыл самое главное – данные! MS Access сразу предлагает вам очень удобный способ хранения любых данных – вместе с кодом ( чего лучше не делать
). В этом и заключается его ограничение. Когда все-таки встает вопрос о сервере СУБД, то MS SQL Serve и MS Access весьма дружны. А если этот сервер не такой дружественный, то можно вспомнить дальнего друга – ODBC.
MS Access не принимает за вас решения. Оно дает вам набор способов, как построить приложение, которых в 90% случаев вполне достаточно. И при этом всегда найдутся лучшие способы для достижения той или иной цели.
Итого. Везде, где фигурируют слова “ввод данных”, “печать отчетов”, может присутствовать MS Access. Вот только я бы не стал использовать его для автоматизации работы предприятия с численностью сотрудников 1000 человек. Как говорится, большому кораблю – большая торпеда.
(с) Скоков Сергей
Повышение сопровождаемости. Часть 1. Формы.
Здравствуйте, уважаемые подписчики.
В этом выпуске мы откроем очень важную тему сопровождаемость. Это то, что экономит время в последующем, когда изменения как правило нужно вносить быстро.
MS Access представляет из себя конструктор со встроенным языком программирования. Формы, отчеты, запросы и пр. никакого отношения к языку не имеют. Можно сказать, что они представляют из себя хранимые настройки классов Form, Report, QureyDef и п.р. При создании формы не обязательно создается модуль класса (далее класс), только если указать в свойстве «наличие модуля» да или создать обработчик события. В этом случае имя класса будет Form_<имя формы>. Это истинно и для отчетов.
К объектам MS Access (формы, отчеты, запросы, таблицы) обращаются по текстовому имени. В результате компилятор не проверяет правильность написания текстовых констант. В процессе жизни проект может пережить много модификаций: добавлений, удалений, переименований. После подобных изменений идет страшная череда тестирований и исправлений ошибок. Один из способов повышения сопровождаемости – это писать «компилируемый код». Да, смешно звучит. Т.е. переносить проверку кода с этапа выполнения на этап компиляции. Сейчас все поясню. Все что будет сказано про форму, в той или иной степени относится к отчетам.
Read the rest of this entry »