Работа с полями. Компонент TField.



TField – компонент для работы с отдельными полями наборов данных. Непосредственно в приложениях не используется. Используются его потомки TStringField, TIntegerField и т.д.

Каждому полю набора данных (НД) может быть поставлен в соответствие компонент TField. Если хотя бы для одного поля набора данных определен TField, то в приложении будут доступны только те поля, для которых созданы компоненты TField. Если ни для одного поля набора данных TField не создавался, то по умолчанию доступны все поля. Эту особенность можно, в частности, использовать для ограничения доступа к отдельным полям НД.

Замечание: использование компонентов TField при создании приложений обеспечивает гораздо более гибкую работу и предоставляет в распоряжение разработчика массу полезных инструментов. Поэтому использование TField рекомендовано всегда, за исключением самых простых англоязычных приложений.

Компоненты TField создаются с помощью редактора полей (рис. 16). Для этого в контекстном меню набора данных выбирается пункт Fields Editor…, после чего появляется окно редактора. Из его контекстного меню можно создать компоненты TField для всех полей НД (Add all fields) или только для выбранных (Add fields...).

 

Рис. 16. Редактор полей и его контекстное меню

 

Компонентам TField по умолчанию (автоматически) присваиваются имена вида: имя набора данных + имя поля. Например, LicaTName, NalichieTKolvo. Соответственно, следует избегать применения подобных имен в других целях.

Помимо имени, для каждого компонента TField можно задать ряд других свойств: только для чтения (ReadOnly), требование обязательного ввода значения (Required), формат показа значения (DisplayFormat), минимальное и максимальное значения и т.д.

Компонент TField обеспечивает доступ к полю в целом, а не только к его значению. Для доступа к значению, хранящемуся в поле, используются свойства Value, а так же AsBoolean, AsCurrency, AsDateTime, AsFloat, AsInteger, AsString, AsVariant.

Общие принципы работы с наборами данных.

Набор данных может находиться в одном из семи состояний:

dsInactive - набор данных закрыт: возможны действия только в отношении всего НД (его удаление или создание); доступ к отдельным записям не возможен;

dsBrowse - состояние просмотра (в это состояние НД переводится после открытия); возможны любые перемещения по НД;

dsEdit - состояние редактирования текущей записи;

dsInsert - состояние добавления новой записи;

dsSetKey - состояние поиска записи; по окончании поиска НД переходит в состояние dsBrowse;

dsCalcFields - состояние расчета вычисляемых полей; по окончании расчета НД переходит в состояние, которое имело место до перехода в dsCalcFields; в этом состоянии могут изменяться только вычисляемые поля;

dsFilter - состояние фильтрации: обработчик OnFilterRecord проверяет, удовлетворяет ли текущая запись условиям фильтрации; по окончании НД переходит в состояние dsBrowse.

Основные приемы перехода между состояниями:

 

dsInactive → dsBrowse

Метод Open (Например: LicaT.Open; - открыть таблицу лиц);

Свойство Active (LicaT.Active := true;- эквивалентно предыдущему)

 

dsBrowse → dsInactive

Метод Close (LicaT.Close; - закрыть таблицу лиц);

Свойство Active (LicaT.Active := false;).

 

Замечание: если в момент закрытия набор данных находится в состоянии dsEdit или dsInsert, то внесенные изменения будут утрачены. В частности, если редактирование допускается непосредственно в TDBGrid, то перед закрытием НД следует проверить – не находится ли он в состоянии редактирования, чтобы пользователь не потерял последние исправления.

 

dsBrowse → dsEdit

Метод Edit (LicaT.Edit; - перейти в режим редактирования текущей записи таблицы лиц).

 

Замечание: метод Edit может вызываться не явно. Например, при редактировании в TDBGrid.

 

dsEdit → dsBrowse

Метод Post (LicaT.Post; - подтверждение изменений, внесенных в текущую запись таблицы лиц);

Метод Canсel (LicaT.Cancel; - отмена изменений).

 

Замечание: эти методы также могут вызываться неявно. Например, при переходе между строками в TDBGrid или при нажатии клавиши Esc.

 

dsBrowse → dsInsert

