環境はWin2000,VB6です
現在クラスを勉強中です。
クラスをデータサーバとして使い,各フォームのデータの更新を通知できるように
ならないかと考えましたがForm側でイベントが拾えません。
Form1のボタンイベントでForm2側でText1.Text="ああああ"としたいのですが
以下のソースを参照ください。
(クラスを経由する必要がないのは理解しています。たくさんフォームがあって
全てのフォームがアンロードする可能性があるとした場合に有効かと思ったのですが・・)
Module1.bas----------------------
Global clsa As Class1
Sub main()
Set clsa = New Class1
Form1.Show
Form2.Show
End Sub
---------------------------------
class1.cls-----------------------
Dim strd As String
Public Event c(ByVal strf As String)
Public Sub b(ByVal strc As String)
RaiseEvent c(strc)
End Sub
----------------------------------
Form1------------------------------
Private Sub Command1_Click()
clsa.b ("ああああ")
End Sub
-----------------------------------
Form2------------------------------
Private WithEvents clsa As Class1
Private Sub clsa_c(ByVal strf As String)
Text1.Text = strf
End Sub
-----------------------------------
Form1のCommand1ボタンをクリックしてもForm2のclsa_c
のイベントが発生しません。
クラスの利点ばかりに目がいって、制限事項が分かって
いないようです。どなたかご指摘いただけないでしょうか?
実行されるインスタンスが違います。
Form1で実行されたメソッドはGlobal宣言されたClass1インスタンスのものが実行されますから、これはWithEvents宣言されていませんから、イベントは発生しません。
このコードでは、WithEevents宣言されたインスタンスのメソッドは全く実行されません。なぜならForm2のプライベート宣言だから。
勉強されたと思いますが、インスタンスとはメモリに作られた『クラスのコピー』です。
このコードでは、有効範囲の異なるコピーが二つ作られていますが、Form1からアクセスできるコピーは、Global宣言したコピーだけです。だから、このコードでは、WithEvents宣言されたコピーは実行されていません。
てか、これでは、コンパイル時にエラーが出ませんか?
解決策は、Global宣言したコピーからイベントを拾ってください。それだけ。
駄長文スマソ。もっと上手い説明ができましたら、どなたかおながいします。
mammal様
回答いただきありがとうございます。
内容は理解できるのですが・・・
>解決策は、Global宣言したコピーからイベントを拾ってください。それだけ。
を実現するのに力不足のようで・・
Form2の記述を以下のように変更してみました。
Set clsD = clsa
でGlobal宣言したクラスをForm2のclsDにコピー
しているつもりです。
・・・がやはりtext1に値が入りません。
Form2------------------------------
Option Explicit
Dim WithEvents clsD As Class1
Public Sub clsa_c(ByVal strf As String)
Text1.Text = strf
End Sub
Private Sub Form_Load()
Set clsD = clsa
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set clsD = Nothing
End Sub
-----------------------------------
>てか、これでは、コンパイル時にエラーが出ませんか?
私のところではエラーは出ずにEXEファイル作成されます^^;
(Form2にはテキストボックスを,Form1にはボタンを配置して
スタートアップの設定をSub main()にしています。)
標準モジュールに宣言したclsa As Class1への参照のセットが行われていないからではないのですか?
Form2のロード時に
Private Sub Form_Load()
Set clsa = Module1.clsa
End Sub
として下さい。
ややこしいのでPrivate変数とグローバル変数の名前は変えたほうがいいかもしれませんね。
Form1も同様にね
おかん様
回答ありがとうございます。
分かりにくいソースで申しわけないです。コメントを反映してみました。
が,それでもForm2のclsa_cのイベント?が発生しません。
参照のセットは行われています。(Module.でglclsAが選択できます)
以下ソースです。
Module1.bas----------------------
Option Explicit
Global glclsA As Class1
Sub Main()
Set glclsA = New Class1
Form1.Show 0
Form2.Show 0
End Sub
Sub Ending() '終了処理
Set glclsA = Nothing
End Sub
---------------------------------
class1.cls-----------------------
Dim strd As String
Public Event Evtest(ByVal strf As String)
Public Sub Testsub(ByVal strc As String)
RaiseEvent Evtest(strc)
End Sub
----------------------------------
Form1------------------------------
Option Explicit
Private Sub Command1_Click()
Module1.glclsA.Testsub ("ああああ")
End Sub
Private Sub Form_Unload(Cancel As Integer) '終了処理
Call Ending
Unload Form2
End Sub
-----------------------------------
Form2------------------------------
Option Explicit
Dim WithEvents clsD As Class1
Private Sub clsD_Evtest(ByVal strf As String)
Text1.Text = strf
End Sub
Private Sub Form_Load()
Set clsD = Module1.glclsA
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set clsD = Nothing
End Sub
-----------------------------------
だからForm1のロードイベントも同じようにって書いてるのに
MSDNライブラリでクラスの説明をもう一回よく読んでください。
よく見たら、動きそうですけどね。
下記サンプルはテスト済みなのでこれと何がちがうか
考えてみてください。
同じ用に思いますが。
'----- Class1.cls
'RaiseEvent C[(arg1, arg2, ... , argn)]
Public Event C(ByVal D As String)
Public Sub B(ByVal D As String)
RaiseEvent C(D)
End Sub
'----- Module1.bas
Sub Main()
Set clsa = New Class1
Form1.Show
Form2.Show
End Sub
'----- Form1.frm
Private Sub Command1_Click()
Module1.clsa.B "AAA"
End Sub
'----- Form2.frm
Private WithEvents clsb As Class1
Private Sub clsb_C(ByVal D As String)
MsgBox D
End Sub
Private Sub Form_Load()
Set clsb = clsa
End Sub
'Module1.bas
Public clsa As Class1
が抜けてました
おかん様のソースですがこちらで動作確認とれました。
こちらで再度自分のソース確認したところ・・・・動きました。
どこかで凡ミスしてたようです。
お手数おかけし申しわけないです。
大変参考になりありがとうございました。
ツイート | ![]() |