2つフォームでクラス内の変数を共有するには?

解決


hikaru  2006-06-21 04:06:27  No: 131946

VB6の初心者です。

Form1からForm2を呼び出します。
Form2を呼び出す前にForm1で使用したClass1の変数の値を保持しておき、
新たに呼び出したForm2にて再びClass1の変数を利用したいのですが、
どのようにすれば良いのでしょうか?

以下のようにしてもForm2側では、Class1の保持した変数を利用できず、
全て"0"かヌルになってしまいます。

Form1
Private Cls As Class1

Private sub Test1()
    Set Cls As Class1
    Cls.Member = Text1.text
End Sub

Form2
Private Cls As Class1

Private sub Test2()
    Set Cls As Class1
    Text2.text = Cls.Member
End Sub

Class1
Private mintValue As Integer←クラス内のみで外部からはプロパティでアクセスする。

Public Property Get Member() As Integer
    Member = mintValue
End Property

Public Property Let Member(ByVal NewValue As Integer)
    mintValue = NewValue
End Property

アドバイスお願いします。


hikaru  2006-06-21 04:18:12  No: 131947

すみません。間違えましたので訂正します。

Form1
Private Cls As Class1

Private sub Test1()
    Set Cls = New Class1
    Cls.Member = Text1.text
End Sub

Form2
Private Cls As Class1

Private sub Test2()
    Set Cls = New Class1
    Text2.text = Cls.Member
End Sub

Class1
Private mintValue As Integer←クラス内のみで外部からはプロパティでアクセスする。

Public Property Get Member() As Integer
    Member = mintValue
End Property

Public Property Let Member(ByVal NewValue As Integer)
    mintValue = NewValue
End Property

アドバイスお願いします。


魔界の仮面弁士  2006-06-21 05:06:21  No: 131948

> Form1からForm2を呼び出します。
> Form2を呼び出す前にForm1で使用したClass1の変数の値を保持しておき、
> 新たに呼び出したForm2にて再びClass1の変数を利用したいのですが、

ならば、「New Class1」するのは、親である Form1 の仕事としましょう。
Form2 側は、自分で New するのではなく、Form1 側から Class1 を
受け取るようにします。たとえば……

Private Sub Test2()
    Set Cls = New Class1
    Text2.Text = Cls.Member
End Sub

を、

Private Sub Test2(ByVal Item As Class1)
    Set Cls = Item
    Text2.Text = Cls.Member
End Sub

という感じにしてみるとか。


LESIA  2006-06-21 14:24:27  No: 131949

クラスではなく標準モジュールにするのはダメですか?

■Form1
Private sub Test1()
    Module1.Member = Text1.text
End Sub

■Form2
Private sub Test2()
    Text2.text = Module1.Member
End Sub

■Module1
Private mintValue As Integer

Public Property Get Member() As Integer
    Member = mintValue
End Property

Public Property Let Member(ByVal NewValue As Integer)
    mintValue = NewValue
End Property


hikaru  2006-06-21 17:39:56  No: 131950

みなさん、ありがとうございます。
魔界の仮面弁士のアドバイスにより、実装しようとしたのですが、

Private Sub Test2(ByVal Item As Class1)
    Set Cls = Item
    Text2.Text = Cls.Member
End Sub

上記の関数をCall Test2 で呼び出そうとすると、”引数は省略できません”
と出てしまいます。
どのように引数を指定すれば良いのでしょうか?
また、コマンドボタン
Private Sub Command1_Click()
の場合は、どうなるのでしょうか?


hikaru  2006-06-21 18:05:25  No: 131951

すみません。
魔界の仮面弁士さん、敬称を忘れていました。失礼致しました。

さらに質問を補足しますと、
Call Test2(Item)
と指定すると”変数が宣言されていません”とエラーが出ます。
おそらく、当然でしょうが。
Private Sub Command1_Click(ByVal Item As Class1)
    Set Cls = Item
    Text2.Text = Cls.Member
End Sub
とすると”プロシージャの宣言がイベントまたはプロシージャの定義と一致しません”とエラーが出ます。

どのように
Private Sub Test2(ByVal Item As Class1)
    Set Cls = Item
    Text2.Text = Cls.Member
End Sub
この関数を使用すれば良いのでしょうか?


魔界の仮面弁士  2006-06-21 19:36:47  No: 131952

コードのイメージだと伝わりにくいようなので、具体例を交えましょうか。

まずは、Form1 から Form2 の呼び出しに関する記載が無かったので、
  '== Form1 ===
  Private Sub Command1_Click()
    Load Form2
    Form2.Show vbModal, Me
  End Sub
もしくは
  '== Form1 ===
  Private F2 As Form2
  Private Sub Command1_Click()
    Set F2 = New Form2
    F2.Show vbModal, Me
  End Sub
