Фільтрування набору даних компонента IBQuery подією OnFilterRecord та з допомогою секції WHERE

При створенні програм для роботи з базами даних, перед розробником постає задача забезпечити зручні засоби для отримання необхідних користувачеві даних. Для цього найчастіше використовують фільтрацію даних по будь-якому набору полів, яка дозволяє виключити з перегляду непотрібні рядки. Наприклад для деякого стовпця «Модель» таблиці «Автомобілі» існує  поле пошуку. Користувач вводить в дане поле модель автомобіля і в результаті отримує список автомобілів, значення поля "Модель" яких співпадає з значенням, яке міститься в пошуковому рядку.

Розглянемо два способи фільтрції набору даних, а саме подією OnFilterRecord та з допомогою секції WHERE. Для цього створимо новий delphi-проект і на головній формі розмістимо усі компоненти (DataSource1, IBQuery1, IBDatabase1, IBTransaction1, DBGrid1, DBNavigator1) так, як показано на малюнку.

Фільтрація набору даних компонента IBQuery полією OnFilterRecord

Фільтрація набору даних компонента IBQuery полією OnFilterRecord

З допомогою компонента IBDatabase1 налаштуємо з'єднання з базою даних autobazar. Далі зв’яжемо компоненти IBDatabase1 та IBTransaction1 один з одним: для властивості DefaultDatabase компонента IBTransaction1 присвоємо значення IBDatabase1; для властивості DefaultTransaction компонента IBDatabase1 присвоємо значення IBTransaction1.

Пов'яжемо компонент IBQuery1 з компонентами IBTransaction1 та IBDatabase1, і для властивості SQL запишемо наступний SQL-запит: SELECT * FROM Cars.

Далі, присвоєм властивості DataSet компонента DataSource1 значення IBQuery1. І для властивості DataSourse компонентів DBGrid1 та DBNavigator1 присвоємо значення DataSource1.

Подія OnFilterRecord

Фільтрація набору даних компонента IBQuery полією OnFilterRecord

Після розміщення усіх компонентів та присвоєння їм необхідних властивостей, приступимо до програмування обробника події OnFilterRecord компонента IBQuery1.

Дана подія виникає при встановленні значення True у властивість Filtered. Обробник події має два параметри: ім’я набору даних (DataSet), який буде фільтруватися та змінну Accept, в яку програма повинна помістити True, якщо біжучий запис задовольняє критерію фільтрації.

Доступ до полів при використанні події OnFilterRecord відбувається через параметр DataSet. Загальне звернення до поля набору даних можна представити так: DataSet ['<ім’я поля>'].

Зауваження: при використанні події OnFilterRecord відбувається послідовний перебір усіх записів із набору даних. Тому бажано використовувати подію OnFilterRecord лише при невеликій кількості записів у таблиці і обмежити його використання при великих об’ємах даних.

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

procedure TForm1.IBQuery1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
Accept := DataSet['Color'] = 'Чорний';
end;

Якщо в обробнику події OnFilterRecord вказати різні критерії фільтрації, то будуть виконуватися обидва. Доповнимо форму компонентами, як показано на наступному малюнку з допомогою яких реалізуємо одночасне накладання кількох умов фільтрування (тобто, суперпозицію фільтрів)

Подія OnFilterRecord

Суперпозицію фільтрів використовуючи подію OnFilterRecord

Для компонентів Button1 та IBQuery1 запишемо наступні обробники подій:

procedure TForm1.IBQuery1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
var
Marka, Color, Cina, CYear: boolean;
begin
//Accept := DataSet['Color'] = 'Чорний';
if (CheckBox1.Checked) then
Marka := (DataSet['Marka'] = Edit1.Text)
else
Marka := True;
if (CheckBox2.Checked) then
Color := (DataSet['Color'] = Edit2.Text)
else
Color := True;
if (CheckBox3.Checked) then
Cina := (DataSet['Cina'] >= StrToInt(Edit3.Text)) and (DataSet['Cina'] <= StrToInt(Edit4.Text))
else
Cina := True;
if (CheckBox4.Checked) then
CYear := (DataSet['CYear'] >= StrToInt(Edit5.Text)) and (DataSet['CYear'] <= StrToInt(Edit6.Text))
else
CYear := True;
Accept := Marka and Color and Cina and CYear;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
IBQuery1.Filtered := False;
IBQuery1.Filtered := True;
end;

