по значениям поля набора данных 3 глава




Установка уровня доступа

В случае многопользовательского доступа к БД для таблицы можно задать уров­ни доступа, которые будут действовать для других приложений. Уровень доступа определяет возможность записи данных в таблицу и их чтения.

Метод LockTable (LockType: TLockType) устанавливает блокировку для табли­цы, при этом параметр LockType задает тип блокировки:

□ ltReadLock (запрещены запись и чтение записей таблицы); этот режим яв­ляется своего рода режимом монопольного доступа;

□ ltWriteLock (запрещена запись в таблицу); другие приложения не могут вы­полнять модификацию записей таблицы, но чтение данных им разрешено.

Метод UnLockTable (LockType: TLockType) снимает установленную ранее блокировку.

Рассмотрим на конкретном примере, как осуществляется блокировка таблицы.

procedure TForml.ButtonlClick(Sender: TObject);

var n: longint;

begin

try

// Блокировка таблицы от внесения изменений Tablel.LockTable(ltWriteLock); // Пересчет окладов Tablel.First;

for n:= 1 to Tablel.RecordCount do begin Tablel.Edit; Tablel.FieldByName('Salary').AsFloat:=

Tablel.FieldByName('Salary').AsFloat + 500; Tablel.Next,• Tablel.Post; end; finaly

// Отмена блокировки таблицы Tablel.UnLockTable(ltWriteLock); end; end;

Оклады всех сотрудников увеличиваются на 5 00 (рублей). На время пересчета таблица блокируется, что защищает ее от внесения изменений другими прило-


Глава 7. Навигационный доступ к данным с помощью BDE


169


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

Сортировка набора данных

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

С отсортированными записями набора данных работать более удобно. Сорти­ровка заключается в упорядочивании записей по определенному полю в порядке возрастания или убывания содержащихся в нем значений. Сортировку можно выполнять и по нескольким полям. Например, при сортировке по двум полям сначала записи упорядочиваются по значениям первого поля, а затем группы записей с одинаковым значением первого поля сортируются по второму полю.

Сортировка наборов данных Table и Query выполняется различными способа­ми. Здесь мы рассмотрим сортировку набора данных Table, для компонента Query вопросы сортировки рассмотрены в главе 8.

Сортировка наборов данных Table выполняется автоматически по текущему индексу. При смене индекса происходит автоматическое переупорядочивание записей. Таким образом, сортировка возможна по полям, для которых создан индекс. Для сортировки по нескольким полям нужно создать индекс, вклю­чающий эти поля.

Направление сортировки определяет параметр ixDescending текущего индекса, по умолчанию он выключен, и упорядочивание выполняется в порядке возрас­тания значений. Если признак ixDescending индекса включен, то сортировка выполняется в порядке убывания значений.

Напомним, что задать индекс (текущий индекс), по которому выполняется сор­тировка записей, можно с помощью свойств indexName или indexFieldNames. Эти свойства являются взаимоисключающими, и установка значения одного из них приводит к автоматической очистке значения другого. В качестве значения свойства IndexName указывается имя индекса, установленное при его создании. При использовании свойства IndexFieldNames указываются имена полей, об­разующих соответствующий индекс.

В связи с тем, что главный индекс (ключ) таблиц Paradox не имеет имени, вы­полнить сортировку по этому индексу можно только с помощью свойства

IndexFieldNames.

Вот небольшой пример, иллюстрирующий сортировку с указанием имен индексов:

procedure TForml.Button4Click(Sender: TObject);

begin

case RadioGroupl.Itemlndex of

0: Tablel.IndexName:= 'indName';


170


Часть II. Технологии доступа к данным


1: Tablel.IndexName:= 'indBirthDay'; end; end;

В качестве набора данных используется компонент Tablel, а сортировка вы­полняется двумя способами: по индексу indName, созданному для поля Name, и по индексу indBirthDay, созданному для поля BirthDay.

Еще один пример сортировки, на этот раз с указанием имен индексных полей (для связанной с набором данных таблицы поле Code задано автоинкрементным и определено в качестве главного индекса):

procedure TForml.Button5Click(Sender: TObject);

begin

case RadioGroupl.Itemlndex of

end;

end;

