Creating calculated fields on runtime (AutoCreateMode = acCombineComputed)

Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
bursch
Posts: 20
Joined: Tue 25 Sep 2018 07:45

Creating calculated fields on runtime (AutoCreateMode = acCombineComputed)

Post by bursch » Wed 08 Apr 2020 05:24

Hi,

there is a problem with create calculated fields on runtime. After some debugging in your components maybe i've found the problem.

The method CreateFields (Line 1147) in MemDS.pas is not called if there a calculated fields, so FieldOptions.AutoCreateMode = acCombineComputed don't work.

Example code:

Code: Select all

	TDatasetAccess(UniQuery1).FieldOptions.AutoCreateMode := acCombineComputed;

	f := TIntegerField.Create(Uniquery1);
	f.FieldName := 'calc';
	f.FieldKind := fkCalculated;
	f.DataSet := Uniquery1;

	Uniquery1.SQL.Text := 'SELECT * FROM foobar';
	Uniquery1.Open;

oleg0k
Devart Team
Posts: 190
Joined: Wed 11 Mar 2020 08:28

Re: Creating calculated fields on runtime (AutoCreateMode = acCombineComputed)

Post by oleg0k » Fri 10 Apr 2020 12:25

Hello,
Below is a working code that should help:

Code: Select all

procedure TForm1.Button1Click(Sender: TObject);
var
UniQuery :TUniQuery;
fd :TIntegerField;
fc1 :TIntegerField;
fc2 :TStringField;

begin
try
UniQuery := TUniQuery.Create(Self);
UniQuery.Connection := UniConnection;
UniQuery.SQL.Text := 'Select * from test';
UniQuery.OnCalcFields := UniQuery1CalcFields;
fd := TIntegerField.Create(nil);
fd.FieldName := 'id';
fd.DataSet := UniQuery;
fd.FieldKind := fkData;

fc1 := TIntegerField.Create(nil);
fc1.FieldName := 'CalcInt';
fc1.DataSet := UniQuery;
fc1.FieldKind := fkCalculated;

fc2 := TStringField.Create(nil);
fc2.FieldName := 'CalcStr';
fc2.DataSet := UniQuery;
fc2.FieldKind := fkCalculated;
UniQuery.Open;
ShowMessage(UniQuery.FieldByName('CalcInt').AsString + #13 + UniQuery.FieldByName('CalcStr').AsString);
finally
UniQuery.Free;
end;

end;

procedure TForm1.UniQuery1CalcFields(DataSet: TDataSet);
begin
Dataset.FieldByName('CalcInt').asInteger := Dataset.FieldByName('id').asInteger + 1234;
Dataset.FieldByName('CalcStr').asString := 'TestCalc' + IntToStr(Dataset.FieldByName('id').asInteger) ;
end;

wbr, Oleg
Devart Team

bursch
Posts: 20
Joined: Tue 25 Sep 2018 07:45

Re: Creating calculated fields on runtime (AutoCreateMode = acCombineComputed)

Post by bursch » Wed 15 Apr 2020 08:00

Hi,

with your solution i've to specify all fields for the query.

By supporting the AutoCreateMode the dataset don't remove the calculated fields. Other fields will be added automaticly without additional lines of code

oleg0k
Devart Team
Posts: 190
Joined: Wed 11 Mar 2020 08:28

Re: Creating calculated fields on runtime (AutoCreateMode = acCombineComputed)

Post by oleg0k » Sat 18 Apr 2020 09:43

Hello, try this:

Code: Select all

procedure TForm1.btnUniClick(Sender: TObject);
var
  FieldDef: TFieldDef;
  Field: TField;
  i:integer;
begin
  UniConnection1.Connected:=True;
  UniQuery1.Prepare;

  UniQuery1.FieldDefs.Add('CalcInt', ftInteger, 0, False);
  for i := 0 to UniQuery1.FieldDefs.Count - 1 do
  begin
    FieldDef := UniQuery1.FieldDefs.Items[i];
    Field := FieldDef.CreateField(UniQuery1);
    if Field.FieldName = 'CalcInt' then
          Field.FieldKind := fkCalculated;
    Field.DataSet := UniQuery1;
  end;

  UniQuery1.OnCalcFields := UniQuery1CalcFields;
  UniQuery1.Open;

end;

procedure TForm1.UniQuery1CalcFields(DataSet: TDataSet);
begin
  Dataset.FieldByName('CalcInt').asInteger := Dataset.FieldByName('id').asInteger + 1234;
end;
wbr, Oleg
Devart Team

bursch
Posts: 20
Joined: Tue 25 Sep 2018 07:45

Re: Creating calculated fields on runtime (AutoCreateMode = acCombineComputed)

Post by bursch » Sat 18 Apr 2020 16:07

Hi,

again i've to write additional source code for adding the query fields. By supporting AutoCreateMode it's also possible to design calc fields on design time and the query fields will be added on runtime.

Maybe you can implement the support of AutoCreateMode in one of your future builds. For the meanwhile i can use your suggestion as a workaround.

oleg0k
Devart Team
Posts: 190
Joined: Wed 11 Mar 2020 08:28

Re: Creating calculated fields on runtime (AutoCreateMode = acCombineComputed)

Post by oleg0k » Tue 21 Apr 2020 07:53

Hello,
Currently, the TUniQuery and TUniTable components do not support the AutoCreateMode property.
You can leave your suggestions at our UserVoice page https://devart.uservoice.com/forums/104 ... y_id=18939,
and if there are many votes for your suggestion, we will implement it.

wbr, Oleg
Devart Team

Post Reply