Следующая статья: Динамическое создание компонента TTable.
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;
aption :='Новая таблица'+MyTable.TableName;
end;
end.