Russian Belarusian English German Japanese Ukrainian

Фильтрация по выражению

CuBook4.25

При использовании фильтрации по выражению набор данных ограничивается записями, удовлетворяющими выражению фильтра, задающему условия отбора записей. Достоинством фильтрации по выражению является то, что она применима к любым полям, в том числе к неиндексированным. В связи с тем, что в процессе отбора просматриваются все записи таблицы, фильтрация по выражению эффективна при небольшом количестве записей.
 
Для задания выражения фильтра набора данных используется его свойство:
__property System::AnsiString Filter = {read=FFilterText, write=SetFiiterText};
Фильтр представляет собой конструкцию, в состав которой могут входить следующие элементы:
  • имена полей таблиц;
  • литералы;
  • операции сравнения;
  • арифметические операции;
  • логические операции;
  • круглые и квадратные скобки.
Если имя поля содержит пробелы, то его заключают в квадратные скобки, в противном случае квадратные скобки необязательны.
 
Литерал представляет собой значение, заданное явно, например, число, строка или символ. Отметим, что имена переменных в выражении фильтра использовать нельзя. Если в фильтр требуется включить значение переменной или свойства какого-либо компонента, то это значение должно быть преобразовано в строковый тип.
 
Операции сравнения представляют собой обычные для языка С++ отношения <, >, =, <=, >= и <>.
 
Арифметическими являются операции +, * и / (сложения, вычитания, умножения и деления соответственно).
 
В качестве логических операций можно использовать AND, OR и NOT (логическое умножение, сложение и отрицание соответственно). Круглые скобки применяются для изменения порядка выполнения арифметических и логических операций.
 
В качестве примеров задания условий фильтрации приведем следующие выражения:
Salary <= 1000
Post = 'Лаборант' OR Post = 'Инженер'
Первое выражение обеспечивает отбор всех записей, для которых значение поля оклада Salary не превышает 1000. Второе выражение обеспечивает отбор записей, поле должности Post которых содержит значение Лаборант или Инженер.
В выражениях фильтрации имена полей заключаются в одиночные апострофы, а не в двойные. Для проверки условия равенства значений используется одиночный знак равенства =, а не двойной, как в операторе if.
Если выражение фильтра не позволяет сформировать сложный критерий фильтрации, то в дополнение к нему можно использовать обработчик события OnFilterRecord.
 
Для активизации и деактивизации фильтра применяется свойство Filtered типа bool. По умолчанию это свойство имеет значение false, и фильтрация выключена. При установке свойству Filtered значения true фильтрация включается, и в набор данных отбираются записи, которые удовлетворяют Фильтру, записанному в свойстве Filter. Если выражение фильтра не задано (по умолчанию), то в набор данных попадают все записи.
Активизация фильтра и выполнение фильтрации возможны также на этапе разработки приложения.
В выражении фильтра нельзя использовать имена полей, в которых присутствуют буквы русского алфавита.
Если выражение фильтра содержит ошибки, то при попытке выполнить его генерируется исключение. Если фильтр не активен (свойство Filtered имеет значение false), то выражение фильтра не анализируется на корректность.
Параметры фильтрации задаются с помощью свойства Fiiteroptions типа TFiiterOptions. Это свойство принадлежит к множественному типу и может принимать комбинации двух значений:
  • foCaseInsensitive - регистр букв не учитывается, т.е. при задании фильтра Post = 'Водитель' Слова Водитель, ВОДИТЕЛЬ или водитель будут восприняты как одинаковые. Значение focaseinsensitive нужно отключать, если требуется различать слова, написанные в различных регистрах;
  • foNoPartiaiCompare - выполняется проверка на полное соответствие содержимого поля и значения, заданного для поиска. Обычно применяется для строк символов. Если известны только первые символы (или символ) строки, то нужно указать их в выражении фильтра, заменив остальные символы на звездочки (*) и выключив значение foNoPartiaicompare. Например, при выключенном значении foNoPartiaicompare для фильтра Post = 'в*' будут отобраны записи, у которых в поле Post содержатся значения Водитель, Вод., Вод-ль или Врач.
По умолчанию все параметры фильтра выключены, и свойство FilterOptions представляет собой пустое множество.
 
Рассмотрим в качестве примера обработчики событий формы, используемой для фильтрации записей набора данных по выражению.
Управление фильтрацией набора данных выполняется с помощью двух кнопок и поля редактирования. При нажатии кнопки Фильтровать (btnFiiter) фильтр активизируется путем присваивания значения true свойству Filtered набора данных. Редактор edtFiiter предназначен для задания выражения фильтра. При активизации фильтра происходит отбор записей, которые удовлетворяют заданному в выражении условию. При нажатии кнопки Без фильтра (btnNoFiiter) фильтр отключается, при этом показываются все записи.
 
