フォームモジュールのモジュール変数はそのフォームのプロパティーなのでしょうか?
例えば、Form1のフォームモジュールの上の方に、
Public a As Integer
というふうに書いてモジュール変数を宣言した場合、この変数aは他のモジュールから
Form1.a
として参照できるのでこの変数aはForm1のプロパティーということになるのでしょうか?
同じように、関数bをForm1のフォームモジュールに、
Public Sub b()
・・・
End Sub
と書いた場合、関数bはForm1のメソッドということになるのでしょうか?
Form1がまだロードされていないときに、例えばWidthプロパティーなどのForm1の元からあるプロパティーを参照しようとするとForm1がロードされてしまいますが(Loadイベントが発生する)、上のモジュール変数aを参照しようとしたときはForm1はロードされませんでした(Loadイベントが発生しなかった)。ということはモジュール変数aはForm1のプロパティーではないということになるのではないでしょうか?
どういうふうに捉えるのが正しいのでしょうか?
どうかよろしくお願いいたします。
> フォームモジュールのモジュール変数はそのフォームのプロパティーなのでしょうか?
VB6 の場合は Yes ですし、VB.NET の場合は No です(今回は VB6 ですね)。
VB6 の場合、Public なモジュールレベル変数は、利用者側からは Property と区別がつきません。
たとえば下記の場合、これは読書き可能な A プロパティおよび B プロパティとして認識されます。
Option Explicit
Public A As Integer
Public Property Get B() As Integer
B = Second(Now())
End Property
Public Property Let B(ByVal v As Integer)
Debug.Print B
End Property
また、ヘルプ(VB6 用の MSDN ライブラリ)の目次から
[Visual Basic ドキュメント]
└[Visual Basic の使用方法]
└[プログラミング ガイド]
└[Visual Basic を使ってできること]
└[オブジェクト]
└[クラスのプロパティおよびメソッドの追加]
└[クラスのプロパティの追加]
とたどると、こうした変数もプロパティの一種であると書かれた文書を見ることができます。
≫ クラスのプロパティの最も簡単な定義方法は、クラス モジュールに
≫ パブリック変数を追加することです。たとえば、Account と名付けられた
≫ クラス モジュールで 2 つのパブリック変数を宣言すると、
≫ 簡単に Account クラスを作成することができます。
≫
≫ Public Balance As Double
≫ Public Name As String
ただしカプセル化という点から言えば、Public な変数ではなくプロパティ プロシージャを用いた方が
望ましいです。特に、(標準 EXE プロジェクトではなく)ActiveX のプロジェクトとして生成する場合には。
> 同じように、関数bをForm1のフォームモジュールに、
> Public Sub b()
> ・・・
> End Sub
> と書いた場合、関数bはForm1のメソッドということになるのでしょうか?
はい。この場合、b はメソッドの宣言を意味します。
しかし、Sub プロシージャである b は「関数」ではありません。VB6 における関数とは
値を返すものであり、通常は『Function プロシージャ』で宣言された物を指します。
> Form1がまだロードされていないときに、例えばWidthプロパティーなどのForm1の
> 元からあるプロパティーを参照しようとするとForm1がロードされてしまいますが
> (Loadイベントが発生する)、上のモジュール変数aを参照しようとしたときは
> Form1はロードされませんでした(Loadイベントが発生しなかった)。
ヘルプの下記項目にある動作ですね。
[Visual Basic ドキュメント]
└[Visual Basic の使用方法]
└[プログラミング ガイド]
└[Visual Basic を使ってできること]
└[オブジェクト]
└[独自のクラスの作成]
└[Visual Basic フォームの有効期間]
> ということはモジュール変数aはForm1のプロパティーではないということになるのではないでしょうか?
それはまた別の問題です。Form1 のプロパティにアクセスすると自動 Load される、というわけでは無く、
「ロードしないと取得できないもの」にアクセスすると、自動的に Load が発生するというだけです。
たとえば、ボタンを貼ると Command1 プロパティ、テキストボックスを貼ると Text1 プロパティが追加されますが、
Dim f As Form2
Set f = New Form2
Dim t As TextBox
Set t = f.Text1
のように記述しても、Form2 はまだロードされません。しかしながら、このあとで
MsgBox t.Text
などとすると、この時点で Form2 がロードされます。しかし、.Text は Form1 のプロパティではありませんよね。
これは、自作プロパティであっても同様です。たとえば、Form2 に
Public Property Get Sample() As TextBox
Set Sample = Me.Text1
End Property
と実装した場合、呼び出し側を
Dim t As TextBox
Set t = Form2.Sample
としても Form2 はロードされませんが、この変数 t のメンバ(BackColor、Name、Move等)を
操作すると、フォームがロードされます。
> 例えばWidthプロパティーなどのForm1の
> 元からあるプロパティーを参照しようとするとForm1がロードされてしまいますが
もしも Width のように、プロパティにアクセスされると自動ロードされるようにしたいのであれば、
ロードを強制するために、プロパティやメソッドの内部で、意図的に「Load Me」を呼び出せば OK です。
たとえば下記のように。
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200606/06060068.txt
魔界の仮面弁士さん、ご回答ありがとうございます。
いつもご丁寧な分かり易い回答をして頂いて本当に恐縮です。
> ただしカプセル化という点から言えば、Public な変数ではなくプロパティ プロシージャを用いた方が望ましいです。
「Property Get」や「Property Let」というものはそういうことに使うためにあったのですか。フォームモジュールでも使えるとはぜんぜん知りませんでした。
> それはまた別の問題です。Form1 のプロパティにアクセスすると自動 Load される、というわけでは無く、
> 「ロードしないと取得できないもの」にアクセスすると、自動的に Load が発生するというだけです。
そうだったのですか。つまりForm1クラスのインスタンスが作成されるのとForm1のウインドウが作成されるのは別のことだったのですね。目から鱗が落ちた感じです。
今までもやもやしていたものがすっきり整理されたような気分です。
ヘルプもしっかり読んで理解を深めて行きたいと思います。
本当にありがとうございました。
ツイート | ![]() |