Разделы из книги Шумакова (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.Набор данных после фильтрации.