Theprasit

Forum Replies Created

Viewing 1 post (of 1 total)
  • Author
    Posts
  • in reply to: Add Calculation Fields Runtime in BeforeOpen #54419
    Theprasit
    Participant

    Hi,

    just sent you a testing code that result in an error.
    This is a N-Tier application that prepare data on server side and transfer as stream over network to client side.
    On client side I used kbmMemTable to load data from stream as use as working table then send update data back to server.

    If you run Button1Click, it’s result in error “mt1: cannot perform this operation on closed dataset”.
    If you run Button2Click, it’s just fined, a calculation field is created as expect.

    I use almost default properties of kbmMemTable and related class (default after create).
    Do I miss anything to fine tune?

    Regards,

    procedure TForm5.Button1Click(Sender: TObject);
    var
    mt_fmt: TkbmBinaryStreamFormat;
    ms: TMemoryStream;
    begin
    mt_fmt:= TkbmBinaryStreamFormat.Create(nil);
    ms:= TMemoryStream.Create;
    try
    // ut is a TUniDacTable which load data from DataBase
    // this part is done on server side and sent a stream over network
    mt2.LoadFromDataSet(ut, [mtcpoStructure]);
    mt2.SaveToStreamViaFormat(ms, mt_fmt);
    ms.Position:= 0;
    
    // this is on client side which get a stream and load back to kbmMemTable
    // mt_fmt on server and client used same properties (default after create)
    mt1.LoadFromStreamViaFormat(ms, mt_fmt);
    
    finally
    mt_fmt.Free;
    ms.Free;
    end;
    dsMem.DataSet:= mt1;
    
    // *** this method got error "mt1: Canoot perform this operation on closed dataset"
    end;
    
    procedure TForm5.Button2Click(Sender: TObject);
    var
    mt_fmt: TkbmBinaryStreamFormat;
    ms: TMemoryStream;
    begin
    mt_fmt:= TkbmBinaryStreamFormat.Create(nil);
    ms:= TMemoryStream.Create;
    try
    // ut is a TUniDacTable which load data from DataBase
    // this part is done on server side and sent a stream over network
    mt2.LoadFromDataSet(ut, [mtcpoStructure]);
    mt2.SaveToStreamViaFormat(ms, mt_fmt);
    ms.Position:= 0;
    
    // this is on client side which get a stream and load back to kbmMemTable
    // mt_fmt on server and client used same properties (default after create)
    mt3.LoadFromStreamViaFormat(ms, mt_fmt);
    
    // mt3 is a temporary kbmMemTable use as my work around solution
    mt1.LoadFromDataSet(mt3, [mtcpoStructure]);
    
    // *** this method run without error, a calculation field is created as expect
    finally
    mt_fmt.Free;
    ms.Free;
    end;
    dsMem.DataSet:= mt1;
    end;
    
    procedure TForm5.mt1BeforeOpen(DataSet: TDataSet);
    var
    fl: TField;
    begin
    mt1.FieldDefs.Update;
    for var ix:= 0 to mt1.FieldDefs.Count- 1 do
    mt1.FieldDefs[ix].CreateField(mt1);
    
    fl:= TStringField.Create(mt1);
    fl.FieldName:= 'Calc';
    fl.FieldKind:= fkCalculated;
    fl.DataSet:= mt1;
    end;
Viewing 1 post (of 1 total)