オブジェクト指向とは?
今回はVBAの「オブジェクト指向」について解説します。
プログラミングではこのオブジェクト指向の考え方が非常に重要です。
初級編という事でオブジェクト指向を紹介してますが、多くのプログラミング教本では、きっと中級以上のレベルで紹介しているのではないかと思います。
確かに難しい考え方ですが、構える必要はありません。
初級編ではオブジェクト指向の最低限の機能や考え方について紹介します。
なぜそんな難しいオブジェクト指向を解説するかと言えば、エクセルVBAでは標準関数のように、標準で用意されているオブジェクトがあります。
これを「Class(クラス)」と言います。
このクラスについては、「【17】VBAの「配列」について」でも少し触れました。
'エクセルのシートA列に入力されている数を代入
ElementNum = WorksheetFunction.CountA(Range("A:A"))
このように、エクセルの処理をする上で、オブジェクト、クラスの概念は欠かせません。
したがって、まずはオブジェクトの概念について説明します。
オブジェクトの概念について
オブジェクト指向とは、プログラミングにおける非常に重要な考え方です。
オブジェクトは、日本語にすると「物」です。
プログラムの機能を物として捉えます。
例えばいい例が自動車です。
自動車はオブジェクト、物ですよね。
自動車には様々な情報と機能があります。
ボディの色やタイヤのサイズといった情報、アクセルやブレーキといった機能があります。
オブジェクト指向とは、プログラミングでも、これと同じような考え方をします。
この説明だけだと、まだまだ抽象的なので、後に分かりやすいように具体例を出します。
まずはオブジェクトの要素3つを紹介します。
- カプセル化
- 継承
- 多態性(ポリモーフィズム)
いきなり難しい言葉が出てきましたが、VBAのオブジェクトは、カプセル化と継承のごく一部の機能しかサポートしていません。
したがって、カプセル化だけ覚えれば覚えれば大丈夫です。
カプセル化とは?
カプセル化は、関連するデータや情報を1つにまとめる事です。
このまとめるのが「カプセル」という事で、カプセル化と呼ばれています。
オブジェクトをサンプルコードを使って動作解説
それではサンプルコードを使って、どの動作を解説していきます。
'★標準モジュール
Function test20()
'クラスモジュールを宣言
Dim testClass As Class1
'クラスオブジェクトを生成する
Set testClass = New Class1
'車の色を確認
MsgBox testClass.carBodyColor
'車の名前を確認
testClass.showCarName
'クラスオブジェクトを破棄する
Set testClass = Nothing
End Function
'★クラスモジュール(「Class1」と命名)
'クラスのメンバ変数
Public carName As String
Public carBodyColor As String
'クラスのコンストラクタ(クラスオブジェクトを生成した時に実行)
Private Sub Class_Initialize()
carName = "カローラ"
carBodyColor = "白"
End Sub
'クラスのメソッド(車の名前を表示する)
Public Sub showCarName()
MsgBox "車の名前は" & carName & "です。"
End Sub
'クラスのデコンストラクタ(クラスオブジェクトを破棄した時に実行)
Private Sub Class_Terminate()
MsgBox "クラスオブジェクトを破棄しました。"
End Sub
今回は今までと違い、2つのサンプルコードがあります。
まず1つは従来解説してきたものと同じ「標準モジュール」であり、もう1つは「クラスモジュール」です。
このクラスモジュールには「Class1」という名前を付けました。
クラスモジュールの作成方法については、最後に解説します。
まずは今まで通り、標準モジュールから解説します。
'クラスモジュールを宣言
Dim testClass As Class1
ここではクラスモジュールの宣言をしています。
宣言したクラスモジュールは、「Class1」と命名されたサンプルコードのクラスモジュールです。
普通の変数宣言と同じように捉えていただいて構いません。
'クラスオブジェクトを生成する
Set testClass = New Class1
次の「クラスオブジェクトを生成する」は今までありませんでした。
ユーザーが作ったクラスオブジェクト(この場合はClass1)は、インスタンス化しなければなりません。
インスタンス化とは、オブジェクトを生成する事で、簡単に行ってしまえば使えるようにする事です。
オブジェクトを生成し、インスタンス化する構文が以下の通りです。
Set <クラスを宣言した変数名> = New <クラス名>
そして次の車の色を表示する記述になり、以下の実行結果が得られます。
'車の色を確認
MsgBox testClass.carBodyColor
ここからはクラスモジュールについて解説いたします。
クラスモジュールには車の色を定義した記述がありますので、抜粋します。
'クラスのメンバ変数
Public carName As String
Public carBodyColor As String
'クラスのコンストラクタ(クラスオブジェクトを生成した時に実行)
Private Sub Class_Initialize()
carName = "カローラ"
carBodyColor = "白"
End Sub
オブジェクトはデータと機能を実装できる物であり、カプセル化と説明しましたが、このClass1の中には、自動車のデータをを入れました。
その情報を入れる変数を、まずはクラス内で宣言しています。
'クラスのメンバ変数
Public carName As String
Public carBodyColor As String
これはクラス「メンバ変数」と呼びます。
これまで変数宣言には「Dim」を使ってきましたが、クラスのメンバ変数には主に「Public」と「Private」を用います。
この2つの違いは後に解説しますので、クラス内で使われると覚えて今は覚えておきましょう。
'クラスのメンバ変数
Public carName As String
Public carBodyColor As String
'クラスのコンストラクタ(クラスオブジェクトを生成した時に実行)
Private Sub Class_Initialize()
carName = "カローラ"
carBodyColor = "白"
End Sub
次に「コンストラクタ」というものがあります。
'コンストラクタの書式
******** *** Class_Initialize()
End Sub
これはオブジェクトを生成した際に、実行される処理です。
標準モジュールでオブジェクトを生成したのは以下の記述の際でした。
'クラスオブジェクトを生成する
Set testClass = New Class1
このクラスオブジェクトを生成した際に、コンストラクタの処理が実行されていました。
つまり2つのメンバ変数に、値が代入されていたという事です。
それを踏まえて、もう1度 標準モジュールを見てみましょう。
'車の色を確認
MsgBox testClass.carBodyColor
「testClass.carBodyColor」に注目します。
まず「testClass」はClass1がインスタンス化された変数で、オブジェクト名になります。
次に「testClass.」とオブジェクト名の後にドットが付きます。
このドットは、Class1の変数(メンバ変数)や関数(メソッド)にアクセス、つまり使うことができます。
「testClass.carBodyColor」で、Class1の「carBodyColor」のメンバ変数にアクセスしています。
メンバ変数「carBodyColor」は、先程コンストラクタで「白」が代入されています。
したがって「MsgBox testClass.carBodyColor」は「白」と表示されるわけです。
次のコードも同じです。
'車の名前を確認
testClass.showCarName
先程は、メンバ変数にアクセスしました。
今度はメンバ関数である「メソッド」にアクセスしています。
つまり、「testClass.showCarName」を記述すると
'クラスのメソッド(車の名前を表示する)
Public Sub showCarName()
MsgBox "車の名前は" & carName & "です。"
End Sub
こちらのメソッドが実行されます。
この中のメンバ変数「carName」はコンストラクタで「カローラ」が代入されています。
よって実行結果は以下の通りです。
最後はクラスオブジェクトを破棄する部分です。
'クラスオブジェクトを破棄する
Set testClass = Nothing
クラスオブジェクトの破棄は必ず必要というわけではありませんが、記述するなら書式は以下の通りです。
Set <クラスを宣言した変数名> = Nothing
クラスオブジェクトを破棄すると、クラスで定義された「デコンストラクタ」が実行されます。
'クラスのデコンストラクタ(クラスオブジェクトを破棄した時に実行)
Private Sub Class_Terminate()
MsgBox "クラスオブジェクトを破棄しました。"
End Sub
これはコンストラクタと同じで、コンストラクタの場合はオブジェクトを生成した直後でしたが、デコンストラクタはオブジェクトを破棄した際に実行されます。
'デコンストラクタの書式
******** *** Class_Terminate()
End Sub
デコンストラクタの実行により、以下の実行結果になります。
以上がサンプルコードの実行動作になります。
説明だけだと分かりにくい方のために、画像4にて動作を図にしました。
オブジェクト指向はプログラミングでつまづく人も多いので、しっかり基本をマスターするようにしましょう。
クラスモジュールの作り方
クラスモジュールの作り方を紹介します。
VBEにて標準モジュールと同じように、右クリックをして「クラスモジュール」を選択します。
またクラス名は標準では「Class1」ですが、画像6の通り「(オブジェクト名)」から変更する事もできます。