エクセルVBAでプロパティを他のモジュールからアクセスできないようにする方法


ban

photo credit: Kecko Oberalp Pass – Lake via photopin (license)

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

「初心者でもわかるエクセルVBAのクラスモジュール」をテーマにシリーズ連載をお伝えしています。

前回の記事はこちらです。

エクセルVBAでProperty Getプロシージャを使って簡単なプロパティを作成する方法
「初心者でもわかるエクセルVBAのクラスモジュール」をテーマにシリーズ進めております。今回はエクセルVBAでProperty Getプロシージャを使って簡単なプロパティを作成する方法をお伝えします。

Property Getプロシージャについてお伝えしました。

さて、作成してきたPersonクラスのプロパティですが、現在の仕様ではあちこちのモジュールから自由に上書きができちゃいます。

ほら、例えばIdプロパティとかは、上書きしちゃったら、そもそものIdとしての意味がないじゃないですか。

今回と次回とで、その点について解決をしていきます。

まず、今回はエクセルVBAでプロパティを他のモジュールからアクセスできないようにする方法です。

では、行ってみましょう!

スポンサーリンク

前回のおさらい

では、まず前回のおさらいからです。

以下のようなエクセル表がありまして、この1行分のデータを表すクラスを作成したんでしたね。

エクセルVBAでクラス化するエクセル表

実際のクラスモジュール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

Public Property Get IsMale() As Boolean
    IsMale = (Me.Gender = "male")
End Property

モジュール変数によるプロパティが5つ、Greetメソッド、そして前回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.Greet

End Sub

処理としては、クラスPersonのインスタンスを生成して、そのプロパティに前述のエクセル表のデータをポコポコと代入していって、Stopステートメントで中断時にローカルウィンドウでその内容を確認できるというわけです。

プロパティの上書きができないようにするには

ただ、ちょっと気になる点があります。

それは、PersonオブジェクトのIdというプロパティなんですけど、上書きできちゃいますよね…?

上書きして変更できちゃったら、Idって何ナノ…ということになっちゃいます。

このようにプロパティには上書きに制限をかけたいときもありますが、どうしたら良いのでしょ?

Privateステートメントでプライベート変数を宣言する

じゃあ、例えばこんなふうにしちゃいましょう。

プロパティをModule1をはじめ、外部のモジュールからはアクセスできないようにしちゃうのです。

ほら、クラスモジュールPersonに宣言していた以下のモジュール変数Idですが

Public Id As String

このように、Publicステートメントを使っちゃっているから、Module1からアクセスできちゃうんです。

だからそうじゃなくて、以下のPrivateステートメントでモジュール変数を宣言してやるのです。

Private 変数名 As

つまり、コードとしては以下のように変更してやるのです。

Private id_ As String

そしたら、誰からも触れられずに済む…しめしめ、というわけですよ。

え?なんで「Id」ではなくて、小文字でかつアンダースコア付きの「id_」なのかって?

プライベート変数にした場合は、このように、変数名を小文字にして、後ろにアンダースコアを付与する慣習があります。

これにはちょっと理由もありますが、後日の解説で明らかになります。

プライベート変数はプロパティなのか確認する

では、 F2 キーを押してオブジェクトブラウザーを確認してみましょう。

オブジェクトブラウザーでプライベート変数を確認

お、ちゃんと「id_」もプロパティとしてメンバーに追加されているようですね。

「詳細ペイン」では

Private id_ As String

となっています。

プロパティにアクセスできないことを確認

では、標準モジュールModule1のSubプロシージャMySubを実行して、動作を確認してみましょう!

コンパイルエラー: データメンバーが見つかりません

ちーん…

コンパイルエラー: メソッドまたはデータメンバーが見つかりません。

あ、そうか。プロパティ名を「id_」に変えたんでしたね。

プロパティ名を変更して…再度実行っと…

コンパイルエラー: データメンバーが見つかりません

はい、ちーん……

そりゃそうです。

他のモジュールからアクセスできないようにプライベート変数にしちゃったんですから…。

上書きはできなくなりましたけど、これでは最初の値を設定することもできないですね。

この問題は次回解決していきます。

まとめ

以上、エクセルVBAでプロパティを他のモジュールからアクセスできないようにする方法をお伝えしました。

クラスモジュールにプライベート変数を宣言すると、それは他のモジュールからアクセスできないプロパティになります。

てか、アクセスできないんじゃ、プロパティとして意味ないじゃん…って思います?

直接アクセスできないなら、迂回してアクセスすればいいんですね。

その役割を果たすのが、Property Letプロシージャということになります。

次回は、そのあたりお伝えしていきますよ。

エクセルVBAでProperty Letプロシージャを使ってプロパティ設定をする方法
「初心者でもわかるエクセルVBAのクラスモジュール」について連載でお送りしております。今回はエクセルVBAでProperty Letプロシージャを使ってプロパティ設定をする方法をお伝えします。

どうぞお楽しみに!

連載目次:初心者でもわかる!エクセルVBAでクラスを作ろう

名前は聞いたことあるけどよくわからない「クラスモジュール」。本シリーズでは、初心者でも少しずつ丁寧にその作り方と便利さについてお伝えしていきますよ!
  1. 【初心者でもできる】エクセルVBAで最も簡単なクラスを作る方法
  2. エクセルVBAでクラスに最も簡単なプロパティを追加する方法
  3. エクセルVBAで自作クラスをインスタンス化する方法
  4. エクセルVBAでクラスに最も簡単なメソッドを追加する方法
  5. エクセルVBAで表の1行分のデータを表すクラスを作成する方法
  6. エクセルVBAでProperty Getプロシージャを使って簡単なプロパティを作成する方法
  7. エクセルVBAでプロパティを他のモジュールからアクセスできないようにする方法
  8. エクセルVBAでProperty Letプロシージャを使ってプロパティ設定をする方法
  9. エクセルVBAでPropety Getプロシージャを使ってプライベート変数にアクセスする方法
  10. エクセルVBAでクラスのインスタンス生成時に初期データを格納するメソッドを作る方法
  11. エクセルVBAでインスタンスの集合をコレクション化する方法
  12. エクセルVBAでコレクション化したインスタンスを取り出す方法
  13. エクセルVBAでクラスモジュールを使って独自のコレクションを作る方法
  14. エクセルVBAでインスタンス生成時に自動で処理を実行するイベントプロシージャClass_Initialize
  15. エクセルVBAで自作コレクションのインスタンス生成時に初期データも投入する方法
  16. エクセルVBAで自作コレクションの要素を取得するプロパティの作り方
  17. エクセルVBAで自作のコレクションに要素を追加するメソッドを作成する
  18. エクセルVBAで自作コレクションの要素を削除するメソッドの作り方
  19. エクセルVBAでエクセル表のデータを反映するメソッドとクラスを使うメリット

タイトルとURLをコピーしました