Телефон: +7 (926) 245-03-63

Динамическое создание таблицы и полей во время выполнения программы

Следующая статья: Динамическое создание компонента 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.
Интересное в интернете: детское бескаркасное кресло