Здесь сортировка выполняется по следующим полям: Name (индекс indName), Name И BirthDay (индекс indNameBirthDay), Code (главный индекс).


Рис. 7.1. Вид формы для сортировки набора данных

А теперь рассмотрим более сложный пример сортировки. В качестве набора данных снова используется компонент Tablel. Пользователь может управлять сортировкой его записей с помощью двух групп переключателей: в первой зада­ется вид, а во второй — направление сортировки. Сортировка выполняется по­сле нажатия кнопки Сортировать (btnsort). Вид формы при проектировании показан на рис. 7.1.


Глава 7. Навигационный доступ к данным с помощью BDE


171


В связи с тем, что компоненты Table и DataSource являются невизуальными и при выполнении приложения не видны, их можно размещать в любом удоб­ном месте формы, где они не мешают другим компонентам. Часто компоненты Table и DataSource помещаются на компоненте DBGrid, как это сделано в рассматриваемом примере.

Ниже приводится обработчик события нажатия кнопки btnSort, вызывающей выполнение сортировки.

procedure TForml.btnSortClick(Sender: TObject);

begin

case RadioGroupl.Itemlndex of

0: Tablel.IndexName:= 'indName';

1: Tablel.IndexName:= 'indBirthDay';

2: Tablel.IndexName:=

end;

case RadioGroup2.Itemlndex of

0: Tablel.IndexDefs

[Tablel.IndexDefs.IndexOf(Tablel.IndexName)].Options:=

Tablel.IndexDefs

[Tablel.IndexDefs.IndexOf(Tablel.IndexName)].Options +

[ixDescending];

1: Tablel.IndexDefs

[Tablel.IndexDefs.IndexOf(Tablel.IndexName)].Options:=

Tablel.IndexDefs

[Tablel.IndexDefs.IndexOf(Tablel.IndexName)].Options -

[ixDescending];

end;

end;

Поля, по которым сортируются записи, устанавливаются через свойство IndexName. При отсутствии сортировки этому свойству присваивается пустая строка. Для таблиц Paradox это означает сортировку по первому полю. Для таб­лиц dBase записи располагаются в порядке их поступления в файл таблицы.

Управление направлением сортировки осуществляется с помощью параметра ixDescending текущего индекса. Для определения номера текущего индекса в списке IndexDefs используется метод IndexOf.

Навигация по набору данных

Навигация по набору данных заключается в управлении указателем текущей за­писи (курсором). Этот указатель определяет запись, с которой будут выполняться такие операции, как редактирование или удаление.


172


Часть II. Технологии доступа к данным


Перемещение по записям

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

Для перемещения указателя текущей записи в наборе данных используются сле­дующие методы:

□ процедура First — установка на первую запись;

□ процедура Next — установка на следующую запись (при вызове метода для последней записи указатель не перемещается);

□ процедура Last — установка на последнюю запись;

□ процедура Prior — установка на предыдущую запись (при вызове метода для первой записи указатель не перемещается);

□ функция MoveBy (Distance: Integer): Integer — перемещение на число записей, определяемое параметром Distance. Если его значение больше ну­ля, то перемещение осуществляется вперед, если меньше нуля — то назад. При нулевом значении параметра указатель не перемещается. Если заданное параметром Distance число записей выходит за начало или конец набора данных, то указатель устанавливается на первую или на последнюю запись. В качестве результата возвращается число записей, на которое переместился указатель.

При перемещении указателя текущей записи учитываются ограничения и фильтр, определенные для набора данных. Таким образом, перемещение выполняется по записям набора данных, которые он содержит в текущий момент времени. Чис­ло записей определяется свойством RecordCount.

Значения указателя текущей записи изменяют также методы, связанные с поис­ком записей, например, метод FindFirst. Они рассматриваются ниже в этой главе.

