トップ > 備忘録 > 【簡単解説】VBAクラスモジュール 1:記述と宣言

【簡単解説】VBA クラスモジュール 1記述と宣言   2021.06.29

クラスとは「新たな階層グループ」のような概念であり、そこに属するメンバーに共通の特性や属性を持たせるといったイメージです。学校で例えるなら、学年とは違う階層である部活や委員会のような感じです。
「VBAの基礎はある程度習得したけど、クラスモジュールは敷居が高く感じる」といった方も多いのではないでしょうか。

ここでは、クラスモジュールの使い方やポイントを備忘録として残します。

内容

●クラスモジュールのメリット
●記述と宣言
 ・Sub・Function
 ・変数
 ・オブジェクト

サンプルファイル

記事に載せてあるコードサンプルのファイル ダウンロード


クラスモジュール

メリット

クラスモジュールのメリットには、次のものが挙げられる。

・SubやFunctionの所属(モジュール)をわかりやすく表記できる
・任意のオブジェクトをグループとして扱える
・オブジェクトに新たなプロパティを追加するようなイメージで扱える

私がよく用いるのは、ユーザーフォームの多数のコントロールを共通のクラスに所属させ、共通のイベントを設定する方法である。
例えば、20のLabelコントロール(Label1~20)を共通のクラスに所属させ、Clickイベントを共有すると、コントロール毎にClickイベントを書かなくてよい。

少し慣れが必要であるが、使えるとメリット大きい。


他のモジュールとの違い

クラスモジュールに記述した変数・サブルーチン・関数等は、そのままでは使用できない。
使用する場合は、クラスのインスタンスを生成し、
 ・インスタンス.変数
 ・インスタンス.関数
といった使い方をする。

インスタンスとは設計図をもとにつくられたものである。ここでいう設計図はクラスにあたる。
インスタンス=クラスの複製という認識でよい。

クラスを使用する際は、そのクラスのインスタンスを生成する過程を必ずたどる。


クラスモジュールの挿入

オブジェクトモジュール名の右クリックメニュー → 「挿入」 → 「クラスモジュール」
あるいはメニューバーの「挿入」→「クラスモジュール」


【お薦め】マクロ・プロシージャを管理する無料のツール!
 Excelマクロ管理ツール

記述と宣言

SubとFunction

サブルーチン(Sub)や関数(Function)のクラスモジュールでの記述は、標準モジュールと同じでよい。
標準モジュールでそれらを使用する場合は「クラスインスタンス.関数」といった記述になる。

●クラスモジュール
Sub Msg(name As String)
    MsgBox name & "さん こんにちは。"
End Sub

Function Total(n1 As Double, n2 As Double, n3 As Double) As Double Total = n1 + n2 + n3 End Function
●標準モジュール
Sub Sample1()
    Dim clsSample1 As Class1 'Class1型のオブジェクト変数を宣言 「Class1」はクラスモジュール名
    Set clsSample1 = New Class1 'インスタンスを生成 オブジェクトへの参照を設定
    
    Call clsSample1.Msg("sakae1")
    MsgBox "合計:" & clsSample1.Total(51, 62.3, 4.7)
End Sub


クラスモジュールと標準モジュールの記述に問題なければ、インテリセンスが表示される。



【補足情報】
標準モジュールの宣言は、前述の形で記述されていることが多いが、次の形でも問題ない。

●標準モジュール[記述]
Sub Sample2()
    Dim clsSample1 As New Class1 'インスタンスを生成
    
    Call clsSample1.Msg("sakae2")
    MsgBox "合計:" & clsSample1.Total(50, 72.6, 13.4)
End Sub

オブジェクト型変数を宣言するときに「New」キーワードを指定すると、オブジェクトのインスタンスが生成される。
その場合は、Setステートメントで改めてオブジェクトへの参照を代入する必要はない。


変数

クラスモジュールのPublic型変数は、どのモジュール・プロシージャでも使用できるが、変数単体では使用できない。「クラスインスタンス.変数」といった形で使用する。

クラスインスタンスの適用範囲を、標準モジュール全体とする場合は、標準モジュールの宣言セクションに記述する。

●クラスモジュール
'宣言セクション
Public strAddress As String
●標準モジュール
'宣言セクション
Dim clsAds As New Class2

Sub Sample3() clsAds.strAddress = ActiveCell.Address(False, False) End Sub
Sub Sample4() MsgBox clsAds.strAddress End Sub