Після запуску скомпільованої програми на екрані повинна появитись приблизно така форма:

Подія OnFilterRecord

Суперпозицію фільтрів використовуючи подію OnFilterRecord

Крім події OnFilterRecord, фільтрацію набору даних компонента IBQuery можна також здійснти з допомогою секції WHERE, яка  містить критерій по якому проводиться відбір.

Розмістимо на формі стандартну кнопку Button2, встановимо для її властивості Caption значення «Вибрати чорні автомобілі» і напишемо наступний код для підпрограми опрацювання події OnClick цієї кнопки:

procedure TForm1.Button2Click(Sender: TObject);
begin
IBQuery1.Active := False;
IBQuery1.SQL.Text := 'SELECT * FROM Cars WHERE color = «Чорний»';
IBQuery1.Active := True;
end;

Запустимо проект на виконання, бачимо, що спочатку виводиться вміст всієї таблиці Cars. Після натискання кнопки Button2 — виводиться інформація лише про чорні автомобілі:

ФІльтрація секцією WHERE

Фільтрація набору даних компонента IBQuery використовуючи секцію WHERE

Таким чином, секція WHERE повністю реалізує фільтрацію, тобто, вибірку результуючого набору даних за критерієм, вказаним після ключового слова WHERE. Давайте доповнимо форму компонентами, як показано на наступному малюнку, та спробуємо реалізувати суперпозицію фільтрів використовуючи секцію WHERE.

onfilterrecord6

Суперпозицію фільтрів використовуючи секцію WHERE

При натисканні на кнопку Button3 беде формуватися SQL запит для компонента IBQuery1 з заданим критерієм відбору. Обробник події OnClick кнопки Button3 має наступний вигляд:

procedure TForm1.Button3Click(Sender: TObject);
var
sql: String;
begin
sql := '';
if (CheckBox5.Checked) then
if (Length(sql) > 0) then
sql := sql + ' AND Marka="' + Edit7.Text + '"'
else
sql := 'Marka="' + Edit7.Text + '"';
if (CheckBox6.Checked) then
if (Length(sql) > 0) then
sql := sql + ' AND Color="' + Edit8.Text + '"'
else
sql := 'Color="' + Edit8.Text + '"';
if (CheckBox7.Checked) then
if (Length(sql) > 0) then
sql := sql + ' AND Cina >=' + Edit9.Text + ' AND Cina <=' + Edit10.Text
else
sql := 'Cina >=' + Edit9.Text + ' AND Cina <=' + Edit10.Text;
if (CheckBox8.Checked) then
if (Length(sql) > 0) then
sql := sql + ' AND CYear >=' + Edit11.Text + ' AND CYear <=' + Edit12.Text
else
sql := 'CYear >=' + Edit9.Text + ' AND CYear <=' + Edit10.Text;
IBQuery1.Active := False;
IBQuery1.SQL.Text := 'SELECT * FROM Cars WHERE ' + sql;
IBQuery1.Active := True;
end;

Запустимо проект на виконання і спробуємо відфільтрувати набір даних компонента IBQuery1 використовуючи в SQL запиті секцію WHERE.

onfilterrecord7

Суперпозицію фільтрів використовуючи секцію WHERE

Скачати проект, який було створено по даній темі можна за посиланням Фільтрація набору даних компонента IBQuery.

Матеріал був корисним, поділись в соціальних мережах:

Якщо тобі сподобалась дана тема, залиш свій коментар