目標
VBAのインターフェースについて利用方法を理解できる
VBAのインターフェースの概要と利用方法
インターフェースの概要
インターフェースとは
インターフェースとはクラスに必要なメソッドをまとめて「宣言」しておくプログラムのことです。
クラスと同様で作成したインターフェースはそれだけでは利用することができません。インターフェースはクラスへ「実装」して利用します。
※下はインターフェースのイメージ
上のイラストでは「クラスA」と「クラスB」に「インターフェースA」を実装しています。このとき、ふたつのクラスで使用されるメソッド名は同じになりますが、違った処理をそれぞれ記載(実装)できます。
インターフェースの利用方法
クラスモジュール(インターフェース)の作成
インターフェースの作成にはクラスモジュールを利用します。クラスモジュールの作成は「挿入」タブ内の「クラスモジュール」を選択して行います。
プロジェクトエクスプローラーにクラスモジュールが作成され「Class1」のシートが作成されます。
作成した「Class1」をダブルクリックするとClass1のエディタがコードウィンドウに表示されます。また左下にはClass1のプロパティウィンドウが表示されます。
新しいクラスモジュールが作成できたら準備は完了です。続けて作成したクラスモジュールの編集をしていきます。
クラスモジュール(インターフェース)の編集
プロパティウィンドウのオブジェクト名の変更をします。今回は「Car」と変更します。オブジェクト名は作成するインターフェースの名前になります。
Carインターフェースにプログラムを記述します。
Option Explicit
'--------------------------------------------------------------------------------------------------------------------
'【Carインターフェースで属性を準備】
Public carModel As String
Public carSheets As Integer
Public engineDisplacement As String
'--------------------------------------------------------------------------------------------------------------------
'【Carインターフェースのメソッド】
Sub searchFor()
End Sub
ここまでで、インターフェースの準備が完了です。
インターフェースをクラスに実装する
ここから準備したインターフェースをクラスへ実装していきます。実装するには実装するクラス内で「Implementsステートメント」を利用します。
「Carインターフェース」を実装する「クラス」を作成します。
「Class1」が準備されます。
「Class1」のオブジェクト名を「TOYOTA」へ変更します。
作成した「TOYOTAクラス」に「Implementsステートメント」を利用して「Carインターフェース」を実装します。
Option Explicit
Implements Car
1.Carインターフェースに「carModel」「carSheets」「engineDisplacement」の3つの属性が準備されているので専用のゲッターとセッターを準備します。ゲッターとセッターの命名には規則がありインターフェース名_属性名としなければいけません。
今回の場合はそれぞれ名前の前に「Car_」を付けます。「Car_carModel」「Car_carSheets」「Car_engineDisplacement」
2.Carインターフェースに準備されているメソッドを全て実装します。(今回はsearchForプロシージャだけです。)
実装したメソッドはインターフェース名_プロシージャ名として準備します。
今回の場合はCarインターフェースのsearchForプロシージャの実装なのでTOYOTAクラスにはCar_searchForプロシージャとしてオーバーライド(上書き)します。
Option Explicit
Implements Car
'--------------------------------------------------------------------------------------------------------------------
'【属性の秘匿化(インターフェースと同じ名前を準備してますが別のものです。)】
Private carModel As String
Private carSheets As Integer
Private engineDisplacement As String
'--------------------------------------------------------------------------------------------------------------------
'【コンストラクタ】
Private Sub Class_Initialize()
Dim Model As Integer
Dim Sheets As Integer
Dim Displacement As Integer
Model = InputBox("興味のある車のタイプを番号でしてください" & Chr(10) & "1:乗用車、2:ワゴン/SUV、3:ボックス")
Sheets = InputBox("シート数を入力してください")
Displacement = InputBox("排気量を選択してください" & Chr(10) & "1:1600未満、2:1600以上~2800未満、3:2800以上")
Select Case Model
Case 1
carModel = "乗用車"
Case 2
carModel = "ワゴン/SUV"
Case 3
carModel = "ボックス"
Case Else
carModel = "乗用車"
End Select
carSheets = Sheets
Select Case Displacement
Case 1
engineDisplacement = "Small"
Case 2
engineDisplacement = "Middle"
Case 3
engineDisplacement = "Large"
Case Else
engineDisplacement = "Small"
End Select
End Sub
'--------------------------------------------------------------------------------------------------------------------
'インターフェースに「carModel」「carSheets」「engineDisplacement」が準備されているので
'専用のゲッターとセッターを準備します。それぞれ名前の前に「Car_」を付ける決まりになっています。
'「Car_carModel」「Car_carSheets」「Car_engineDisplacement」
'【Car_carModelのgetter】
Public Property Get Car_carModel() As String
Car_carModel = carModel
End Property
'【Car_carModelのsetter】
Public Property Let Car_carModel(ByVal Model As String)
carModel = Model
End Property
'【Car_carSheetsのgetter】
Public Property Get Car_carSheets() As Integer
Car_carSheets = carSheets
End Property
'【Car_carSheetsのsetter】
Public Property Let Car_carSheets(ByVal SheetsNum As Integer)
carSheets = SheetsNum
End Property
'【Car_carSizeのgetter】
Public Property Get Car_engineDisplacement() As String
Car_engineDisplacement = engineDisplacement
End Property
'【Car_carSizeのsetter】
Public Property Let Car_engineDisplacement(ByVal carSize As String)
engineDisplacement = carSize
End Property
'--------------------------------------------------------------------------------------------------------------------
'【Carインターフェースに実装されているメソッド→実装するクラスではCar_searchForで記載】
Public Sub Car_searchFor()
Worksheets("sheet1").Range("A1").Select
If carModel = "乗用車" And carSheets <= 4 And engineDisplacement = "Small" Then
Range("A1").value = "ヤリス"
Range("B1").value = "パッソ"
ElseIf carModel = "乗用車" And carSheets <= 4 And engineDisplacement = "Middle" Then
Range("A1").value = ""
Range("B1").value = ""
MsgBox "お求めの物はございません。"
ElseIf carModel = "乗用車" And carSheets <= 4 And engineDisplacement = "Large" Then
Range("A1").value = ""
Range("B1").value = ""
MsgBox "お求めの物はございません。"
ElseIf carModel = "乗用車" And carSheets > 4 Then
Range("A1").value = ""
Range("B1").value = ""
MsgBox "お求めの物はございません。"
ElseIf carModel = "ワゴン/SUV" And carSheets <= 7 And engineDisplacement = "Small" Then
Range("A1").value = ""
Range("B1").value = ""
MsgBox "ワゴン/SUVはMiddle以上になっています。"
ElseIf carModel = "ワゴン/SUV" And carSheets <= 7 And engineDisplacement = "Middle" Then
Range("A1").value = "RAV"
Range("B1").value = "C-HR"
ElseIf carModel = "ワゴン/SUV" And carSheets <= 7 And engineDisplacement = "Large" Then
Range("A1").value = "ラウンドクルーザー"
Range("B1").value = "ラウンドクルーザープラド"
ElseIf carModel = "ワゴン/SUV" And carSheets > 7 Then
Range("A1").value = ""
Range("B1").value = ""
MsgBox "お求めの物はございません。"
ElseIf carModel = "ボックス" And carSheets <= 9 And engineDisplacement = "Small" Then
Range("A1").value = "ライトエース"
Range("B1").value = ""
ElseIf carModel = "ボックス" And carSheets <= 9 And engineDisplacement = "Middle" Then
Range("A1").value = "タウンエース"
Range("B1").value = ""
ElseIf carModel = "ボックス" And carSheets <= 9 And engineDisplacement = "Large" Then
Range("A1").value = "ハイエース"
Range("B1").value = ""
ElseIf carModel = "ボックス" And carSheets > 9 Then
MsgBox "お求めの物はございません。"
End If
End Sub
ここでもうひとつクラスを作成してインターフェースを実装していきます。クラスモジュールをひとつ追加してオブシェクト名を「NISSAN」にします。
NISSANクラスには次のようにプログラムを準備します。Car_searchForプロシージャ内の記述がTOYOTAクラスのものと異なるようになっています。(多態性:ポリモーフィズム)それ以外は全て同じ内容になっています。
Option Explicit
Implements Car
'--------------------------------------------------------------------------------------------------------------------
'【属性の秘匿化(インターフェースと同じ名前を準備してますが別のものです。)】
Private carModel As String
Private carSheets As Integer
Private engineDisplacement As String
'--------------------------------------------------------------------------------------------------------------------
'【コンストラクタ】
Private Sub Class_Initialize()
Dim Model As Integer
Dim Sheets As Integer
Dim Displacement As Integer
Model = InputBox("興味のある車のタイプを番号でしてください" & Chr(10) & "1:乗用車、2:ワゴン/SUV、3:ボックス")
Sheets = InputBox("シート数を入力してください")
Displacement = InputBox("排気量を選択してください" & Chr(10) & "1:1600未満、2:1600以上~2800未満、3:2800以上")
Select Case Model
Case 1
carModel = "乗用車"
Case 2
carModel = "ワゴン/SUV"
Case 3
carModel = "ボックス"
Case Else
carModel = "乗用車"
End Select
carSheets = Sheets
Select Case Displacement
Case 1
engineDisplacement = "Small"
Case 2
engineDisplacement = "Middle"
Case 3
engineDisplacement = "Large"
Case Else
engineDisplacement = "Small"
End Select
End Sub
'--------------------------------------------------------------------------------------------------------------------
'【Car_carModelのgetter】
Public Property Get Car_carModel() As String
Car_carModel = carModel
End Property
'【Car_carModelのsetter】
Public Property Let Car_carModel(ByVal Model As String)
carModel = Model
End Property
'【Car_carSheetsのgetter】
Public Property Get Car_carSheets() As Integer
Car_carSheets = carSheets
End Property
'【Car_carSheetsのsetter】
Public Property Let Car_carSheets(ByVal SheetsNum As Integer)
carSheets = SheetsNum
End Property
'【Car_carSizeのgetter】
Public Property Get Car_engineDisplacement() As String
Car_engineDisplacement = engineDisplacement
End Property
'【Car_carSizeのsetter】
Public Property Let Car_engineDisplacement(ByVal carSize As String)
engineDisplacement = carSize
End Property
'--------------------------------------------------------------------------------------------------------------------
'【Carインターフェースに実装されているメソッド→実装するクラスではCar_searchForで記載】
'【NISSAN専用のメソッド】
Public Sub Car_searchFor()
Worksheets("sheet1").Range("A1").Select
If carModel = "乗用車" And carSheets <= 4 And engineDisplacement = "Small" Then
Range("A3").value = "サクラ"
Range("B3").value = "ノート"
ElseIf carModel = "乗用車" And carSheets <= 4 And engineDisplacement = "Middle" Then
Range("A3").value = ""
Range("B3").value = ""
MsgBox "お求めの物はございません。"
ElseIf carModel = "乗用車" And carSheets <= 4 And engineDisplacement = "Large" Then
Range("A3").value = ""
Range("B3").value = ""
MsgBox "お求めの物はございません。"
ElseIf carModel = "乗用車" And carSheets > 4 Then
Range("A3").value = ""
Range("B3").value = ""
MsgBox "お求めの物はございません。"
ElseIf carModel = "ワゴン/SUV" And carSheets <= 7 And engineDisplacement = "Small" Then
Range("A3").value = ""
Range("B3").value = ""
MsgBox "ワゴン/SUVはMiddle以上になっています。"
ElseIf carModel = "ワゴン/SUV" And carSheets <= 7 And engineDisplacement = "Middle" Then
Range("A3").value = "キックス"
Range("B3").value = "エクストレイル"
ElseIf carModel = "ワゴン/SUV" And carSheets <= 7 And engineDisplacement = "Large" Then
Range("A3").value = "エクストレイルパワー"
Range("B3").value = ""
ElseIf carModel = "ワゴン/SUV" And carSheets > 7 Then
Range("A3").value = ""
Range("B3").value = ""
MsgBox "お求めの物はございません。"
ElseIf carModel = "ボックス" And carSheets <= 9 And engineDisplacement = "Small" Then
Range("A3").value = "セレナ"
Range("B3").value = ""
ElseIf carModel = "ボックス" And carSheets <= 9 And engineDisplacement = "Middle" Then
Range("A3").value = "エルグランド"
Range("B3").value = ""
ElseIf carModel = "ボックス" And carSheets <= 9 And engineDisplacement = "Large" Then
Range("A3").value = "キャラバン"
Range("B1").value = ""
ElseIf carModel = "ボックス" And carSheets > 9 Then
MsgBox "お求めの物はございません。"
End If
End Sub
標準モジュールを準備してCarインターフェースを実装したTOYOTAクラスとNISSANクラスをインスタンス化して利用します。
Module1内の記述
Sub IsOperator()
Dim rentCar1 As Object
Set rentCar1 = New TOYOTA
Dim rentCar2 As Object
Set rentCar2 = New NISSAN
rentCar1.Car_searchFor
MsgBox "先ほど入力された情報は次の通りです" & Chr(10) & rentCar1.Car_carModel & Chr(9) & rentCar1.Car_carSheets & Chr(9) & rentCar1.Car_engineDisplacement
rentCar2.Car_searchFor
MsgBox "先ほど入力された情報は次の通りです" & Chr(10) & rentCar2.Car_carModel & Chr(9) & rentCar2.Car_carSheets & Chr(9) & rentCar2.Car_engineDisplacement
Set rentCar1 = Nothing
Set rentCar2 = Nothing
End Sub
インターフェースを実装したクラスのインスタンス化はDimで型(インターフェース)を宣言してSetでインターフェースを実装したクラスを代入します。今回はオブシェクト型で型を作ってそれぞれのクラスを代入しています。
Dim rentCar1 As Object
Set rentCar1 = New TOYOTA
メソッドの呼び出しはクラス名.インターフェース名_メソッド名となっています。(ゲッターとセッターも同様)
rentCar1.Car_searchFor
rentCar1.Car_carModel
rentCar1.Car_carSheets
rentCar1.Car_engineDisplacement
使用後は後始末をします。
Set rentCar1 = Nothing
実行結果
TOYOTAクラスのsearchForプロシージャが表示されます。
続けてNISSANクラスのsearchForプロシージャが表示されます。
Sheet1のセルに値が入力されます。(1行目はTOYOTAの結果・2行目はNISSANの結果)
今回の内容は以上となります。次回は以前作成したユーザーフォームを利用したシステムの一部をクラスを用いたプログラムに変更をしていきます。
ブックマークのすすめ
「ほわほわぶろぐ」を常に検索するのが面倒だという方はブックマークをお勧めします。ブックマークの設定は別記事にて掲載しています。