マクロは最低限と思っています。関数で記述できるものはマクロで記載しないよう、後輩にもそのように指導(?)して来ました。なぜなら、マクロを書ける人は少なく、また、コメントが十分でないと解析も困難で、引き継ぎ時に問題が生じると考えたからです。
なので、
この辺りまでは関数だけでできる
というのを書いてみたいと思います。
機能
以下の2つの情報があるとします。
- 購入者ID・商品ID・購入個数・日付
- 商品ID・価格
これらデータから、
- 「開始日」と「終了日」を入れると購入額の大きな順に購入者IDと購入額合計を自動算出する
ツールを関数だけで作りたいと思います。
インターフェース
データは以下です。通常日付順かとは思いますが、ランダムであっても処理できます。

こちらは単価表です。

以下のシートで、「開始日」と「終了日」を入れると上記データから処理を行い出力します。

なお「データの順番変更」はデバック用に「購入者ID・商品ID・購入個数・日付」のデータセット(行)をランダムに変更しても結果に影響が無いことを確認するために準備しました。すみませんが、こちらはマクロを使用しています。
実装
関数の実装は「対象レコード」と「購入者」です。(ファイルは一番下にリンクがあります。)
「対象レコード」では関係するレコードのみをピックアップします。
(1)セルB3を見てみると
=IF(AND(購入者!I$2<=A3,A3<=購入者!I$3),1,””)
としています。A3の日付がシート「購入者」の日付内であることを確認しています。
(2)列C~Fは列Bで判定して範囲内であったものを出力しています。(式は省略)
(3)列HとIで重複を削除しています。ここが少し工夫している個所となります。
列Hでは出現回数をカウントしています。2以上だと複数回出現したことになります。
=IF(B3<>””,COUNTIF($C$2:$C3,C3),””)
列Iでは初めての出現(=列Hが1)の場合に表示するよう設定しています。
=IF(G3=1,C3,””)
(4)「購入者」のシートに移ります。列Cでは(3)で作成した重複削除の購入者一覧を作成しています。エラー(購入者が列Aの番号分いない)場合は空白とします。
=IFERROR(VLOOKUP(A6,対象レコード!$H$2:$I$78,2,FALSE),””)
(5)列Dでは(4)での購入者の購入額合計をSUMIFで求めます。
=SUMIF(対象レコード!C$2:C$78,C6,対象レコード!F$2:F$78)
(6)列Bに戻りますが合計順にソートするためRANK関数を使用します。
=RANK(D6,D$6:D$35)
素直に列Eとすればよいのですが次の(7)で使用するVLOOKUPの列番号は負の値を入れられないので、このような順番となっています。
(7)ソート結果です。G列、H列で(6)のランク順に並べ替えます。
=IFERROR(VLOOKUP(A6,$B$6:$C$35,2,FALSE),””)
=IF(C6<>””,VLOOKUP(A6,$B$6:$D$35,3,FALSE),””)
お疲れさまでした。
まとめ
マクロを使わなくても一定の処理はできる様子がうかがえればと思って作ってみました。
ファイルは こちら になります。

