- - * - WhiteUnicorn - * - -




* #WhiteUnicorn/ StartPage/ Documentation/DelphiFAQ >


3171:Dynamically creating a TTable & fields at runtime

KEYWORDS: TTable, Calculated Fields, Table, creation, runtime AREA: Applicatio

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.

        TI



* #WhiteUnicorn/ StartPage/ Documentation/DelphiFAQ >



- - * - Anastasija aka WhiteUnicorn - * - - LJLiveJournal
PFPhotoFile