На установленную закладку можно перейти с помощью метода GotoBookmark. Процедура GotoBookmark (Bookmark: TBookmark) позиционирует указатель текущей записи на закладку, указанную параметром Bookmark. Если закладка предварительно не создана и ее значение равно Nil, то текущий указатель не перемещается.
Для удаления закладки используется метод FreeBookmark. Процедура
FreeBookmark (Bookmark: TBookmark) сбрасывает значение закладки в Nil и освобождает занимаемую ею память.
(_____ ЗамечаниеJ
Попытка перейти на удаленную закладку путем вызова метода GotoBookmark приводит к возникновению исключения. К такому же эффекту приводит попытка повторного освобождения закладки методом FreeBookmark.
Целесообразно перед использованием закладки уточнить, существует ли она. Функция BookmarkValid (Bookmark: TBookmark): Boolean проверяет наличие закладки, заданной параметром Bookmark. Если закладка найдена, то в качестве результата функция возвращает значение True, в противном случае — False.
Можно устанавливать и использовать несколько закладок.
Вот пример, иллюстрирующий использование закладок для перехода к нужным записям:
procedure TForml.ButtonlClick(Sender: TObject); // Описание переменной типа закладка var bm: TBookmark;
184
Часть II. Технологии доступа к данным
begin
// Создание закладки bm bm:= Tablel.GetBookmark; Tablel.DisableControls; Tablel.First;
while not Tablel.EOF do begin
// Обработка записей
Tablel.Next;
end; // Переход на закладку bm
if Tablel.BookmarkValid(bm) then Table1.GotoBookmark(bm); // Освобождение закладки bm
if Tablel.BookmarkValid(bm) then Tablel.FreeBookmark(bm); Tablel.EnableControls; end;
Перед началом цикла перебора записей на текущей записи набора данных Tablel устанавливается закладка bm. По окончании цикла для восстановления прежнего положения текущего указателя выполняется переход на закладку, и закладка удаляется. Перед переходом на закладку проверяется ее существование.
Аналогичным образом закладки можно использовать и для перехода к заранее выбранным и отмеченным записям.
Фильтрация записей
Фильтрация — это задание ограничений для записей, отбираемых в набор данных. Напомним, что набор данных представляет собой записи, выбранные из одной или нескольких таблиц. Состав записей в наборе данных в данный момент времени зависит от установленных ограничений, в том числе от фильтров. Система Delphi дает возможность осуществлять фильтрации записей:
□ по выражению;
□ по диапазону.
По умолчанию фильтрация записей не ведется, и набор данных Table содержит все записи связанной с ним таблицы БД, а в набор данных Query включаются все записи, удовлетворяющие SQL-запросу, содержащемуся в свойстве SQL.
(Замечание^
При включении фильтрация записей действует в дополнение к другим ограничениям, например, SQL-запросу компонента Query или ограничению, налагаемому отношением "главный-подчиненный" между таблицами БД. Отметим, что для компонента Query SQL-запрос является средством отбора записей в набор данных, а фильтрация дополнительно ограничивает состав этих записей.
Глава 7. Навигационный доступ к данным с помощью BDE 185
Фильтрация по выражению
При использовании фильтрации по выражению набор данных ограничивается записями, удовлетворяющими выражению фильтра, задающему условия отбора записей.
Достоинством фильтрации по выражению является то, что она применима к любым полям, в том числе к неиндексированным. В связи с тем, что в процессе отбора просматриваются все записи таблицы, фильтрация по выражению эффективна при небольшом количестве записей.
Для задания выражения фильтра используется свойство Filter типа string. Фильтр представляет собой конструкцию, в состав которой могут входить следующие элементы:
□ имена полей таблиц;
□ литералы;
□ операции сравнения;
□ арифметические операции;
□ логические операции;
□ круглые и квадратные скобки.
Если имя поля содержит пробелы, то его заключают в квадратные скобки, в противном случае квадратные скобки необязательны.
Литерал представляет собой значение, заданное явно, например, число, строка или символ. Отметим, что имена переменных в выражении фильтра использовать нельзя. Если в фильтр требуется включить значение переменной или свойства какого-либо компонента, то это значение должно быть преобразовано в строковый тип.
Операции сравнения представляют собой обычные для языка Pascal отношения <, >, =, <=, >=и о.
Арифметическими являются операции +, -, * и / (сложения, вычитания, умножения и деления соответственно).
В качестве логических операций можно использовать and, or и not (логическое умножение, сложение и отрицание соответственно).
Круглые скобки применяются для изменения порядка выполнения арифметических и логических операций.
В качестве примеров задания условий фильтрации приведем следующие выражения:
Salary <= 2000
Post = 'Лаборант' OR Post = 'Инженер'
Первое выражение обеспечивает отбор всех записей, для которых значение поля оклада (salary) не превышает 2000. Второе выражение обеспечивает отбор записей, поле должности (Post) которых содержит значение Лаборант или Инженер.
186
Часть II. Технологии доступа к данным
Если выражение фильтра не позволяет сформировать сложный критерий фильтрации, то в дополнение к нему можно использовать обработчик события
OnFilterRecord.
Для активизации и деактивизации фильтра применяется свойство Filter типа Boolean. По умолчанию это свойство имеет значение False, и фильтрация выключена. При установке свойства Filtered в значение True фильтрация включается, и в набор данных отбираются записи, которые удовлетворяют фильтру, записанному в свойстве Filter. Если выражение фильтра не задано (по умолчанию), то в набор данных попадают все записи.
(_____ ЗамечаниеJ
Активизация фильтра и выполнение фильтрации возможны также на этапе разработки приложения.
Если выражение фильтра содержит ошибки, то при попытке выполнить его генерируется исключение. Если фильтр неактивен (свойство Filtered имеет значение False), то выражение фильтра не анализируется на корректность.
Параметры фильтрации задаются с помощью свойства FilterOptions типа TFilterOptions. Это свойство принадлежит к множественному типу и может принимать комбинации двух значений:
□ foCaseinsensitive — регистр букв не учитывается, т. е. при задании фильтра Post = 'Водитель' слова Водитель, ВОДИТЕЛЬ ИЛИ водитель будут восприняты как одинаковые. Значение foCaseinsensitive нужно отключать, если требуется различать слова, написанные в различных регистрах;
□ foNoPartialCompare — выполняется проверка на полное соответствие содержимого поля и значения, заданного для поиска. Обычно применяется для строк символов. Если известны только первые символы (или символ) строки, то нужно указать их в выражении фильтра, заменив остальные символы на звездочки (*) и выключив значение foNoPartialCompare. Например, при выключенном значении foNoPartialCompare для фильтра Post = 'В*' будут отобраны записи, у которых в поле Post содержатся значения Водитель, Вод., Вод-ль ИЛИ Врач.
По умолчанию все параметры фильтра выключены, и свойство FilterOptions имеет значение [ ].
Рассмотрим в качестве примера обработчики событий формы, используемой для фильтрации записей набора данных по выражению. Вид формы приведен на рис. 7.4.
Управление фильтрацией набора данных выполняется с помощью двух кнопок и поля редактирования. При нажатии кнопки Фильтровать (btnFilter) фильтр активизируется путем присваивания значения True свойству Filtered набора данных. Редактор edtFilter предназначен для задания выражения фильтра. При активизации фильтра происходит отбор записей, которые удовлетворяют заданному в выражении условию. При нажатии кнопки Все записи (btnAllRecord) фильтр отключается, при этом показываются все записи.
Глава 7. Навигационный доступ к данным с помощью BDE
187
Рис. 7.4. Фильтрация по выражению
Ниже приведены три обработчика событий модуля формы Forml приложения.
procedure TForial.FormCreate(Sender: TObject); begin
Tablel.FilterOptions:= [foCaselnsensitive]; Tablel.Filtered:= False; end;
procedure TForml.btnFilterClick(Sender: TObject); begin
Tablel.Filtered:= True; Tablel.Filter: = edtFilter.Text; end;
procedure TForml.btnAHRecordClick (Sender: TObject);
begin
Tablel.Filtered:= False;
end;
Включение и выключение фильтра осуществляется через свойство Filtered. Фильтрация выполняется без учета регистра букв.
В приведенном примере пользователь должен самостоятельно набирать выражение фильтра. Это предоставляет пользователю достаточно широкие возможности управления фильтрацией, но требует от него знания правил построения выражений.
Часто удобно предоставить пользователю список готовых выражений (шаблонов) для выбора. При этом пользователь получает также возможность редактировать выбранное выражение и корректировать весь список. Такой режим реализуется, например, с помощью компонентов ComboBox и Memo.
188
Часть II. Технологии доступа к данным
Если набор условий фильтрации ограничен и не изменяется, то пользователь может управлять отбором записей с помощью таких компонентов, как флажки
(CheckBox) и переключатели (RadioButton).
Рассмотрим в качестве примера обработчики событий формы приложения, в которой пользователю предоставлена возможность управлять фильтрацией по двум полям или по выражению, либо совсем отключать фильтрацию (рис. 7.5).
Рис. 7.5. Управление фильтрацией по выражению
Условия фильтрации по полям Salary и BirthDay заданы в виде двойного неравенства на этапе разработки приложения и при выполнении приложения не могут быть изменены пользователем. Пользователь может задавать в этом неравенстве минимальное и максимальное значения. Фильтрация записей присходит при нажатии кнопки Фильтровать. В обработчике события нажатия этой кнопки автоматически формируется выражение фильтра на основании выбранного для фильтрации поля и введенных пользователем значений.
Ниже приведены обработчики событий модуля формы Forml приложения.
procedure TForml.FormCreate(Sender: TObject); begin
Tablel.Filter:=
Tablel.FilterOptions:= [foCaselnsensitive]; Tablel.Filtered:= True; end;
procedure TForml.btnFilterClick(Sender: TObject);
begin
// Фильтровать по окладу
if rbFilterSalary.Checked then Tablel.Filter:= 'Salary > ' + edtSalaryMin.Text + ' AND Salary < ' + edtSalaryMax.Text;
Глава 7. Навигационный доступ к данным с помощью BDE
189
// Фильтровать по дате рождения
if rbFilterBirthDay.Checked then Tablel.Filter:=
'BirthDay > ' + DateToStr(dtpBirthDayMin.Date) +
' AND BirthDay < ' + DateToStr(dtpBirthDayMax.Date);
// Фильтровать по выражению
if rbFilterExpression.Checked then Tablel.Filter:= edtFilter.Text;
// Отключить фильтрацию
if rbNoFilter.Checked then Tablel.Filter:=
end;
Для ввода значений минимальной и максимальной даты применяются два компонента типа TDateTimePicker (dtpBirthDayMin И dtpBirthDayMax), С ПОМОЩЬЮ которых пользователь может выбирать дату. Для ограничения значения оклада использованы однострочные редакторы edtSalaryMin и edtSalaryMax.
Поскольку в выражении фильтра нельзя использовать имена переменных и свойств компонентов, то при его формировании набранные пользователем значения должны преобразовываться в строковый тип. В приведенном примере это относится к значению даты.
Аналогично задаются и более сложные условия формирования фильтра, в том числе с помощью логических операций OR и not. Кроме того, пользователь может, как и в предыдущем примере, управлять процессом отбора записей с помощью выражения фильтра, которое вводится в редакторе edtFilter.
В данном примере, в отличие от предыдущего, при отключении фильтрации фильтр остается активным, однако его выражение очищается.
Приведем еще один пример на фильтрацию — реализуем электронную записную книжку. Для этого совместно с набором данных будем использовать элемент управления вкладками TabControl, расположенный на странице Win32 Палитры компонентов.
Рассмотрим обрабочики событий формы приложения, имитирующего записную книжку со списком телефонов. Вид книжки с распечаткой фамилий на букву А показан на рис. 7.6.
Список владельцев телефонов хранится с таблице Notebook.db, с которой связан набор данных Tablel. Содержимое списка отображается в компоненте DBGridl. Пользователь может отобразить все фамилии или вывести фамилии, начинающиеся с определенной буквы.
Для управления отбором записей используется фильтрация. Флажок Показывать все записи (checkBoxl) активизирует и деактивизирует фильтр. По умолчанию флажок установлен, при этом фильтр неактивен, и отображаются все фамилии. Если флажок CheckBoxl сброшен, то выполняется фильтрация. Отбор записей осуществляется по первой букве фамилии, которая выбирается с помощью вкладок компонента TabControll.
190
Часть II. Технологии доступа к данным
Рис. 7.6. Записная книжка
Ниже приведены обработчики событий модуля формы Forml приложения.
procedure TForial.FormCreate(Sender: TObject);
begin
DBGridl.Align:= alClient;
// Разрешена фильтрация по частичному совпадению и независимо от регистра букв
Tablel.FilterOptions:= [foCaselnsensitive]; // Отключение фильтрации
CheckBoxl.Checked:= True; CheckBoxlClick(Sender); // Первоначальное формирование выражения фильтра (для буквы А) TabControllChange(Sender); end;
procedure TFo rial.CheckBoxlClick(Sender: TObject);
begin
if CheckBoxl.Checked
then Tablel.Filtered:= False
else Tablel.Filtered:= True;
end;
// Формирование выражения фильтра
// Фильтрация ведется по совпадению первой буквы фамилии
procedure TForml.TabControllChange(Sender: TObject);
begin
Tablel. Filter: = 'Name = ' ' '+TabControll.Tabs [TabControll.Tablndex] + '
end;
Глава 7. Навигационный доступ к данным с помощью BDE
191
Здесь при выборе закладки автоматически формируется выражение фильтра, включающее в себя название (букву) выбранной закладки и символ *. Фильтрация выполняется независимо от регистра букв и по частичному совпадению, для чего параметры фильтра содержат значение foCaseinsensitive и не содержат
foNoPartialCompare.
При включении фильтрации путем установки свойства Filtered в значение True для каждой отбираемой в набор данных записи генерируется событие OnFilterRecord типа TFilterRecordEvent. В процессе отбора записей набор данных автоматически переводится в режим dsFilter, при этом в нем запрещаются действия, связанные с изменением записей. Тип TFilterRecordEvent описан следующим образом:
type TFilterRecordEvent = procedure(DataSet: TDataSet; var Accept: Boolean) of object;
Логический параметр Accept указывает, включать ли в определяемый параметром DataSet набор данных запись, для которой сгенерировано событие OnFilterRecord. По умолчанию параметр Accept имеет значение True, и в набор данных включаются все записи, удовлетворяющие условию фильтра, определяемому свойством Filter. При установке параметра Accept в значение False запись в набор данных не включается.
В обработчике события OnFilterRecord можно определять дополнительные к выражению фильтра условия фильтрации. По своему действию основные и дополнительные условия как бы соединены логической операцией and, т. е. для отбора записи в набор данных требуется соблюдение обоих условий. В отличие от выражения фильтра, в обработчике события OnFilterRecord можно кодировать любые сколь угодно сложные проверки с помощью средств языка Delphi.
Таким образом, набор данных Table допускает два способа задания условий фильтрации: с помощью выражения фильтра Filter и в обработчике события
OnFilterRecord.
(_____ ЗамечаниеJ
Обработчик события OnFilterRecord вызывается для каждой записи, считываемой в набор данных, поэтому код его должен быть коротким и оптимизированным, чтобы не снижать производительность приложения в целом.
Событие OnFilterRecord генерируется для каждой записи также при использовании методов поиска FindFirst, FindLast, FindNext и FindPrior (см. в данной главе ниже), независимо от значения свойства Filtered.
В случае набора данных Query для отбора записей можно использовать:
□ SQL-запрос;
□ обработчик события OnFilterRecord;
□ выражение фильтра.
192
Часть II. Технологии доступа к данным
Напомним, что для связанных таблиц на отбор записей в набор данных также влияет ограничение, налагаемое отношением "главный-подчиненный" между таблицами БД.
Фильтрация по диапазону
При фильтрации по диапазону в набор данных включаются записи, значения полей которых попадают в заданный диапазон, т. е. условием фильтрации является выражение вида значение > нижней границы AND значение < верхней границы (вместо операторов сравнения < и > можно использовать операторы <= и >=). Такая фильтрация применяется к наборам данных Table.
Достоинством фильтрации по диапазону является высокая скорость обработки записей. В отличие от фильтрации по выражению, когда последовательно просматриваются все записи таблицы, фильтрация по диапазону ведется индексно-последовательным методом, поэтому этот способ фильтрации применим только для индексированных полей. Индекс поля, диапазон которого задан в качестве критерия для отбора записей, должен быть установлен как текущий с помощью свойства indexName или indexFieldNames. Если текущий индекс не установлен, то по умолчанию используется главный индекс.
Для включения и выключения фильтрации по диапазону применяются методы ApplyRange и CancelRange. Первый из них активизирует фильтр, а второй — деактивизирует. Предварительно для индексного поля (полей), по которому выполняется фильтрация, следует задать диапазон допустимых значений.
Методы SetRangeStart и SetRangeEnd устанавливают нижнюю и верхнюю границу диапазона соответственно. Названные процедуры не имеют параметров, и для задания границ диапазона используется просто инструкция присваивания. При этом методы SetRangeStart и SetRangeEnd переводят набор данных в режим dsSetKey.
Для изменения предварительно установленных границ диапазона предназначены методы EditRangeStart и EditRangeEnd, действие которых аналогично действию методов SetRangeStart и SetRangeEnd соответственно.
Совместно с этими методами используется свойство KeyExclusive типа Boolean, которое определяет, как учитывается заданное граничное значение при анализе записей. Если свойство KeyExclusive имеет значение False (по умолчанию), то записи, у которых значения полей фильтрации совпадают с границами диапазона, включаются в состав набора данных, если же свойство имеет значение True, то такие записи в набор данных не попадают. Свойство KeyExclusive действует отдельно для нижней и верхней границы. Значение этого свойства должно устанавливаться сразу после вызова методов EditRangeStart,EditRangeEnd, SetRangeStart И SetRangeEnd.
Вот как в программе устанавливается нижняя граница диапазона:
Tablel.SetRangeStart;
Tablel.KeyExclusive:= True;
Tablel.FieldByName('Price').AsFloat:= 10.75;
Глава 7. Навигационный доступ к данным с помощью BDE
193
Индекс по полю Price должен быть текущим. Записи, содержащие в поле цены (Price) значение 10. 75, не входят в отфильтрованный набор данных, поскольку свойству KeyExclusive присвоено значение True. Отметим, что инструкция присваивания, выполняемая после вызова метода SetRangeStart, не меняет значение поля текущей записи, а устанавливает нижнюю границу диапазона.
Когда одна из границ диапазона не задана, то диапазон открыт, т. е. нижняя граница становится равной минимальному возможному, а верхняя граница — максимальному возможному значению этого поля.
Если фильтрация выполняется одновременно по нескольким полям, то после вызова методов SetRangeStart или SetRangeEnd должны стоять несколько инструкций присваивания, каждая из которых определяет границу по одному полю. Предварительно в качестве текущего должен быть установлен индекс, построенный по этим полям.
Вот пример процедуры, в которой фильтрация осуществляется по нескольким полям:
procedure TForml.btnFilterClick(Sender: TObject);
begin
with Tablel do begin
IndexName:= 'indNameBirthDay';
SetRangeStart;
FieldByName('Name').AsString:= 'A';
FieldByName('BirthDay').AsString:= Editl.Text;
SetRangeEnd;
FieldByName('Name').AsString:= 'Б';
ApplyRange;
end; end;
Здесь для фильтрации одновременно используются поля Name и BirthDay. Набор данных содержит только записи, соответствующие сотрудникам, которые родились позже даты, введенной в поле редактирования Editl, и с фамилиями, которые начинаются с букв айв. Верхняя граница для даты рождения не задается.
Неправильный ввод даты в поле редактирования Editl является ошибкой и при попытке присвоить это значение полю даты вызывает исключение. Для предотвращения ошибок, связанных с набором даты, можно использовать компонент DateTimePicker или проверять вводимые в поле редактирования символы и блокировать неправильный ввод, например, с помощью обработчика события OnKeyPress.
В качестве примера рассмотрим обработчики событий модуля формы приложения, обеспечивающего фильтрацию по диапазону (рис. 7.7).
194
Часть II. Технологии доступа к данным
Рис. 7.7. Фильтрация по диапазону
Ниже приведены обработчики событий модуля формы Forml приложения.
procedure TForml.FormCreate(Sender: TObject); begin
Tablel.IndexName:= 'indSalary'; end;
// Фильтрация по полю Salary
// Индекс по этому полю должен быть установлен как текущий
procedure TForml.btnFilterClick(Sender: TObject);
begin
with Tablel do begin
// Установка нижней границы диапазона
SetRangeStart;
FieldByName('Salary').AsString:= edtRangeMin.Text;
// Установка верхней границы диапазона
SetRangeEnd;
FieldByName('Salary').AsString:= edtRangeMax.Text;
// Включение филь трации
ApplyRange;
end; end;
// Отключение фильтрации
procedure TForml.btnNoFilterClick(Sender: TObject);
begin
Tablel.CancelRange;
end;
Пользователь может отбирать записи, задавая нижнюю и верхнюю границы оклада. Фильтрация выполняется по полю Salary. Предварительно индекс по этому полю должен быть установлен как текущий, в противном случае при попытке фильтрации по диапазону возникнет исключение.
Глава 7. Навигационный доступ к данным с помощью BDE
195
Метод SetRange объединяет возможности методов SetRangeStart, SetRangeEnd и ApplyRange. Процедура SetRange (const StartValues, EndValues: array of const) позволяет одновременно задать границы диапазона и выполнить фильтрацию. Параметры StartValues и EndValues являются массивами констант и содержат значения для нижней и верхней границы диапазона соответственно. Если фильтрация выполняется по нескольким полям, то граничные значения для этих полей перечисляются в параметрах StartValues и EndValues через запятую. Например:
// Должен быть установлен текущий индекс,
// построенный по полям должности и оклада
Tablel.SetRange(['Преподаватели', 1200], ['Преподаватели', 1500]);
В набор данных попадают записи о преподавателях, имеющих оклад от 1200 до 1500 рублей. Поля, по которым выполняется фильтрация и для значений которых устанавливаются границы диапазона, в явном виде не указываются, а являются полями текущего индекса. Соответствующий текущий индекс должен быть установлен до вызова метода SetRange.
Для отмены фильтрации, выполненной с помощью методов ApplyRange или SetRange, используется метод CancelRange. Другим вариантом отмены предыдущей фильтрации является задание новых границ диапазона, например, методами SetRangeStart И SetRangeEnd.
(_____ ЗамечаниеJ
Если текущий индекс был изменен, то фильтрация по предыдущему индексу перестает действовать, и в наборе данных будут видимы все записи. При возвращении к прежнему текущему индексу фильтрация также не действует, несмотря на то, что диапазон был задан при предыдущей фильтрации.
При выполнении фильтрации по диапазону возможен отбор записей по частичному совпадению значений символьных полей, когда задаются только начальные символы строки. В отличие от фильтрации по выражению, при фильтрации по диапазону отсутствует свойство, аналогичное FilterOptions с параметром
foCaseInsensitive.
В качестве нижней границы указываются символы, являющиеся началом строки, а для получения значения верхней границы можно добавить справа от них строку яяя. Как правило, символьные значения в полях для фильтрации не могут содержать несколько идущих подряд букв я, а код прописной буквы я больше, чем коды других букв, в результате в набор данных попадут записи, поля которых содержат значения, начинающиеся с заданных символов. Если в полях таблицы могут оказаться строки, включающие в себя добавленную строку яяя, то можно увеличить количество букв я в строке, добавляемой при формировании верхней границы диапазона. При использовании осмысленных слов вероятность такого совпадения близка к нулю, в крайнем случае, в отфильтрованном наборе данных может оказаться несколько лишних записей.
196
Часть II. Технологии доступа к данным
Чтобы продемонстрировать фильтрацию с проверкой на частичное совпадение значений, изменим обработчики событий для записной книжки (см. рис. 7.7) так:
procedure TForial.FormCreate(Sender: TObject); begin
DBGridl.Align:= alClient;
// Главный ключ (по полю Name) используется как текущий индекс Tablel.IndexFieldNames:= 'Name';
// Первоначальное задание границ диапазона (для буквы А) // TabControllChange(Sender); // Отключение фильтрации
CheckBoxl.Checked:= True; CheckBoxlClick(Sender); end;
procedure TForml.CheckBoxlClick(Sender: TObject);
begin
if CheckBoxl.Checked
then Tablel.CancelRange
else TabControllChange(Sender);
end;
// Задание границ диапазона
// Фильтрация по совпадению первой буквы фамилии
procedure TForml.TabControllChange(Sender: TObject);
var Letter: string[1];
begin
Letter:= TabControll.Tabs[TabControll.Tablndex];
Tablel.CancelRange;
Tablel.SetRange([Letter], [Letter + 'яяя']);
end;
В случае набора данных Query, используя средства SQL, можно отбирать записи по частичному совпадению не только начальных символов строки, но и по вхождению заданных символов в любое место строки.
Навигация с псевдофильтрацией
Система Delphi предоставляет возможность перемещения по набору данных, в котором фильтрация выключена, как по отфильтрованному. Методы FindFirst, FindLast, FindNext и FindPrior перемещают указатель текущей записи соответственно на первую, последнюю, следующую и предыдущую записи, удовлетворяющие условиям фильтрации.
Условия фильтрации должны быть заданы предварительно с помощью выражения фильтра Filter и/или обработчика события OnFilterRecord. При этом фильтр может быть выключен путем установки свойства Filtered в значение False.
Глава 7. Навигационный доступ к данным с помощью BDE
197
На время действия каждого из названных методов набор данных автоматически переводится в режим dsFilter, в результате чего записи временно фильтруются, и осуществляется переход на требуемую запись. Связанные с набором данных визуальные компоненты на время фильтрации отображают прежний состав записей набора данных. В результате пользователь не видит хода временной фильтрации, хотя ему запрещено изменять записи, пока набор данных находится в режиме dsFilter.
Таким образом, методы FindFirst, FindLast, FindNext И FindPrior обеспечивают навигацию по записям, удовлетворяющим условиям фильтра, в неот-фильтрованном наборе данных.
(_____ ЗамечаниеJ
При действии методов FindFirst, FindLast, FindNext и FindPrior используется механизм фильтрации, последовательно перебирающий все записи набора данных, поэтому их применение эффективно только для относительно небольших наборов данных.