AV referencing persistent field object by name

Discussion of open issues, suggestions and bugs regarding Virtual Data Access Components for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
francoff
Posts: 7
Joined: Wed 03 Oct 2012 05:41

AV referencing persistent field object by name

Post by francoff » Wed 03 Oct 2012 06:14

Hi.
I am making some experiments with Virtual Table Free (last) and D 2009.

I have found that referencing a field directly by field.name (e.g. Table1Field1.AsString) raises an AV Exception, while using usual FieldByName or FieldValues works properly.
Directly referencing persistent fields not only is extremely faster (which matters only in loops on large numbers of records), but also allows to check correct naming at compile time.

I think this is a bug, so I have set up a small example to reproduce it.
Let me know how I can post/send to You.
Regards.

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Re: AV referencing persistent field object by name

Post by AlexP » Wed 03 Oct 2012 13:46

hello,

We couldn't reproduce the AV when working with persistent fields of VirtualTable, please send your sample demonstrating the problem to alexp*devart*com

francoff
Posts: 7
Joined: Wed 03 Oct 2012 05:41

Re: AV referencing persistent field object by name

Post by francoff » Thu 04 Oct 2012 06:52

Hi.
I think that the AV Exception might be simply due to the fact that no persistent TFields are present at runtime so you cannot reference them directly by name. At runtime, may be, there are only dynamic TField objects, and persistent fields created at designtime are no longer available.
This is only an assumption, and, if it is correct, it may be by design (which should be made clear) or due to a flaw. In any case if there is no other way to create persistent fields, this is a real disadvantage.

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Re: AV referencing persistent field object by name

Post by AlexP » Fri 05 Oct 2012 09:12

hello,

When using the VirtualTable.Assign method, all the existing data and fields in the table are cleared. Therefore, after data loading, the fields created earlier become nil.
There are two way to solve this problem:

1) Relate the fields in the following way:

Code: Select all

Table1.Open;
vt1.Assign(Table1);
vt1DATA := TDateField.Create(nil);
vt1DATA.FieldName := 'DATA';
vt1DATA.DataSet := vt1;
vt1NOTE := TStringField.Create(nil);
vt1NOTE.FieldName := 'NOTE';
vt1NOTE.DataSet := vt1;
vt1.Open;
Table1.Close;
2) Or, if the structures of the table and VirtualTable are similar, use the TCRBatchMove component for data transfer between datasets

francoff
Posts: 7
Joined: Wed 03 Oct 2012 05:41

Re: AV referencing persistent field object by name

Post by francoff » Sat 06 Oct 2012 05:49

Hi Alex.
Thank you very much for helping.

After some research, I ended up with a piece of code that seems to work and lends itself to be transformed in a generic routine.
It is assumed that persistent fields were created for the base table (and also for Virtual Table otherwise direct references to field objects would give a compile error):

...
var
i: integer;
Field, NewField: TField;
begin

vt1.DisableControls;
try
Table1.Open;
try
vt1.Assign(Table1);
finally
Table1.Close;
end;
for i := 0 to Table1.FieldCount - 1 do
begin
Field := Table1.Fields;
NewField := vt1.FieldDefs.CreateField(Self);
//CreateField(vt1) somehow gives AV again
NewField.Visible := Field.Visible;
NewField.Name := 'vt1' + NewField.FieldName;//<- this is the key point to solve AV issue.
NewField.DisplayLabel := Field.DisplayLabel;
NewField.DisplayWidth := Field.DisplayWidth;
NewField.EditMask := Field.EditMask;
if IsPublishedProp(Field, 'currency') then
SetPropValue(NewField, 'currency', GetPropValue(Field, 'currency'));
// may be here it can be improved adding more published props.
end;
finally
vt1.EnableControls;
end;
...

Post Reply