Метод Insert (LicaT.Insert; - вставка новой записи после текущей);

Метод Append (LicaT.Append; - вставка новой записи в конец НД).

Замечание: методы могут вызываться неявно.

dsInsert→ dsBrowse

Метод Post (подтверждение изменений в текущей записи);

Метод Cancel (отмена изменений).

 

Как отмечалось выше, переходы между состояниями НД могут вызываться неявно. Поэтому для выяснения текущего состояния набора данных может понадобиться метод State, который возвращает информацию о состоянии НД в виде констант: dsInactive, dsBrowse, ...

Например, перед началом выполнения каких-либо действий в НД следует проверить, открыт ли он:

if not LicaT.Active then LicaT.Open;

поскольку попытка выполнения действий в закрытом НД повлечет ошибку.

Перед закрытием формы с возможностью редактирования в TDBGrid следует проверить, не находится ли НД в состоянии редактирования:

 

if LicaT.State in [dsEdit, dsInsert] then LicaT.Post;


Фильтрация в наборах данных.

Фильтрация - это отображение в НД только тех записей, которые удовлетворяют определенному условию (фильтру).

Для осуществления фильтрации в TDataSet используются свойства: Filter, FilterOptions, Filtered и событие OnFilterRecord.

В свойстве Filter указывается условие фильтрации в виде строки SQL-подобного синтаксиса. В этой строке могут использоваться только имена полей, литералы (явно заданные значения), операторы отношения (>, <, <=, =>,<> ), а также логические операторы (OR, AND, NOT). Переменные, объявленные в программе, здесь использовать нельзя.

Например, для показа только тех проводок, в которых передающим было лицо с условным номером 1, а принимающим – с номером 3, фильтр следует задать следующим образом:

 

DM.ProvodkiT.Filter := ’([Rashod]=1) AND ([Prihod]=3)’;

 

Свойство FilterOptions устанавливает режимы выполнения фильтрации для условия Filter (и только для него). Можно указать два режима:

foCaseInsensitive - игнорирование регистра букв;

foNoPartialCompare - поиск по точному соответствию. Если этот режим выключен (foNoPartialCompare = False), то в фильтре можно использовать символ ‘*’ для указания произвольного числа любых символов. Например, для выбора всех лиц, наименование которых начинается с «Ив», «ИВ», «ив», следует задать фильтр:

 

DM.LicoTb.Filter:=’[Name]=”ИВ*”’;

 

с включенной опцией foCaseInsensitive и выключенной foNoPartialCompare.

Значительно большие возможности фильтрации представляет обработчик события OnFilterRecord. Его процедура имеет два параметра: имя фильтруемого НД и параметр Accept. В отфильтрованный НД включаются только те записи, для которых в теле процедуры параметр Accept будет установлен в True. Приведенный выше пример можно переписать следующим образом:

 

procedure DM.ProvodkiT.FilterRecord(DataSet: TDataSet;

                               var Accept: Boolean);

begin

Accept := (DataSet[‘Rashod’]=1) AND

                  (DataSet[‘Prihod’]=3);

end;

 

Следует отметить, что обработчик OnFilterRecord представляет более гибкие возможности для фильтрации НД, чем свойство Filter. В частности, в нем можно использовать и программные переменные.

Свойство Filtered используется для включения/выключения фильтрации. Причем это касается фильтрации, заданной как в свойстве Filter, так и в обработчике OnFilterRecord.

Замечание 1. Фильтры в свойстве Filter и обработчике OnFilterRecord могут использоваться одновременно. Соответственно, в отфильтрованный НД будут включаться записи, удовлетворяющие обоим условиям фильтрации.

Замечание 2. В условия фильтрации могут включаться любые поля, в том числе и те, по которым индексы не строились. Как следствие, фильтрация может потребовать полного перебора всех записей НД. Поэтому использовать в фильтрах неиндексированные поля для больших НД следует с осторожностью, чтобы не замедлить работу с БД.

Замечание 3. Возможно последовательное перемещение по записям, удовлетво­ряющим условиям фильтрации, и при выключенной фильтрации (Filtered = False). Для этого используются методы:

