ExcelVBAのクラスモジュールについて、基本的なことからその使いどころについて解説したいと思います。
クラスモジュールとは
自作のオブジェクトのことです。
そもそもエクセルには、さまざまなオブジェクトが用意されています。オブジェクトとは操作の対象となるものです。
例えばワークブック、ワークシート、レンジ、オートシェイプなどです。
また、外部のライブラリを使用するFileSystemObjectやDictionaryオブジェクトがあります。
プロパティとメソッドとは
オブジェクトにはそれぞれプロパティとメソッドがあります。
プロパティとメソッドとはオブジェクトを操作するためのものです。
プロパティ オブジェクトの属性を表します。(例)値、色、大きさなどです。 例えば、Rangeオブジェクトには、プロパティとして、Valueプロパティ、Fontプロパティ、Addressプロパティ・・などたくさんあります。 (例)・Range(“A1”).Value ・ Range(“A1”).Address
メソッド オブジェクトの動作です。(例)消す、移動する、選択する・・などたくさんあります。
例えば、Rangeオブジェクトには、メソッドとして、Delete、Copy、Select・・などたくさんあります。 (例)・Range(“A1”).Delete ・ Range(“A1”).Copy
VBE画面でF2キー(オブジェクトブラウザ)を押すと、オブジェクトのプロパティやメソッドを確認することができます。
Rangeオブジェクトには、以下のようにさまざまなプロパティやメソッドが存在します。
オブジェクト・プロパティの基本についての記事はこちら
メソッドについての基本についての記事はこちら
クラス
上記の説明を踏まえて、では改めてクラスとは何か?
つまり、オブジェクトを自作して、更に、プロパティやメソッドも自作するということです。
○○というクラスのオブジェクトを作って、例えばその大きさを表すプロパティや移動するやコピーするメソッドなどを作るということです。
では、早速実際のモジュールを見ながら説明します。
クラスモジュールの挿入とオブジェクトの生成
「挿入」タブ→「クラスモジュール」でクラスモジュールを挿入することができます。
プロパティのオブジェクト名を任意の名前にします。オブジェクト名は自分がわかりやすいものにするのが良いです。今回は「車」というクラス名にしました。
オブジェクトの生成
ワークシートやレンジオブジェクトは元々Excelにあるオブジェクトなので、何か手を加えなくても使うことが出来ます。しかし、クラスはまず生成しないとオブジェクトとして使うことができません。それをインスタンス化といいます。
よって、下記のように変数を宣言するような形でオブジェクトを生成します。おまじないのようなものです。これでcarが車クラスのオブジェクトとして使えるようになります。
Dim car As 車
Set car = New 車
または
Dim car As New 車
クラスモジュールのコード
下記は実際のクラスのコードです。
①の部分がプロパティです。このように変数を宣言するような形でクラスのプロパティを設定します。(プロパティ名はタイヤとガソリンというプロパティを設定しました。)
②~⑧はメソッドです。サブプロシージャを作るようにメソッドを設定します。
①プロパティ
①について、この車クラスは2つのプロパティを設定しています。この時点で、これらのプロパティが機能するということはありません。
②クラスイニシャライズ
このイニシャライズとは初期設定のようなもので、クラスを宣言(今回なら車クラスを宣言)した時点で、設定されます。
タイヤ=50となっています。つまりタイヤプロパティに50が初期設定で代入されます。必ずしないといけないというわけではありません。初期値を設定したい時などに便利です。
イニシャライズの方法
画像のように上の2つのドロップダウンリストから「Class」「Initialize」を選ぶことでひな形が現れます。
③~⑥メソッド
③空気メソッド、④空気調整メソッド、⑤給油メソッド、⑥排出メソッドを作っています。
③空気メソッド:タイヤプロパティに10が加算されるメソッドです。
④空気調整メソッド:タイヤプロパティからxが減算されるメソッドです。
⑤給油メソッド:ガソリンプロパティに10が加算されるメソッドです。
⑥排出メソッド:ガソリンプロパティからxが減算されるメソッドです。
⑦~⑧メソッド
⑦空気圧メソッド、⑧残量メソッドを作っています。ファンクション型になっており、返り値としてそれぞれタイヤプロパティ、ガソリンプロパティが設定されています。
標準モジュールのコード
先ほど設定した車クラスのオブジェクトを、標準モジュールで使っていきます。
車クラスのプロパティやメソッドは「car」という名前で生成したオブジェクト(インスタンス化)で使えるようになります。
下の画像のように「car」の後にピリオドを入れると、設定したメソッドの一覧が出現します。しかし、タイヤ、ガソリンプロパティは出現しません。なぜか・・・?
それは定義したときにPrivateで定義しているからです。少し戻ってクラスモジュールを確認してみてください。これは変数宣言と一緒でPrivateで宣言すると外部のプロシージャからはアクセスできません。(これは変数宣言でも一緒ですよね)
アクセスできないようにするのは理由がありますが、それは後程説明します。
もし、プロパティをアクセス可能にしたければ、Publicで定義します。
何度もいいますが、クラスは自作のオブジェクトです。よって、このようにプロパティやメソッドの候補が出現するのは、下記のように、レンジオブジェクトの後にピリオドを打てばプロパティやメソッドの候補が出現することと一緒です。
コード解説
順番にコードを解説します。
まず、クラスを生成(インスタンス化)します。これで車クラスのcarオブジェクトが誕生しました。
同時に、クラスイニシャライズでタイヤプロパティに50が代入されます。
続いて、空気メソッドです。
空気メソッドは、タイヤプロパティに10が加算されます。タイヤプロパティはイニシャライズで50が設定されて、更に10が加算されるので、現在60になっています。
標準プロシージャに戻って、今度は空気調整メソッドです。メソッドは引数を設定することも可能です。ここでは、引数60が設定されています。
引数60が空気調整メソッドに引き渡され、タイヤプロパティは現在60ですが、引数60が減算されるため0になります。
また、標準プロシージャに戻って、今度は給油メソッドです。
給油メソッドは下記のようにガソリンプロパティに10が加算されます。よって、現在、ガソリンプロパティは10です。
排出メソッドです。排出メソッドの引数は0です。
引数0が排出メソッドに引き渡され、ガソリンプロパティは現在10のままです。
またまた、標準モジュールに戻って、最後に結果を表示します。
空気圧結果メソッドと残量メソッドです。
空気圧結果メソッドはタイヤプロパティが返り値、残量メソッドはガソリンプロパティが返り値です。
'標準モジュール
Sub クラスTEST_1()
Dim car As 車
Set car = New 車
car.空気
car.空気調整 (60)
car.給油
car.排出 (0)
MsgBox "タイヤの空気:" & car.空気圧結果
MsgBox "のガソリンの残量:" & car.残量
End Sub
'クラスモジュール
Private タイヤ As Long
Private ガソリン As Long
Private Sub Class_Initialize()
タイヤ = 50
End Sub
Sub 空気()
タイヤ = タイヤ + 10
End Sub
Sub 空気調整(x As Integer)
タイヤ = タイヤ - x
End Sub
Sub 給油()
ガソリン = ガソリン + 10
End Sub
Sub 排出(x As Integer)
ガソリン = ガソリン - x
End Sub
Function 空気圧結果() As Integer
空気圧結果 = タイヤ
End Function
Function 残量() As Integer
残量 = ガソリン
End Function
クラスを使わなかった場合
最後にクラスモジュールを使わなかった場合のコードを載せておきます。
'クラスを使わなかった場合
Private タイヤ As Long
Private ガソリン As Long
Sub クラスTEST_2()
タイヤ = 50
Call 空気
Call 空気調整(60)
Call 給油
Call 排出(0)
タイヤ = 空気圧結果
ガソリン = 残量
MsgBox "タイヤの空気:" & タイヤ
MsgBox "のガソリンの残量:" & 残量
End Sub
Sub 空気()
タイヤ = タイヤ + 10
End Sub
Sub 空気調整(x As Integer)
タイヤ = タイヤ - x
End Sub
Sub 給油()
ガソリン = ガソリン + 10
End Sub
Sub 排出(x As Integer)
ガソリン = ガソリン - x
End Sub
Function 空気圧結果() As Integer
空気圧結果 = タイヤ
End Function
Function 残量() As Integer
残量 = ガソリン
End Function
これらを見比べると特にクラスモジュールは必要ないように感じます。。。。。
では、クラスモジュールが必要な場合、クラスを使った方が便利な場面とはどのような場面なのか?
それについては次回紹介したいと思います。
・筆者オススメのVBAの本はこちら↓
まとめ
- クラスは自作のオブジェクトであり、プロパティ、メソッドが存在する。
- クラスの使用するにはオブジェクトの生成(インスタンス化)が必要
- メソッドには引数を設定することができる
初めてクラスを見ると頭がこんがらがってしまいますが、このサイトのような簡単なコードでステップインを使ってコードの流れを見ていくと理解しやすいと思います。
次回は、さらにクラスが有効な場面はどんな場面なのか?に絞って解説します。楽しみに待っていてください!
コメント