Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
-
bursch
- Posts: 20
- Joined: Tue 25 Sep 2018 07:45
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
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
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
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
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
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