MyBaseを試してみる。(Index、FilterでAggregateが変!?)
Index、Filterを設定するとAggregateの値がおかしくなります。どこか使い方が間違ってるのかな?よくわからないけど、Aggregateを使うときには、このことに注意が必要です。
起動時画面
その1
その2
★OnFilterRecordを使った場合
その1
その2
いろいろ試した結果、インデックスを入れ替えず、Filterプロパティでフィルター処理すれば正常な動作をしているようです。フィルター時には、フィルター処理後の合計金額が表示されますし、解除後は、正しい合計金額が表示されました。しかしOnFilterRecordでフィルター処理した場合は、正しく表示されませんでした。
起動時画面
その1
1.[ITEMでソート]を押すと、ITEMでソートされて、合計金額は表示されません。 ITEMでの並び替えは、合計金額の計算に影響はないでしょうって言いたく なりますが、表示されないなら別にいいけどー(^-^)
2.[ORD_IDXでソート]を押すと、再度、合計金額が表示されます。
3.フィルター[ON]を押すと、フィルター処理された合計金額が表示されます。
4.ここで[ITEMでソート]を押すと、なんと合計金額は2倍になりました。
5.驚いて[ORD_IDXでソート]を押すと、合計金額は3倍になりました。
6.これはいけないと思い、フィルター[OFF]を押すと元に戻りました。
その2
1.フィルター[ON]を押して、フィルター処理後の合計金額が正しいことを確認します。
2.フィルター[OFF]を押して、合計金額が正しいことを確認します。
3.[ITEMでソート]を押すと、なんと合計金額は2倍になりました。
4.驚いて[ORD_IDXでソート]を押すと、合計金額は3倍になりました。
5.再び[ITEMでソート]を押すと、なんと合計金額は、4倍になりました。
6.もう一度[ORD_IDXでソート]を押すと、なんと合計金額は、5倍になりました。
[ITEMでソート]、[ORD_IDXでソート]を交互に押すと、合計金額はとどまるところを 知らないようです。(^-^)
★OnFilterRecordを使った場合
その1
1.[ITEMでソート]を押すと・・・ITEMでソートされて、合計金額は表示されません。
2.[ORD_IDXでソート]を押すと・・・再度、合計金額が表示されます。
3.フィルター[ON]を押すと・・・合計金額が表示されません。
しかしここで、次のレコードに移動させるとフィルター処理前の合計金額が 表示されています。
4.ここで[ITEMでソート]を押すと・・・合計金額は表示されません。
5.驚いて[ORD_IDX]を押すと・・・合計金額は表示されません。
6.これはいけないと思い、フィルター[OFF]を押すと・・・合計金額は表示されません。
その2
1.フィルター[ON]を押すと・・・合計金額が表示されません。 しかしここで、次のレコードに移動させるとフィルター処理前の合計金額が 表示されました。
2.フィルター[OFF]を押して、合計金額が正しいことを確認します。 合計金額は正しく表示されました。
と思ったけど、フィルター処理されたレコードに移動させると、 合計金額が消えてしまいました。
3.[ITEMでソート]を押すと・・・合計金額は表示されません。
4.驚いて[ORD_IDX]を押すと・・・合計金額は表示されません。
5.[ITEMでソート]を押すと・・・合計金額は表示されません。
6.[ORD_IDXでソート]を押すと・・・合計金額は表示されません。
7.[ITEMでソート]、[ORD_IDXでソート]を交互に押すと・・・ 合計金額は表示されません。
いろいろ試した結果、インデックスを入れ替えず、Filterプロパティでフィルター処理すれば正常な動作をしているようです。フィルター時には、フィルター処理後の合計金額が表示されますし、解除後は、正しい合計金額が表示されました。しかしOnFilterRecordでフィルター処理した場合は、正しく表示されませんでした。
// COMMON // サンプルデータを追加します。 procedure MakeSample(CDS: TClientDataSet); var No: Integer; F: Boolean; begin F := CDS.Active; if not F then CDS.Open; try // サンプルデータの追加 No := 0; with CDS do begin Inc(No); Appendrecord([No, 'Delphi XE2 Starter ESD',10,'本',18000]); Inc(No); Appendrecord([No, 'Delphi XE2 Professional ESD',5,'本',94000]); Inc(No); Appendrecord([No, 'Delphi XE2 Enterprise ESD',10,'本',236000]); Inc(No); Appendrecord([No, 'Delphi XE2 Ultimate ESD',3,'本',356000]); Inc(No); Appendrecord([No, 'Delphi XE2 Architect ESD',1,'本',416000]); CheckBrowseMode; end; finally if not F then CDS.Close; end; end; // データベースの作成 procedure CreateDB(CDS: TClientDataSet); var I: Integer; begin // データベースの作成 CDS.Close; CDS.FieldDefs.Add('ORD',ftInteger); CDS.FieldDefs.Add('ITEM',ftWideString,30); CDS.FieldDefs.Add('QTY',ftFloat); CDS.FieldDefs.Add('UNIT',ftWideString,4); CDS.FieldDefs.Add('PRICE',ftCurrency); CDS.IndexDefs.Add('ORD_IDX','ORD', [ixPrimary]); //CDS.IndexDefs.Add('ITEM_IDX','ITEM', []); CDS.CreateDataSet; CDS.Close; for I := 0 to CDS.FieldDefs.Count - 1 do CDS.FieldDefs[I].CreateField(CDS); // 計算フィールド with TCurrencyField.Create(CDS) do begin FieldName := 'AMOUNT'; Visible:=True; FieldKind := fkInternalCalc; DataSet := CDS; end; // 集合フィールド with TAggregateField.Create(CDS) do begin DisplayLabel := '合計'; DisplayWidth := 10; DisplayFormat := '#,###,###,###'; AlignMent := taRightJustify; FieldKind := fkAggregate; FieldName := 'TOTAL_F'; ReadOnly := True; Expression := 'SUM(AMOUNT)'; Active := True; DataSet := CDS; end; CDS.AggregatesActive := True; // インデックスの設定 CDS.IndexName := 'ORD_IDX'; // 表示用にフィールド幅を設定 CDS.FieldByName('ORD').DisplayWidth := 3; CDS.FieldByName('ITEM').DisplayWidth := 25; CDS.FieldByName('QTY').DisplayWidth := 3; CDS.FieldByName('UNIT').DisplayWidth := 4; CDS.FieldByName('PRICE').DisplayWidth := 8; CDS.FieldByName('AMOUNT').DisplayWidth := 10; // 計算フィールドの設定 CDS.OnCalcFields := Form1.CalcFields; // DBEditの設定 Form1.DBEdit1.DataField := 'TOTAL_F'; CDS.Open; // サンプルデータの作成 MakeSample(CDS); end; procedure TForm1.FormCreate(Sender: TObject); begin CreateDB(ClientDataSet1); end; procedure TForm1.ClientDataSet1FilterRecord(DataSet: TDataSet; var Accept: Boolean); begin Accept := AnsiPos(Edit1.Text, DataSet.FieldByName('ITEM').AsString) > 0; end; // 計算フィールド procedure TForm1.CalcFields(DataSet: TDataSet); begin DataSet.FieldByName('AMOUNT').AsCurrency := DataSet.FieldByName('QTY').AsFloat * DataSet.FieldByName('Price').AsCurrency; end; // フィルターON procedure TForm1.SpeedButton3Click(Sender: TObject); begin //ClientDataSet1.Filter := 'ITEM LIKE '+QuotedStr('%'+ Edit1.Text+'%'); ClientDataSet1.Filtered := True; end; // フィルターOFF procedure TForm1.SpeedButton4Click(Sender: TObject); begin ClientDataSet1.Filtered := False; ClientDataSet1.Filter := ''; end; // インデックス ITEM procedure TForm1.SpeedButton2Click(Sender: TObject); begin ClientDataSet1.IndexFieldNames := 'ITEM'; // ClientDataSet1.IndexName := 'ITEM_IDX'; end; // インデックス ORD_IDX procedure TForm1.SpeedButton1Click(Sender: TObject); begin ClientDataSet1.IndexName := 'ORD_IDX'; end; // Helpより // メモ: IndexFieldNames プロパティと // IndexName プロパティは相互に排他的です。 // 一方を設定するともう一方はクリアされます。
| 固定リンク