りんごさんも回答されているようにテーブル→クエリ→フォーム→レポートがベストだと思います。
DSumは重くなります。
りんごさんが提示したリンク先
■T'sWare Access Labo #28 ~明細データテーブルの集計を考える~
には、
DSum関数を使った集計は、他のクエリーに比べて処理時間が極端に少なく、特にレコード移動した場合の優位性は歴然・・・・・・定義域集計関数は一般に遅いといわれるがなぜ?、理屈はサブクエリーと同じだと思うのだが
というような解説がありますが、これはテスト方法が間違っている。あるいはテスト結果の解釈が間違っていると思います。
テスト法は、DAOでレコードセットを開く、最終レコードへ移動する、ということだけをしています。
実際に使用する場合、集計結果を利用するはずです。集計結果を取得せずに最終レコード移動だけするという無意味な処理で速度を比較しても無意味だと思います。
具体的には下記のような処理にかかる時間を計測しています。
Set qdf = dbs.QueryDefs(strQryName)
Set rst = qdf.OpenRecordset() 'レコードセットを開く
rst.MoveLast '最終レコードへ移動
rst.Close
qdf.Close
これでは上記で説明したように無意味なテストです。
下記のように各レコードにアクセスして集計結果を取得する処理を計測すべきでしょう。
Set qdf = dbs.QueryDefs(strQryName)
Set rst = qdf.OpenRecordset() 'レコードセットを開く
Do until rst.EOF
Debug.Print rst!発注数 & "," & rst!入庫数 & "," & rst!出庫数
rst.MoveNext
Next
rst.Close
qdf.Close
これだとDSumが一番遅くなるはずです。レポートに出力する場合も、集計結果を出力することになるのでDSumが一番遅くなるはずです。
また、上記リンク先には下記のような解説もあります。
DSum関数を使ったクエリー「DSum集計」をデータシートビューで開くと、他のクエリーに比べて非常に画面表示に時間がかかる(1行ずつダラダラと表示されていく)のに、VBAのレコードセットとして扱うとかなり速い
実際にクエリを開くと時間がかかるといっています。
レコードセットとして扱うと速いといってますが、OpenRecordset と MoveLast だけでは速いのは間違いではないですが、実際問題、OpenRecordset と MoveLast だけの処理というのはありえません。
T'sWareさんのサイトは有用な情報が多いのですが、たまにこのように外してい情報があるので注意が必要だと思います。
私の経験上、下記のような動作だと推測しています。
集計クエリでは、OpenRecordsetした時点で集計をしている。
サブクエリを利用した集計では、OpenRecordsetした時点では集計はしていない。レコード移動するときに集計する。
DSumでは、OpenRecordsetした時点では集計しない、レコード移動しただけも集計しない、集計結果にアクセスするときにはじめて集計する。
DSumでの「他のクエリーに比べて非常に画面表示に時間がかかる(1行ずつダラダラと表示されていく) 」という動作からもそう推測できます。表示するとき(集計結果にアクセスするとき)にはじめて集計されるということだと思います。