エクセルVBAクラス備忘録 public使う使わないどうする?

20240303 エクセルVBAクラス備忘録 public使う使わないどうする?

エクセルVBA オブジェクト指向備忘録クラス 

 

<前書き>
エクセルVBAオブジェクト指向、初心者です。
VBA自体は、以前から使用していました。
オブジェクト指向というものがあることは、知っていましたが、ネットなどを見てもよく分からず、挫折した過去あり。
<以上前書き>

 

今回の疑問
クラスのproperty(変数)にprivateを使うか、publicを使うか問題。
まあ、普通に考えれば、privateの方が「安全」なので、privateを使うのがいいのかもしれないが、書くのがめんどくさい。
(使い分けも、クラスの場合ピンと来ていない・・・)

 

===========================================
ファイルA
標準モジュール
' 例: 意図しない変更を防げない場合public
Sub ExampleUsage()
    Dim myExample As New clsExample
    myExample.ExampleValue = 1000 ' 直接変更(入力時候補出る)
    Debug.Print myExample.ExampleValue
    
End Sub

 

クラスclsExample
Public ExampleValue As Integer

======================================
ファイルB
標準モジュール
' 例: 意図しない変更を防げる場合 private
Sub ExampleUsage()
    Dim myExample As New clsExample
    myExample.Value = 2000 ' 値を設定(入力時候補は出る)
    Debug.Print myExample.Value

End Sub

 

クラスclsExample
Private ExampleValue As Integer

Public Property Let Value(newValue As Integer)
    ExampleValue = newValue
End Propert

Public Property Get Value() As Integer
    Value = ExampleValue
End Property

======================================
上記コメントに、「意図しない変更を防げる場合 private」とか書いたが、実際は、同じように書き換えをしている。
コード入力の際も、AもBも、myExample.まで書いたら、次の候補を表示してくれる。


BingAIに質問するとカプセル化・隠ぺいなど説明してくれるが、ピンと来ない。
(手続き型ならpublicの使い分け分かると言うか、publicはほぼ使わない)


publicにしてどこからでも書き換えられると困るというが、インスタンス化のコードを書く必要があるので、そんなに困ることはあるのだろうか?
なら、下記のように、クラス内に値を持たせたらどうか?
(コードは適当です。すみません。汗)

====================================
ファイルC
標準モジュール
' 例: 意図しない変更を防げる場合
Sub ExampleUsage()
    Dim myExample As New clsExample
    myExample.Value = 0   ’仮に置きました
    Debug.Print myExample.Value   ’2000が表示
    
End Sub


Private ExampleValue As Integer

Public Property Let Value(newValue As Integer)
    ExampleValue = 2000
End Property

Public Property Get Value() As Integer
    Value = ExampleValue
End Property

====================================
または、Property Letに入ったら、if文などで制御かけるとか。
(よく分からないけど。)

 

++++++++++++++++++++++++++++++++
その他疑問:

別ファイルから、クラス(変数)が使われてしまうのか、気になった。

例えば、AAというファイルに、下記のコードがあります。(標準モジュールとクラス)

AAファイル

標準モジュール
Sub ExampleUsage()
    Dim myExample As New clsExample
    myExample.ExampleValue = 1000  
    Debug.Print myExample.ExampleValue
    
End Sub


クラスclsExample
Public ExampleValue As Integer


/////////////////////////////////
BBというファイルに、標準モジュールだけあった場合、

BBファイル
標準モジュール
Sub ExampleUsage()
    Dim myExample As New clsExample
    myExample.ExampleValue = 1000 
    Debug.Print myExample.ExampleValue
    
End Sub

///////////////////////////////
BBのファイルは、「クラスが定義されていない」とエラーになります。
そのままでは、他のブックのクラスは、他のファイルのプロジェクトでは使えないようです。


「BBにも、クラスclsExample」を設定しないと動かないのか?BingAI様に聞いたところ、)
①Bにもクラスを置くか

②参照設定を追加する
とのことでした。
「参照設定」について、ネットで調べてみたが、面倒なのでやってません。
参照設定まで使っているエクセルユーザーは自分の周りにいないので、Aのブックから、Bのクラスを呼び出して、おかしな挙動をするというようなことはなさそうです。
(自分の周りでは。)

 

よく分からないが、手続き型を見るみたいに、ステップ実行してみていくと・・・
Property Letなどクラスを使う場合、処理過程でたくさん変数を持つことになり、メモリとかすごく食うのでは?とか、
今回の疑問のように、変数のスコープで問題が起こらないかとか、不安になります。汗

 

・・・やってみるしかないのかな。