Page 1 of 1

MemDataSet "field not found" on setting calculated field val

Posted: Fri 14 May 2010 10:11
by upscene
Hi,

For some reason, TMemDataSet raises "Field not found" when setting a value on a calculated field.

I tried reproducing this in a test application, but there it works fine.

The Delphi "Field not found" error has quotes around the field name and I noticed TMemDataSet has not.

I do not have the source of TMemDataSet, so I cannot trace into it :(

This error has been annoying me for hours.

Here's the call stack:

Code: Select all

kernel32.RaiseException
TMemDataSet.GetFieldDescNo + $71
TMemDataSet.SetFieldData + $19A
TDataSet.SetFieldData +$4B
TMemDataSet.SetFieldData + $3C
TField.SetData + $89
...
All fields are set to ReadOnly = False.

The code in OnCalcField is very simple:

Code: Select all

var
  n: Integer;
begin
  for n := 0 to DataSet.FieldCount - 1
  do if DataSet.Fields[n].Calculated
     then DataSet.Fields[n].AsBoolean := False
and the name of the field in the error message is the name of DataSet.Fields[n]

Any clue what could cause this?


Edit:
The calculated field is added before I do .Open -- when I call .Prepare before the call to FieldDefs.Update and adding the fields, the test application fails with the error message "Field not found." when this is not done, it works fine.

So, currently, this is what's done:

1) query with SQL statement
2) .Prepare
3) .FieldDefs.Update;
4) add calculated field
5) .Open
6) In OnCalcFields event: MyCalcField.AsBoolean := False;

Step 6 fails if step 2 is included, why?

Posted: Fri 14 May 2010 12:32
by Dimon
The problem occurs because the Prepare method creates fields of resultset. To solve the problem call Prepare after creating fields.

Posted: Fri 14 May 2010 12:44
by upscene
Dimon wrote:The problem occurs because the Prepare method creates fields of resultset. To solve the problem call Prepare after creating fields.
The fields are created automatically at run-time, I'm explicitly calling FieldDefs.Update to fill the fields, as before Open, there aren't any FieldDefs.

Next, I'm calling TDataSet.CreateFields and then adding my calculated field.

Posted: Fri 14 May 2010 12:49
by Dimon
Call the Prepare method after adding the calculated field.

Posted: Fri 14 May 2010 12:53
by upscene
Dimon wrote:Call the Prepare method after adding the calculated field.
Can I call it a 2nd time? Cause I'm only adding the calculated field in a specific case and this case is determined by checking for specific field types in the result set (which is user defined).

Posted: Fri 14 May 2010 14:00
by Dimon
In this case you should unprepare the query, create fields, and prepare the query again, like this:

Code: Select all

  if NeedToCreateFields then begin
    MSQuery1.UnPrepare;
    CreateFields;
    MSQuery1.Prepare;
  end;