Разделы из книги Шумакова (http://www.brain2life.com/category-18-1.html)
Поиск записей в наборах данных
6.4.1. Метод Locate
function Locate (const KeyFields: String; const KeyValues: Variant;
Options: TLocateOptions): Boolean;
Метод Locate ищет первую запись, удовлетворяющую критерию поиска, и, если такая запись найдена, делает ее текущей. В этом случае в качестве результата возвращается True. Если запись не найдена, возвращается False.
Список KeyFields указывает поле или несколько полей, по которым задается поиск. В случае нескольких поисковых полей их названия разделяются точкой с запятой. Критерии поиска задаются в вариантном массиве KeyValues так, что i-е значение в KeyValues ставится в соответствие i-му полю в KeyFields. Options позволяет указать необязательные значения режимов поиска:
LoCaseInsensitive - поиск ведется без учета высоты букв, т. е. если в KeyValues указано «принтер», а в некоторой записи в данном поле встретилось «Принтер» или «ПРИНТЕР», запись считается удовлетворяющей условию поиска;
loPartialKey - запись считается удовлетворяющей условию поиска, если она содержи часть поискового контекста; например, удовлетворяющими контекста «Ма» будут признаны записи со значениями в искомом поле «Машин», «Макаров» и т. д.
Locate производит поиск по любому полю; поле или поля по которым производится поиск, могут не только не входить в текущий индекс, но и не быть индексными вообще.
В случае если поля поиска входят в какой-либо индекс, Locate использует этот индекс при поиске. Если искомые поля входят в несколько индексов, трудно сказать, какой из них будет использован. Соответственно, трудно предсказать, какая запись из множества записей, удовлетворяющих критерию поиска, будет сделана текущей особенно в случае если поиск ведется не по текущему индексу.
При поиске по полям, не входящим ни в один индекс, применяются фильтры BDE.
Пусть имеется ТБД «Сотрудники кафедры» с целочисленным полем TabNum (Табельный номер) и строковыми целями FIO (ФИО), Doljnost (Должность), UchStepen (Ученая степень). ТБД имеет индексы по полям TabNum, FIO. Осуществим поиск по полям Doljnost и UchStepen (индексное и неиндексное) при различных текущих индексах в НД. Поисковый контекст - ‘доцент’, ' кхн’ при режиме частичного совпадения значений:
procedure TFormX.LocateButtonClick(Sender: TObject);
Begin
Tablel.Locate('Doljnost;UchStepen',
VarArrayOf(['доцент','кхн']),[loPartialKey]);
end;
Результаты поиска показаны на рис. 6.2 и 6.3. Как видно из рисунков, при различных текущих индексах результаты поиска также могут быть различными.
![]() |
Рис. 6.2. Поиск при текущем индексе по полю TabNum.
![]() |
Рис. 6.3. Поиск при текущем индексе по полю FIO.
6.4.2. Метод Lookup
function Lookup (const KeyFields:String; const KeyValues: Variant;
const ResultFields: String): Variant;
Метод Lookup находит запись, удовлетворяющую условию, но не делает ее текущей, а возвращает значения некоторых полей этой записи. Тип результата – Variant или вариантный массив. Независимо от успеха поиска записи указатель текущей записи в НД не изменяется. В отличие от Locate Lookup осуществляет поиск только на точное соответствие критерия поиска и значения полей записи. В KeyFields указывается список полей, по которым необходимо осуществить поиск. При наличии в этом списке более чем одного поля соседние поля разделяются точкой с запятой. KeyValues указывает поисковые значения полей, список которых содержится в KeyFields.
Если имеется несколько поисковых полей, каждому i-му полю в списке KeyFields ставится в соответствие i-e значение в списке KeyValues. При наличии одного поля его поисковое значение можно указывать в качестве KeyValues непосредственно; в случае нескольких полей их необходимо приводить к типу вариантного массива при помощи VarArrayOf.
В качестве поисковых полей можно указывать поля как входящие в какой-либо индекс, так и не входящие в него; тип текущего индекса не имеет значения. Если поисковые поля входят в какие-либо индексы, их использование производится автоматически; в противном случае используются фильтры BDE.
Если в результате поиска запись не найдена, метод Lookup возвращает Null, чтоможно проверить с помощью оператора
if VarType(LookupResults) = varNull then...
В противном случае Lookup возвращает из этой записи значения полей, список которых содержит ResultFields. При этом размерность результата зависит от того, сколько результирующих полей указано в ResultFields:
• одно поле - результатом будет значение соответствующего типа или Null, еслиполе в найденной записи содержит пустое значение;
• несколько полей - результатом будет вариантный массив, число элементов в котором меньше или равно числу результирующих полей (некоторые поля найденной записи могут содержать пустые значения).
Пример А. Одно результирующее поле (результат - значение типа Variant). Будем осуществлять поиск в ТБД «Сотрудники» по полю FIO. Поисковое значение будем вводить в однострочном редакторе Edit1. В качестве результата используем значение поля UchStepen (ученая степень) найденной записи:
Procedure TFormX.LookuplButtonClick(Sender: TObject);
Var
LookupResults: Variant;
Begin
// Осуществляем поиск:
LookupResults:= Tablel.Lookup('FIO', Editl.Text, 'UchStepen');
// Проверяем, содержит ли результат пустое значение или Null:
case VarType(LookupResults) of
varEmpty: Label 1.Caption:= 'Пустой результат';
varNull: Label1.Caption:= 'Запись не найдена';
Else
Label 1.Caption := LookupResults;
end; //case
end;
Пример Б. Несколько результирующих полей (результат-вариантный массив).
Напомним некоторые приемы использования вариантного массива. Если переменная типа Variant является вариантным массивом, функция VarIsArray возвращает True, верхнюю и нижнюю границы массива можно определить при помощи функций VarArrayLowBound и VarArrayHighBound, а тип каждого элемента - с помощью VarType.
Будем осуществлять поиск в ТБД «Сотрудники» по полю FIO. Поисковое значение будем вводить в Edit1, а в качестве результата используем значения полей TabNum, Doljnost и UchStepen найденной записи (табельный номер, должность, ученая степень), которые будем показывать в трех компонентах TLabel1:
procedure TFormX.LookupButtonClick(Senders TObject);
Var
LookupResults: Variant;
Begin
// Ищем запись:
LookupResults:= Table1.Lookup(‘FIO’
Edit1.Text, ‘TabNum;Dpljnost;UchStepen’);
// Проверяем: результат - вариантный массив?
if VarIsArray(LookupResults) then
Begin
Labell.Caption:= LookupResults[0];
if LookupResults[1] < > Null then
Label2.Caption:= LookupResults[1];
if LookupResults[2] < > Null then
Label3. Caption:=LookupResults[2];
end else
// Результат— не вариантный массив, а единичное значение
case VarType(LookupResults) of
varEmpty: Label1.Caption:= 'Пустой результат’;
varNull: Label1. Caption:= 'Запись не найдена';
end; //case
end;
Если запись не найдена, VarType(LookupResults) возвращает значение varNull. Если поиск по какой-либо причине не был произведен, VarType(LookupResults) возвращает значение varEmpty. Если какое-либо из полей, чьи значение возвращаются в результате поиска в вариантном массиве, содержит пустое значение, соответствующий элемент вариантного массива также будет содержать пустое значение (Null). В этом случае обращение к нему возбудит исключительную ситуацию, поэтому нужна предварительная проверка.
6.5. ФИЛЬТРАЦИЯ ЗАПИСЕЙ
Помимо описываемых ниже средств для фильтрации данных могут использоваться методы SetRange, ApplyRange (и сопутствующие им методы) в компоненте ТТаble и секция WHERE SQL -запроса в компонентах TQuery и TStoredProc.
6.5.1. Свойство Filter
Свойство Filter позволяет задать критерий фильтрации. В этом случае НД будет отфильтрован, как только его свойство Filtered станет равным True. Синтаксис описания критерия похож на синтаксис секции WHERE SQL -запроса с тем исключением, что имена переменные программы указывать нельзя, можно указывать имена полей и литералы (явно заданные значения); можно использовать обычные операции отношения и логические операторы AND, NOT, и OR, напрмер:
([Doljnost] = ‘доцент’) AND ([TabNum] > 300000)
Строку критерия фильтрации можно ввести во время прогона программы или на этапе конструирования формы. Например, с помощью такого обработчика события OnChecked компонента ComboBox1 критерий фильтрации считывается из редактора Edit1 и помещается в свойство Filter компонента Table1 (рис. 6.4 и 6.5):
procedure TForml.CheckBoxIClick (Sender: TQbject);
Begin
Tablel.Filter:= Editl.Text;
Tablel.Filtered:= CheckBoxl.Checked;
end;
С помощью свойства
type TFilterOption = (foCaseInsensitive, foNoPartialCompare);
property FilterOptions: TFilterOptions;
программист может определить дополнительные условия фильтрации строковых полей: foCaseInsensitive - фильтрация производится без учета разницы в высоте букв;
foNoPartialCompare - поиск производится на точное соответствие.
![]() |
Рис. 6.4. Наборы данных до фильтрации.
![]() |
Рис. 6.5.Набор данных после фильтрации.










