Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_БД.doc
Скачиваний:
28
Добавлен:
04.05.2019
Размер:
4.03 Mб
Скачать

Тема. Фильтрация записей.

Фильтрация – это задание ограничений для записей, которые отбираются в набор данных. Система Delphi позволяет выполнить фильтрацию записей по выражению и по диапазону. Для реализации фильтрации по выражению используются следующие свойства компонента Table:

Filter: String; - определяет текущий фильтр (условие) для набора данных. Содержит определенные ограничения на значения полей.

При записи условий фильтрации можно использовать:

имена полей таблицы, кроме имен вычисляемых полей !!

литералы,

операции отношения =, >, >=, <, <=, <> ,

арифметические операции + - * /

логические операции and, or и not,

круглые скобки.

Например,

  1. TbTovar.Filter:=’Cena<=1000 and Cena>100’;

  2. DM2.TbTovar.Filter:='T_Nazv='+'''к*''';

или DM2.TbTovar.Filter:='T_Nazv='+#39+'к*'+#39;

  1. TbSotruniki.Filter:='S_Birthday>'''+ DateToStr(StrToDate(Edit1.Text))+'''';

  2. TbSotruniki.Filter:='S_Birthday>'''+ DateToStr(StrToDate('01.12.1981'))+'''';

Filtered: Boolean – определяет, будут ли доступны все записи набора данных (false) или только отфильтрованные (true).

Например,

{В поле Edit1 задается условие фильтрации, а по кнопке Button1 задается режим фильтрации}

procedure Tform1.Button1Click (Sender:TObject);

begin

Table1.Filter:=Edit1.Text;

Table1.Filtered:=True;

end;

Примеры выражения, формируемого в поле Edit1:

  1. T_Kol_vo<21 AND T_Kol_vo>10

  2. T_Nazv='с*'

  3. P_Date>'31.12.2006' OR P_Kol_vo<50

FilterOptions: TFilterOptions - параметры фильтрации, свойство множественного типа и может принимать комбинации двух значений:

foCaseInsensitive – регистр букв не учитывается,

foNoPartialCompare – выполняется проверка на полное соответствие содержимого поля и значения, заданного для поиска. При выключенном значении для фильтра Tovar=’K*’ будут отобраны все записи, для которых в поле Tovar первым символом является символ K.

По умолчанию обе опции выключены.

Например, DM2.TbTovar.FilterOptions:=[foCaseInsensitive];

Пример. Формирование выражения из значений различных компонентов для текстового и числового поля:

Table1.Filter:=ComboBox1.Text+Edit1.Text+''''+Edit2.Text+'''';

где ComboBox1.Text- имя поля, Edit1.Text – отношение, Edit2.Text – значение.

Пример 1. Фильтрация по выражению в таблице Sotrudniki. (Alias:Sotrudniki)

procedure TForm1.FormCreate(Sender: TObject);

begin

TbSotrudniki.Filter:='';

TbSotrudniki.FilterOptions:=[foCaseInsensitive];

TbSotrudniki.Filtered:=true;

end;

procedure TForm1.btnFilterClick(Sender: TObject);

begin

// Фильтровать по дате рождения

if rbBirthday.Checked then TbSotrudniki.Filter:='S_Birthday>'''+

DateToStr(dtpbirthdaymin.Date)+''' AND S_Birthday<'''+

