t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBA オブジェクトのメソッドチェーン

メソッドチェーンとは

メソッドチェーンとは、ひとつのオブジェクトに対して複数メソッドを1ステートメントで実行するテクニックである。
具体的には、オブジェクトのメソッドが自分自身を返すように設計することで、メソッドをドットで繋ぐだけで次々とそのオブジェクトに指令を与えることができるというもの。

例えばPersonというオブジェクトにNameとAgeの2つのフィールドとIntroduceという自己紹介をするメソッドがあるとする。

普通はこのように複数行で記述する。

p = New Person
p.Name = "Yamada Taro"
p.Age = 20
p.Introduce

メソッドチェーンテクニックを用いると、次のように記述することができる。

p = New Person
p.SetName("Yamada Taro").SetAge(20).Introduce

もちろん、デフォルトでこのような書き方ができるわけではなく、クラスモジュールをメソッドチェーンが可能なように設計しないといけない。

作り方

クラスモジュールPersonを用意し、次のコードを張り付ける。

Public Name As String
Public Age As Integer

Function SetName(name_ As String) As Person
    Name = name_
    Set SetName = Me
End Function

Function SetAge(age_ As Integer) As Person
    Age = age_
    Set SetAge = Me
End Function

Function Introduce() As Person
    Debug.Print "Hello!"
    Debug.Print "My name is " & Name & ". "
    Debug.Print "I'm " & Age & " years old."
    Debug.Print "Nice to meet you."
    Set Introduce = Me
End Function

メソッドチェーンはPropertyプロシージャとは相性が悪いのでFunctionで作っている。

あとは標準モジュールで次のように実行する。

Sub hoge()
    Dim p As Person
    Set p = New Person
    p.SetName("Taro Yamada").SetAge(20).Introduce
End Sub

実行結果がこちら。

Hello!
My name is Taro Yamada. 
I'm 20 years old.
Nice to meet you.

今回のPersonクラスではIntroduceも自分自身を返すように設計したので、次のように連続で人物情報を入れ替えることも。。

Sub hoge()
    Dim p As Person
    Set p = New Person
    p.SetName("Taro Yamada").SetAge(20).Introduce _
        .SetName("Jiro Suzuki").SetAge(30).Introduce _
        .SetName("Saburo Satou").SetAge(40).Introduce
End Sub

注意点として、今回は説明のためのサンプルであって、実務で利用する際は人物情報を表すオブジェクトを使いまわすのには問題がある。
たとえば年齢の変更忘れにより前の人物情報の一部が残ってしまうなど。
ブランクであれば出力結果を見ておかしいと気付けるけど、間違った情報が混入すると気付くきっかけが失われ、ビジネス上の問題に発展する。
安全で良いコードとは、プログラムのトラブルをプログラムの問題にとどめ、ビジネスの問題に発展させないコードである。

話が逸れたけど、メソッドチェーンの解説は以上。
VBAにはWithステートメントがあるのであんまりありがたみは無いかもしれないけど、将来「まさにここはメソッドチェーンの独断場!」と思う場面に出くわすかもしれないので一応紹介。

参考(英語)
www.sitepoint.com

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。