Delphi: использование TClientDataset в качестве набора данных в памяти - PullRequest
20 голосов
/ 08 ноября 2008

Согласно этой странице, можно использовать TClientDataset как набор данных в памяти, полностью независимый от любых реальных баз данных или файлов. Он описывает, как настроить структуру таблицы набора данных и как загрузить в нее данные во время выполнения. Но когда я попытался следовать его инструкциям в D2009, шаг 4 (table.Open) вызвал исключение. Он сказал, что у него не указан провайдер.

Весь смысл примера на этой странице - создать набор данных, который не нуждается в поставщике. Страница неправильная, устарела или я что-то пропустил? И если страница неправильная, что мне нужно использовать для создания полностью независимого набора данных в памяти? Я использовал TJvMemoryData, но, если возможно, я бы хотел уменьшить количество дополнительных зависимостей, которые мой набор данных добавляет в мой проект.

Ответы [ 11 ]

21 голосов
/ 08 ноября 2008

Во время выполнения вы можете использовать table.CreateDataset или, если это находится в области проектирования, вы можете щелкнуть правой кнопкой мыши на CDS и выбрать Создать набор данных. Вы должны иметь определенные столбцы / типы для CDS, прежде чем вы сможете сделать это.

20 голосов
/ 08 ноября 2008

Если это поможет в дальнейшем, вот фрагмент кода, в котором я создал ClientDataset, который используется в качестве таблицы в памяти:

procedure TfrmPRMain.ConfigureDataset;
begin
  With cdsMain do begin
    FieldDefs.Add('bDelete', ftBoolean);
    FieldDefs.Add('sSource', ftString, 10);
    FieldDefs.Add('iSection', ftInteger);
    FieldDefs.Add('iOrder', ftInteger);
    FieldDefs.Add('sBranch', ftString, 10);
    FieldDefs.Add('sPulseCode', ftString, 10);
    FieldDefs.Add('sCode', ftString, 10);
    FieldDefs.Add('dtWorkDate', ftDate);
    FieldDefs.Add('iWorkWeek', ftInteger);
    FieldDefs.Add('sName', ftString, 50);
    CreateDataSet;
    LogChanges := False;
    Open;
  end;
end;

Вы можете просто подставить свои собственные данные и перейти. Jack

8 голосов
/ 17 ноября 2008

Не забудьте включить MIDAS.DLL в вашу установку или просто включить MidasLib в пункте использования. В противном случае использование TClientDataSet вызовет ошибку на компьютере клиента. Может быть, это очевидно, но я действительно однажды забыл это.

7 голосов
/ 08 ноября 2008

Вы можете использовать table.CreateDataSet

5 голосов
/ 09 ноября 2008

Код с этой страницы не работает в ЛЮБОЙ версии Delphi. Вызов CreateDataSet уже переводит набор данных в активное состояние («открыто»). Вы должны использовать .CreateDataSet ИЛИ .Open. Не оба.

Используйте .Open, если вы хотите извлечь данные из Provider (через свойство ProviderName), и .CreateDataSet, если вы хотите заполнить набор данных самостоятельно.

Кстати: для более подробной информации о ClientDataSets и его функциях, посмотрите превосходные статьи Кэри Дженсена о сети разработчиков CodeGear (сначала прочитайте самые старые)

3 голосов
/ 26 мая 2009

Если вам нужен набор данных в памяти без зависимостей, высокое качество и богатые функциональные возможности (не говоря уже о бесплатном!), Я настоятельно рекомендую kbmMemTable . Делает все, что делает TClientDataset, а затем некоторые.

1 голос
/ 12 октября 2011

Камни кладбища ниже для некоторых компонентов libre

Во времена Delphi 5 / Delphi 7 были инициативы по превращению любого объекта с опубликованными свойствами (точнее - массива или некоторого набора из них) в базу данных. На Torry.net это CollectionDataSet и Object DataSet За годы до LINQ и тому подобное. Но так как код DB-VCL мало документирован и является спагетти начиная с 16-битной Delphi 1.0 - у них нет разработки.

Существует также основанный на обратном вызове (основанный на событиях) набор объектов Snap Object, не слишком устаревший. Хотя это оставляет слишком много ИМХО на плечах разработчиков.

Таблица TDBF.sf.net работала в оперативной памяти, но была ранее удалена. TDBF тоже мертв.

rxLib / JediVCL имеет набор данных Memory. Хотя целью rxLib была совместимость на уровне исходного кода, начиная с 16-битной Delphi 1 до Delphi 5. Это сильно подорвало код. В JVCL было некоторое внимание и удаление устаревшего кода, но он все еще наполовину испечен, когда нужно немного глубже, чем обычное использование.

Существуют также бесплатные компоненты DCU, такие как SQLMemoryTable, но не для последних выпусков. Интересно, можно ли использовать Firebird Embedded / SQLite для создания таблицы в памяти без использования системных хаков, таких как RAMdrive: -)

1 голос
/ 19 апреля 2009

по какой-то причине это не работает для меня. Я выполняю CreateDataset во время разработки, но приложение по-прежнему вылетает. Это все еще неизвестно для меня. Одно предупреждение. НЕ ДЕЛАЙТЕ ЭТОГО:

XXXClientDataSet.Close;
XXXClientDataSet.Open;

потому что он сообщит об ошибке. Вместо Open используйте

xxxClientDataSet.CreateDataset;

В моем приложении мне нужно было сбросить данные и загрузить их снова, и это снова вызвало сообщение об ошибке.

0 голосов
/ 17 мая 2014

Для меня это было вызвано несоответствием midas.dll. Я исправил это, добавив MidasLib в пункт использования основной программы (таким образом, статически связывая библиотеку). Больше информации здесь: http://codeverge.com/embarcadero.datasnap/tclientdataset-createdataset-failing-wit/1097715 и здесь: http://edn.embarcadero.com/article/29297

0 голосов
/ 02 мая 2013

Это исправленный рабочий код, упомянутый ОП в первом посте. Вы получаете таблицу памяти из TClientDataset, показанного в DBGrid.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBClient, Grids, DBGrids, StdCtrls, MidasLib;

type
  TForm1 = class(TForm)
    MemTable: TClientDataSet;
    Button1: TButton;
    Button2: TButton;
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  i: word;
begin
  MemTable.DisableControls;
  for i := 1 to 20000 do
  begin
    MemTable.Append;
    MemTable.FieldByName('ID').AsInteger       := i;
    MemTable.FieldByName('Status').AsString    := 'Code'+IntToStr(i);
    MemTable.FieldByName('Created').AsDateTime := Date();
    MemTable.FieldByName('Volume').AsFloat     := Random(10000);
    MemTable.Post;
  end;
  MemTable.EnableControls;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  MemTable.IndexFieldNames := 'Volume';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MemTable.FieldDefs.Add('ID',      ftInteger, 0, False);
  MemTable.FieldDefs.Add('Status',  ftString, 10, False);
  MemTable.FieldDefs.Add('Created', ftDate,    0, False);
  MemTable.FieldDefs.Add('Volume',  ftFloat,   0, False);
  MemTable.CreateDataSet;
end;

end.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...