Использование TDataSource для проверки состояния БД:
TDataSource имеет три ключевых события, связанных с состоянием БД
OnDataChange
OnStateChange
OnUpdateData
OnDataChange происходит всякий раз, когда Вы переходите на новую запись, или состояние DataSet сменилось с dsInactive на другое, или начато редактирование. Другими словами, если Вы вызываете Next, Previous, Insert, или любой другой запрос, который должен привести к изменению данных, связанных с текущей записью, то произойдет событие OnDataChange. Если в программе нужно определить момент, когда происходит переход на другую запись, то это можно сделать в обработчике события OnDataChange:
procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin
if DataSource1.DataSet.State = dsBrowse then begin
DoSomething;
end;
end;
Событие OnStateChange событие происходит всякий раз, когда изменяется текущее состояние DataSet. DataSet всегда знает, в каком состоянии он находится. Если Вы вызываете Edit, Append или Insert, то TTable знает, что он теперь находится в режиме редактирования (dsEdit или dsInsert). Аналогично, после того, как Вы делаете Post, то TTable знает что данные больше не редактируется, и переключается обратно в режим просмотра (dsBrowse).
Dataset имеет шесть различных возможных состояний, каждое из которых включено в следующем перечисляемом типе:
TDataSetState = (dsInactive, dsBrowse, dsEdit, dsInsert,
dsSetKey, dsCalcFields);
В течение обычного сеанса работы, БД часто меняет свое состояние между Browse, Edit, Insert и другими режимами. Если Вы хотите отслеживать эти изменения, то Вы можете реагировать на них написав примерно такой код:
procedure TForm1.DataSource1StateChange(Sender: TObject);
var
S: String;
begin
case Table1.State of
dsInactive: S := 'Inactive';
dsBrowse: S := 'Browse';
dsEdit: S := 'Edit';
dsInsert: S := 'Insert';
dsSetKey: S := 'SetKey';
dsCalcFields: S := 'CalcFields';
end;
Label1.Caption := S;
end;
OnUpdateData событие происходит перед тем, как данные в текущей записи будут обновлены. Например, OnUpdateEvent будет происходить между вызовом Post и фактическим обновлением информации на диске.
События, генерируемые TDataSource могут быть очень полезны. Иллюстрацией этого служит следующий пример. Эта программа работает с таблицей COUNTRY, и включает TTable, TDataSource, пять TEdit, шесть TLlabel, восемь кнопок и панель. Действительное расположение элементов показано на рис.11. Обратите внимание, что шестой TLabel расположен на панели внизу главной формы.
Рис.11: Программа STATE показывает, как отслеживать текущее состояние таблицы.
Для всех кнопок напишите обработчики, вроде:
procedure TForm1.FirstClick(Sender: TObject);
begin
Table1.First;
end;
В данной программе есть одна маленькая хитрость, которую Вы должны понять, если хотите узнать, как работает программа. Так как есть пять отдельных редакторов TEdit на главной форме, то хотелось бы иметь некоторый способ обращаться к ним быстро и легко. Один простой способ состоит в том, чтобы объявить массив редакторов:
Edits: array[1..5] of TEdit;
Чтобы заполнить массив, Вы можете в событии OnCreate главной формы написать:
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
for i := 1 to 5 do
Edits[i] := TEdit(FindComponent('Edit' + IntToStr(i)));
Table1.Open;
end;
Код показанный здесь предполагает, что первый редактор, который Вы будете использовать назовем Edit1, второй Edit2, и т.д. Существование этого массива позволяет очень просто использовать событие OnDataChange, чтобы синхронизировать содержание объектов TEdit с содержимом текущей записи в DataSet:
procedure TForm1.DataSource1DataChange(Sender: TObject;
Field: TField);
var
i: Integer;
begin
for i := 1 to 5 do
Edits[i].Text := Table1.Fields[i - 1].AsString;
end;
Всякий раз, когда вызывается Table1.Next, или любой другой из навигационных методов, то будет вызвана процедура показанная выше. Это обеспечивает то, что все редакторы всегда содержат данные из текущей записи.
Всякий раз, когда вызывается Post, нужно выполнить противоположное действие, то есть взять информацию из редакторов и поместить ее в текущую запись. Выполнить это действие, проще всего в обработчике события TDataSource.OnUpdateData, которое происходит всякий раз, когда вызывается Post:
procedure TForm1.DataSource1UpdateData(Sender: TObject);
var
i: Integer;
begin
for i := 1 to 5 do
Table1.Fields[i - 1].AsString := Edits[i].Text;
end;
Программа будет автоматически переключатся в режим редактирования каждый раз, когда Вы вводите что-либо в одном из редакторов. Это делается в обработчике события OnKeyDown (укажите этот обработчик ко всем редакторам):
procedure TForm1.Edit1KeyDown(Sender: TObject;
var Key: Word; Shift: TShiftState);
begin
if DataSource1.State <> dsEdit then
Table1.Edit;
end;
Этот код показывает, как Вы можете использовать св-во State DataSource, чтобы определить текущий режим DataSet.
Обновление метки в статусной панели происходит при изменении состояния таблицы:
procedure TForm1.DataSource1StateChange(Sender: TObject);
var
s : String;
begin
case DataSource1.State of
dsInactive : s:='Inactive';
dsBrowse : s:='Browse';
dsEdit : s:='Edit';
dsInsert : s:='Insert';
dsSetKey : s:='SetKey';
dsCalcFields : s:='CalcFields';
end;
Label6.Caption:=s;
end;
Данная программа является демонстрационной и ту же задачу можно решить гораздо проще, если использовать объекты TDBEdit.