Что такое Lookup или эффективная работа с Microsoft Access могла быть эффективней, если не…
Грибанов Сергей Юрьевич
E-Mail prbasic@lcpi.lipetsk.ru
Вначале небольшая выдержка из справочной системы MSAccess по свойству формы .Filter
***********************************************************************************************
Свойство «Фильтр» (Filter)
Свойство Фильтр (Filter) определяет подмножество записей, выводящихся после применения фильтра к форме, запросу или таблице.
Значения
Значение свойства Фильтр (Filter) определяется строковым выражением, содержащим предложение
WHERE без ключевого слова WHERE. Например, следующие инструкции Visual Basic определят фильтр, отбирающий клиентов из России:Me.Filter = "Страна = 'Россия'"
Me.FilterOn = True
***********************************************************************************************
Рассмотрим частный случай для форм, т.к. на практике пользователи чаще работают именно с формами.
Из написанного: "Значение свойства Фильтр (Filter) определяется строковым выражением, содержащим предложение
WHERE без ключевого слова WHERE " ясно что строковое выражение содержит СТАНДАРТНУЮ строчку SQL, только без ключевого слова WHERE, следовательно, эта строчка должна обрабатываться стандартными функциями Access ApplyFilter, Dlookup и другими, которые используют SQL, а также в объектах Recordset и им подобных, это утверждение почти верно, но на практике, оказалось, по другому, хочу отметить также, что на длину строки SQL в свойстве формы .Filter наложено ограничение на размер в 2048 байт.Зачем вообще нужно свойство .Filter в формах? Где его можно использовать?
Не знаю, для чего конкретно хотела использовать его Microsoft, хороших примеров на данную тему я так и не встретил, мне это свойство подходило для конкретной задачи поставленной заказчиком. Задача заключалась в следующем:
Имелась форма с записями, пользователь должен был находить какие-то данные и на их основе создавать несколько табличных форм, содержащих найденные записи и строить несколько временных отчетов подряд для сверки каких-то своих данных, полей форма содержала много и создать фиксированное количество форм и отчетов для всех условий было довольно затруднительно, проще было создать одну форму на которую накладывались условия, в зависимости от данных найденных в основной форме, для этих целей я и выбрал свойство .Filter формы, казалось бы, все замечательно, применил пользователь фильтр к форме, открыл табличную форму, где на данные накладывалось условие по WHERE .Filter, свернул ее, нашел новые данные, открыл новую форму и т.д. и действительно все работает, когда фильтр применяется из собственноручно написанного кода, например DoCmd.AppleyFilter ,"[Id]=100". В этом случае строчка в .Filter будет содержать
"[Id]=100", проблемы возникли, когда пользователь стал применять команды "Исключить выделенное" и "Фильтр по выделенному", они показали некорректную работу с присоединенными значениями в списках формы и как выяснилось в дальнейшем некорректную работу почти во всем.Для того чтобы понять, в чем заключается неудобство встроенных функций, рассмотрим конкретный пример, который прилагается к данной статье.
Имеется небольшая БД, состоящая из нескольких таблиц (в данном случае используются две), и между двумя из них установлена связь по конкретному полю, очень распространенный прием, (см рисунок)
Поле [CodeTypeID] в основной таблице (Data)Склад
содержит в данном примере коды типов
комплектующих, которые связанны с
соответствующей списочной таблицей (см. рисунок)
в отношении многие к одному. Повторяюсь, очень
простой и очень распространенный вариант
построения структуры БД, на основе этих таблиц
создана форма (см. рисунок), которая содержит
поле, и два раскрывающихся списка, один из
списков (Тип) содержит два столбца, первый
столбец включает код типа и имеет нулевую ширину,
он же связан с основным полем [CodeTypeID] в
основной таблице (Data)Склад, второй столбец
собственно отображает название типа
комплектующих, тоже достаточно распространенный
вариант. Теперь запустите данный пример и
откройте форму "BugLookup", поместите курсор
на поле "Склад" и нажмите в Меню кнопку
"Фильтр по выделенному", после этого
нажмите кнопку "Показать Me.Filter" на форме,
вы увидите, что-то вроде (([(Data)Склад].Склад="Петров")),
проанализируйте увиденное, что ж вполне
приемлемая строчка SQL получается, а теперь
нажимайте на "Фильтр по выделенному"
еще раз и нажмите кнопку "Показать Me.Filter",
что же мы видим? Строчка стала иметь следующий
вид ((([(Data)Склад].Склад="Петров")))
AND (([(Data)Склад].Склад="Петров")), часть
конструкции постоянно повторяется не неся уже
никакой смысловой информации, при многократных
нажатиях строчка будет лишь увеличиваться пока
не исчерпается лимит на размер строки в Me.Filter
- 2048 байт. Исходя из этого, сформулируем:
1. Вы можете бесконечно применять фильтр по выделенному полю, пока не достигните ограничения на длину строчки SQL, при этом количество записей не изменится, а строка SQL в фильтре будет однообразно расти.
Рассмотрим теперь пример для команды "Исключить выделенное", предварительно очистите свойство .Filter формы (Кнопка "Удалить Me.Filter"), поместите курсор на поле "Склад" и нажмите в меню кнопку "Исключить выделенное", нажмите кнопку "Показать Me.Filter", строка .Filter будет иметь вид
((Not[(Data) Склад].Склад="Петров")), здесь все нормально и с точки зрения разбора полученной строки SQL, проблем не будет, но если вы еще раз нажмете кнопку "Исключить выделенное", случится следующее: либо форма перейдет на новую запись, либо, если у вас стоит запрет на ввод новых записей в форме, все элементы в области данных исчезнут и вам придется нажать кнопку "Удалить фильтр" для отображенья всех записей, что не всегда удобно, а в некоторых случаях может привести к ошибке. Исходя из этого, сформулируем:2. При исключении записи по выделенному полю, существует вероятность, что значение этого поля уникально, в результате чего исключатся все записи, и форма станет без элементов управления.
Рассмотрим пример для поля "Тип", оно отличается от других наличием присоединенного столбца, очистите свойство .Filter формы (Кнопка "Удалить Me.Filter"), поместимте на данное поле курсор и нажмите кнопку "Фильтр по выделенному", нажмите кнопку "Показать Me.Filter", строка .Filter будет иметь вид
((Lookup_ctrlТип.Тип="RES"))., что уже неприемлемо, мало того, что появился неизвестный префикс Lookup, так и данные берутся не из поля, а из элемента управления ctrlТип. Эта строчка уже не обрабатывается стандартными функциями (Dcount и т.д.). Исходя из этого, сформулируем:3. При выборе команды "Фильтр по выделенному" и "Исключить выделенное" к полям, содержащих присоединенный столбец, строчка SQL в свойстве формы Filter, примет необрабатываемый вид.
Полученные три формулировки сводили к нулю использование свойства Filter формы, пришлось создать свой алгоритм для этих целей. Откройте форму "FixLookup" из данного примера, и проделайте операции перечисленные выше.
Для замены стандартных функций Access нам потребуется одна главная и несколько вспомогательных функций, они размещены в модуле acFormUtl в прилагаемой БД, это
1.
FrmFilterSelection -основная функция для замены "Фильтр по выделенному" и "Исключит выделенное"2.
FrmSort -функция для замены сортировок от А до Я и от Я до А3.
FrmShowAllRecords -функция замены "Удалить фильтр/Показать все записи"4.
MeBuildCriteria -функция замены BuildCriteria из за некорректной работы с символами шаблона ,а также функция cmdBarButtonED в модуле формы для задания свойств .Enabled в меню для кнопок отвечающих за фильтрацию и сортировку. Также необходимо включить следующий код на событие формы Open:Private Sub Form_Open(Cancel As Integer)
Me.FilterOn = False 'Запрещаем
применение сохраненных фильтров
Me.OrderByOn = False 'Запрещаем применение сохраненной
сортировки
Me.Filter = "" 'Обнуляем фильтр
End Sub
Функции 1,2,3 в форме должны всегда использоваться вместе, они пересекаются по свойству .Filter и не включения любой из них приведет к некорректной работе других. Эти функции рекомендуется использовать в меню, в последнем случае они обязательно должны быть объявлены как Function, а не Sub, что связанно с их вызовами Access из меню или панелей инструментов.
Подробно разбирать эти функции в данной статье я не буду, код достаточно прост.
С помощью этих функций неудобства устраняются, не реализовал я, пожалуй, только фильтрацию по выделенным участкам поля, например у Microsoft можно выделить год в поле с датой и он отфильтрует записи с указанным годом, на мой взгляд, это уже лишнее, но и это в принципе реализуется, добавил также возможность поиска записей содержащих NULL.

В конкретном контексте замена этих функций может показаться непринципиальной, но они лишь часть более обширного кода предназначенного для удобной навигации по записям в форме. В следующей статье будет рассмотрен пример для создания удобных шаблонных фильтров для формы (см. рисунок).
----------
MAUG: Вместе с примером Вы также можете загрузить и полный текст статьи в формате Microsoft Word.
Интересно также почитать комментарии на статью, файл Comments.doc, вместе с примером
|
Written and designed by |