11

TClientDataSetのデータセットによって提供される、がありますTTable。データセットには、郵便番号(string、5)と通り(string、20)の2つのフィールドがあります。

実行時に、3番目のフィールド(文字列、20)を表示したいと思います。このフィールドのルーチンは、パラメータとして郵便番号を取得し、この郵便番号に属する都市を返します。

問題は、既存のフィールドに計算フィールドを追加することだけです。データ自体の入力は問題ではありません。

私は試した:

  cds.SetProvider(Table1);
  cds.FieldDefs.Add('city', ftString, 20);

  cds.Open;

  cds.Edit;
  cds.FieldByName('city').AsString := 'Test';  // --> errormessage (field not found)
  cds.Post;

cdsは私のclientdatasetでTable1あり、パラドックステーブルですが、問題は他のデータベースでも同じです。

前もって感謝します

4

5 に答える 5

25

基になるデータに存在するもの以外のフィールドを追加する場合は、既存のフィールドも手動で追加する必要があります。フィールドを追加するときはデータセットを閉じる必要がありますが、FieldDefs.Updateすべてのフィールドの詳細を手動で追跡したくない場合は、必要なメタデータを使用できます。基本的には次のようなものです:

var
  i: Integer;
  Field: TField;
begin    
  cds.SetProvider(Table1);

  // add existing fields
  cds.FieldDefs.Update;
  for i := 0 to cds.FieldDefs.Count - 1 do 
    cds.FieldDefs[i].CreateField(cds);

  // add calculated field
  Field := TStringField.Create(cds);
  Field.FieldName := 'city';
  Field.Calculated := True;
  Field.DataSet := cds;

  cds.Open;
end;


Cary Jensenによるこの優れた記事も参照してください。

于 2011-02-08T15:06:27.080 に答える
5

SQLに24個のフィールドがあるので、もっと簡単な解決策を見つけました。それらをすべて手動で追加したくなかったので、代わりに次のようにダミーフィールドをsqlステートメントに追加しました。

select '      ' as city, the rest of the fields ... 

これは、プログラムのOnAfterOpenイベントで変更できます。

十分な空のスペース、たとえば5文字の5つの空のスペースを残して、そのフィールドの長さをSQLで定義する必要があったので、都市名の長さを知る必要があります。

于 2011-02-09T08:49:19.693 に答える
3

存在しないフィールドに対するより正確なクエリを共有したいと思います。スペースではなく、キャストを使用する方が良いに違いありません!

select E.NAME, E.SURNAME, cast(null as varchar(20)) as CITY
from EMPLOYEE E

例えば| Marc'O | Polo | <NULL> |

より正確で、フィールドサイズを明確に確認でき、理解しやすく、簡単で、安全です!

于 2014-06-06T11:37:22.097 に答える
3

CreateDatasetフィールドを追加した後に 使用する必要があります。

cds.SetProvider(Table1);
cds.FieldDefs.Add('city', ftString, 20);
cds.CreateDataset; 

cds.Open;
cds.Edit;
cds.FieldByName('city').AsString := 'Test';  
cds.Post;
于 2015-05-13T10:27:24.887 に答える
1

既存の「動的」データ フィールド (プロバイダー側​​から) を追加のクライアント側永続フィールド (計算、ルックアップ、内部計算、集計) と結合する場合は、CDS をサブクラス化する必要があります。追加のブール値プロパティ CombineFields を導入し、BindFields (新しい Delphi バージョンの場合) または InternalOpen 全体 (d2006/2007 で行ったように) を次の行でオーバーライドします。

DefaultFields または CombineFields の場合は CreateFields。{ TODO -ovavan -cSIC : CombineFields が true の場合、永続フィールドはデフォルトのフィールドと共存します }

これにより、FieldDefs/CreateField を使用した実行時の混乱をすべて回避できます。

于 2012-04-28T07:47:15.387 に答える