Delphi World - Динамическое создание таблицы и полей во время выполнения программы
Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Динамическое создание таблицы и полей во время выполнения программы

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.

Проект Delphi World © Выпуск 2002 - 2017
Автор проекта: Эксклюзивные курсы программирования