はじめに
本記事は前回の記事の続きとなります。前回は設計思想を整理しました。
【VBA】オブジェクト指向プログラミングのエッセンスを借りて構造化に挑む話
本テーマでは以下のカテゴリを書いていきます。
- 配列操作
- ライブラリ化
- 構造化
今回から汎用的に使える配列操作の機能を作っていきます。
実務でVBAを書いていると、特定の業務に依存したツールは増えていきますが、それらを別のマクロに再利用するのは意外と簡単ではありません。
そこで、業務ロジックを一旦離れ、Excelの基本機能である「データの加工」そのものに焦点を当てていきます。
なお、本連載では「配列の1行目はヘッダー行」という前提で話を進めさせていただきます。
配列操作でどうしても欲しいExcelの基本機能は以下のようなものではないでしょうか。
- データの抽出(フィルタ)
- データの削除
- 並べ替え
- 重複の削除
- ヘッダー(列)の選択と並べ替え
- SQL文での操作
これらをサクッと扱える「配列操作ライブラリ」が構築できるようにするため、フィルタを題材に「配列操作をどのように分解し、組み合わせるか」という観点で話を進めていきます。
フィルタを体系化する
以下の「3つの基本コンポーネント」を組み合わせることで、直感的に使える「2つのメイン機能」を実現します。
(名称は今後の拡張や他の言語を参考にしています)
【3つの基本コンポーネント】
-
Whereメソッド
条件に合致する「行番号」だけをリスト(Long配列)として取得する。 -
PickRowsメソッド
行番号リストを受け取り、該当する行を新しい配列に入れる。 -
DropRowsメソッド
行番号リストを受け取り、該当する行以外を新しい配列に入れる。
【組み合わせて実現するメイン機能】
- Filterメソッド(
Where+PickRows)
「条件に合うものだけ」を取り出す、お馴染みのフィルタ。 - Deleteメソッド(
Where+DropRows)
「条件に合うものを取り除く」という、逆転の発想の削除機能。
通常のフィルタは「条件と抽出」が一体になっています。そのため、複雑な条件になるほど、処理全体を書き直す必要が出てきます。
本設計では、条件(Where)と抽出(PickRows)を分離することで、「条件だけ差し替える」ことが可能になります。
例えば以下のようなケースです。
- 列Aと列Bの組み合わせで条件判定したい
- 前行との比較で抽出したい
- 別テーブルと突き合わせて抽出したい
このような条件は、通常のフィルタでは書きづらくなります。
しかし「行番号リスト」を返す設計であれば、Whereの実装に依存しない条件にも対応できます。利用側で行番号リストさえ作れば、高速な「抽出エンジン」であるPickRowsをそのまま再利用できるのです。
なお、Filter + Filter で段階的に絞り込むAND条件、Whereの結果(行番号)を結合(重複除去)することでOR条件を実現できます。
次回は、これらの機能を実装するための土台作りをします。
VBAエンジニアを常に悩ませる「LBound/UBoundの計算」や「+1の呪い」……。
あの配列操作の悪夢を軽減させるための、基盤となる小さな工夫となります。