みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
「初心者でもわかるエクセルVBAのクラスモジュール」をテーマにシリーズ連載を進めております。
前回の記事はこちらです。
エクセル表の1行分のデータをクラス化する方法をお伝えしました。
さて、皆さんは「Propertyプロシージャ」というキーワードは聞いたことありますか?
VBAでは、Subプロシージャ、Functionプロシージャに加えて、そのPropertyプロシージャでも「手続き」を作ることができるのですが…あまり見かけないですよね?
知りたいですよね!?
ということで、今回はエクセルVBAでProperty Getプロシージャを使って簡単なプロパティを作成する方法をお伝えします。
では、行ってみましょう!
前回までのおさらい
前回までで以下のエクセル表の1行分のデータを表すクラスを作成しました。
クラスモジュール「Person」には以下のようなコードを書きました。
Public Id As String
Public FirstName As String
Public Gender As String
Public Birthday As Date
Public Sub Greet()
MsgBox Me.FirstName & "です、こんにちは!"
End Sub
エクセル表の見出しに対応する4つのプロパティと、Greetメソッドを定義しています。
また、標準モジュール「Module1」には、確認用のSubプロシージャとして以下のコードを書きました。
Sub MySub()
Dim p As Person
Set p = New Person
With Sheet1
p.Id = .Cells(2, 1).Value
p.FirstName = .Cells(2, 2).Value
p.Gender = .Cells(2, 3).Value
p.Birthday = .Cells(2, 4).Value
End With
Stop
'p.Greet
End Sub
この例では、2行目のBobさんのデータについてインスタンスを生成して、Personオブジェクト化をしたわけですね。
男性かどうかを判定するプロパティ
クラスPersonには、すでに4つのプロパティを定義しているわけですが、これにもう1つプロパティを追加したいと思います。
どういうものかというと、そのPersonオブジェクトが男性かどうかを判定する「IsMaleプロパティ」です。
男性であればTrueを、女性であればFalseを返す、ブール型のプロパティを考えています。
モジュール変数を追加する場合
プロパティは、クラスモジュールにモジュール変数を宣言することで追加できますので、クラスモジュールPersonの宣言セクションに、以下の一文を追加するという方法が考えられます。
Public IsMale As Boolean
この場合、標準モジュールModule1のほうは、以下のようなコードにすればいいでしょうか(ついでに、検証しやすいように、行番号を変数iに持たせるようにしました)。
Sub MySub()
Dim p As Person: Set p = New Person
Dim i As Long: i = 2
With Sheet1
p.Id = .Cells(i, 1).Value
p.FirstName = .Cells(i, 2).Value
p.Gender = .Cells(i, 3).Value
p.Birthday = .Cells(i, 4).Value
p.IsMale = (p.Gender = "male")
End With
Stop
'p.Greet
End Sub
しかし、これでは性別を表すGenderプロパティがこの後の処理で変更になった場合(現実的にあるかどうかは別としてw)、IsMaleプロパティも設定し直すのを忘れないようにしないといけません。
IsMaleプロパティを参照しようとしたときに、都度Genderプロパティの値から判定して値を返すようにできればいいのですが…
と、そのようなことを実現するのが、Property Getプロシージャということになります。
Property Getプロシージャとは
Property Getプロシージャは、プロシージャですから「手続き」を定義することができます。
どんな手続を定義するかというと、「プロパティを取得する際の手続き」を定義します。
つまり、何らかの手続を経てプロパティを取得することができます。
書き方はこうです。
’処理
プロシージャ名 = 戻り値
End Property
なんとなくFucntionプロシージャに似ていますね?
戻り値を返す仲間なので、Property GetプロシージャとFunctionプロシージャの定義の仕方は似ています。
Property Getプロシージャでプロパティを定義する
では、Property Getプロシージャを用いて、男性かどうかを判定するIsMaleプロパティを作成してみましょう。
クラスモジュールPersonに、以下のProperty Getプロシージャを追加しましょう。
Public Property Get IsMale() As Boolean
IsMale = (Me.Gender = "male")
End Property
これでOK。
先ほど、Module1に追加しようとしていたGenderプロパティの判定処理を、クラスモジュールのProperty Getプロシージャに書いたという感じですかね。
では、例のごとく、F2 キーでオブジェクトブラウザーを開いて確認してみましょう。
クラスPersonにIsMaleプロパティが追加されていることが確認できます。
しかも、下部の「詳細ペイン」を見ると、以下のように記載されています。
Public Property IsMale As Boolean
読み取り専用
ここを見ると、プロパティがモジュール変数で宣言されたものなのか、Property Getプロシージャで定義されたものなのかがわかりますね。
しかも、Property Getプロシージャのみで作成したプロパティは「読み取り専用」になるわけですね。書き込みされても困りますもんね。
Property Getプロシージャによるプロパティの動作を確認
では、Property Getプロシージャで作成したIsMaleプロパティの動作を確認してみましょう。
標準モジュールModule1を以下のように検証できるように変更しました。
Sub MySub()
Dim p As Person: Set p = New Person
Dim i As Long: i = 2
With Sheet1
p.Id = .Cells(i, 1).Value
p.FirstName = .Cells(i, 2).Value
p.Gender = .Cells(i, 3).Value
p.Birthday = .Cells(i, 4).Value
End With
Stop
p.Gender = "female"
Stop
'p.Greet
End Sub
実行して1回目のStopステートメントの中断時にローカルウィンドウを確認すると
- Genderプロパティ: “male”
- IsMaleプロパティ: True
となっています。
- Genderプロパティ: “female”
- IsMaleプロパティ: False
Genderプロパティの値に連動して、IsMaleプロパティの値も変更されていますね。
Bobさんには悪い気がしますが…
まとめ
以上、エクセルVBAでProperty Getプロシージャを使って簡単なプロパティを作成する方法をお伝えしました。
Property Getプロシージャを使うと、何らかの手続きによってプロパティを取得することができます。
このように、クラスモジュールにプロシージャを追加していくことで、クラスに対する操作を追加したり、データを計算・加工して取り出したり、といった機能を追加することができます。
このエクセル表のデータに関する手続きはクラスモジュールがバッチリ担当してくれているとなれば、コードの管理…めっちゃわかりやすくなりますよね。
さて、次回はプロパティをプライベートにするという話を紹介していきます。
どうぞお楽しみに!
連載目次:初心者でもわかる!エクセルVBAでクラスを作ろう
名前は聞いたことあるけどよくわからない「クラスモジュール」。本シリーズでは、初心者でも少しずつ丁寧にその作り方と便利さについてお伝えしていきますよ!- 【初心者でもできる】エクセルVBAで最も簡単なクラスを作る方法
- エクセルVBAでクラスに最も簡単なプロパティを追加する方法
- エクセルVBAで自作クラスをインスタンス化する方法
- エクセルVBAでクラスに最も簡単なメソッドを追加する方法
- エクセルVBAで表の1行分のデータを表すクラスを作成する方法
- エクセルVBAでProperty Getプロシージャを使って簡単なプロパティを作成する方法
- エクセルVBAでプロパティを他のモジュールからアクセスできないようにする方法
- エクセルVBAでProperty Letプロシージャを使ってプロパティ設定をする方法
- エクセルVBAでPropety Getプロシージャを使ってプライベート変数にアクセスする方法
- エクセルVBAでクラスのインスタンス生成時に初期データを格納するメソッドを作る方法
- エクセルVBAでインスタンスの集合をコレクション化する方法
- エクセルVBAでコレクション化したインスタンスを取り出す方法
- エクセルVBAでクラスモジュールを使って独自のコレクションを作る方法
- エクセルVBAでインスタンス生成時に自動で処理を実行するイベントプロシージャClass_Initialize
- エクセルVBAで自作コレクションのインスタンス生成時に初期データも投入する方法
- エクセルVBAで自作コレクションの要素を取得するプロパティの作り方
- エクセルVBAで自作のコレクションに要素を追加するメソッドを作成する
- エクセルVBAで自作コレクションの要素を削除するメソッドの作り方
- エクセルVBAでエクセル表のデータを反映するメソッドとクラスを使うメリット
コメント
タカハシ様
初めまして。
いつも記事を興味深く拝見させていただいております。
私はExcel VBAをチームの業務効率化に利用している孤独なノンプログラマ―の一人です。
最近クラスについて勉強しているところなのですが、過去にご指摘のように、巷にはクラスに関する情報がほとんどないため、このシリーズの記事は特に何度も読み返させていただいています。
さて、本記事のサンプルコードについて質問させてください。
コードの一部にある下記の記載が難解だったのですが、
p.IsMale = (p.Gender = “male”)
これは
If d.Gender = “male” Then
d.isMale = True
Else:
d.isMale= False
End If
と同一の機能を持ったコードという理解でよろしいでしょうか?
また、この書き方は私にとって全く馴染みがなく、どこをどのように考えればそのような記述が可能になるのか今一つ理解ができませんでした。
コードをシンプルに書く上で使えそうな書き方でしたので、ぜひ取り入れたいと思っているのですが、現状では応用が効かない知識となってしまっています。
(実行一時停止状態で、イミディエイトウィンドウに”?Gender = “male” ” と記述すると ”True” が返ってくることは突き止めましたw”
そこで、記事の本題からは外れていて大変恐縮なのですが、なぜ上記のような書き方が可能なのか解説いただけないでしょうか。
VBA以外のプログラムについては全く知識がなく、もしかするとごく常識的なことかもしれませんが、よろしくお願いいたします
本田さん
コメントありがとうございます!
こちらのコードですが、以下のような一般的な変数の代入ステートメントと同様にとらえてください。
それで、「式」の部分が
になっているわけですが、これはブール式または条件式と呼ばれるものになります。
その式の中心となっているのが比較演算子「=」で、左辺と右辺が等しければ式全体がTrueに、さもなければFalseに評価されます。
提示いただいた以下の式と同様の意味になります。
ご確認いただければ幸いです。