FindFirst – найти первую запись, удовлетворяющую условиям фильтрации;

FindNext – найти следующую запись, удовлетворяющую условиям фильтрации;

FindPrior – предыдущую запись;

FindLast – последнюю запись.

Эти методы возвращают True, если соответствующая запись найдена.

Несмотря на то, что ищутся записи, удовлетворяющие фильтру, НД отображается полностью в неотфильтрованном виде. По сути, в процессе применения указанных методов НД кратковременно переводится в отфильтрованное состояние. Поэтому использовать эти методы для больших НД также не рекомендуется (см. замечание 2).


Поиск в наборах данных.

Метод Locate ищет первую запись, имеющую искомые значения полей. Если такая запись найдена, то делает ее текущей и возвращает True, иначе False. Метод определяется следующим образом:

 

function Locate(const KeyFields: string;

           const KeyValues: Variant;

           Options: TLocateOptions): Boolean;

 

Параметр KeyFields содержит список имен полей, по которым производится поиск. Имена в списке разделяются точкой с запятой.

Параметр KeyValues - вариантный массив, который содержит искомые значения. Первое значение для первого поля из списка KeyFields, второе – для второго и т.д.

Параметр Options указывает условия поиска:

loCaseInsensitive - игнорирование регистра букв;

loPatrtialKey - поиск по частичному соответствию, то есть могут быть заданы только начальные символы значения (здесь символ ‘*’ не используется).

Примеры. Найти в таблице наличия запись, в которой содержится количество предметов с условным номером 25 у лица с условным номером 2:

 

DM.NalichieT.Locate(‘Lico;Predmet’,

                VarArrayOf([2,25]),[]);

 

Найти в таблице лиц первое лицо, наименование которого начинается с символов, содержащихся в строковой переменной NameLic:

 

var NameLic: string;

. . .

NameLic := ‘ИВ’;

. . .

DM.LicaT.Locate(‘Name’, NameLic, [loCaseInsensitive,

                             loPatrtialKey]);

Замечание 1. Поиск возможен по любым полям, в том числе и по неиндексированным. Если индексы есть, то они используются. Если есть несколько индексов по полям поиска, то предсказать какой из них будет использован нельзя. Поэтому, если искомое значение содержится в нескольких записях, то предсказать какая из записей будет найдена первой нельзя. При отсутствии индексов метод работает медленно, поскольку выполняет последовательный перебор записей.

Замечание 2. Иногда после обработки искомой записи возникает необходимость возврата к записи, которая была текущей до начала поиска. Для этого могут использоваться так называемые «закладки» TBookMark, в отношении которых применимы следующие методы:

function GetBookMark: TBookMark; - создает закладку для текущей записи;

procedure GotoBookMark (BookMark: TBookMark); - перемещает курсор на запись, помеченную закладкой;

procedure FreeBookMark (BookMark: TBookMark); - освобождает ресурсы, назначенные закладке;

function BookMarkValid (BookMark: TBookMark): Boolean; - возвращает True, если закладка указывает на некоторую запись.

 

Метод Lookup также как и метод Locate ищет первую запись, удовлетворяющую критериям поиска, но не делает ее текущей, а возвращает значения некоторых ее полей. Поиск производится только на точное совпадение (режимов Options здесь нет).

Метод определяется следующим образом:

 

function Lookup (const KeyFields: string;

            const KeyValues: Variant;

            const ResultFields: string): Variant;

 

Назначение параметров KeyFields и KeyValues то же, что и для Locate. Параметр ResultFields содержат список имен полей, значения которых должны быть возвращены.

Вид результата зависит от количества возвращаемых полей. Если поле одно, то возвращается его значение или NULL (если полю не присвоено никакого значения). Если полей несколько, то результатом будет вариантный массив, содержащий значения (или NULL для полей, значения которым не присвоены). Если запись не будет найдена, то тип результата (varType) будет varNULL; если поиск по каким-либо причинам не был произведен, то тип результата будет varEmpty.

 

Замечание. Использованная в примере функция VarIsArray возвращает True, если переменная типа Variant является массивом.


Дата добавления: 2018-05-31; просмотров: 393; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!