のように、「モーダルで表示」させるという前提で書いてみます。

また、最初に記載されたコードにある
  『Private Cls As Class1』
はエラーになる(Form の Cls メソッドと名前が競合する)はずなので、
以下では Private mCls As Class1 という名前に置き換えて説明しますね。

-----------

まずやるべきことは、メソッド引数やプロパティなどを使って、
「Form1で生成されたインスタンス」を「Form2内の変数」に
セットできるようにしなければいけない、という事になります。

そして、その受け渡しの方向として、幾つかの 選択肢があります。
  《1》 Form1 側が、Form2 に Class1 を渡す。
  《2》 Form2 側が、Form1 の Class1 を受け取りに行く。
  《3》 Form1 側が、Form1 と Form2 の双方から見える位置に
        Class1 を置いておき、Form2 はそれを読みに行く。

また、それをどのようにして受け渡すのか、という話もあります。
  《a》 プロパティを使って渡す。
  《b》 メソッドの引数にて渡す。
  《c》 イベントの引数にて渡す。

------------

たとえば元のコードでは、Class1 内の mintValue 変数を、
Member という名前の Public プロパティとして公開していましたよね。
《a》の方法は、これの応用です。

《a》の手法を、《1》の方向で処理するなら、Form2 内に
  Friend Property Let Prop(ByVal Item As Class1)
    Set mCls = Item
  End Property
といった実装を加えておきます。この場合、Form1 の呼び出し処理は
    Set mCls = New Class1
    Load Form2
    Set Form2.Prop = mCls
    Form2.Show vbModal, Me
などと書けるかと思います。

一方、《a》-《2》という組み合わせで処理するなら、Form1 側に
  Friend Property Get Prop() As Class1
    Set Prop = mCls
  End Property
といった実装を加えておきます。この場合は、Form2 側では、
    Set mCls = 親となるForm1のインスタンス.Prop
  のようにして受け取る事になりますが…この手法だと、Form1 の存在を
  Form2 側が知らなくてはいけなくなってしまいます。これは、フォームの
  親子関係の結びつきが強くなってしまうので、避けた方が良いでしょう。

《a》-《3》という組み合わせについては、LESIAさんが提示されているので、
ここでは言及しないでおきます。

------------

《b》を使った方法については、さらに、その引数を Test2 メソッド自体に
付け加えるのか、それとも、Class1 を受け渡すための別のメソッドを用意するのか、
といった点も考えておきます。

たとえば、《b》-《1》として、Test2 メソッド自体の定義を変えるなら、
  '=== Form1 ===
  Option Explicit
  Private mCls As Class1
  Private Sub Test1()
    Load Form2
    Set mCls = New Class1
    mCls.Member = CInt(Text1.Text)
    Form2.Test2 mCls
    Form2.Show vbModal, Me
    Set Form2 = Nothing
  End Sub
  Private Sub Command1_Click()
    Call Test1
  End Sub

  '=== Form2 ===
  Option Explicit
  Private mCls As Class1
  Friend Sub Test2(ByVal Item As Class1)
    Set mCls = Item
    Text2.Text = CStr(mCls.Member)
  End Sub
などといった実装ができます。

あるいは、《b》-《1》とするが、元の「Private Sub Test2()」の定義を
崩さないようにするなら、こういう書き方もありますね。

  '=== Form1 ===
  Option Explicit
  Private mCls As Class1
  Private Sub Test1()
    Set mCls = New Class1
    mCls.Member = CInt(Text1.Text)
    Load Form2
    Form2.ShowModalDialog mCls
    Set Form2 = Nothing
  End Sub
  Private Sub Command1_Click()
    Call Test1
  End Sub

  '=== Form2 ===
  Option Explicit
  Private mCls As Class1
  Private Sub Test2()
    Text2.Text = CStr(mCls.Member)
  End Sub
  Friend Function ShowModalDialog(ByVal Item As Class1) As Boolean
    Set mCls = Item
    Load Me
    Call Test2
    Me.Show vbModal
  End Function

------------

とまぁ、他にもいろいろと実装方法はあるでしょうが、キリが無いので
とりあえず、この辺で止めておきます。(^^;


hikaru  2006-06-21 20:32:09  No: 131953

魔界の仮面弁士さん
いくつものパターンにわたり具体的な例で説明していただき、ありがとうございました。
おかげさまで、《b》-《1》の方法で実装し、うまくいきました。
一つの処理をするのにたくさんやり方がありますね。
大変勉強になりました。
ありがとうございました。


hikaru  2006-06-21 20:32:17  No: 131954

魔界の仮面弁士さん
いくつものパターンにわたり具体的な例で説明していただき、ありがとうございました。
おかげさまで、《b》-《1》の方法で実装し、うまくいきました。
一つの処理をするのにたくさんやり方がありますね。
大変勉強になりました。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加