01-VBA

クラスの利用方法|Excel VBA (Part.2) | 現役エンジニア&プログラミングスクール講師

目標

VBAのコンストラクタについて理解できる
VBAのカプセル化について理解できる
カプセル化に必要なゲッターとセッターをについてVBAでの記述方法を理解できる
クラスに自由にメソッドを追加できる

VBAのクラスの重要構文

VBAのコンストラクタ

コンストラクタの概要

コンストラクタはクラスのインスタンスが作成されたときに自動で動くメソッドです。

クラスはnew演算子を利用してインスタンス化します。前回の記事を例にとると次の2行目の部分がインスタンス化の操作となっています。

Dim rentCar1 As Car ‘(Car型の入れ物「rentCar1」を宣言します)
Set rentCar1 = New Car ‘(宣言したrentCar1にCarのオブジェクトを代入します)

この時点でコンストラクタは自動で動いて初期設定などを済ませてくれます。

なのでインスタンスを作るたびにコンストラクタはそれぞれのインスタンス内で勝手に処理を進めて終わらせておいてくれます。

コンストラクタの作成方法

コンストラクタは次の手順で作成できます。

1.コンストラクタを準備するクラスを開く
2.オブジェクトボックスで「Class」を選択
3.プロシージャボックスで「Initialize」を選択

次のイベントプロシージャが作成されます。これがコンストラクタになります。このプロシージャの中に動かしたい処理を記述します。

Private Sub Class_Initialize ()
  処理を記述
End Sub

Carクラスでは次のようにプログラムを記述していました。

'【コンストラクタ】
Private Sub Class_Initialize()

    Dim carModel As Integer
    Dim carSheets As Integer
    Dim engineDisplacement As Integer
    
    carModel = InputBox("興味のある車のタイプを番号でしてください" & Chr(10) & "1:乗用車、2:ワゴン/SUV、3:ボックス")
    carSheets = InputBox("シート数を入力してください")
    engineDisplacement = InputBox("排気量を選択してください" & Chr(10) & "1:1600未満、2:1600以上~2800未満、3:2800以上")
    
    Select Case carModel
        Case 1
        this_carModel = "乗用車"
        Case 2
        this_carModel = "ワゴン/SUV"
        Case 3
        this_carModel = "ボックス"
        Case Else
        this_carModel = "乗用車"
    End Select
    
    this_carSheets = carSheets
    
    Select Case engineDisplacement
        Case 1
        this_engineDisplacement = "Small"
        Case 2
        this_engineDisplacement = "Middle"
        Case 3
        this_engineDisplacement = "Large"
        Case Else
        this_engineDisplacement = "Small"
    End Select
    
End Sub

今回は準備していませんがVBAのクラスには「デストラクタ」というイベントプロシージャがあります。これは「コンストラクタ」が「インスタンス生成時」に動くのに対してインスタンスが「破棄されるタイミング」で動くメソッドになっています。

参考:デストラクタの利用方法

VBAでデストラクタを利用する場合は次のイベントプロシージャを利用します。

Private Sub Class_Terminate ()
  処理を記述
End Sub

参考:コンストラクタの作成方法

デストラクタは次の手順で作成できます。

1.デストラクタを準備するクラスを開く
2.オブジェクトボックスで「Class」を選択
3.プロシージャボックスで「Terminate」を選択

デストラクタはクラスのインスタンスが破棄されるときに自動で動くメソッドです。オブジェクトの破棄は「Set インスタンス名 = Nothing」で行います。前回の記事を例にとると次の1行がインスタンスの破棄をする操作となっていて、この操作でデストラクタが呼び出されます。

Set rentCar1 = Nothing

VBAのクラスのカプセル化

カプセル化の概要

クラスに準備した大切な属性(値を入れる箱)に対して入力と出力をメソッドを経由させて行わせることをカプセル化といいます。メソッドを経由しない方法でのアクセスはできないように設定します。

