2

次のようなマスター/詳細 ClientDataSet があります (これらは実行時に作成/入力され、API 呼び出しから返されたデータが入力され、データベース接続はありません):

Services:
  ID
  Name
  BasePrice
  etc.

AddOns:
  Selected
  ID
  ServiceID
  Name
  Quantity
  UnitCost
  TotalCost
  etc.

サービスをドロップダウン フィールドとして表示し、そのサービスで利用可能なアドオンをグリッドに入力します。フィールド「TotalCost」は、グリッドの独自の列に表示される計算フィールドです。「選択済み」フィールドは、グリッドに表示されるチェックボックスを追跡するために使用され、顧客が特定のアドオンを望んでいることを示します。

これはすべて期待どおりに機能します。次に、サービスとアドオンの合計コストを計算する必要があります。以下を使用して取得できるサービスのコスト:

ClientDataSetServices.FieldByName('BasePrice').Value

ただし、選択した各アドオンから TotalCost を取得できません。Aggregate フィールドを使用できると思っていましたが、検索の結果、マスター/詳細設定を使用してこれを実行できないことがわかりました。また、次のように ClientsDataSet の詳細を単純に反復しようとしました。

  (within the CalcFields method of the details ClientDataSet)
  // Add parts to parts cost
  grdMain.DataSource.DataSet.First;
  while not grdMain.DataSource.DataSet.Eof do begin

    if (grdMain.DataSource.DataSet.FieldByName('Selected').Value) then begin
      FPartsCost := FPartsCost +      
                    grdMain.DataSource.DataSet.FieldByName('TotalPrice').Value;
    end;

    grdMain.DataSource.DataSet.Next;
  end;

しかし、これは無限ループを引き起こします。コードのこの部分をデバッグすると、...DataSet.First が CalcFields (または CalcFields を呼び出している別のもの) を呼び出していることがわかります。

選択したアドオンの DataSet を繰り返し処理して、総コストを動的に計算するにはどうすればよいですか (選択または数量が変更されるたびに)。

- 編集 -

次のように、詳細テーブルに集計を設定しようとしました。

  • TAggregate 'AggregatePrice' を追加
  • 次のようにフィールドを設定します。 Active - True Name - AggregatePrice' Expression - SUM(TotalPrice) GroupingLevel - 1 IndexName - ServiceId Visible - True

これを実行すると、「フィールド 'TotalPrice' は集計で使用される正しいタイプの計算フィールドではありません。内部計算を使用してください」というエラー メッセージが表示されます。

4

2 に答える 2

5

編集後、答えは明らかです。単純な Cal​​cField の代わりに InternalCalc フィールドを使用してください。

計算は引き続き OnCalcField 内で行われますが、dsInternalCalc の TDataset.State を確認する必要があります。

これが必要なのは、集計が dsInternalCalc の後、dsCalcFields 状態の前に計算されるためです。

ちなみに、InternalCalc フィールドはインデックスに使用できますが、単純な Cal​​cField は使用できません。

于 2012-04-25T21:46:37.083 に答える
0

1 つの方法は、詳細に Cloned Cursor を使用することです。これは、データセットのコピーであり、ソースのコンテンツとの同期が保たれていますが、独立してナビゲートできます。

例えば。

CopyCDS.CloneCursor(OriginalCDS,False); // check params in help to see options
CopyCDS.First;
while not CopyCDS.EOF do
  begin
  // do stuff to calculate what you need
  CopyCDS.Next;
  end;

複製されたカーソルには、元のカーソルに関連付けられた計算フィールドやイベントがないため、必要に応じてそれらを再度設定する必要があることに注意してください。

于 2012-04-25T16:32:21.007 に答える