今、悩んでいるというか、不思議に思っていることがあります。
ACCESS2003 VBAで、VBAコードでメインのフォームから、ある帳票フォームのインスタンスを作成しています。メインフォームのモジュールに以下のように記述し、
Dim 帳票1 as Form
で、ボタンのクリックイベントで、
set 帳票1 = New Form_帳票の元フォーム
とインスタンスを生成します。更に、この帳票フォームには、同様に子フォームを持っています。こちらも同様に帳票フォームモジュールに、
Dim 詳細1 as Form
として、あるボタンのクリックイベントに、
set 詳細1 = New Form_詳細フォーム
と、しています。ここで、帳票1の閉じるボタンを押しても、詳細1のフォームは、閉じません。
同様に、帳票の元フォームに
Dim 帳票2 as form
ボタンクリックで、
Set 帳票2 = New Form_帳票2の元フォーム
とします。さらに帳票2の元フォームには、
Dim Child帳票 as Form
ボタンクリックで、
Set Child帳票 = New Form_帳票2の元フォーム
としています。
これで、Child帳票は、いくつもいくつもインスタンス化されます。そこで、今までの動作に準じて、たくさんあるChild帳票の大元を閉じると、こちらは子フォームが全部閉じます。例えば10個子フォームを作って、途中を閉じるとちゃんとその子だけが閉じます。最初の例の帳票1フォームを閉じても、詳細1フォームが閉じないのと、何が違うのか分かりません。私は、フォームが閉じるときには、そのメンバクラス(フォーム)は、破壊されるものだと思っていたのですが、そうでもないようです。どなたかわかりやすく、教えていただけないでしょうか?
再現しながら考えてみます。
「btn1」「btn2」「btn3」を持つフォーム「F1」を作ります。
フォーム「F1」を「F2」「F3」名でコピーします。
フォーム「F1」に以下を記述します。
Dim frm As Form
Private Sub btn1_Click()
Set frm = New Form_F2
frm.Visible = True
End Sub
Private Sub btn2_Click()
DoCmd.Close acForm, Me.Name, acSaveNo
End Sub
Private Sub btn3_Click()
Set frm = Nothing
End Sub
フォーム「F2」にも記述をコピーして
Set frm = New Form_F2
部分を
Set frm = New Form_F3
に変更します。
フォーム「F3」の「btn1」「btn3」は削除し
Private Sub btn2_Click()
DoCmd.Close acForm, Me.Name, acSaveNo
End Sub
を記述しておきます。
フォームは出来上がったので、保存して閉じておきます。
フォーム「F1」を起動し、「btn1」をクリックし子フォーム「F2」を表示します。
フォーム「F2」の「btn1」をクリックし子フォーム「F3」を表示します。
この状態が、添付図上段になります。
ここで「F2」を閉じると、ご質問にあったものになるかと思います。
フォーム「F1」「F3」が表示されていて、何故「F3」が表示されているのか・・・
(添付図中段) ご質問の解釈はこれで良かったでしょうか。
続いて、「F1」の「btn3」(クリア)をクリックすると、「F3」は消えます。(添付図下段)
また、この時「btn3」(クリア)ではなく「btn1」(子フォーム起動)をクリックしてみると、「F3」は消え、「F2」が表示されます。
この動きで、雰囲気わかられたのではないでしょうか。
「btn3」クリックでは、Set frm = Nothing
「btn1」クリックでは、無条件に Set frm = New Form_F2
以下、適切な言葉・用語は不慣れなので、また、嘘かもしれないので雰囲気でお願いします。
フォーム「F2」を閉じたことによって、Access の管理上から「F2」は消えましたが、
親の「F1」では、まだ frm で参照しているためメモリの開放は行われなかった。
また「F2」だったメモリ上には「F3」を参照している frm が生きていたので「F3」は表示されていた。
という事になるのかと思います。
インスタンスを作って子を管理する場合、
・自分が閉じられる時には、自分が抱える子は Nothing してあげる
・また、自分が親に管理されているのなら、閉じられる事を親に教えて Nothing してもらう
等の細工が必要と思います。
その辺の例として、以下が参考になると思います。
同じフォームを複数表示する その2
http://hatenachips.blog34.fc2.com/blog-entry-5.html
余談)
前回のご質問で(すぐに閉じられてしまったので)・・・
サブフォームの組み込み方で以下の様な記述がありましたが、意味はないような気がします。
Dim child as Form
Set Child = New ChildForm
サブフォームコントロール1.SourceObject = Child.name
サブフォームコントロールに組み込まれた Form と Child は違うものだと思います。
Dim frm As Form
Private Sub btn1_Click()
Set frm = New Form_F1
Me.FSUB.SourceObject = frm.Name
If (frm Is Me.FSUB.Form) Then
MsgBox "SAME"
Else
MsgBox "NONE"
End If
Set frm = Nothing
End Sub
として確認してみると、
・NONE が表示される
・ Set frm = Nothing しても指定したフォームが表示されている
確認の仕方がまずかったらすみません・・・
お礼
回答有り難うございます。 大変申し上げにくいのですが、私の確認ミスでした。子供が消える方は、Closeイベントで子供フォームにNothingを代入していました。お騒がせして申し訳ございません。実は、今度はまた違う悩みが発生したのですが、また自分のミスかもしれないので、もうちょっと考えることにして、今回はこれにて解決とさせて頂きます。また、どうしょうもなくなったら、お聞きするかも知れません。その時にはよろしくお願い致します。 なお、前の質問にまでお応えいただいて、恐縮です。 実は、前の質問に関する部分は、当該子フォームが上手く機能させられなくて、実装を断念してしまいました。それ以降、その部分については考えを進めていないので、教えていただいた事は、後日の課題とさせて頂きます。