カプセル化をすることで意図しない入力値に対するエラー(システムのストップ)を防げます。エラーが起こるとどうしてもシステムは強制終了などの停止機能が働いてしまいます。人による入力ミスのように頻繁に起こるエラーに対して大きな効力があります。

カプセル化の手順

1.クラス内の属性に「Private」を付ける
2.クラス内の属性を取得できるメソッドを準備する
3.クラス内の属性に値をセットできるメソッドを準備する

カプセル化の手順1

クラス内の属性に「Private」を付けます

'【属性の秘匿化】
Private this_carModel As String
Private this_carSheets As Integer
Private this_engineDisplacement As String

「Private」を付けると他のプロシージャから「インスタンス名.属性名」のような呼び出しが出来なくなります。今回のプログラムでも標準モジュールから「rentCar1.this_carModel」での操作は行えなくなっています。

「Private」を付けた属性は属性を直接指定した取得も入力もできなくなっています。そこで取得と入力には別の方法が必要になります。これをゲッターとセッターというメソッドで行えるようにします。

カプセル化の手順2

クラス内の属性を取得できるメソッド(ゲッター)を準備します。VBAでゲッターを作成するにはProperty Getステートメントを利用します。手順は次の通りになります。

1.Property Getステートメントにメソッド名と型を取り付けます。
※この時のメソッド名は式の中の「受け取り側の変数名」と同じ名前になります。
※型にはクラスの秘匿化した属性の型と同じ型を宣言します。
2.ステートメント内に次の順で式を作成します。
※メソッド名と同じ変数名 = クラスの秘匿化した属性名

Public Property Get carType() As String
carType = this_carModel
End Property

Propertyの前には「Public」「Private」「Friend」「Static」を利用できます。省略することも可能です。

Property Getステートメントで作成したメソッドはFunctionプロシージャと同じように戻り値があります。勿論ですが、戻り値はゲッターが使用されたプロシージャ内に返されます。

Public Property Get carType() As String
    carType = this_carModel
End Property

Public Property Get SheetsNum() As String
    SheetsNum = this_carSheets
End Property

Public Property Get carSize() As String
    carSize = this_engineDisplacement
End Property

カプセル化の手順3

クラス内の属性値にセットできるメソッド(セッター)を準備します。VBAでセッターを作成するにはProperty Letステートメントを利用します。手順は次の通りになります。

1.Property Letステートメントに「メソッド名」と「型を指定した引数」を取り付けます。引数名は自由に指定できます。
※この時のメソッド名はProperty Getステートメントのメソッド名と同じになります。
※型にはクラスの秘匿化した属性の型と同じ型を宣言します。
3.ステートメント内に次の順で式を作成します。
クラスの秘匿化した属性名 = 引数

Public Property Let carType(ByVal carModel As String)
this_carModel = carModel
End Property

Propertyの前には「Public」「Private」「Friend」「Static」を利用できます。省略することも可能です。

Property Letステートメントは値の設定に利用します。オブジェクトの設定にはProperty Setステートメントを利用します。

Public Property Let carType(ByVal carModel As String)
    this_carModel = carModel
End Property

Public Property Let SheetsNum(ByVal SheetsNum As String)
    this_carSheets = SheetsNum
End Property

Public Property Let carSize(ByVal carSize As String)
    this_engineDisplacement = carSize
End Property

以上でVBAでのカプセル化は完了です。

クラスへのオリジナルのメソッド作成

クラスにはゲッターとセッター以外にも自由にメソッドを準備できます。メソッドの作成はプロシージャの作成と同じ様に行えます。

