Dynamically creating a TTable & fields at runtime - by Borland Developer Support Staff
Technical Information Database
TI1467D.txt - Dynamically creating a TTable & fields at runtime
Category :Database Programming
Platform :All-32Bit
Product :All32Bit,
Description:
Delphi allows rapid addition and configuration of database
elements to a Delphi project within the design environment, but
there are situations where information needed to create and
configure objects is not known at design time. For instance, you
may want to add the ability to add columns of calculated values
(using formulas of the users own creation) to an application at
runtime. So without the benefit of the design environment,
Object Inspector, and TFields editor, how do you create and
configure TFields and other data related components
programmatically?
The following example demonstrates dynamically creating a TTable,
a database table based off the TTable, TFieldDefs, TFields,
calculated fields, and attaches an event handler to the OnCalc
event.
To begin, select New Application from the File menu. The entire
project will be built on a blank form, with all other components
created on-the-fly.
In the interface section of your forms unit, add an OnCalcFields\
event handler, and a TaxAmount field to the form declaration,
as shown below.
Later we will create a TTable and hook this handler to the TTable's
OnCalcFields event so that each record read fires the OnCalcFields
event and in turn executes our TaxAmountCalc procedure.
type
TForm1 = class(TForm)
procedure TaxAmountCalc(DataSet: TDataset);
private
TaxAmount: TFloatField;
end;
In the implementation section add the OnCalc event handler as
shown below.
procedure TForm1.TaxAmountCalc(DataSet: TDataset);
begin
Dataset['TaxAmount'] := Dataset['ItemsTotal'] *
(Dataset['TaxRate'] / 100);
end;
Create a OnCreate event handler for the form as shown below (for
more information on working with event handlers see the Delphi
Users Guide, Chapter 4 "Working With Code").
procedure TForm1.FormCreate(Sender: TObject);
var
MyTable: TTable;
MyDataSource: TDataSource;
MyGrid: TDBGrid;
begin
{ Create the TTable component -- the underlying
database table is created later. }
MyTable := TTable.Create(Self);
with MyTable do
begin
{ Specify an underlying database and table.
Note: Test.DB doesn't exist yet. }
DatabaseName := 'DBDemos';
TableName := 'Test.DB';
{ Assign TaxAmountCalc as the event handler to
use when the OnCalcFields event fires for
MyTable. }
OnCalcFields := TaxAmountCalc;
{ Create and add field definitions to the TTable's
FieldDefs array, then create a TField using the
field definition information. }
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%';
{ Create a calculated TField, assign properties,
and add to MyTable's field definitions array. }
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;
{ Create the new database table using MyTable as
a basis. }
MyTable.CreateTable;
end;
{ Create a TDataSource component and assign
to MyTable. }
MyDataSource := TDataSource.Create(Self);
MyDataSource.DataSet := MyTable;
{ Create a data aware grid, display on the
form, and assign MyDataSource to access
MyTable's data. }
MyGrid := TDBGrid.Create(Self);
with MyGrid do
begin
Parent := Self;
Align := alClient;
DataSource := MyDataSource;
end;
{ Start your engines! }
MyTable.Active := True;
Caption := 'New table ' + MyTable.TableName;
end;
The following is the full source for the project.
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 := 'New table ' + MyTable.TableName;
end;
end.
Reference:
3/31/99 10:20:34 AM