Ниже приведены три обработчика событий главного модуля приложения.
void __fastcall TForm1::Formereate(TObject *Sender)
{
Table1->Active=true;
Table1->FilterOptions>>foCaseInsensitive;
Table1->Filtered = false;
}
//------------------------
void __fastcall TForm1::NotFilterlClick(TObject *Sender)
{
Table1->Filtered = false;
}
//------------------------
void __fastcall TForm1::FilterClick(TObject *Sender)
{
Table1->Filtered = true;
Table1->Filter = EditFilter->Text;
}
Включение и выключение фильтра осуществляется через свойство Filtered. Фильтрация выполняется без учета регистра букв.
 
В приведенном примере пользователь должен самостоятельно набирать выражение фильтра. Это предоставляет пользователю достаточно широкие возможности управления фильтрацией, но требует от него знания правил построения выражений.
 
Например, чтобы задать фильтрацию по значению поля типа даты, можно использовать следующий обработчик события:
void __fastcall TForm1::FilterClick(TObject *Sender)
{
Table1->Filtered = true;
Table1->Filter = "HireDate<'01.01.1990'" ;
}
Здесь при фильтрации обеспечивается отбор записей, в которых значение поля HireDate (дата приема на работу) содержит дату более раннюю, чем 01.01.1990, т.е. отбираются данные о сотрудниках, принятых на работу до указанной даты.
 
Часто удобно предоставить пользователю список готовых выражений (шаблонов) для выбора. При этом пользователь получает также возможность редактировать выбранное выражение и корректировать весь список. Такой режим реализуется, например, с помощью компонентов ComboBox и Memo.
 
Если набор условий фильтрации ограничен и не изменяется, то пользователь может управлять отбором записей с помощью таких компонентов, как флажки (CheckBox) и переключатели (RadioButton).
 
Можно задавать и более сложные условия формирования фильтра, в том числе с помощью логических операций OR и NOT. Кроме того, пользователь может, как и в предыдущем примере, управлять процессом отбора записей с помощью выражения фильтра, которое вводится в текстовом редакторе компонента типа TEdit.
 
При необходимости фильтр можно оставить активным, но отменить фильтрацию путем очистки выражения фильтра, например:
Table1->Filter = ' ';
При включении фильтрации путем установки свойству Filtered значения true для каждой отбираемой в набор данных записи генерируется событие onFiiterRecord типа TFiiterRecordEvent. В процессе отбора записей набор данных автоматически переводится в режим dsFilter, при этом в нем запрещаются действия, связанные с изменением записей. Тип TFiiterRecordEvent описан следующим образом:
typedef void __fastcall (__closure *TFiiterRecordEvent)(TDataSet* DataSet, bool ScAccept);
Логический параметр Accept указывает, включать ли в определяемый параметром DataSet набор данных запись, для которой сгенерировано событие OnFiiterRecord. По умолчанию параметр Accept имеет значение true, и в набор данных включаются все записи, удовлетворяющие условию фильтра, определяемому свойством Filter. При установке параметра Accept в значение false запись в набор данных не включается.
 
В обработчике события OnFiiterRecord можно определять дополнительные к выражению фильтра условия фильтрации. По своему действию основные и дополнительные условия как бы соединены логической операцией AND, т.е. для отбора записи в набор данных требуется соблюдение обоих условий. В отличие от выражения фильтра, в обработчике события OnFiiterRecord можно кодировать любые сколь угодно сложные проверки с помощью средств языка С++.
 
Таким образом, набор данных Table допускает два способа задания условий фильтрации: с помощью выражения фильтра Filter и в обработчике события OnFilterRecord.
Обработчик события OnFilterRecord вызывается для каждой записи, считываемой в набор данных, поэтому код его должен быть коротким и оптимизированным, чтобы не снижать производительность приложения в целом.
Событие OnFilterRecord генерируется для каждой записи также при использовании методов поиска FindFirst, FindLast, FindNext и FindPrior независимо от значения свойства Filtered.
В случае набора данных Query для отбора записей можно использовать:
  • SQL-запрос;
  • обработчик события OnFilterRecord;
  • выражение фильтра.
Напомним, что для связанных таблиц на отбор записей в набор данных также влияет ограничение, налагаемое отношением «главный-подчиненный» между таблицами БД.
Если заметили ошибку, выделите фрагмент текста и нажмите Ctrl+Enter

Добавить комментарий