-
MiAn (14.03.11 21:28) [0]Есть проблема. До текущего времени пользовались датасетами от баз данных (TIBQuery и подобное). Когда он выполняет Open, то в методе BeforeOpen можно динамически создавать доп. поля (допустим, служебные для журнала при использовании DBGrid'а). В виде:procedure TForm1.DataSet1BeforeOpen(DataSet: TDataSet);
begin
with DataSet.FieldDefs.AddFieldDef do
begin
DataType := ftBoolean;
Name := 'SomeName';
end;
DataSet.FieldDefs.Items[DataSet.FieldDefs.Count-1].CreateField(DataSet);
end;
Но с TClientDataSet так сделать не получается.
TClientDataSet нельзя делать .Open, надо делать CreateDataSet, в котором он и создает все поля. А только в конце метода CreateDataSet он сам вызывает Open.
Если использовать вышеприведенный код, то он отрабатывает, но не делает что нужно. Таким образом созданные поля не видны в DataSet, FindField('SomeName') = nil.
Так и не смогли разобраться почему это происходит... И самый главный вопрос - как это обойти?
Схема работы такая - у нас на форме лежит TClientDataSet, мы отдаем ссылку на него некоему самописному внешнему провайдеру, он открывает его и заполняет данные. А нам надо еще доп. поля создать свои (например, типа boolean, чтобы галочки в гриде рисовать) и куда вот вклиниться для получения нужного, -
что мешает вместо DataSet1BeforeOpen сделать процедуру например MyBeforeOpen и вызывать ее до CreateDataSet?
если уж на то пошло, можно и наследника TClientDataSet-а написать с перекрытием метода, и вызовом своего BeforeOpen с нужном месте... -
MiAn (15.03.11 13:37) [2]
> что мешает вместо DataSet1BeforeOpen сделать процедуру например
> MyBeforeOpen и вызывать ее до CreateDataSet?
> Схема работы такая - у нас на форме лежит TClientDataSet,
> мы отдаем ссылку на него некоему самописному внешнему провайдеру,
> он открывает его и заполняет данные
> если уж на то пошло, можно и наследника TClientDataSet-а
> написать с перекрытием метода
CreateDataSet является статической процедурой в TClientDataSet -
> Схема работы такая - у нас на форме лежит TClientDataSet,
это ничего не объясняет... будет такая - отдаете ссылку на него, с полностью сформированным FieldDefs, он открывает его и заполняет данные...
???
где проблема?
> CreateDataSet является статической процедурой в TClientDataSet
и что? свою процедуру классу не добавить из-за этого? -
MiAn (15.03.11 14:57) [4]
> это ничего не объясняет... будет такая - отдаете ссылку
> на него, с полностью сформированным FieldDefs, он открывает
> его и заполняет данные
как вы понимаете, стандартная задача провайдера - САМОЛИЧНО создать поля, чтобы их потом заполнить, ибо только он знает какие колонки будут в датасете. Логично, что большинство провайдеров перед этим очищают филд дефс...
> и что? свою процедуру классу не добавить из-за этого?
процедуру добавить можно. Но кто ее будет вызывать? -
> как вы понимаете, стандартная задача провайдера
нет не понимаю, и практически этим не пониманием постоянно пользуюсь прописывая поля датасетам в десигн тайме и после их спокойно открывая любыми таинственными провайдерами.
> Но кто ее будет вызывать?
> некоему самописному внешнему провайдеру,
? -
MiAn (15.03.11 17:16) [6]
> нет не понимаю, и практически этим не пониманием постоянно
> пользуюсь прописывая поля датасетам в десигн тайме и после
> их спокойно открывая любыми таинственными провайдерами.
да... пожалуй, вы абсолютно правы. Провайдер действует некрасиво, но он так делает... А дело в том, что переписать его поведение - есть некоторые проблемы, хотелось решить это "со стороны датасета".
Ну и соответственно по этой же причине метод в TClientDataSet внедрить сложно.
В принципе, проблема решена. На событии AfterOpen сделали код аля:.Close;
.AddField
.Open
вроде работает... -
Polevi © (23.03.11 07:29) [7]писатели....
-
Loginov Dmitry © (25.03.11 17:52) [8]
> (TIBQuery и подобное). Когда он выполняет Open, то в методе
> BeforeOpen можно динамически создавать доп. поля
А в SQL почему бы это не сделать? -
> А в SQL почему бы это не сделать?
какая разница? это же у них было раньше, сейчас -
> Но с TClientDataSet так сделать не получается.
притом с CreateDataSet. -
> На событии AfterOpen сделали код аля:
>
Ох уж эти аляльщики...
.AddField
.CreateDataSet
.Open