Конференция "Базы" » Как инициализировать динамически поля TClientDataSet
 
  • 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, чтобы галочки в гриде рисовать) и куда вот вклиниться для получения нужного,
  • sniknik © (14.03.11 22:37) [1]
    что мешает вместо DataSet1BeforeOpen сделать процедуру например MyBeforeOpen и вызывать ее до CreateDataSet?

    если уж на то пошло, можно и наследника TClientDataSet-а написать с перекрытием метода, и вызовом своего BeforeOpen с нужном месте...
  • MiAn (15.03.11 13:37) [2]

    > что мешает вместо DataSet1BeforeOpen сделать процедуру например
    > MyBeforeOpen и вызывать ее до CreateDataSet?



    > Схема работы такая - у нас на форме лежит TClientDataSet,
    >  мы отдаем ссылку на него некоему самописному внешнему провайдеру,
    >  он открывает его и заполняет данные



    > если уж на то пошло, можно и наследника TClientDataSet-а
    > написать с перекрытием метода


    CreateDataSet является статической процедурой в TClientDataSet
  • sniknik © (15.03.11 14:00) [3]
    > Схема работы такая - у нас на форме лежит TClientDataSet,
    это ничего не объясняет... будет такая - отдаете ссылку на него, с полностью сформированным FieldDefs, он открывает его и заполняет данные...
    ???
    где проблема?

    > CreateDataSet является статической процедурой в TClientDataSet
    и что? свою процедуру классу не добавить из-за этого?
  • MiAn (15.03.11 14:57) [4]

    > это ничего не объясняет... будет такая - отдаете ссылку
    > на него, с полностью сформированным FieldDefs, он открывает
    > его и заполняет данные

    как вы понимаете, стандартная задача провайдера - САМОЛИЧНО создать поля, чтобы их потом заполнить, ибо только он знает какие колонки будут в датасете. Логично, что большинство провайдеров перед этим очищают филд дефс...


    > и что? свою процедуру классу не добавить из-за этого?

    процедуру добавить можно. Но кто ее будет вызывать?
  • sniknik © (15.03.11 16:02) [5]
    > как вы понимаете, стандартная задача провайдера
    нет не понимаю, и практически этим не пониманием постоянно пользуюсь прописывая поля датасетам в десигн тайме и после их спокойно открывая любыми таинственными провайдерами.

    > Но кто ее будет вызывать?
    > некоему самописному внешнему провайдеру,
    ?
  • 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 почему бы это не сделать?
  • sniknik © (25.03.11 18:56) [9]
    > А в SQL почему бы это не сделать?
    какая разница? это же у них было раньше, сейчас -
    > Но с TClientDataSet так сделать не получается.
    притом с CreateDataSet.
  • Johnmen © (27.03.11 01:36) [10]

    > На событии AfterOpen сделали код аля:
    >

    Ох уж эти аляльщики...
    .AddField
    .CreateDataSet
    .Open
 
Конференция "Базы" » Как инициализировать динамически поля TClientDataSet
Есть новые Нет новых   [134431   +15][b:0][p:0.001]