前回(はじめてのプログラミング#003)の投稿では、実際にプログラミングを行い、イベントを体感しました。
今回は、「プログラムの共通化」であるモジュールについて解説していきます。
なお、このブログの解説動画をYoutubeに用意していますので、あわせてご確認ください
前回は、シート1でカーソルを移動したときに、A1セルに今カーソルがある場所を表示しました。同じようにシート2、シート3でもカーソルを動かしたときにA1セルにカーソルの場所を表示してみましょう。
まずは、単純にSheet1に書いたプログラムをSheet2、Sheet3にコピーしてみましょう。
コピぺするだけなので問題なく動作すると思います。
では、全てのシートでA1セルに表示していたカーソルの場所をB3セルに表示するように変更してみましょう。
3シート分変更するだけなので、面倒と思いながらも短時間で変更できると思います。
でも、もし100シートあったとしたら、どうでしょうか??
非常に面倒です。そして、100シート変更中に間違える可能性もあります。
そこで、共通化(標準モジュール化)の考えが出てきます。
同じ処理をするプログラムを1つにまとめることを「(共通)モジュール化」と言います。
プログラムを1ヵ所だけに書いて、実行したい場所から呼び出します。
各シートごとのプログラムの処理は、シートごとに書いてきました。
では、全シートで使用する共通モジュールはどこに書くのでしょうか?
結論としては、どこに書いてもプログラムは動作します。
とは言っても、どこに書いたかわからなくなる可能性があります。
100シートあるブックの77シート目に共通モジュールを書いた場合、見つけるのに日が暮れてしまいます。
そこでExcelには共通モジュールを書く専用の場所が用意されています。
その名も「標準モジュール」です。
標準モジュールの追加は2通りあります。
VBAProject の空白部で右クリックし[挿入]→[標準モジュール]を選択するパターン
ツールアイコンの[ユーザ フォームの挿入]右の▼から[標準モジュール]を選択するパターン
どちらでも同じです。
標準モジュール「Module1」が追加されました。
ここへSheet1 ~ Sheet3 に書いていたプログラムと全く同じものを書きました。
せっかくなので標準モジュールにも名前を付けましょう。
「せっかく」と言うよりは、ちゃんとした名前を付けておかないと、後々「どこの標準モジュール」に書いたのかわからなくなります。
それでは、本末転倒です。
Module1を選択し、「オブジェクト名」に名前を付けます。今回は、「SheetModule」としました。
前回(はじめてのプログラミング#003)で解説した、「アクセス修飾子」を覚えていますか?
アクセス修飾子と言います。Excelでは、主に Private と Public の2種類があります。
このアクセス修飾子は、他のオブジェクトから使えるかどうか です。「Privateは使えない」「Publicは使える」となります。
先ほど、標準モジュールに記述したプログラムは、
Private Sub Worksheet_SelectionChange(Byval Target As Range)
ActiveSheet.Range("A1") = Target.Address
End Sub
と、アクセス修飾子が「Private」なっています。
たとえ共通モジュールを用意しても、このままでは Sheet1~Sheet3 から使うことができません。
「Private」を「Public」に変更しておきましょう。
Public Sub Worksheet_SelectionChange(Byval Target As Range)
ActiveSheet.Range("A1") = Target.Address
End Sub
Sheet1に書いたWorksheet_SelectionChangeと標準モジュール(SheetModule)に書いたWorksheet_SelectionChangeに違いがあることに気づきましたか?
Sheet1 の Worksheet_SelectionChange は
WorksheetオブジェクトのSelectionChangeイベントと認識されています。
一方、SheetModule の Worksheet_SelectionChange は {General} の Worksheet_SelectionChangeプロシージャとして認識されています。
この違いは、標準モジュールには「イベントがない」からです。
標準モジュールに書いたプログラムは、あくまでも「共通のプログラム部品」であり、Sheet1など、他の場所で発生したイベントから呼び出されて使われます。
では、さっそく標準モジュールに書いたWorksheet_SelectionChangeプロシージャを使ってみましょう。
Sheet1に書いたプログラム
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
ActiveSheet.Range("A1") = Target.Address
End Sub
を
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Call SheetModule.Worksheet_SelectionChange(Target)
End Sub
に変更します。このプログラムを解説していきます。
Call で他のプロシージャを呼び出しています。
ここでは、SheetModule にある Worksheet_SelectionChange プロシージャを呼び出しています。
パラメータ(引数)として、Target 変数を渡しています。
先述の通り、標準モジュールはイベントがないため、カーソルの場所が変わったことを検知できません。そのため、どこにカーソルがあるのかもわかりません。
そこで、Sheet1のイベント Worksheet_SelectionChange でカーソルの移動を検知し、カーソルの場所をパラメータとして標準モジュールに教えてあげる必要があります。
(Target) の部分がパラメータです・
ここで、Call と SheetModule は、省略可能です。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Worksheet_SelectionChange Target
End Sub
このように書いても動作します。
なお、Call を省略した場合、パラメータの()も不要になります。
ただし、注意が必要です。
それは、プロシージャ名が重複しないこと です。
SheetModule.Worksheet_SelectionChange と書いた場合は、標準モジュール SheetModuleにある Worksheet_SelectionChange であることがわかります。
ですが、SheetModule を省略した場合、どこの Worksheet_SelectionChange なのかわからなくなります。同じ名前があったら、どっちのWorksheet_SelectionChangeなのか判断ができずエラーになります。
Excelのイベント用プロシージャ名は オブジェクト_イベント となります。
Worksheet オブジェクトの SelectionChange イベント なので Worksheet_SelectionChange です。イベント用プロシージャと標準モジュールのプロシージャを区別する為に標準モジュールでは「_」(アンダバー)を使わないプロシージャ名にすることをお勧めします。
また、何をするためのプロシージャなのか分かりやすくするために ShowCurrentSelection (表示する。今選択されている項目を)のように動詞+名詞 の命名にするとよいでしょう。
今回は、共通で使えるプログラム部品「モジュール」の作り方について解説しました。
次回は、モジュールの汎用性について解説する予定です。
- PR -
Google Adsense
- PR -
Google Adsense