Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 7 of 7 total
Thread tedbquery, beforeopen + changed fields or add calculated fields
Mon, Oct 14 2019 5:17 AMPermanent Link

Yusuf Zorlu

MicrotronX - Speditionssoftware vom Profi

Hi, we are working a lot with tedbquery and creating onbeforeopen
calculated or lookupfields in runtime.

Can someone please test following

1. create a tedbquery on your form, connect it to your session /
database

2. create following in onBeforeOpen:
procedure TForm1.tPos3BeforeOpen(DataSet: TDataSet);
var
   i, imax:integer;
begin
   try
       if dataset.fielddefs.updated=false then
      DataSet.FieldDefs.Update; // << second call = crash!
   except
       on e:Exception do begin
           showmessage(e.message);
       end;
   end;

   imax:=DataSet.fielddefs.count;
   for i:=0 to imax-1 do begin
       if dataset.findfield(dataset.fielddefs[i].Name)=nil then begin
           DataSet.fielddefs[i].createfield(DataSet, nil, '',false);
       end;
   end;
end;

3. now in code, define one sql with 3 fields as result from any table
in your database i.e.:

procedure TForm1.Button1Click(Sender: TObject);
begin
   tpos3.SQL.Text:='select field1, field2, field3 from mytable';
   tpos3.open;

   showmessage('result with 3 field, now change to 1 field');

   tpos3.close;

   tpos3.sql.text:='select field4 from mytable';
   tpos3.open;
end;

Can someone confirm that the second open will crash in line
"dataset.fielddefs.update" or may i'm doing something wrong?

--
--
Yusuf Zorlu | MicrotronX
Mon, Oct 14 2019 6:07 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Yusuf


I can confirm that its happening. It seems to come from InternalClose in DB, but I can't find the actual spot. I suggest reporting to Tim

Out of interest I'm going to spend another hour or so on it and if I find anything I'll post back.

Roy Lambert
Mon, Oct 14 2019 6:33 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Yusuf


I think it has something to do with using BeforeOpen ie before the query is set up. Use AfterOpen and it runs.

Reading your post again what I'm not sure about is this

"creating onbeforeopen calculated or lookupfields in runtime"

Can you explain? I would have thought OnCalcFields  was the right place for this, possibly a generated or computed field in the database.


Roy Lambert
Mon, Oct 14 2019 7:30 AMPermanent Link

Yusuf Zorlu

MicrotronX - Speditionssoftware vom Profi

Roy Lambert wrote:

> I think it has something to do with using BeforeOpen ie before the
> query is set up. Use AfterOpen and it runs.
>
> Reading your post again what I'm not sure about is this
>
> "creating onbeforeopen calculated or lookupfields in runtime"
>
> Can you explain? I would have thought OnCalcFields  was the right
> place for this, possibly a generated or computed field in the
> database.

Hi Roy,

we're using this to create dynamically definable fields (from customer
side) for different edbtable and edbquery components onBeforeOpen to be
able to add new field definitions as lookup or calculated fields like
this:

function mxAddSqlResultField(vdataset: tdataset; vFieldname: string;
vlength: integer; vFieldDataType: tfieldtype = ftWideString;
vInternalCalcField:boolean=false): tField;
begin
   if vdataset.FindField(vFieldname) = nil then
   begin
       with vdataset.FieldDefs.Addfielddef do begin
           Name := vFieldname;
           DataType := vFieldDataType;
           Required := false;
           if datatype=ftString then Size := vlength;
           if datatype=ftWideString then Size := vlength;
           with CreateField(vdataset, nil, vFieldname, false) do
           begin
               DisplayLabel := vFieldname;
               FieldKind := fkCalculated;
               if datatype=ftstring then Size := vlength;
               if datatype=ftWideString then Size := vlength;
               Name := vdataset.name + vFieldname;
               ProviderFlags := [];
               ReadOnly := not vinternalcalcfield;
               InternalCalcField:=vInternalCalcField;
           end;
       end;
   end;
   result := vdataset.FindField(vFieldname);
end;
function mxAddLookupField(vta, vtalookup: tdataset; vname, vschlussel,
vschlussellookup, vresultfeld: string; vlaenge: integer; vusecache:
boolean = false; vFieldType:TFieldType=ftWideString): tField;
var
   vtempfield: tField;
   imax, i: integer;
begin
   if vta.FindField(vname) = nil then
   begin
       if vta.FindField(vschlussel) <> NIL then begin
           if (vtalookup.FindField(vresultfeld)<>nil) or
(vtalookup.Active=false) then begin
               with vta.FieldDefs.Addfielddef do begin
                   Name := vname;
                   DataType := vFieldType;
                   Required := false;
                   if vFieldType=ftstring then Size := vlaenge;
                   if vFieldType=ftWideString then Size := vlaenge;

                   with CreateField(vta, nil, vname, false) do
                   begin
                       DisplayLabel := vname;

                       FieldKind := fkLookup;
                       KeyFields := vschlussel;
                       LookupDataSet := vtalookup;
                       LookupKeyFields := vschlussellookup;
                       LookupResultField := vresultfeld;

                       if vFieldType=ftstring then Size := vlaenge;
                       if vFieldType=ftWideString then Size := vlaenge;

                       Name := vta.name + vname;
                       LookupCache := vusecache;
                       ProviderFlags := [];
                   end;
               end;
           end; // resultfeld o
       end;
   end;
end;


Creating calculated fields and lookupfields should be done in
OnBeforeOpen. I have informed Tim about this with a demo on friday and
hope that he gets back soon with a hint for us...

--
--
Yusuf Zorlu | MicrotronX
Mon, Oct 14 2019 7:31 AMPermanent Link

Yusuf Zorlu

MicrotronX - Speditionssoftware vom Profi

Roy Lambert wrote:

> Yusuf
>
>
> I can confirm that its happening. It seems to come from InternalClose
> in DB, but I can't find the actual spot. I suggest reporting to Tim
>
> Out of interest I'm going to spend another hour or so on it and if I
> find anything I'll post back.
>
> Roy Lambert

OK, so it has nothing to do with our Delphi IDE, it seems to be a
generic problem ... not existed some months ago ... Thanks for feedback
and your time

--
--
Yusuf Zorlu | MicrotronX
Mon, Oct 14 2019 9:56 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Yusuf


I'm running D2007 so it may have been around for a while

Roy Lambert
Mon, Oct 14 2019 10:26 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Yusuf


I am extremely grateful I never had a need to do anything even remotely like that.

Roy Lambert
Image