Datetostr(dtpbirthdaymax.Date)+'''';

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

if rbexpression.Checked then TbSotrudniki.Filter:=Edexpression.Text;

// Фильтрация отсутствует

if rbnofilter.Checked then begin

TbSotrudniki.Filter:='';

Edexpression.Text:='';

end;

end;

Фильтрация по диапазону. В набор данных включаются записи, значения которых попадают в заданный диапазон. Условием фильтрации является выражение вида:

значение>нижняя_граница AND значение<верхняя_граница

Фильтрация по диапазону ведется индексно-последовательным методом и применяется для индексированных полей. Индекс поля должен быть установлен текущим с помощью свойств IndexName или IndexFieldNames. Если текущий индекс не установлен, то по умолчанию используется главный индекс. Для реализации фильтрации по диапазону используются следующие свойства и методы набора данных Table.

Методы:

SetRangeStart – устанавливает нижнюю границу диапазона.

SetRangeEndустанавливает верхнюю границу диапазона.

ApplyRangeустанавливает фильтр, который ограничивает диапазон записей для просмотра с использованием индексированного поля.

Например,

// формирование списка записей, количество которых – двузначное число.

procedure TForm1.BtnFilterClick(Sender: TObject);

begin

TbTovar.IndexFieldNames:='Kol_vo';

TbTovar.SetRangeStart;

TbTovar.Fields[2].AsInteger:=10; // поле Kol_vo

TbTovar.SetRangeEnd;

TbTovar.Fields[2].AsInteger:=99;

TbTovar.ApplyRange;

end;

CancelRange – отменяет фильтрацию по диапазону, установленную методом ApplyRange.

Например,

// отмена фильтрации по диапазону

procedure TForm1.BtnAllRecordClick(Sender: TObject);

begin

TbTovar.CancelRange;

end;

Свойство:

KeyExclusive: Booleanопределяет как учитывается заданное граничное значение: если =true – записи, значения которых совпадают с границами диапазона не включаются в набор данных, если = false – то включаются. Свойство действует отдельно для верхней и нижней границ.

Например,

// установка верхней границы

TbTovar.IndexFieldNames:='Cena';

TbTovar.SetRangeEnd;

TbTovar.KeyExclusive: = true;

TbTovar.FieldByName (‘Cena’).AsFloat:=200;

Если одна из границ диапазона фильтрации не задана, то диапазон считается открытым.

Если фильтрация выполняется по нескольким полям, то после вызова методов SetRangeStart и SetRangeEnd должны быть записаны несколько операторов присваивания, каждый из которых задает границу по одному полю.

Метод

SetRange(const StartValues, EndValues: array of const) – устанавливает начальное и конечное значение ранга доступных записей. Параметр StartValues указывает значение поля, даваемое первой записи в ранге, параметр EndValuesпоследней записи в ранге. Выполняется назначение ранга набору данных. Отменяется такая фильтрация методом CancelRange.

Например,

procedure TForm1.BtnFilterClick(Sender: TObject);

begin

TbTovar.IndexFieldNames:='Tovar;Cena';

TbTovar.SetRange(['тетрадь',10],['тетрадь',100]);

end;

Для фильтрации по частичному совпадению значений символьных полей задаются начальные символы строки как нижняя граница, а как верхняя граница задается та же строка, дополненная символами ‘яяя’.

Например,

TbTovar.SetRange([‘т’], [‘т’+’яяя’]); 

Фильтрация по событию OnFilteredRecord ??!!

Пример.

// фильтрация по ограничениям для значений двух полей

procedure TForm1.Button2Click(Sender: TObject);

begin

TbTovar.IndexFieldNames:='T_Nazv';

TbTovar.SetRangeStart;

TbTovarT_Nazv.AsString:=Edit1.Text;

TbTovar.SetRangeEnd;

TbTovarT_Nazv.AsString:=Edit3.Text;

TbTovar.ApplyRange;

TbTovar.IndexFieldNames:='T_Cena';

TbTovar.SetRangeStart;

TbTovarT_Cena.AsFloat:=strtofloat(Edit2.Text);

TbTovar.SetRangeEnd;

TbTovarT_Cena.AsFloat:=strtofloat(Edit4.Text);

TbTovar.ApplyRange;

end;

Пример-2. Фильтрация по диапазону по нескольким полям, одно из полей типа PickList.

procedure TForm1.FormCreate(Sender: TObject);

var i:integer;

begin

TbTovar.FilterOptions:=[foCaseInsensitive];

TbTovar.Filtered:=False;

// формирование списка ComboBox значений PickLista из поля Prim

for i:=0 to DBGTovar.Columns[4].PickList.Count-1 do

CmbPrim.Items.Add(DBGTovar.Columns[4].PickList.Strings[i]);

CmbPrim.Text:=CmbPrim.Items[0];

end;

procedure TForm1.BtnFilterClick(Sender: TObject);

begin

with TbTovar do

if (CmbPrim.Text<>'') and (EdMin_Tovar.Text<>'') and (EdMax_Tovar.Text<>'') then begin

IndexName:='ind_PrimTovar';

SetRangeStart; KeyExclusive:=False;

FieldByName('T_Prim').AsString:=CmbPrim.Text;

FieldByName('T_Nazv').AsString:=EdMin_Tovar.Text;

SetRangeEnd; KeyExclusive:=False;

FieldByName('T_Prim').AsString:=CmbPrim.Text;

FieldByName('T_Nazv').AsString:=EdMax_Tovar.Text;

ApplyRange

end

else ShowMessage('Заполните все поля фильтрации!');

end;

procedure TForm1.BtnAllClick(Sender: TObject);

begin

TbTovar.CancelRange;

end;

Пример-3. Фильтрация по полю подстановки для БД Pokupka.

procedure TForm1.FormCreate(Sender: TObject);

begin

// сортировка по наименованию товара

DM2.TbTovar.IndexName:='ind_tovar';

// формирование списка наименований товаров из таблицы Tovar

ComboBox1.Items.Clear;

DM2.TbTovar.First;

while not DM2.TbTovar.Eof do begin

ComboBox1.Items.Append(DM2.TbTovarT_Nazv.AsString);

DM2.TbTovar.Next;

end;

ComboBox1.Text:=ComboBox1.Items[0];

end;

procedure TForm1.BtnFilterClick(Sender: TObject);

var cod:integer;

s : string;

begin

if ComboBox1.Text<>'' then begin

s:=ComboBox1.Text; DM2.TbTovar.First;

while not DM2.TbTovar.Eof do begin

if DM2.TbTovarT_Nazv.AsString=s then

cod:=DM2.TbTovarT_Code.AsInteger;

DM2.TbTovar.Next;

end;

DM2.TbPokupka.IndexFieldNames:='P_Tovar';

DM2.TbPokupka.SetRange([cod],[cod]);

end

else ShowMessage('Выберите наименование товара!');

end;

procedure TForm1.BtnAllClick(Sender: TObject);

begin

DM2.TbPokupka.CancelRange;

DM2.TbPokupka.First;

end;

procedure TDM2.TbTovarAfterPost(DataSet: TDataSet);

begin

// сортировка по наименованию товара

DM2.TbTovar.IndexName:='ind_tovar';

// формирование списка наименований товаров из таблицы Tovar

Form1.ComboBox1.Items.Clear;

DM2.TbTovar.First;

while not DM2.TbTovar.Eof do begin

Form1.ComboBox1.Items.Add(DM2.TbTovarT_Nazv.AsString);

DM2.TbTovar.Next;

end;

Form1.ComboBox1.Text:=Form1.ComboBox1.Items[0];

end;

procedure TDM2.TbTovarAfterDelete(DataSet: TDataSet);

begin

TbTovarAfterPost(DataSet);

end;

Связанные таблицы.

Delphi позволяет создать приложение для двух таблиц, связанных между собой с помощью полей связи. Поля связи обязательно должны быть индексированными.

Таблицы связываются по принципу "главный-подчиненный" (один-ко-многим, один-к-одному, многие-ко-многим). При перемещении по записям главной таблицы будут автоматически доступны те записи подчиненных таблиц, у которых значения поля связи равно значению поля связи текущей записи главной таблицы. Такой отбор записей подчиненной таблицы подобен фильтрации.

Для установления связи между главной (Master) и подчиненной (Detail) таблицами используются следующие Свойства подчиненной таблицы (набор данных Table):

MasterSource: TDataSource; - имя компонента источника данных главной (родительской) таблицы для установления отношения между таблицами типа главная-подчиненная (родительская-дочерняя). Набор данных, который ассоциируется с указываемым источником данных, становится главной таблицей, а текущая таблица – подчиненной.

IndexName: String; - текущий индекс подчиненной таблицы.

IndexFieldNames: String; - поле или поля связи текущего индекса подчиненной таблицы.

MasterFields: String; - поле или поля из главной таблицы, которые служат для связи с соответствующими полями данной подчиненной таблицы. Поля в списке отделяются точкой с запятой. Двойным щелчком мышью в поле значения свойства MasterFields откроется диалоговое окно Field Link Designer. В этом окне нужно указать какое поле подчиненной (Detail) таблицы будет связано с полем главной (Master) таблицы. Указанное поле станет значением свойства MasterFields.

где:

Available Indexes – список индексов подчиненной таблицы,

Detail Fields – поля, входящие в выбранный индекс подчиненной таблицы,

Master Fields – поля главной таблицы,

Joined Fields – связь между полями двух таблиц.

При работе со связанными таблицами необходимо учитывать следующее:

  1. при изменении (редактировании) поля связи записи главной таблицы нужно соответственно изменять значения поля связи всех подчиненных записей.

  2. При удалении записи главной таблицы нужно удалять и соответствующие ей записи в подчиненной таблице (каскадное удаление).

  3. При добавлении записи в подчиненную таблицу значение поля связи формируется автоматически по значению поля связи главной таблицы.

Пример. Работа со связанными таблицами Tovar и Prodaga.

(Листинг программы).

Между таблицами устанавливается связь "главный-подчиненный". Таблица Tovar – главная, таблица Prodaga – подчиненная. Для связи используются поля: T_Code (в главной таблице), P_Code (в подчиненной).

В верхней части главной формы приложения выводится информация о товарах, а в нижней части информация о продаже товара. При выборе в таблице Товары (Tovar) записи о товаре в таблице Продажа (Prodaga) автоматически отображаются только те записи, которые соответствуют продаже именно этого товара.

Модификация данных таблиц с помощью компонентов DBGrid запрещена. Добавление и удаление записей главной таблицы выполняется с помощью кнопок Добавить и Удалить.

При удалении записи с данными о товаре сначала удаляются все соответствующие записи подчиненной таблицы, а затем удаляется запись с данными о товаре в главной таблице.

Переключатель Показать все записи позволяет разорвать связь между таблицами. Сначала он выключен, и связь между таблицами существует.