はじめてのプログラミング#004

  • SYSTEM
  • 2022年06月27日 00時03分

前回(はじめてのプログラミング#003)の投稿では、実際にプログラミングを行い、イベントを体感しました。
今回は、「プログラムの共通化」であるモジュールについて解説していきます。

なお、このブログの解説動画をYoutubeに用意していますので、あわせてご確認ください

目次

  1. すべてのシートでイベントを動作させる
  2. 標準モジュール
    1. 標準モジュールはどこに書く?
    2. 標準モジュールを追加する
  3. アクセス修飾子
  4. 標準モジュールはイベントを知らない
  5. 標準モジュールを使ってみよう
  6. まとめ

1.すべてのシートでイベントを動作させる

前回は、シート1でカーソルを移動したときに、A1セルに今カーソルがある場所を表示しました。同じようにシート2、シート3でもカーソルを動かしたときにA1セルにカーソルの場所を表示してみましょう。


まずは、単純にSheet1に書いたプログラムをSheet2、Sheet3にコピーしてみましょう。

コピぺするだけなので問題なく動作すると思います。


では、全てのシートでA1セルに表示していたカーソルの場所をB3セルに表示するように変更してみましょう。
3シート分変更するだけなので、面倒と思いながらも短時間で変更できると思います。

でも、もし100シートあったとしたら、どうでしょうか??
非常に面倒です。そして、100シート変更中に間違える可能性もあります。

そこで、共通化(標準モジュール化)の考えが出てきます。

2.標準モジュール

同じ処理をするプログラムを1つにまとめることを「(共通)モジュール化」と言います。
プログラムを1ヵ所だけに書いて、実行したい場所から呼び出します。

2-1.標準モジュールはどこに書く?

各シートごとのプログラムの処理は、シートごとに書いてきました。

では、全シートで使用する共通モジュールはどこに書くのでしょうか?
結論としては、どこに書いてもプログラムは動作します。
とは言っても、どこに書いたかわからなくなる可能性があります。
100シートあるブックの77シート目に共通モジュールを書いた場合、見つけるのに日が暮れてしまいます。

そこでExcelには共通モジュールを書く専用の場所が用意されています。
その名も「標準モジュール」です。

2-2.標準モジュールを追加する

標準モジュールの追加は2通りあります。

VBAProject の空白部で右クリックし[挿入]→[標準モジュール]を選択するパターン

ツールアイコンの[ユーザ フォームの挿入]右の▼から[標準モジュール]を選択するパターン

どちらでも同じです。


標準モジュール「Module1」が追加されました。

ここへSheet1 ~ Sheet3 に書いていたプログラムと全く同じものを書きました。


せっかくなので標準モジュールにも名前を付けましょう。
「せっかく」と言うよりは、ちゃんとした名前を付けておかないと、後々「どこの標準モジュール」に書いたのかわからなくなります。
それでは、本末転倒です。

Module1を選択し、「オブジェクト名」に名前を付けます。今回は、「SheetModule」としました。

3.アクセス修飾子

前回(はじめてのプログラミング#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

4.標準モジュールはイベントを知らない

Sheet1に書いたWorksheet_SelectionChangeと標準モジュール(SheetModule)に書いたWorksheet_SelectionChangeに違いがあることに気づきましたか?

Sheet1 の Worksheet_SelectionChange は
WorksheetオブジェクトのSelectionChangeイベントと認識されています。

一方、SheetModule の Worksheet_SelectionChange は {General} の Worksheet_SelectionChangeプロシージャとして認識されています。


この違いは、標準モジュールには「イベントがない」からです。

標準モジュールに書いたプログラムは、あくまでも「共通のプログラム部品」であり、Sheet1など、他の場所で発生したイベントから呼び出されて使われます。

5.標準モジュールを使ってみよう

では、さっそく標準モジュールに書いた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) の部分がパラメータです・

ここで、CallSheetModule は、省略可能です。

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 (表示する。今選択されている項目を)のように動詞+名詞 の命名にするとよいでしょう。

6.まとめ

今回は、共通で使えるプログラム部品「モジュール」の作り方について解説しました。

次回は、モジュールの汎用性について解説する予定です。