上記のSample3を実行するとアクティブセルのアドレスが、Class2クラスのインスタンスであるclsAdsのもつ変数、strAddressに代入され保持される。
Sample4を実行すると保持されているアドレスを確認できる。


クラスモジュールのPrivate型変数は、クラス内でしか使用できない。
そのため次のように、プロパティの取得や設定用として使用することが多い。

●クラスモジュール
'宣言セクション
Private strAddress As String

Property Get ActAds() As String '取得用プロパティ ActAds = strAddress End Property
Property Let ActAds(newAddress As String) '設定用プロパティ strAddress = newAddress End Property
●標準モジュール
'宣言セクション
Dim clsAds2 As New Class3

Sub Sample5() clsAds2.ActAds = ActiveCell.Address(False, False) 'プロパティを設定 End Sub
Sub Sample6() MsgBox clsAds2.ActAds 'プロパティを取得 End Sub

上記のSample5を実行すると、アクティブセルのアドレスが、Class3クラスのインスタンスであるclsAds2のもつ、ActAdsプロパティに設定される。
Sample6を実行すると、ActAdsプロパティの値が取得され表示される。

【補足情報】Property(プロパティ)
 上記のクラスモジュール記述を例に挙げる。

●クラスモジュール
'宣言セクション
Private strAddress As String

Property Get ActAds() As String '取得用プロパティ ActAds = strAddress End Property
Property Let ActAds(newAddress As String) '設定用プロパティ strAddress = newAddress End Property

上記コードを見てわかる通り、Property(プロパティ)の使い方はSubやFunctionと異なる。
Get(取得)とLet(設定)では、共通のプロシージャ名(プロパティ名)を用いる。
プロパティ取得の際は、変数(今回の例ではstrAddress)に保持してある値を渡す形になる。
プロパティ設定の際は、受け取った変数(今回の例ではnewAddress)をクラス内の変数(strAddress)に渡す形になる。

そのような仕組みから、使用する変数とプロパティの型は共通でなければならない。

オブジェクト

次はオブジェクトの場合である。
次のコードは、クラスモジュールでオブジェクトと、オブジェクトのアドレス格納用プロパティを記述し、標準モジュールでそれらを利用しているサンプルである。
アクティブシートの2つのShapeオブジェクトを対象としている。


●クラスモジュール
'宣言セクション
Private mySP As Shape
Private strAddress As String

'///オブジェクト Public Property Get Shp() As Shape 'オブジェクト取得用プロパティ Set Shp = mySP End Property
Public Property Let Shp(newSP As Shape) 'オブジェクト設定用プロパティ Set mySP = newSP End Property
'/// Property Get SpAds() As String '取得用プロパティ SpAds = strAddress End Property
Property Let SpAds(newAds As String) '設定用プロパティ strAddress = newAds End Property
●標準モジュール
'宣言セクション
Dim objSP(1 To 2) As New Class4

Sub Sample7() objSP(1).Shp = ActiveSheet.Shapes("スマイル 1") objSP(2).Shp = ActiveSheet.Shapes("スマイル 2") objSP(1).SpAds = objSP(1).Shp.TopLeftCell.Address(False, False) objSP(2).SpAds = objSP(2).Shp.TopLeftCell.Address(False, False) End Sub
Sub Sample8() If objSP(1).Shp Is Nothing Then Exit Sub MsgBox objSP(1).SpAds If objSP(2).Shp Is Nothing Then Exit Sub MsgBox objSP(2).SpAds End Sub

Sample7を実行すると、ShapeとそのShapeの位置するセルアドレスが、インスタンスのもつプロパティに設定される。
Sample8を実行すると、インスタンスのプロパティから、アドレスが取得され表示される。

インスタンスのプロパティにオブジェクトを設定する場合、一般的には次のようにSetステートメントを使用することが多い。
Set objSP(1).Shp = ActiveSheet.Shapes("スマイル 1")

しかしサンプルコードを見てわかる通り、「Set」を使用しなくとも構わない。
サンプルコードでは、標準モジュールに「Set」が記述されていないが、クラスモジュールで「Set」するため、問題なく実行できる。
クラスモジュールの記述を見れば、引数の参照渡しのようなイメージであることがわかる。



ページトップへ戻る
Copyright(C) 2009- 坂江 保 All Rights Reserved.