Page 1 of 1

Creating calculated fields on runtime (AutoCreateMode = acCombineComputed)

Posted: Wed 08 Apr 2020 05:24
by bursch
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;

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

Posted: Fri 10 Apr 2020 12:25
by oleg0k
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

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

Posted: Wed 15 Apr 2020 08:00
by bursch
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

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

Posted: Sat 18 Apr 2020 09:43
by oleg0k
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

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

Posted: Sat 18 Apr 2020 16:07
by bursch
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.

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

Posted: Tue 21 Apr 2020 07:53
by oleg0k
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