Динамическое создание таблицы и полей во время выполнения программы
Delphi в режиме разработки позволяет быстро добавлять и
настраивать в вашем проекте компоненты для работы с базами данных, но есть
ситуации, когда вам нужно создавать и конфигурировать объекты во время
выполнения программы. Например, во время выполнения программы вам может
понадобиться добавить колонку с вычисляемым полем (используя алгоритмы
пользователя). Поэтому вопрос: как, не используя среды разработки, Инспектора
Объектов и редактора TFields, создавать и сконфигурировать TField и другие
компоненты для связки данных?
В следующем примере показано динамическое создание TTable, таблицы базы
данных в связке с TTable, TFieldDefs, TFields, вычисляемых полей и подключение
обработчика для события OnCalc.
Для начала выберите пункт New Application меню File. Будет создан новый
проект с пустой формой, на которой мы и будет создавать на лету наши компоненты.
В секцию interface вашего модуля формы добавьте, как показано ниже,
объявление обработчика события OnCalcFields и поля TaxAmount. Позже мы создадим
TTable и назначим этот обработчик событию TTable OnCalcFields, который позволит
при чтении каждой записи вызывать событие OnCalcFields, которое, в свою очередь,
выполнит нашу процедуру TaxAmountCalc.
type
TForm1 = class(TForm)
procedure TaxAmountCalc(DataSet: TDataset);
private
TaxAmount: TFloatField;
end;
|
В секции implementation создайте обработчик события OnCalc как показано
ниже:
procedure TForm1.TaxAmountCalc(DataSet: TDataset);
begin
Dataset['TaxAmount'] := Dataset['ItemsTotal'] *
(Dataset['TaxRate'] / 100);
end;
|
Создайте обработчик формы OnCreate как показано ниже (для получения
дополнительной информации о создании обработчиков событий обратитесь к Delphi
Users Guide, Chapter 4 "Working With Code").
procedure TForm1.FormCreate(Sender: TObject);
var
MyTable: TTable;
MyDataSource: TDataSource;
MyGrid: TDBGrid;
begin
{ Создаем компонент TTable -- связанная
таблица базы данных будет создана ниже. }
MyTable := TTable.Create(Self);
with MyTable do
begin
{ Определяем основную базу данных и таблицу.
Примечание: Test.DB пока не существует. }
DatabaseName := 'DBDemos';
TableName := 'Test.DB';
{ Назначаем TaxAmountCalc обработчиком события,
чтобы использовать его при наступлении события
OnCalcFields в MyTable. }
OnCalcFields := TaxAmountCalc;
{ Создаем и добавляем определения полей к массиву TTable
FieldDefs, затем создаем TField с использованием
информации из определения поля. }
with FieldDefs do
begin
Add('ItemsTotal', ftCurrency, 0, false);
FieldDefs[0].CreateField(MyTable);
Add('TaxRate', ftFloat, 0, false);
FieldDefs[1].CreateField(MyTable);
TFloatField(Fields[1]).DisplayFormat := '##.0%';
{ Создаем вычисляемое TField, назначаем свойства,
и добавляем поле к массиву определений MyTable. }
TaxAmount := TFloatField.Create(MyTable);
with TaxAmount do
begin
FieldName := 'TaxAmount';
Calculated := True;
Currency := True;
DataSet := MyTable;
Name := MyTable.Name + FieldName;
MyTable.FieldDefs.Add(Name, ftFloat, 0, false);
end;
end;
{ Создаем в базе данных новую таблицу,
используя в качестве основы MyTable. }
MyTable.CreateTable;
end;
{ Создаем компонент TDataSource
и назначаем его MyTable. }
MyDataSource := TDataSource.Create(Self);
MyDataSource.DataSet := MyTable;
{ Создаем табличную сетку, отображаем
на форме, и назначаем MyDataSource для
получения доступа к данным из MyTable. }
MyGrid := TDBGrid.Create(Self);
with MyGrid do
begin
Parent := Self;
Align := alClient;
DataSource := MyDataSource;
end;
{ Запускаем нашу конструкцию! }
MyTable.Active := True;
Caption := 'Новая таблица ' + MyTable.TableName;
end;
|
Ниже приведен полный исходный код проекта:
unit gridcalc;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, Grids, DBGrids, ExtCtrls, DBCtrls, DB,
DBTables, StdCtrls;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure TaxAmountCalc(DataSet: TDataset);
private
TaxAmount: TFloatField;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.TaxAmountCalc(DataSet: TDataset);
begin
Dataset['TaxAmount'] := Dataset['ItemsTotal'] *
(Dataset['TaxRate'] / 100);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
MyTable: TTable;
MyDataSource: TDataSource;
MyGrid: TDBGrid;
begin
MyTable := TTable.Create(Self);
with MyTable do
begin
DatabaseName := 'DBDemos';
TableName := 'Test.DB';
OnCalcFields := TaxAmountCalc;
with FieldDefs do
begin
Add('ItemsTotal', ftCurrency, 0, false);
FieldDefs[0].CreateField(MyTable);
Add('TaxRate', ftFloat, 0, false);
FieldDefs[1].CreateField(MyTable);
TFloatField(Fields[1]).DisplayFormat := '##.0%';
TaxAmount := TFloatField.Create(MyTable);
with TaxAmount do
begin
FieldName := 'TaxAmount';
Calculated := True;
Currency := True;
DataSet := MyTable;
Name := MyTable.Name + FieldName;
MyTable.FieldDefs.Add(Name, ftFloat, 0, false);
end;
end;
MyTable.CreateTable;
end;
MyDataSource := TDataSource.Create(Self);
MyDataSource.DataSet := MyTable;
MyGrid := TDBGrid.Create(Self);
with MyGrid do
begin
Parent := Self;
Align := alClient;
DataSource := MyDataSource;
end;
MyTable.Active := True;
Caption := 'Новая таблица ' + MyTable.TableName;
end;
end.
|
|