'--------------------------------------------------------------------------------------------------------------------
'【Carクラスの独自メソッド】
Public Sub searchFor()
    Worksheets("sheet1").Range("A1").Select
    
    If this_carModel = "乗用車" And this_carSheets <= 4 And this_engineDisplacement = "Small" Then
        Range("A1").value = "ヤリス"
        Range("B1").value = "パッソ"
    ElseIf this_carModel = "乗用車" And this_carSheets <= 4 And this_engineDisplacement = "Middle" Then
        Range("A1").value = ""
        Range("B1").value = ""
        MsgBox "お求めの物はございません。"
    ElseIf this_carModel = "乗用車" And this_carSheets <= 4 And this_engineDisplacement = "Large" Then
        Range("A1").value = ""
        Range("B1").value = ""
        MsgBox "お求めの物はございません。"
    ElseIf this_carModel = "乗用車" And this_carSheets > 4 Then
        Range("A1").value = ""
        Range("B1").value = ""
        MsgBox "お求めの物はございません。"
        
    ElseIf this_carModel = "ワゴン/SUV" And this_carSheets <= 7 And this_engineDisplacement = "Small" Then
        Range("A1").value = ""
        Range("B1").value = ""
        MsgBox "ワゴン/SUVはMiddle以上になっています。"
    ElseIf this_carModel = "ワゴン/SUV" And this_carSheets <= 7 And this_engineDisplacement = "Middle" Then
        Range("A1").value = "RAV"
        Range("B1").value = "フォレスター"
    ElseIf this_carModel = "ワゴン/SUV" And this_carSheets <= 7 And this_engineDisplacement = "Large" Then
        Range("A1").value = "ラウンドクルーザー"
        Range("B1").value = "アウトランダー"
    ElseIf this_carModel = "ワゴン/SUV" And this_carSheets > 7 Then
        Range("A1").value = ""
        Range("B1").value = ""
        MsgBox "お求めの物はございません。"
        
    ElseIf this_carModel = "ボックス" And this_carSheets <= 9 And this_engineDisplacement = "Small" Then
        Range("A1").value = "ライトエース"
        Range("B1").value = ""
    ElseIf this_carModel = "ボックス" And this_carSheets <= 9 And this_engineDisplacement = "Middle" Then
        Range("A1").value = "タウンエース"
        Range("B1").value = ""
    ElseIf this_carModel = "ボックス" And this_carSheets <= 9 And this_engineDisplacement = "Large" Then
        Range("A1").value = "ハイエース"
        Range("B1").value = ""
    ElseIf this_carModel = "ボックス" And this_carSheets > 9 Then
        MsgBox "お求めの物はございません。"
    End If
    
End Sub

作成したCarクラスの中身(再掲載)

Option Explicit
'--------------------------------------------------------------------------------------------------------------------
'【属性の秘匿化】
Private this_carModel As String
Private this_carSheets As Integer
Private this_engineDisplacement As String
'--------------------------------------------------------------------------------------------------------------------
'【コンストラクタ】
Private Sub Class_Initialize()

    Dim carModel As Integer
    Dim carSheets As Integer
    Dim engineDisplacement As Integer
    
    carModel = InputBox("興味のある車のタイプを番号でしてください" & Chr(10) & "1:乗用車、2:ワゴン/SUV、3:ボックス")
    carSheets = InputBox("シート数を入力してください")
    engineDisplacement = InputBox("排気量を選択してください" & Chr(10) & "1:1600未満、2:1600以上~2800未満、3:2800以上")
    
    Select Case carModel
        Case 1
        this_carModel = "乗用車"
        Case 2
        this_carModel = "ワゴン/SUV"
        Case 3
        this_carModel = "ボックス"
        Case Else
        this_carModel = "乗用車"
    End Select
    
    this_carSheets = carSheets
    
    Select Case engineDisplacement
        Case 1
        this_engineDisplacement = "Small"
        Case 2
        this_engineDisplacement = "Middle"
        Case 3
        this_engineDisplacement = "Large"
        Case Else
        this_engineDisplacement = "Small"
    End Select
    
End Sub

'--------------------------------------------------------------------------------------------------------------------
'【属性初期化の代用】
Public Function Init(carModel As String, carSheets As Integer, engineDisplacement As String) As Car

    Set Init = Me
    this_carModel = carModel
    this_carSheets = carSheets
    this_engineDisplacement = engineDisplacement

End Function

'--------------------------------------------------------------------------------------------------------------------
'【this_carModelのgetter】
Public Property Get carType() As String
    carType = this_carModel
End Property
'【this_carModelのsetter】
Public Property Let carType(ByVal carModel As String)
    this_carModel = carModel
End Property
'【this_carSheetsのgetter】
Public Property Get SheetsNum() As Integer
    SheetsNum = this_carSheets
End Property
'【this_carSheetsのsetter】
Public Property Let SheetsNum(ByVal SheetsNum As Integer)
    this_carSheets = SheetsNum
End Property
'【this_carSizeのgetter】
Public Property Get carSize() As String
    carSize = this_engineDisplacement
End Property
'【this_carSizeのsetter】
Public Property Let carSize(ByVal carSize As String)
    this_engineDisplacement = carSize
End Property

'--------------------------------------------------------------------------------------------------------------------
'【Carクラスの独自メソッド】
Public Sub searchFor()
    Worksheets("sheet1").Range("A1").Select
    
    If this_carModel = "乗用車" And this_carSheets <= 4 And this_engineDisplacement = "Small" Then
        Range("A1").value = "ヤリス"
        Range("B1").value = "パッソ"
    ElseIf this_carModel = "乗用車" And this_carSheets <= 4 And this_engineDisplacement = "Middle" Then
        Range("A1").value = ""
        Range("B1").value = ""
        MsgBox "お求めの物はございません。"
    ElseIf this_carModel = "乗用車" And this_carSheets <= 4 And this_engineDisplacement = "Large" Then
        Range("A1").value = ""
        Range("B1").value = ""
        MsgBox "お求めの物はございません。"
    ElseIf this_carModel = "乗用車" And this_carSheets > 4 Then
        Range("A1").value = ""
        Range("B1").value = ""
        MsgBox "お求めの物はございません。"
        
    ElseIf this_carModel = "ワゴン/SUV" And this_carSheets <= 7 And this_engineDisplacement = "Small" Then
        Range("A1").value = ""
        Range("B1").value = ""
        MsgBox "ワゴン/SUVはMiddle以上になっています。"
    ElseIf this_carModel = "ワゴン/SUV" And this_carSheets <= 7 And this_engineDisplacement = "Middle" Then
        Range("A1").value = "RAV"
        Range("B1").value = "フォレスター"
    ElseIf this_carModel = "ワゴン/SUV" And this_carSheets <= 7 And this_engineDisplacement = "Large" Then
        Range("A1").value = "ラウンドクルーザー"
        Range("B1").value = "アウトランダー"
    ElseIf this_carModel = "ワゴン/SUV" And this_carSheets > 7 Then
        Range("A1").value = ""
        Range("B1").value = ""
        MsgBox "お求めの物はございません。"
        
    ElseIf this_carModel = "ボックス" And this_carSheets <= 9 And this_engineDisplacement = "Small" Then
        Range("A1").value = "ライトエース"
        Range("B1").value = ""
    ElseIf this_carModel = "ボックス" And this_carSheets <= 9 And this_engineDisplacement = "Middle" Then
        Range("A1").value = "タウンエース"
        Range("B1").value = ""
    ElseIf this_carModel = "ボックス" And this_carSheets <= 9 And this_engineDisplacement = "Large" Then
        Range("A1").value = "ハイエース"
        Range("B1").value = ""
    ElseIf this_carModel = "ボックス" And this_carSheets > 9 Then
        MsgBox "お求めの物はございません。"
    End If
    
End Sub

クラスが完成したら利用ができます。利用する時はインスタンス化して利用します。クラスのインスタンス化については前回の記事を参考にしてください。

今回の内容は以上となります。

初心者も実践で通用!「VBA・VBS」おすすめ書籍5選 | 現役エンジニア&プログラミングスクール講師「VBA・VBS」初心者の方が実践業務の中でそれらを活用しt活躍できるために必要な知識を習得できる書籍を紹介しています。ページの下部には「おすすめのITスクール情報」「おすすめ求人サイト」について情報を掲載中。...

ブックマークのすすめ

「ほわほわぶろぐ」を常に検索するのが面倒だという方はブックマークをお勧めします。ブックマークの設定は別記事にて掲載しています。

「お気に入り」の登録・削除方法【Google Chrome / Microsoft Edge】| 現役エンジニア&プログラミングスクール講師「お気に入り」の登録・削除方法【Google Chrome / Microsoft Edge】について解説している記事です。削除方法も掲載しています。...
【パソコン選び】失敗しないための重要ポイント | 現役エンジニア&プログラミングスクール講師【パソコン選び】失敗しないための重要ポイントについての記事です。パソコンのタイプと購入時に検討すべき点・家電量販店で見かけるCPUの見方・購入者が必要とするメモリ容量・HDDとSSDについて・ディスプレイの種類・バッテリーの持ち時間や保証・Officeソフト・ウィルス対策ソフトについて書いています。...
RELATED POST
01-VBA

ExcelVBAのCellsプロパティ | 現役エンジニア&プログラミングスクール講師

2022年8月18日
プログラミング学習 おすすめ書籍情報発信 パソコン初心者 エンジニア希望者 新人エンジニア IT業界への就職・転職希望者 サポートサイト Programming learning Recommended schools Recommended books Information dissemination Computer beginners Prospective engineers New engineers Prospective job seekers in the IT industry Support site
01-VBA

初心者のためのExcelVBAのオブジェクト | 現役エンジニア&プログラミングスクール講師

2022年8月8日
プログラミング学習 おすすめ書籍情報発信 パソコン初心者 エンジニア希望者 新人エンジニア IT業界への就職・転職希望者 サポートサイト Programming learning Recommended schools Recommended books Information dissemination Computer beginners Prospective engineers New engineers Prospective job seekers in the IT industry Support site
01-VBA

Excel VBA の「デバッグ」(Part.2)「ステップモード」「ブレークポイント」| 現役エンジニア&プログラミングスクール講師

2022年12月14日
プログラミング学習 おすすめ書籍情報発信 パソコン初心者 エンジニア希望者 新人エンジニア IT業界への就職・転職希望者 サポートサイト Programming learning Recommended schools Recommended books Information dissemination Computer beginners Prospective engineers New engineers Prospective job seekers in the IT industry Support site
01-VBA

ExcelVBAのActiveCellプロパティ | 現役エンジニア&プログラミングスクール講師

2022年8月15日
プログラミング学習 おすすめ書籍情報発信 パソコン初心者 エンジニア希望者 新人エンジニア IT業界への就職・転職希望者 サポートサイト Programming learning Recommended schools Recommended books Information dissemination Computer beginners Prospective engineers New engineers Prospective job seekers in the IT industry Support site
01-VBA

Excel VBA の エラー処理(Part.2)| 現役エンジニア&プログラミングスクール講師

2022年12月27日
プログラミング学習 おすすめ書籍情報発信 パソコン初心者 エンジニア希望者 新人エンジニア IT業界への就職・転職希望者 サポートサイト Programming learning Recommended schools Recommended books Information dissemination Computer beginners Prospective engineers New engineers Prospective job seekers in the IT industry Support site
01-VBA

Excel VBA の「オブジェクト活用」(Part.2)【セル活用編】| 現役エンジニア&プログラミングスクール講師

2022年12月15日
プログラミング学習 おすすめ書籍情報発信 パソコン初心者 エンジニア希望者 新人エンジニア IT業界への就職・転職希望者 サポートサイト Programming learning Recommended schools Recommended books Information dissemination Computer beginners Prospective engineers New engineers Prospective job seekers in the IT industry Support site