| Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
| Все форумы / Delphi |
![]() |
||
| Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
|
V.Borzov Member Откуда: Саратов Сообщений: 284 |
Здравствуйте! Люблю TclientDataset, но не могу никак добиться создания поля в открытом наборе (созданном через CreateDataset, например). Как-то ковырялся в коде, пришел к умозаключению, что это в принципе невозможно из-за проверки на активность и выдаче ошибки в этом случае в функциях создания полей. Или ошибся? Кто-нибудь достигал каких-то в этом результатов? Интересует возможность создания хотя бы калькулируемых полей, про ftData уж и не заикаюсь... .. на открытом датасете. .. D7. может что-то в других версиях изменилось? |
| 7 фев 09, 15:19 [6791795] Ответить | Цитировать Сообщить модератору | |
|
Джибс Member Откуда: 🐾🐾🐾🐾🐾🐾 Сообщений: 45861 |
А в чем смысл данного ? |
| 7 фев 09, 15:21 [6791804] Ответить | Цитировать Сообщить модератору | |
|
Michael Longneck Member Откуда: Москва Сообщений: 2299 |
А в чём проблема закрыть сначала? |
| 7 фев 09, 15:21 [6791805] Ответить | Цитировать Сообщить модератору | |
|
V.Borzov Member Откуда: Саратов Сообщений: 284 |
закрыл - потерял данные. |
||
| 7 фев 09, 15:26 [6791818] Ответить | Цитировать Сообщить модератору | |||
|
miksoft Member Откуда: Сообщений: 37699 |
Мне с похожим вопросом помогли тут |
| 7 фев 09, 15:28 [6791819] Ответить | Цитировать Сообщить модератору | |
|
Senya_L Member Откуда: Москва Сообщений: 5381 |
> Автор: V.Borzov > Здравствуйте! > > Люблю TclientDataset, Напрасно. Есть In-Memory датасеты (если пользуетесь по этой причине). Не забывайте, что приложение, использующее этот компонент, тянет за собой MIDAS.DLL. > но не могу никак добиться создания поля в открытом наборе (созданном через > CreateDataset, например). Задлянафига? Нельзя разве создать вычисляемое поле до открытия датасета? Posted via ActualForum NNTP Server 1.4 |
| 7 фев 09, 15:28 [6791820] Ответить | Цитировать Сообщить модератору | |
|
V.Borzov Member Откуда: Саратов Сообщений: 284 |
В том, что нужно для работы пару калькулируемых полей. или даже тройку. а данные получены из другого датасета, копированием, причем не вручную, когда создаешь сам поля + 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] Ответить | Цитировать Сообщить модератору | |||
|
Michael Longneck Member Откуда: Москва Сообщений: 2299 |
Midas.dll можно и не брать - uses MidasLib Другое дело, что все поля можно и заранее создать. Что собственно требуется? |
| 7 фев 09, 15:33 [6791829] Ответить | Цитировать Сообщить модератору | |
|
Senya_L Member Откуда: Москва Сообщений: 5381 |
> Автор: miksoft > Мне с похожим вопросом помогли тут > Автор хочет не просто в рантайме, а на открытом датасете такое проделать. Posted via ActualForum NNTP Server 1.4 |
| 7 фев 09, 15:34 [6791832] Ответить | Цитировать Сообщить модератору | |
|
V.Borzov Member Откуда: Саратов Сообщений: 284 |
Главный ньюанс - скорость копирования из источника в этот датасет. пример привел выше. Пример работает мухой. все остальные, че видел - тупо копируют по полям перебором. Для образования пойдет, но в промышленности - не катит ИМХО. Все остальное и здесь катит прекрасно и быстро, вот только заданный вопрос в subj пока и смущает.
uses MidalLib
Чуть выше привел пример. |
||||||
| 7 фев 09, 15:35 [6791837] Ответить | Цитировать Сообщить модератору | |||||||
|
V.Borzov Member Откуда: Саратов Сообщений: 284 |
Не, нам AdoQuery, совсем другой компонент, к тому же, исходное условие такое, что нет возможности сначала задать структуру, потом скопировать (если только не тупым перебором исходного датасета, что означает потерю скорости в разы или даже десятки раз по сравнению с тем примером, что я написал (readdataset). В FibDataset, к примеру, даже есть CreateCalcField, точное название не помню. напрямую задачу решает, но у себя. |
||
| 7 фев 09, 15:40 [6791845] Ответить | Цитировать Сообщить модератору | |||
|
Senya_L Member Откуда: Москва Сообщений: 5381 |
> Автор: V.Borzov > Главный ньюанс - скорость копирования из источника в этот датасет. > пример привел выше. Пример работает мухой. все остальные, че видел - тупо > копируют по полям перебором. Для образования пойдет, но в промышленности - > не катит ИМХО. Все остальное и здесь катит прекрасно и быстро, вот только > заданный вопрос в subj пока и смущает. > У нас с Вами разные TClientDataSet. Дайте мне свой :) Вообще-то этот компонент прожорливый, зараза. И по использованию пямяти, и по сетевому трафику. Posted via ActualForum NNTP Server 1.4 |
| 7 фев 09, 15:41 [6791846] Ответить | Цитировать Сообщить модератору | |
|
Michael Longneck Member Откуда: Москва Сообщений: 2299 |
Заберите данные в один cds. Скопируйте поля (поля а не данные) в другой. Добавьте туда по вкусу вычисляемые. Потом через cds2.Data := cds1.Data передайте. В чём проблема не вижу. |
| 7 фев 09, 15:54 [6791853] Ответить | Цитировать Сообщить модератору | |
|
V.Borzov Member Откуда: Саратов Сообщений: 284 |
Я б сделал свой, да не вышло. Иногда выходит патчик залить в какой-нибудь стандартный компонент и исходник программе подсунуть, иногда нет. fib патчики, для FastReport, для quickreport, черт бы его побрал, для Indy и даже для ActnMan и ActnCtrl прокатило. А здесь, точно не помню, но затык случился, вроде бы, как раз в том куске, что прилинковывается через midaslib (или midas.dll). Полностью переписать разве только если в типа TMYClientDataset. Но по этому пути тоже отлуп случился. Кажется, опять же с тем же самым - неполный доступ к исходникам. В итоге пришел к выводу, что НИЗЗЯ. но надежда умирает последней...
ПО памяти - не скажу в сравнении. А по трафику - для этого собираюсь использовать другие компоненты. То есть, руку набил пока в использовании его именно как "датасет в памяти". То есть, взял из TFibDataset тупо, по-быстрому скопировал (см.пример) и пошел работать себе дальше. сам TFibDataset уже не нужен. Причины: а) скопировал, и не паришься, пофиг тебе все коннекты и дисконнекты, б) универсализация какая-никакая кода.. Мало ли, придется когда-нибудь уйти с Fib, к примеру.. |
||||
| 7 фев 09, 15:54 [6791854] Ответить | Цитировать Сообщить модератору | |||||
|
V.Borzov Member Откуда: Саратов Сообщений: 284 |
Это было в попытках решить. Проблема в том, что второй датасет потеряет полностью структуру при попытке копирования из первого. |
||
| 7 фев 09, 15:56 [6791857] Ответить | Цитировать Сообщить модератору | |||
|
Michael Longneck Member Откуда: Москва Сообщений: 2299 |
Ничего нигде не теряется. Я добавляю любые поля 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] Ответить | Цитировать Сообщить модератору | |
|
V.Borzov Member Откуда: Саратов Сообщений: 284 |
То есть, идея такая: если есть стандартный код/компонент, который принципиально не хуже/особо не хуже, то лучше юзать его. Если нет, то лучше юзать какое-нибудь приемлемое бесплатное с открытыми кодами. Если нет, то что-нибудь за деньги, с открытыми кодами. Если нет, то убиться. Если нет, то писать свое. Пока я на первом "если" в сомнениях мечусь. и только с одним этим вопросом. ну есть еще один обнаруженный мааахонький, некорректная работа с int64, при сортировке кажется. Но обходится, или даже в следующих версиях Delphi, может, пофикшено... Больше проблем не находил. Ну в рамках решаемой задачи "датасет в памяти". Насчет памяти, опять же - взял таблицу DB формата. Начал копирование. Где-то после копирования трети данных встало с ошибкой. После применения патчика к TClientDataset стало копировать где-то половину, потом встает. Памяти расходуется при этом меньше, чем сама таблица DB имеет. засчет обрезания строк. Результ вполне приемлемый для TClientDataset. Сравнивал с Memdata от Jedi, там получше, но непырципиально. C MemTable от EhLib не связывался по причине второго "если". |
||
| 7 фев 09, 16:08 [6791879] Ответить | Цитировать Сообщить модератору | |||
|
V.Borzov Member Откуда: Саратов Сообщений: 284 |
[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] Ответить | Цитировать Сообщить модератору | |
|
Michael Longneck Member Откуда: Москва Сообщений: 2299 |
AnyDac хорошая библиотека. Но платная. Соответственно при разработках фрилансеру её надо закладывать в стоимость проекта. И прочая. А с глупыми подростками спорить не надо. После подобной аргументации, обычно, можно сразу переходить к кулачному изложению сути вопроса (ибо статусный поединок и есть скрытая цель такой аргументации). Правило - к каждой цели - подходящие средства. :) PS Сорри модераторам, неудержался |
| 7 фев 09, 16:49 [6791951] Ответить | Цитировать Сообщить модератору | |
|
Танцор Пасадобля Member Откуда: S.PR Сообщений: 240 |
По исползованию памяти и трафику не компонент прожорлив, а ваши запросы, обратно TClientDataSet отправляет лишь дельту изменений. |
||
| 7 фев 09, 18:36 [6792144] Ответить | Цитировать Сообщить модератору | |||
|
Senya_L Member Откуда: Москва Сообщений: 5381 |
> Автор: Танцор Пасадобля > > По исползованию памяти и трафику не компонент прожорлив, > а ваши запросы, обратно TClientDataSet отправляет лишь дельту > изменений. > Я говорю про обычные селект-запросы "в лоб". Используемый в TClientDataSet механизм передачи и хранения данных неоптимален. В свое время наткнулся на тормоза с получением большого больших рекордсетов (был молод и тянул на клиента много строк, обычное дело). Стал лазить по исходникам, понял, что с большими объемами там лучше не связываться. Posted via ActualForum NNTP Server 1.4 |
| 7 фев 09, 18:47 [6792176] Ответить | Цитировать Сообщить модератору | |
|
Танцор Пасадобля Member Откуда: S.PR Сообщений: 240 |
Большие объемы - это сколько? |
||
| 7 фев 09, 18:51 [6792181] Ответить | Цитировать Сообщить модератору | |||
|
Senya_L Member Откуда: Москва Сообщений: 5381 |
> Автор: Танцор Пасадобля > Большие объемы - это сколько? > "Больше-меньше" - понятие относительное. :) Лучше вообще не связываться. Posted via ActualForum NNTP Server 1.4 |
| 7 фев 09, 19:12 [6792216] Ответить | Цитировать Сообщить модератору | |
|
Танцор Пасадобля Member Откуда: S.PR Сообщений: 240 |
Почему так мрачно? Нормально cds работает если грамотно использовать... |
||
| 7 фев 09, 19:18 [6792223] Ответить | Цитировать Сообщить модератору | |||
|
Senya_L Member Откуда: Москва Сообщений: 5381 |
> Автор: Танцор Пасадобля > Почему так мрачно? Нормально cds работает если грамотно > использовать... > Если грамотно, то все можно к делу приладить. Но создалось в свое время ощущение (возможно, неправильное), что MIDAS вообще сама по себе уж слишком узко заточена была. Эдакая наивная идея, что можно "взять" данные с сервера, изменить/добавить/удалить и отослать дельту. Не все укладывается в эту схему. Считайте это за религию и что не сумел приготовить :) Posted via ActualForum NNTP Server 1.4 |
| 7 фев 09, 19:28 [6792234] Ответить | Цитировать Сообщить модератору | |
| Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
| Все форумы / Delphi | ![]() |
|