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

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

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.

{/codecitation}

Добавить комментарий