Microsoft Access 掲示板

売上を様々な形で集計するときの動作速度について

7 コメント
views
4 フォロー

日々売上を入力していくテーブルがあるときに、
そのテーブルのレコードを取引先ごとや年ごと月ごとに集計するときには
条件を指定するフォームをつくり、そこからレポートを作成するという流れになりますか?

PCのスペックにもよると思いますが、レコードがどの程度になると、動作的に常用できなくなりますか?
上記のような集計ですと、テーブルの全レコードを対象としてDSum関数で計算することになると思うのですが
DSum関数はとても実用的ではない、といったネットの解説で読んだので不安です

エアー
作成: 2021/05/16 (日) 17:02:22
通報 ...
1
りんご 2021/05/16 (日) 19:32:45 48103@0e907

テーブル→クエリ→フォーム→レポートでいいと思う。
Dsum動作比較は、下記、サイトがありました。

■T'sWare Access Labo #28 〜明細データテーブルの集計を考える〜
tsware

3
りんご 2021/05/16 (日) 23:46:37 48103@0e907 >> 1

 ごめんなさい、Dsum動作比較のサイトを紹介しましたが、中身をよくわかっていませんでした。ちょうど使ってみて、使い勝手がいいじゃんと思ったんですけど、重くなりそうになったら要変更ですね。
 下記、Hatenaさんの解説を読んで下さい、納得です。

2

りんごさんも回答されているようにテーブル→クエリ→フォーム→レポートがベストだと思います。
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行ずつダラダラと表示されていく) 」という動作からもそう推測できます。表示するとき(集計結果にアクセスするとき)にはじめて集計されるということだと思います。

4
エアー 2021/05/17 (月) 17:58:09 58219@6dd7b

詳しい解説ありがとうございます
やはりDsumを使わなくてすむなら使わないほうがいいんですね。マスタとかレコードが少ないテーブルで
なんらかの集計をするときにパッと使える関数といった使い方のほうがいいのかもしれませんね

テーブル→クエリ→フォーム→レポート
といった処理にする場合、
テーブルのレコードに対する集計条件(年度や取引先、商品などをテキストボックスに入力して指定する)を都度変えるのなら
テーブル→フォーム→クエリ→フォーム→レポート
ということになりますか?

5
hatena 2021/05/17 (月) 19:00:07 修正

適材適所で選択できるようになるといいでしょう。

フォームやレポートでグループ単位の集計を表示する場合は、複数の集計が必要になるのでDSumは重くなるので避けた方かいいでしょうか。
ただし、フォームでデータ編集もしたいときだと、集計クエリだと更新できないので、DSumで集計を表示する場合もあります。

フォームやレポート上にあるデータの全体の合計を1つのみ表示する場合はテキストボックスのコントロールソースにDSum関数を使って表示させてもいいでしょうか。

6
エアー 2021/05/18 (火) 16:51:56 58219@6dd7b

基本的には取引先ごとの年間集計が必要になると思うので、前もってクエリを作成しておき
年間集計ボタンを押すとそれを表示させるのがよさそうですね
集計なので基本的に編集することもなさそうですし

集計なので個々のレコードが表示されないと思うのですが、なぜその集計金額になったのかを確認するために、

年数 取引先 金額  
2020 AAA  10000  詳細
2020 BBB   20000  詳細
2021  AAA  2000   詳細

と集計を出したときに、各集計の横に詳細ボタンを配置して押すと
フォームを開いて、集計元のレコード一覧を表示させることなどはできますか?

7
りんご 2021/05/18 (火) 19:13:15 48103@0e907

 例えば、最初の行2020,AAA,10000を選ぶと、集計前のクエリが絞り込まれて、2020,AAAのレコード一覧が表示されるという方針はいかがでしょうか?
 この方針でやってみるならば、スレを閉じて、集計前のクエリを絞り込むフォーム作りから始めましょう。