【问题标题】:Cannot assign data to client dataset无法将数据分配给客户端数据集
【发布时间】:2014-07-17 07:08:53
【问题描述】:

我在我的 Delphi 应用程序中使用分配有本地数据的 TClientDataSet 来比较位于 2 个不同数据库中的 2 个表之间的数据。我正在使用的东西:

  • SpPlansQuery: TADOQuery – 原始数据查询
  • PPUQuery: TADOQuery – 更改数据查询(使用与 SpPlansQuery 不同的 ADO 连接)
  • ComparisonDataSet: TClientDataSet – 数据集仅显示 2 个先前查询之间的差异

我正在尝试如下填写ComparisonDataSet(我大大减少了代码以突出显示问题):

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;

据您所知,ComparisonDataSet 包含名为 ARTICLEARTICLE_PPU 的字段,当我尝试将值分配给 ComparisonDataSet['ARTICLE'] 时,出现异常消息“无法将 (Null) 的变体类型转换为类型 (Integer)” .我知道这一点是因为我尝试直接分配给该字段但得到了相同的结果。

ARTICLE是一个长度为20个字符的字符串字段。

谁能指出如何为 TClientDataSet 中的字段分配值而不会出错?

按照下面的要求,这是我的字段定义:

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

ComparisonSpPlanUnit.pas:

ComparisonDataSetARTICLE: TStringField;

【问题讨论】:

  • 提示:你有if ComparisondataSet.Active then ComparisonDataSet.Close;。您应该能够删除 if 检查。请记住:没有任何贡献的代码可能对应用程序的运行无害,但它确实会妨碍代码维护。
  • 您是如何定义该字段的。您可能需要提供 DFM 的 sn-p 或实际定义 ComparisonDataSet 结构的代码。
  • @CraigYoung 添加了字段定义
  • 我有点茫然,现在无法进行实验,但是您尝试过FieldByName()吗?我也对这条线有点怀疑:ComparisonDataSet[ReplaceStr(FieldsStr1, '_PPU', '')]。鉴于 const 值 FieldStr1,我希望它的计算结果为:ComparisonDataSet['Article;Contractor_S;Recipient_S;OrderNum;OrderNum2;OrdN;Title;Queue;KolSht;Weight1;Material;Drawing;Graph']。这是正确的吗?您确定要识别单个字段,而不是所有字段?
  • 谢谢。其实我找到了解决办法。我有一个导致异常的计算字段。

标签: delphi delphi-xe2 tclientdataset


【解决方案1】:

在调试过程中,我发现在Data.DB 模块的源代码内部,TStringField.SetVarValue 过程内部引发了异常,所以这似乎是一个错误。但我错了:更深入的调试突出显示在计算自动计算字段期间引发了异常。

所以我不得不改变我的其他功能:

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;

现在可以使用了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 2018-02-14
    相关资源
    最近更新 更多