VBAの書籍を見ていると、だいたい標準モジュールにマクロを書くように指示されている。マクロの記録で保存されるのが標準モジュールということもその理由かもしれないし、そもそも「標準」という名前が「ふつうはここに書け」という指示に見えるのかもしれない。
シートモジュールも一応申し訳程度に使い方が説明されていたりする。たとえばシートのイベントを拾う処理はシートモジュールに書くとか、シートモジュールにRange("A1")と書くとアクティブシートではなく、そのシートのA1セルを指すとか。
でも積極的にシートモジュールにマクロを書こうという説明は見かけない。
シートモジュールはもっと普通に使っていいと思う。
どういうときにシートモジュールを使うと便利なのか
たとえば、一つのブックにたくさんシートがあって、それぞれにマクロが存在するような場合、全部標準モジュールに書いてしまうと後から見たときにどのマクロがどのシートに作用するものなのか分からなくなる。そこで、シートに関するマクロをそのシートのモジュールにまとめるとスッキリする。
そんなにたくさんシートがなくても、シートと不可分のマクロはシートモジュールに書くと良い。不可分というのは、そのシートが無いと意味をなさないようなマクロである。たとえば特定シートのRangeに直接値を突っ込むようなマクロはそのシートモジュールに書けばよい。
【参考】過去にシートモジュールに書いた例
thom.hateblo.jp
実務ではシート依存のマクロって結構あるはずなので、そういうのはほとんどシートモジュールに書いてしまえる。
逆に標準モジュールに書くケース
標準モジュールのメリットは、エクスポートして別のブックに簡単に移動できることだ。
つまり、いろんなシート・いろんなブックで汎用的に使えるようなマクロは標準モジュールに書いたほうが良い。あとは汎用的なFunctionプロシージャ。実質的に特定シートからしか使われてなくても、関数としては他にも使える可能性があれば、標準モジュールに書いておけばいい。
標準モジュールって名前が、「原則ここに」というニュアンスを醸し出してしまうのだが、どちらかといえば「汎用」に近い意味だと思う。
あとは、特定のシートを操作するマクロでも、そのシートが消えたり作られたりするケースでは標準モジュールを使うしかない。シートモジュールに書いたマクロはシートとべったりくっついているので、シートが消えればマクロも消える。同様の理由で、コピーされるシートにもマクロは書かないほうが良い。シートをコピーするとマクロごとコピーされてしまうためだ。
2つ以上のシートに跨る処理はどこに書くか
これは悩みどころであるが、シートに依存するところはそれぞれのシートにプロパティとして実装し、標準モジュールから操作する形で良いかと思う。
【参考】アプリ設定をシートにプロパティとして実装させた例
thom.hateblo.jp
あとこちらは2つ以上のシートではないが、プロパティと処理を分離している例として挙げておく。
※記事の最後のコード参照
thom.hateblo.jp
メインコードは以下の部分で、赤、緑、青、色見本がそれぞれプロパティである。
Sub 明るく() 赤 = 赤 + 20 緑 = 緑 + 20 青 = 青 + 20 色見本 = RGB(赤, 緑, 青) End Sub Sub 暗く() 赤 = 赤 - 20 緑 = 緑 - 20 青 = 青 - 20 色見本 = RGB(赤, 緑, 青) End Sub
上の例では全部シートモジュールに書いているが、明るく、暗くという命令を標準モジュールに書いた場合は[シートオブジェクト名.赤]などとすればプロパティにアクセスできる。
MVCに学ぶ設計手法
この先はちょっとややこしい話。
※参考情報なのでここまでの内容ですでに混乱してる方はスキップしてください。
MVCというのはModel、View、Controllerの略で、アプリケーションの設計手法のひとつである。
つまりデータと見た目とロジックはそれぞれ分離しなさいねって事かと。
まずこちらの記事でざっくりMVCの雰囲気を理解する。
qiita.com
実際にExcel VBAでMVCをやっている例も。
qiita.com
さて、MVCという語は誤用も多いみたいで、私も誰かに習った訳ではないので「これがMVCだ」なんて話はできない。ここで話すことは「MVCに学ぶ」であって「MVCを学ぶ」ではない。
Modelというのは先日書いた以下の記事がまさにモデルの話。
thom.hateblo.jp
Viewとはユーザーインターフェース。つまりユーザーが見たり書き換えたりする部分で、Excelではシートがそれに該当するだろう。
これはまさにこの記事で書いたシートにプロパティを実装することでViewになる。
Controllerは標準モジュールで良いのかな。
ってなことを考えながら書いたのが以下の記事。
thom.hateblo.jp
MVCをハッキリわかってないので、これがMVCだと宣言するつもりはないけれど、データはクラスに、シート操作はシートモジュールに、それらを操作するメイン処理は標準モジュールに分離できたのでメンテナンス性は良いと思う。
まとめ
シートモジュールはもっと普通に使って良い。特にシートと不可分のマクロはシートモジュールに書くとマクロの作用するシートがはっきりするので、コードの整理整頓になる。
2つのシートにまたがる処理は、シート固有の処理をプロパティとして実装すると標準モジュールに書くメインのコードが楽になる。