Одним из вариантов такого поиска является динамическая фильтрация списка по ключевым словам. Динамическая - значит налету, прямо в процессе ввода ключевых слов пользователем. Скажем, у вас есть список сотрудников, в котором отображаются: идентификатор, ФИО, год рождения, адрес. Вы набираете "77 кр". Список сокращается. В нем остаются только те сотрудники, в данных у которых встречаются число 77 и/или слово "кр". Например, с сотрудники с фамилиями "Кравцов", "Окрошкин", проживающие на улице "Крапивина", с почтовым индексом 667770, с 1977 годом рождения, c идентификаторами 77, 777, 6772 и т.п. Поиск может осуществляться по принципу '77 ИЛИ кр' или '77 И кр' - как удобнее.
Подобный способ фильтрации хорош тем, что практически любая информация, известная пользователю, быстро приведет его к нужной записи в списке. Причем приведет быстро, за пару секунд. Главное, чтобы необходимая информация в списке была.
Конечно, можно сделать специальную форму поиска с четырьмя полями: ФИО, адрес, год рождения, идентификатор. Да еще поместить ее в отдельное окно. Можно.. Но зачем? Такие формы оправданы только в случае больших массивов данных, когда поиск ведется с помощью SQL-запросов и для ускорения поиска используются индексы по полям таблиц базы данных. Если же список целиком сидит в памяти (десяток, сотня, несколько тысяч строк), то достаточно одной строки поиска, которая легко помещается рядом со списком. Согласитесь, что место для одного дополнительного поля ввода над/под списком выделить можно всегда.
Теперь о реализации такого фильтра на Delphi. Здесь два важных момента. Во-первых, фильтр должен прикручиваться к любой форме буквально одной-двумя строками кода. Тогда его будет удобно использовать. Во-вторых, фильтр должен быть ориентирован на работу TDataSet, т.к. именно этот класс (и его наследники) используется для хранения списков в клиентских приложениях для работы с базами данных.
Для себя я реализовал такой фильтр в виде модуля FastFilter. Делать отдельный компонент я не стал - фильтр должен годится и для приложений, использующих не только стандартный TEdit, но и сторонние компоненты ввода.
Чтобы прикрутить фильтр к форме достаточно создать экземпляр класса
TFastFilterCommon:
TForm1 = class(TForm) ... private m_F: TFastFilterCommon; end; procedure TForm1.FormCreate(Sender: TObject); begin m_F := TFastFilterCommon.Create( editFilter //поле ввода фильтра , dataSetToFilter //фильтруемый DataSet , false //'a b' означает 'a ИЛИ b' (а не 'a И b') ); end; procedure TForm1.FormDestroy(Sender: TObject); begin m_F.Free; end;Фильтрация будет вестись по всем полям DataSet. Если нужна фильтрация только по выбранным полям, то нужно перечислить эти поля в конструкторе:
m_F := TFastFilterCommon.Create( editFilter //поле ввода фильтра , dataSetToFilter //фильтруемый DataSet , ['Name', 'Surname', 'Address'] //поля для фильтрации , false //'a b' означает 'a ИЛИ b' (а не 'a И b') );Класс содержит внутренний таймер, определяющий задержку между завершением ввода и началом фильтрации. Пользователь набрал слово, прошло 0.2 сек, если пользователь ничего больше не нажимает, начинается фильтрация. Если пользователь не хочет ждать, он может нажать Ctrl+Enter и фильтрация начнется мгновенно.
В фильтре работают клавиши Up и Down. Они позволяют перемещаться по датасету не выходя из поля ввода.
Модуль FastFilter содержит два класса: TFastFilter и TFastFilterCommon. Первый содержит только статические функции, которые реализуют необходимые обработчики в общем виде. Второй заточен под стандартный TEdit. Если используется нестандартный вариант TEdit, то потребуется создать дополнительный класс TFastFilterXXX (или вызывать функции TFastFilter прямо из формы).
Важное ограничение: FastFilter предполагает, что все данные, по которым нужно вести фильтрацию, содержатся в отображаемом на экране DataSet. Но так бывает далеко не всегда. Пример - фильтрация списка клиентов по номерам телефонов. Номера телефонов хранятся, естественно, в другом DataSet, отдельно от списка клиентов, т.к. у каждого клиента может быть по несколько телефонов. В подобных случаях стандартный TFastFilterCommon потребует доработки.
Browse source codes,
download source codes, view short description in English.
Комментариев нет:
Отправить комментарий