LoginSignup
128
182

More than 3 years have passed since last update.

VBAでクラスをつくる

Last updated at Posted at 2017-01-02

VBAでのクラスの作り方です。

2019/10/12: 一部文言等、修正しました。

クラスモジュールを挿入する

image.png
こんな感じでクラスモジュールを挿入します。

クラスの名前を付ける

image.png

プロパティウィンドウの「(オブジェクト名)」の欄でクラスの名称を設定します。

これで空のクラスができました。

メンバ変数を定義する

クラスのメンバ変数を定義してみます。

Person(クラスモジュール)
Option Explicit

' メンバ変数
Public Name As String
Private Age As Long

Privateとつけたものはクラスの外からはアクセスできません。
Publicは外からアクセスできます。
(アクセス修飾子といいます)

メソッドを作る

メソッドを追加した例です。

Person(クラスモジュール)
Option Explicit

' メンバ変数
Public Name As String
Private Age As Long
Public Mother As Person

' メソッド
Public Sub SayHello()
    MsgBox "Hello, I'm " & Name & "!"
End Sub

' 引数付き
Public Sub SayHelloTo(otherPersonName As String)
    MsgBox "Hello, " & otherPersonName & "!" & vbNewLine & _
        "I'm " & Name & "!"
End Sub

' 戻り値あり(関数)
Public Function GetAge() As Long
    GetAge = Age
End Function

' オブジェクトを返す関数(Setをつけること!)
Public Function GetMother() As Person
    Set GetMother = Mother
End Function

メンバ変数と同様、頭にPublicをつけると外からアクセスでき、Privateではアクセスできません。

オブジェクト型を返す時は Set をつける必要があります。

Meキーワード

Meはクラスモジュールでは自身のインスタンスを指します。
image.png

InitializeとTerminate

Class_Initializeはクラスのインスタンスが生成されたときに呼ばれます。引数はつけられません。
Class_Terminateはクラスのインスタンスが破棄されたときに呼ばれます。
ただし、ガーベージコレクションが動くタイミングは必ずしも分からないので、リソース(ex. DBへの接続など)を解放するメソッドを別に作るのが良いといわれています。

Person(クラスモジュール)追加分
' 初期化処理
Private Sub Class_Initialize()
    Name = "Bob"
    Age = 30
    Set Mother = Nothing

    Debug.Print "initalized"
End Sub

' 終了時処理
Private Sub Class_Terminate()
    Name = ""
    Age = 0
    Set Mother = Nothing

    ' その他、使用しているリソースの解放処理を行う
    '

    Debug.Print "terminated"
End Sub

これらのメソッドはPrivateにします。Publicにするとintellisense(コード補完)で見えてしまいます。

クラスの使い方

クラスの使い方です。

標準モジュール
Option Explicit

Sub test1()
    ' オブジェクト型の変数を宣言
    Dim p As Person

    ' インスタンス生成
    Set p = New Person

    ' 値をセットする
    p.Name = "Bob"

    ' 値を取得してみる
    Debug.Print "age: " & p.GetAge()

    ' メソッド呼び出し
    Call p.SayHello

    ' オブジェクト破棄(スコープから出るとガーベージコレクションによって勝手に破棄されます)
    Set p = Nothing
End Sub

結果

image.png
image.png

プロパティ プロシージャを使う

先ほどの例ではメンバ変数Nameに外部から直接値を設定していましたが、それだと例えば空文字列ならエラーを出すといった処理ができません。
メンバ変数の設定時や取得時に何か処理をするには、プロパティ プロシージャを使います。

Person(クラスモジュール)
Option Explicit

' メンバ変数
' NameとMotherをPrivateにした
Private Name As String
Private Age As Long
Private Mother As Person

' 初期化処理
Private Sub Class_Initialize()
    Name = "Bob"
    Age = 30
    Set Mother = Nothing

    Debug.Print "initalized"
End Sub

' 終了時処理
Private Sub Class_Terminate()
    Name = ""
    Age = 0
    Set Mother = Nothing

    ' その他、使用しているリソースの解放処理を行う
    '

    Debug.Print "terminated"
End Sub

' メソッド
Public Sub SayHello()
    MsgBox "Hello, I'm " & Name & "!"
End Sub

' 引数付き
Public Function SayHelloTo(otherPersonName As String) As Person
    MsgBox "Hello, " & otherPersonName & "!" & vbNewLine & _
        "I'm " & Name & "!"
End Function

' プロパティプロシージャ
Property Get MyName() As String
    MyName = Name
End Property

Property Let MyName(namae As String)
    If namae = "" Then
        ' 氏名がブランクならエラー
        Err.Raise 10000, , "名前がブランクです"
    End If

    Name = namae
End Property

Property Get MyAge() As Long
    ' 5歳さばを読んでみる
    MyAge = Age - 5
End Property

Property Get MyMother() As Person
    Set MyMother = Mother
End Property

Property Set MyMother(haha As Person)
    Set Mother = haha
End Property

値を設定するときは、値型ならばLet、オブジェクト型ならばSetを使います。値の取得は、どちらもGetです。
なお、ここでMyAgeGetのプロパティ プロシージャしかないので、readonlyプロパティとか言ったりすることもあります。

使い方です。

標準モジュール
Option Explicit

Sub test1()
    Dim p As Person

    ' インスタンス生成
    Set p = New Person

    ' 値をセットする
    p.MyName = "Bob"

    ' オブジェクト型をセットする
    Dim mom As Person
    Set mom = New Person
    Set p.MyMother = mom

    ' 値を取得してみる
    Debug.Print "age: " & p.MyAge

    ' メソッド呼び出し
    Call p.SayHello

    ' オブジェクト破棄(スコープから出るとガーベージコレクションによって勝手に破棄されます)
    Set p = Nothing
End Sub

結果

image.png

image.png

Nothing

オブジェクト型で変数を宣言した後、初期状態だとNothingが変数に入っています。(JavaとかでのNullに相当)
Nothingかどうか検査するには、If p Is Nothing Then ...のようにIsを使います。

関連

クラスの応用編はこちら→https://qiita.com/Kamo123/items/a39c8f3ffdc5e665de98

参考文献

VBA Developer's Handbook: Edition 2
https://www.google.co.jp/search?q=VBA+Developer's+Handbook%3A+Edition+2&ie=&oe=

VBAについて網羅的に載っている本です。
現在は絶版になっているようですが、google playストアで電子版を買えました。

128
182
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
128
182