(Замечание^

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

Рассмотрим следующий пример:

procedure TForml.Button3Click(Sender: TObject); var s: real;

n: integer; begin s = 0;


Глава 7. Навигационный доступ к данным с помощью BDE


173


// Установка текущего указателя на первую запись

Tablel.First;

for n:= 1 to Tablel.RecordCount do begin

s:= s + Tablel.FieldByName('Salary').AsFloat;

// Перемещение текущего указателя на следующую запись

Tablel.Next;

end; Label2.Caption:= FloatToStr(s); end;

В приведенной процедуре перебираются все записи набора данных Tablel, при этом в переменной s накапливается сумма значений, содержащихся в поле Salary. Перебор записей осуществляется с помощью метода Next, вызываемого в цикле. Предварительно с помощью метода First указатель устанавливается на первую запись. После выполнения кода указатель будет установлен на по­следнюю запись.

Отметим, что используемая для перебора записей переменная п имеет тип integer, совпадающий с типом longint свойства RecordCount.

Аналогичным образом можно перебрать все записи набора данных, начиная с последней. Естественно, при этом нужно вызывать методы Last и Prior.

Для контроля положения указателя текущей записи можно использовать свойст­во RecNo, которое содержит номер записи, считая от начала набора данных (для локальных таблиц dBase и Paradox).

Для таблиц Paradox свойство RecNo можно использовать еще и для перехода к записи с известным номером: такой переход выполняется установкой свойства RecNo в значение, равное номеру нужной записи. Например:

procedure TForml.ButtonlClick(Sender: TObject);

begin

Tablel.RecNo:= StrToInt(Editl.Text);

end;

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

Для определения начала и конца набора данных при перемещении указателя те­кущей записи можно использовать свойства bof и eof типа Boolean соответст­венно. Эти свойства доступны для чтения при выполнении приложения. Свой­ство bof показывает, находится ли указатель на первой записи набора данных. Этому свойству присваивается значение True при установке указателя на первой записи, например, сразу после вызова метода First. Свойство eof показывает, находится ли указатель на последней записи набора данных. Этому свойству устанавливается значение True при размещении указателя на последней записи.


174


Часть II. Технологии доступа к данным


(_____ ЗамечаниеJ

Для пустого набора данных свойства BOF и EOF имеют значения True.

При изменении порядка сортировки или фильтрации, а также при удалении или до­бавлении записей значения свойств BOF и EOF могут изменяться. Например, если направление сортировки изменяется на противоположное, то первая запись стано­вится последней.

При работе с таблицами одновременно нескольких приложений, когда постоянно до­бавляются или удаляются записи, значения свойств bof и eof соответствуют дей­ствительному состоянию набора данных в определенные моменты времени. Так, свойство EOF устанавливается в значение True сразу после выполнения метода Last. Если после этого другим приложением в конец набора данных добавлена но­вая запись, то значение свойства EOF становится неправильным.

Рассмотрим еще один пример, иллюстрирующий работу с указателем текущей записи:

procedure TForml.Button2Click(Sender: TObject);

var s: real;

begin

s:= 0;

Tablel.First;

while not Tablel.EOF do begin

s:= s + Tablel.FieldByName('Salary').AsFloat;

Tablel.Next;

end; s:= s + Tablel.FieldByName('Salary').AsFloat; Label2.Caption:= FloatToStr(s); end;

Как и в предыдущем примере, здесь перебираются все записи набора данных Tablel и подсчитывается сумма значений, содержащихся в поле Salary. Отли­чие заключается в том, что использован итерационный цикл с верхним оконча­нием, условием выхода из которого является достижение последней записи на­бора данных.

Иногда в цикле выполняются сложные действия. При этом на перебор записей набора данных может потребоваться достаточно большое время, в течение кото­рого приложение (и компьютер) не реагирует на команды пользователя. Поэто­му в циклы, надолго загружающие работой компьютер, рекомендуется вставлять вызов метода Application. ProcessMessages, обеспечивающий системе Windows возможность обрабатывать сообщения. Кроме того, программист дол­жен предусмотреть досрочный выход из длительного цикла, например, с помо­щью переменной-признака.

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


Глава 7. Навигационный доступ к данным с помощью BDE


175


При перемещении по записям набора данных связанные с ним визуальные ком­поненты отображают изменения данных, причем смена отображения может происходить достаточно быстро, вызывая неприятное мелькание на экране. Чтобы избежать этого эффекта, можно программно до начала цикла перебора записей временно отключить набор данных от всех связанных с ним визуальных компонентов, а по окончании цикла снова подключить. Для этого предназначе­ны методы DisableControls и EnableControls.

Рассмотрим следующий пример. Пусть в цикле перебираются все записи набора данных Table 1, начиная с первой, и подсчитывается сумма значений, содержа­щихся в поле salary. Для запуска и остановки процесса расчета используются кнопки Начать (btnworkstart) и Прервать (btnWorkBreak). Поле индикатора ProgressBarl служит для показа хода работы, а процент перебранных записей отображается в надписи lblWorkPercent, находящейся рядом с индикатором. На рис. 7.2 показан вид формы во время выполнения приложения.

Код модуля приведенной на рис. 7.2 формы имеет вид:

unit uNavig; interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Db, DBTables, Grids, DBGrids, StdCtrls, ExtCtrls, DBCtrls, ComCtrls;

type

TForml = class(TForm)

 

btnClose: TButton;
DataSourcel: TDataSource;
Tablel: TTable;
DBGridl: TDBGrid;
Panell: TPanel;
ProgressBarl: TProgressBar;
btnWorkStart: TButton;
btnWorkBreak: TButton;
Labell: TLabel;
lblWorkPercent: TLabel;
lblSum: TLabel;

procedure btnCloseClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure btnWorkStartClick(Sender: TObject); procedure btnWorkBreakClick(Sender: TObject);


176


Часть II. Технологии доступа к данным


private

{ Private declarations } public

{ Public declarations }

end; var Forml: TForml;

WorkBreak: boolean;

implementation

{$R *.DFM}

procedure TForml.FormCreate(Sender: TObject); begin

btnWorkStart.Enabled:= True; btnWorkBreak.Enabled: = False; WorkBreak:= False; end;

procedure TForml.btnWorkStartClick(Sender: TObject);

label 10;

var s: real;

begin

btnWorkStart.Enabled:= False;

btnWorkBreak.Enabled:= True;

s:= 0;

ProgressBarl.Max:= Tablel.RecordCount;

Tablel.DisableControls;

Tablel.First;

while not Tablel.EOF do begin

s:= s + Tablel.FieldByName('Salary').AsFloat;

// Без этого вызова не будет обрабатываться нажатие кнопки // btnWorkBreak

Application.ProcessMessages;

ProgressBarl.Position:= Tablel.RecNo;

lblWorkPercent.Caption:=

IntToStr(Round(ProgressBarl.Position/ProgressBarl.Max*100)) +

if WorkBreak then goto 10;

Tablel.Next;

end; lblSum.Caption:= 'Итого ' + FloatToStr(s); 10: Tablel.EnableControls;


Глава 7. Навигационный доступ к данным с помощью BDE


177


ProgressBarl.Position:= 0; lblWorkPercent.Caption:= ''; btnWorkStart.Enabled: = True; btnWorkBreak.Enabled: = False; WorkBreak:= False; end;

procedure TForial.btnWorkBreakClick(Sender: TObject) begin

WorkBreak: = True; end;

procedure TForml.btnCloseClick(Sender: TObject); begin Close; end;

end.

Рис. 7.2. Форма приложения, выполняющего перебор записей набора данных

Цикл обработки запускается нажатием кнопки btnWorkStart. Перед началом цикла определяется максимальное значение индикатора ProgressBarl, перемен­ная WorkBreak устанавливается в False, а визуальные компоненты отключаются от набора данных Tablel. В цикле происходит подсчет суммы, а также отображе­ние хода выполнения работ в поле индикатора ProgressBarl и надписи lblWorkPercent. По окончании цикла результат отображается в надписи lblSum, и визуальные компоненты снова подключаются к набору данных Tablel.


178


Часть II. Технологии доступа к данным


Для прерывания обработки служит кнопка btnWorkBreak, при ее нажатии пе­ременная-признак WorkBreak принимает значение True. Значение этой пере­менной проверяется в цикле обработки, и если оно равно True, то цикл пре­кращается путем вызова процедуры Break. Чтобы при выполнении цикла обрабатывались событие нажатия кнопки btnWorkBreak и другие события, в цикл включен вызов метода ProcessMessages.

При любом изменении положения указателя текущей записи для набора данных генерируются события BeforeScroll и AfterScroll типа TDataSetNotifyEvent.

Пользователь имеет возможность перемещаться по набору данных с помощью элементов управления, в качестве которых часто используются компоненты DBGrid и DBNavigator. Управление этими элементами с помощью мыши или клавиатуры приводит к автоматическому вызову соответствующих методов, пе­ремещающих указатель текущей записи в заданное место. Например, после на­жатия кнопкок First record, Prior record, Next record или Last record компонента DBNavigatorl косвенно вызываются методы First, Prior, Next или Last, пе­ремещающие указатель текущей записи соответственно на первую, предыдущую, следующую или последнюю записи набора данных, с которым связан (через ис­точник данных DataSource) компонент DBNavigatorl.

Другим вариантом является размещение в форме элементов управления, напри­мер, кнопки Button, предназначенных для навигации по набору данных. Кроме того, часто в форме также размещаются элементы (обычно кнопки) для управ­ления такими операциями, как редактирование, вставка записей, фильтрация и сортировка набора данных.

Рассмотрим в качестве примера форму приложения, в которой осуществляется перемещение по набору данных с помощью пяти кнопок (рис. 7.3). При нажа­тии какой-либо из этих кнопок вызывается соответствующий метод перемеще­ния текущего указателя в заданном направлении. Например, при нажатии кноп­ки Предыдущая запись (btnPrior) вызывается метод Prior. При перемещении указателя на произвольное число записей дополнительно используется обрат­ный счетчик SpinEditl, в поле которого вводится это число.

Код модуля uNavig2 рассматриваемой формы приложения имеет следующий вид:

unit uNavig2;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, DBGrids, Db, DBTables, Spin;

type

TForml = class(TForm)

DataSourcel: TDataSource; Queryl: TQuery;


Глава 7. Навигационный доступ к данным с помощью BDE


179


DBGridl: TDBGrid;

btnFirst: TButton;

btnNext: TButton;

btnPrior: TButton;

btnLast: TButton;

lblRecord: TLabel;

btnMoveBy: TButton;

SpinEditl: TSpinEdit;

procedure FormCreate(Sender: TObject); procedure btnFirstClick(Sender: TObject); procedure btnNextClick(Sender: TObject); procedure btnPriorClick(Sender: TObject); procedure btnLastClick(Sender: TObject); procedure QuerylAfterScroll(DataSet: TDataSet) procedure btnMoveByClick(Sender: TObject);

private

{ Private declarations } public

{ Public declarations }

end;

var

Forml: TForml;

implementation

{$R *.DFM}

procedure TForml.FormCreate(Sender: TObject); begin

// Набор данных является редактируемым Queryl.RequestLive:= True; Queryl.Close; Queryl.SQL.Clear;

Queryl.SQL.Add('SELECT * FROM Goods.db'); Que г у 1. Open; SpinEditl.Value:= 0; end;

// Переход на первую запись

procedure TForml.btnFirstClick(Sender: TObject);


180


Часть II. Технологии доступа к данным


begin

Queryl.First; end;

// Переход к следующей записи

procedure TForml.btnNextClick(Sender: TObject); begin

Queгу1.Next; end;

// Переход к предыдущей записи

procedure TForml.btnPriorClick(Sender: TObject); begin

Queryl.Prior; end;

// Переход на последнюю запись

procedure TForml.btnLastClick(Sender: TObject); begin

Queryl.Last; end;

// Перемещение на число записей, заданное в счетчике SpinEditl procedure TForml.btnMoveByClick(Sender: TObject); begin

Queryl.MoveBy(SpinEditl.Value); end;

// Вывод номера записи и пересчет границ счетчика procedure TForml.QuerylAfterScroll(DataSet: TDataSet); begin

lblRecord.Caption:= 'Запись номер ' + IntToStr(Queryl.RecNo); SpinEditl.MinValue:= 1 - Queryl.RecNo;

SpinEditl.MaxValue:= Queryl.RecordCount - Queryl.RecNo; end;

end.

Сразу после того, как положение указателя изменилось, в надписи lblRecord выводится номер текущей записи в наборе данных. Пересчитываются мини­мальное и максимальное значения обратного счетчика, определяющие диапазон допустимых значений, указываемых при вызове метода MoveBy. Эти действия кодируются в обработчике события OnAfterScroll для того, чтобы информа­ция о текущей записи обновлялась сразу после перемещения текущего указате­ля. Событие OnAfterScroll происходит также при открытии набора данных, когда указатель текущей записи устанавливается на первую запись.


Глава 7. Навигационный доступ к данным с помощью BDE


181


Рис. 7.3. Форма приложения, в которой осуществляется перемещение по набору данных

В качестве набора данных использован компонент Queryl, задание основных свойств которого выполняется при создании формы. SQL-запрос (select * from Goods. db) указан в свойстве SQL. Он обеспечивает получение всех полей и записей таблицы Goods.db. Свойство RequestLive установлено в значение True, чтобы обеспечить возможность редактирования набора данных. Таким образом, в рассмотренном примере компонент Query практически не отличается от компонента Table в плане работы с редактируемым набором данных, связан­ным с одной таблицей.

Иногда при подключении к одной таблице нескольких наборов данных возни­кает необходимость синхронизации их текущих указателей. Для этих целей ис­пользуется метод GotoCurrent (Table: TTable), устанавливающий указатель на текущую запись в наборе данных Table. Например:

Tablel.GotoCurrent(Table2);

Здесь в наборе данных Tablel текущий указатель устанавливается на запись, которая является текущей в наборе данных ТаЫе2.

Переход по закладкам

Побочным эффектом выполнения ряда операций с наборами данных является изменение положения указателя текущей записи. Часто этот эффект нежелате­лен, т. к. после выполнения такой операции указатель находится не в том месте, где был до начала операции. При этом приходится снова отыскивать нужную запись и позиционировать на ней указатель, что неудобно даже при небольшом количестве записей.

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


182


Часть II. Технологии доступа к данным


(_____ ЗамечаниеJ

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

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

Переход на определенную запись может понадобиться также для позициониро­вания указателя на запись, информация о которой была сохранена. Осуществ­ляемые при этом действия не отличаются от указанных выше. Информация, необходимая для выполнения последующего перехода к требуемой записи, мо­жет запоминаться предварительно в удобный момент, например, при просмотре или редактировании записи.

Вот пример, иллюстрирующий, как восстановить положение текущего указателя:

var RecordNumber: integer;

// Запоминание номера текущей записи RecordNumber:= Queryl.RecNo;

// Операция, изменяющая положение указателя

// Переход к записи с запомненным номером

Queryl.First;

Queryl.MoveBy(RecordNumber - 1);

Здесь для перемещения текущего указателя используется номер записи, запоми­наемый в переменной RecordNumber.

В таблицах Paradox для возврата к записи можно установить свойство RecNo набора данных в предварительно сохраненное значение. Например:

var RecordNumber: integer;

// Запоминание номера текущей записи RecordNumber:= Tablel.RecNo;

// Операция, изменяющая положение указателя

// Переход к записи с запомненным номером Tablel.RecNo:= RecordNumber;

Вопросы, связанные с поиском записей, рассматриваются в данной главе ниже.


Глава 7. Навигационный доступ к данным с помощью BDE


183


Кроме описанных способов, для перехода на определенную запись можно использовать закладки — специальные пометки каких-либо записей. Закладка имеет тип TBookmark, представляющий собой обычный указатель Pointer, с помощью которого можно ссылаться на различные объекты, в данном случае — на записи набора данных.

Перед использованием закладку нужно создать, т. е. определить запись, с кото­рой эта закладка связана. Для этого предназначена функция GetBookmark: TBookmark, которая создает закладку на текущей записи набора данных. Воз­вращаемую закладку обычно запоминают в переменной типа TBookmark и впо­следствии используют для перехода к помеченной ею записи.

Иногда закладка может неверно указывать позицию связанной с ней записи, при этом говорят о нестабильности закладки. Стабильность закладки в значительной степени зависит от форматов таблиц. Так, для таблиц dBase закладка всегда ста­бильна; для таблиц Paradox закладка стабильна, если у таблицы определен глав­ный ключ. Таким образом, закладка устойчиво указывает на связанную с ней за­пись в тех случаях, когда существует признак, позволяющий однозначно различать записи. В противном случае закладка может быть нестабильной и ошибочно ука­зывать на другую запись набора данных. Для проверки стабильности закладки ис­пользуется функция DBlGetCursorProps (модуль DBE).



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: