Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Создать поле в открытом TClientDataset ?  [new]
V.Borzov
Member

Откуда: Саратов
Сообщений: 139
Здравствуйте!

Люблю TclientDataset, но не могу никак добиться создания поля в открытом наборе (созданном через CreateDataset, например). Как-то ковырялся в коде, пришел к умозаключению, что это в принципе невозможно из-за проверки на активность и выдаче ошибки в этом случае в функциях создания полей. Или ошибся? Кто-нибудь достигал каких-то в этом результатов? Интересует возможность создания хотя бы калькулируемых полей, про ftData уж и не заикаюсь...
.. на открытом датасете.
.. D7. может что-то в других версиях изменилось?
7 фев 09, 15:19    [6791795]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Джибс
Member

Откуда: 🐾🐾🐾🐾🐾🐾
Сообщений: 45860
А в чем смысл данного ?
7 фев 09, 15:21    [6791804]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Michael Longneck
Member

Откуда: Москва
Сообщений: 2262
А в чём проблема закрыть сначала?
7 фев 09, 15:21    [6791805]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
V.Borzov
Member

Откуда: Саратов
Сообщений: 139
Michael Longneck
А в чём проблема закрыть сначала?


закрыл - потерял данные.
7 фев 09, 15:26    [6791818]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
miksoft
Member

Откуда:
Сообщений: 36214
Мне с похожим вопросом помогли тут
7 фев 09, 15:28    [6791819]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381

> Автор: V.Borzov
> Здравствуйте!
>
> Люблю TclientDataset,

Напрасно. Есть In-Memory датасеты (если пользуетесь по этой причине). Не
забывайте, что приложение, использующее этот компонент, тянет за собой
MIDAS.DLL.

> но не могу никак добиться создания поля в открытом наборе (созданном через
> CreateDataset, например).

Задлянафига? Нельзя разве создать вычисляемое поле до открытия датасета?

Posted via ActualForum NNTP Server 1.4

7 фев 09, 15:28    [6791820]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
V.Borzov
Member

Откуда: Саратов
Сообщений: 139
Джибс
А в чем смысл данного ?


В том, что нужно для работы пару калькулируемых полей. или даже тройку. а данные получены из другого датасета, копированием, причем не вручную, когда создаешь сам поля + createdataset, а более-менее универсальным типа такого:

function ReadDataset(SourceDataset :TDataSet) :OleVariant;
var  dsp : TDatasetProvider;
begin
  Result := NULL;

  dsp := TDatasetProvider.Create(nil);
  try
     sourcedataset.DisableControls;
     try
       if sourcedataset.Active then sourcedataset.First; 
       dsp.DataSet := sourcedataset;
       result := dsp.data;
     finally
       SourceDataSet.EnableControls;
     end
   finally
     dsp.Free;
   end;
end;

Тут ничего не поделаешь, кроме как создать эти поля после копирования. До копирования создавать структуру тоже бесполезно.
7 фев 09, 15:31    [6791824]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Michael Longneck
Member

Откуда: Москва
Сообщений: 2262
Midas.dll можно и не брать - uses MidasLib

Другое дело, что все поля можно и заранее создать. Что собственно требуется?
7 фев 09, 15:33    [6791829]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381

> Автор: miksoft
> Мне с похожим вопросом помогли тут
>

Автор хочет не просто в рантайме, а на открытом датасете такое проделать.

Posted via ActualForum NNTP Server 1.4

7 фев 09, 15:34    [6791832]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
V.Borzov
Member

Откуда: Саратов
Сообщений: 139
Senya_L


Напрасно. Есть In-Memory датасеты (если пользуетесь по этой причине).


Главный ньюанс - скорость копирования из источника в этот датасет. пример привел выше. Пример работает мухой. все остальные, че видел - тупо копируют по полям перебором. Для образования пойдет, но в промышленности - не катит ИМХО. Все остальное и здесь катит прекрасно и быстро, вот только заданный вопрос в subj пока и смущает.

Senya_L


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



uses MidalLib


Senya_L

Задлянафига? Нельзя разве создать вычисляемое поле до открытия датасета?


Чуть выше привел пример.
7 фев 09, 15:35    [6791837]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
V.Borzov
Member

Откуда: Саратов
Сообщений: 139
miksoft
Мне с похожим вопросом помогли тут


Не, нам AdoQuery, совсем другой компонент, к тому же, исходное условие такое, что нет возможности сначала задать структуру, потом скопировать (если только не тупым перебором исходного датасета, что означает потерю скорости в разы или даже десятки раз по сравнению с тем примером, что я написал (readdataset).

В FibDataset, к примеру, даже есть CreateCalcField, точное название не помню. напрямую задачу решает, но у себя.
7 фев 09, 15:40    [6791845]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381

> Автор: V.Borzov
> Главный ньюанс - скорость копирования из источника в этот датасет.
> пример привел выше. Пример работает мухой. все остальные, че видел - тупо
> копируют по полям перебором. Для образования пойдет, но в промышленности -
> не катит ИМХО. Все остальное и здесь катит прекрасно и быстро, вот только
> заданный вопрос в subj пока и смущает.
>

У нас с Вами разные TClientDataSet. Дайте мне свой :)
Вообще-то этот компонент прожорливый, зараза. И по использованию пямяти, и
по сетевому трафику.

Posted via ActualForum NNTP Server 1.4

7 фев 09, 15:41    [6791846]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Michael Longneck
Member

Откуда: Москва
Сообщений: 2262
Заберите данные в один cds. Скопируйте поля (поля а не данные) в другой. Добавьте туда по вкусу вычисляемые. Потом через cds2.Data := cds1.Data передайте. В чём проблема не вижу.
7 фев 09, 15:54    [6791853]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
V.Borzov
Member

Откуда: Саратов
Сообщений: 139
Senya_L

> Автор: V.Borzov
> Главный ньюанс - скорость копирования из источника в этот датасет.
> пример привел выше. Пример работает мухой. все остальные, че видел - тупо
> копируют по полям перебором. Для образования пойдет, но в промышленности -
> не катит ИМХО. Все остальное и здесь катит прекрасно и быстро, вот только
> заданный вопрос в subj пока и смущает.
>

У нас с Вами разные TClientDataSet. Дайте мне свой :)


Я б сделал свой, да не вышло. Иногда выходит патчик залить в какой-нибудь стандартный компонент и исходник программе подсунуть, иногда нет. fib патчики, для FastReport, для quickreport, черт бы его побрал, для Indy и даже для ActnMan и ActnCtrl прокатило. А здесь, точно не помню, но затык случился, вроде бы, как раз в том куске, что прилинковывается через midaslib (или midas.dll). Полностью переписать разве только если в типа TMYClientDataset. Но по этому пути тоже отлуп случился. Кажется, опять же с тем же самым - неполный доступ к исходникам. В итоге пришел к выводу, что НИЗЗЯ. но надежда умирает последней...


Senya_L

Вообще-то этот компонент прожорливый, зараза. И по использованию пямяти, и
по сетевому трафику.


ПО памяти - не скажу в сравнении. А по трафику - для этого собираюсь использовать другие компоненты. То есть, руку набил пока в использовании его именно как "датасет в памяти". То есть, взял из TFibDataset тупо, по-быстрому скопировал (см.пример) и пошел работать себе дальше. сам TFibDataset уже не нужен. Причины: а) скопировал, и не паришься, пофиг тебе все коннекты и дисконнекты, б) универсализация какая-никакая кода.. Мало ли, придется когда-нибудь уйти с Fib, к примеру..
7 фев 09, 15:54    [6791854]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
V.Borzov
Member

Откуда: Саратов
Сообщений: 139
Michael Longneck
Заберите данные в один cds. Скопируйте поля (поля а не данные) в другой. Добавьте туда по вкусу вычисляемые. Потом через cds2.Data := cds1.Data передайте. В чём проблема не вижу.


Это было в попытках решить. Проблема в том, что второй датасет потеряет полностью структуру при попытке копирования из первого.
7 фев 09, 15:56    [6791857]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Michael Longneck
Member

Откуда: Москва
Сообщений: 2262
Ничего нигде не теряется. Я добавляю любые поля Calc и InternalCalc и всё работает проблем. Никакая структура не теряется. Другое дело если свовсем разная структура, то естественно копировать руками.
unit Unit25;

interface

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

type
  TForm25 = class(TForm)
    Table1: TTable;
    ClientDataSet1: TClientDataSet;
    DataSource1: TDataSource;
    DataSource2: TDataSource;
    DBGrid1: TDBGrid;
    DBGrid2: TDBGrid;
    ClientDataSet1CustNo: TFloatField;
    ClientDataSet1Company: TStringField;
    ClientDataSet1Addr1: TStringField;
    ClientDataSet1Addr2: TStringField;
    ClientDataSet1City: TStringField;
    ClientDataSet1State: TStringField;
    ClientDataSet1Zip: TStringField;
    ClientDataSet1Country: TStringField;
    ClientDataSet1Phone: TStringField;
    ClientDataSet1FAX: TStringField;
    ClientDataSet1TaxRate: TFloatField;
    ClientDataSet1Contact: TStringField;
    ClientDataSet1LastInvoiceDate: TDateTimeField;
    ClientDataSet1Test: TStringField;
    Button1: TButton;
    DataSetProvider1: TDataSetProvider;
    procedure ClientDataSet1CalcFields(DataSet: TDataSet);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form25: TForm25;

implementation

{$R *.dfm}

procedure TForm25.Button1Click(Sender: TObject);
begin
  ClientDataSet1.Data := DataSetProvider1.Data;
end;

procedure TForm25.ClientDataSet1CalcFields(DataSet: TDataSet);
begin
ClientDataSet1Test.Value := 'Всякое';
end;

end.

object Form25: TForm25
  Left = 0
  Top = 0
  Caption = 'Form25'
  ClientHeight = 466
  ClientWidth = 554
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object DBGrid1: TDBGrid
    Left = 22
    Top = 114
    Width = 524
    Height = 147
    DataSource = DataSource1
    TabOrder = 0
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = 'Tahoma'
    TitleFont.Style = []
  end
  object DBGrid2: TDBGrid
    Left = 22
    Top = 276
    Width = 487
    Height = 147
    DataSource = DataSource2
    TabOrder = 1
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = 'Tahoma'
    TitleFont.Style = []
  end
  object Button1: TButton
    Left = 452
    Top = 22
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 2
    OnClick = Button1Click
  end
  object Table1: TTable
    Active = True
    DatabaseName = 'DBDEMOS'
    TableName = 'customer.db'
    Left = 142
    Top = 98
  end
  object ClientDataSet1: TClientDataSet
    Aggregates = <>
    Params = <>
    OnCalcFields = ClientDataSet1CalcFields
    Left = 362
    Top = 42
    object ClientDataSet1Test: TStringField
      FieldKind = fkInternalCalc
      FieldName = 'Test'
      Size = 250
    end
    object ClientDataSet1CustNo: TFloatField
      FieldName = 'CustNo'
    end
    object ClientDataSet1Company: TStringField
      FieldName = 'Company'
      Size = 30
    end
    object ClientDataSet1Addr1: TStringField
      FieldName = 'Addr1'
      Size = 30
    end
    object ClientDataSet1Addr2: TStringField
      FieldName = 'Addr2'
      Size = 30
    end
    object ClientDataSet1City: TStringField
      FieldName = 'City'
      Size = 15
    end
    object ClientDataSet1State: TStringField
      FieldName = 'State'
    end
    object ClientDataSet1Zip: TStringField
      FieldName = 'Zip'
      Size = 10
    end
    object ClientDataSet1Country: TStringField
      FieldName = 'Country'
    end
    object ClientDataSet1Phone: TStringField
      FieldName = 'Phone'
      Size = 15
    end
    object ClientDataSet1FAX: TStringField
      FieldName = 'FAX'
      Size = 15
    end
    object ClientDataSet1TaxRate: TFloatField
      FieldName = 'TaxRate'
    end
    object ClientDataSet1Contact: TStringField
      FieldName = 'Contact'
    end
    object ClientDataSet1LastInvoiceDate: TDateTimeField
      FieldName = 'LastInvoiceDate'
    end
  end
  object DataSource1: TDataSource
    DataSet = Table1
    Left = 58
    Top = 64
  end
  object DataSource2: TDataSource
    DataSet = ClientDataSet1
    Left = 170
    Top = 34
  end
  object DataSetProvider1: TDataSetProvider
    DataSet = Table1
    Left = 262
    Top = 16
  end
end
7 фев 09, 16:07    [6791877]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
V.Borzov
Member

Откуда: Саратов
Сообщений: 139
Senya_L

Вообще-то этот компонент прожорливый, зараза. И по использованию пямяти, и
по сетевому трафику.


То есть, идея такая: если есть стандартный код/компонент, который принципиально не хуже/особо не хуже, то лучше юзать его. Если нет, то лучше юзать какое-нибудь приемлемое бесплатное с открытыми кодами. Если нет, то что-нибудь за деньги, с открытыми кодами. Если нет, то убиться. Если нет, то писать свое.

Пока я на первом "если" в сомнениях мечусь. и только с одним этим вопросом. ну есть еще один обнаруженный мааахонький, некорректная работа с int64, при сортировке кажется. Но обходится, или даже в следующих версиях Delphi, может, пофикшено... Больше проблем не находил. Ну в рамках решаемой задачи "датасет в памяти".

Насчет памяти, опять же - взял таблицу DB формата. Начал копирование. Где-то после копирования трети данных встало с ошибкой. После применения патчика к TClientDataset стало копировать где-то половину, потом встает. Памяти расходуется при этом меньше, чем сама таблица DB имеет. засчет обрезания строк. Результ вполне приемлемый для TClientDataset. Сравнивал с Memdata от Jedi, там получше, но непырципиально.

C MemTable от EhLib не связывался по причине второго "если".
7 фев 09, 16:08    [6791879]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
V.Borzov
Member

Откуда: Саратов
Сообщений: 139
[quot Michael Longneck]Ничего нигде не теряется. Я добавляю любые поля Calc и InternalCalc и всё работает проблем. Никакая структура не теряется. Другое дело если свовсем разная структура, то естественно копировать руками.
[/quot]

Упс, не может быть, не верю! Работает! Как я не догнал....

[SRC delphi]procedure TForm1.Button1Click(Sender: TObject);
var Field :TField;
begin
  with cds1 do begin
    with fielddefs do
    begin
      Clear;
      Add('field1',ftinteger);
    end;

    createdataset;
    Append;
    FieldByName('field1').AsInteger := 1;
    post;
  end;

  with cds2 do
  begin

    Field := TIntegerField.Create(Self);
    Field.FieldKind := fkdata;
    Field.FieldName := 'field1';
    Field.dataset := CDS2;

    Field := TIntegerField.Create(Self);
    Field.FieldKind := fkCalculated;
    Field.FieldName := 'field2';
    Field.dataset := CDS2;
    //Fields.Add(Field);


    data := cds1.data;
  end;

end;

procedure TForm1.CDS2CalcFields(DataSet: TDataSet);
begin
  dataset.FieldByName('field2').AsInteger := 2;
end;
Сенкс, респект!

Владимир.
7 фев 09, 16:27    [6791911]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Michael Longneck
Member

Откуда: Москва
Сообщений: 2262
AnyDac хорошая библиотека. Но платная. Соответственно при разработках фрилансеру её надо закладывать в стоимость проекта. И прочая.

А с глупыми подростками спорить не надо. После подобной аргументации, обычно, можно сразу переходить к кулачному изложению сути вопроса (ибо статусный поединок и есть скрытая цель такой аргументации).

Правило - к каждой цели - подходящие средства. :)

PS Сорри модераторам, неудержался
7 фев 09, 16:49    [6791951]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Танцор Пасадобля
Member

Откуда: S.PR
Сообщений: 240
Senya_L

У нас с Вами разные TClientDataSet. Дайте мне свой :)
Вообще-то этот компонент прожорливый, зараза. И по использованию пямяти, и
по сетевому трафику.

По исползованию памяти и трафику не компонент прожорлив,
а ваши запросы, обратно TClientDataSet отправляет лишь дельту изменений.
7 фев 09, 18:36    [6792144]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381

> Автор: Танцор Пасадобля
>
> По исползованию памяти и трафику не компонент прожорлив,
> а ваши запросы, обратно TClientDataSet отправляет лишь дельту
> изменений.
>

Я говорю про обычные селект-запросы "в лоб". Используемый в TClientDataSet
механизм передачи и хранения данных неоптимален. В свое время наткнулся на
тормоза с получением большого больших рекордсетов (был молод и тянул на
клиента много строк, обычное дело). Стал лазить по исходникам, понял, что с
большими объемами там лучше не связываться.

Posted via ActualForum NNTP Server 1.4

7 фев 09, 18:47    [6792176]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Танцор Пасадобля
Member

Откуда: S.PR
Сообщений: 240
Senya_L
Стал лазить по исходникам, понял, что с
большими объемами там лучше не связываться.

Большие объемы - это сколько?
7 фев 09, 18:51    [6792181]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381

> Автор: Танцор Пасадобля
> Большие объемы - это сколько?
>

"Больше-меньше" - понятие относительное. :)
Лучше вообще не связываться.

Posted via ActualForum NNTP Server 1.4

7 фев 09, 19:12    [6792216]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Танцор Пасадобля
Member

Откуда: S.PR
Сообщений: 240
Senya_L

"Больше-меньше" - понятие относительное. :)
Лучше вообще не связываться.

Почему так мрачно? Нормально cds работает если грамотно использовать...
7 фев 09, 19:18    [6792223]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ?  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381

> Автор: Танцор Пасадобля
> Почему так мрачно? Нормально cds работает если грамотно
> использовать...
>

Если грамотно, то все можно к делу приладить.
Но создалось в свое время ощущение (возможно, неправильное), что MIDAS
вообще сама по себе уж слишком узко заточена была. Эдакая наивная идея, что
можно "взять" данные с сервера, изменить/добавить/удалить и отослать дельту.
Не все укладывается в эту схему. Считайте это за религию и что не сумел
приготовить :)

Posted via ActualForum NNTP Server 1.4

7 фев 09, 19:28    [6792234]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить