Cannot assign data to client dataset

时光毁灭记忆、已成空白 提交于 2019-12-12 05:27:01

问题


I'm using TClientDataSet assigned with local data in my Delphi application to compare data between 2 tables located in 2 different databases. Things I'm using:

  • SpPlansQuery: TADOQuery – original data query
  • PPUQuery: TADOQuery – changed data query (uses different ADO connection than SpPlansQuery)
  • ComparisonDataSet: TClientDataSet – dataset showing only differences between 2 previous queries

I'm trying to fill ComparisonDataSet as follows (I heavily reduced my code to highlight problem):

procedure TComparisonSpPlanForm.RefillDataSet;
const
  // IMPORTANT: check that fields count in next 2 lines would be the same
  FieldsStr1 = 'Article_PPU;Contractor_S_PPU;Recipient_S_PPU;OrderNum_PPU;OrderNum2_PPU;OrdN_PPU;Title_PPU;Queue_PPU;KolSht_PPU;Weight1_PPU;Material_PPU;Drawing_PPU;Graph_PPU';
  FieldsStr2 = 'Title_1;Title_3;Title_4;num;inum;onum;Title;QNum;num_of;weight;Title_2;Drawing;Graph';
var
  Deleted: Boolean;
  FieldValues2: Variant;
  FieldValues1: Variant;
begin
  ComparisonDataSet.DisableControls;
  // clear ComparisonDataSet
  if ComparisonDataSet.Active then
    ComparisonDataSet.Close;
  ComparisonDataSet.CreateDataSet;
  // deleted records
  SpPlansQuery.First;
  while not SpPlansQuery.Eof do
  begin
    FieldValues1 := SpPlansQuery[ReplaceStr(FieldsStr1, '_PPU', '')];
    Deleted := not PPUQuery.Locate('ID', Integer(SpPlansQuery['PPONREC']), []);
    if Deleted then
    begin
      ComparisonDataSet.Append;
      // next string throws exception and this is a big problem
      ComparisonDataSet[ReplaceStr(FieldsStr1, '_PPU', '')] := FieldValues1; 
      ComparisonDataSet.Post;
    end;
    SpPlansQuery.Next;
  end;
  ComparisonDataSet.First;
  ComparisonDataSet.EnableControls;
end;

As far you can guess, ComparisonDataSet contains fields named ARTICLE and ARTICLE_PPU and exception with message "Cannot convert variant type of (Null) into type (Integer)" occurs when I try to assign value to ComparisonDataSet['ARTICLE']. I know this because I tried assigning directly to that field but got the same result.

ARTICLE is a string field with length of 20 characters.

Can anyone point me how to assign values to fields in a TClientDataSet without getting errors?

As requested below, this is my field definition:

In ComparisonSpPlanUnit.dfm:

object ComparisonDataSet: TClientDataSet
  Aggregates = <>
  FieldDefs = <
  ...
    item
      Name = 'ARTICLE'
      DataType = ftString
      Size = 20
    end>
  ...
  object ComparisonDataSetARTICLE: TStringField
    DisplayLabel = #1057#1090#1072#1090#1100#1103
    FieldName = 'ARTICLE'
  end
  ...
end

In ComparisonSpPlanUnit.pas:

ComparisonDataSetARTICLE: TStringField;

回答1:


During debug I found that exception is raised deep inside source code of Data.DB module, inside TStringField.SetVarValue procedure, so it seemed a bug. But I was wrong: deeper debugging highlighted that exception is raised during calculation of auto-calculated fields.

So I had to change my other function:

procedure TComparisonSpPlanForm.ComparisonDataSetCalcFields(DataSet: TDataSet);
begin
  // comparing to Null is essential!
  if DataSet['Oper'] <> Null then
    case DataSet['Oper'] of
      0: DataSet['OperStr'] := 'insert';
      1: DataSet['OperStr'] := 'update';
      2: DataSet['OperStr'] := 'delete';
      else
        DataSet['OperStr'] := 'other';
    end
  else
    DataSet['OperStr'] := 'other';
end;

and it works now.



来源:https://stackoverflow.com/questions/23905201/cannot-assign-data-to-client-dataset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!