- ベストアンサー
VB6で2つのフォームを使ってプログラムについて
- Windows XP VB6(SP?)の環境で2つのフォーム(1と2)を使用してプログラムを作成しています。1からエクセルのデータを呼び込んで表示し、さらにデータを追加し、コマンドボタンを押すと2が表示されます。一部のデータはラベルに表示し、さらにデータを追加できます。1と2のデータをエクセルの帳票に登録・保存します。2のフォームは登録・保存の際にアンロードします。
- 1順目ではうまくデータが表示されますが、2順目ではパブリック変数を使用して表示されたデータのみが正しく反映されます。フォーム上では表示されていますが、デバッグプリントするとデータが空欄になっているため、登録・保存できません。どうすれば解決するかわかりません。
- VB6を半年ほど学んでいます。これについてわからないことができれば、教えていただきたいです。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
そもそもクラス(Formもクラスの一種)は New というキーワードで インスタンス(実体)の生成が必要です。 ところが、VB が余計な。。。というか裏で色々と自動でやってしまう 事があって注意が必要です。 本来のフォーム表示手順は以下です。 'Form1 に記入 Private Sub Command1_Click() Dim f As Form2 '参照変数を用意 Dim i As Integer For i = 1 To 3 Set f = New Form2 'インスタンス生成 f.Show Next '最後に操作しているフォームに命令 '※この時点で1つ目と2つ目の Form2 は f では操作できない f.Text1.Text = CStr(i) End Sub Form 名を直接指定した場合、VB が裏でフォーム名と同じ参照変数を 作って、そこにデフォルトインスタンスを格納します。 アンロードしてもう一度 Form 名を直接指定した場合、同じ参照変数 に、新しい画面のインスタンスを生成し、表示します。 このため、正しくアンロードできていない場合や、パブリック変数に 過去のフォームの参照が残っていた場合、実際に命令している画面 と表示している画面が違っていたという事がよくあります。 Form に命令する直前に命令する対象のフォームへ Show 命令を 出してみて下さい。別のフォームが表示される場合は、命令の 対象が別になってしまっているという事です。
その他の回答 (2)
- MARU4812
- ベストアンサー率43% (196/452)
メモリ上でのインスタンス(実体)の生成から破棄までの タイミングのイメージがつかめていないと同じ事は起こる でしょう。 モジュールにしたら全て解決する問題ではありませんし。 (例えばWindow右上の×ボタンで閉じると次に開く時に エラーになったり) 'モジュールを使わず、デフォルトインスタンスで統一する手法 '注)明示的にアンロードせずに×ボタンで閉じる '****Form1***** Public ex As String Private Sub Command1_Click() ex = "e" Form2.Show End Sub Private Sub Command2_Click() ex = "" Form2.Show End Sub '******Form2******** Private Sub Form_Load() Label1 = Form1.ex End Sub Private Sub Form_Unload(Cancel As Integer) Debug.Print "Form2_Unloadされました" & Now End Sub Load,Unload の Debug.Print してみるとか。
- Siegrune
- ベストアンサー率35% (316/895)
2順目のときform2のForm_Load()は動いていますか? 注: msgbox("動いた") とかをform2のForm_Load()に加えて確認できます。 書いてある例なら、form2のForm_Load()が2順目に動いていないと思いますが。 >この間2フォームの登録・保存で2のフォームはアンロードする。 というのは、本当にunloadしてますか? hideでも画面から消えますけど。 hideされた状態なら、showしても、Form_load()は動きません。 >2順目になると、パブリック変数を使用して、テキストやラベルに表 >示された、ものはうまくデーターが反映されるが 例もパブリック変数では? というか、うまくデータが反映しているものと反映しないものはどこが違うのですか?
補足
さっそくの回答ありがとうございます。 >書いてある例なら、form2のForm_Load()が2順目に動いていないと思いますが。 form2のForm_Load()のすぐしたで、MsgBox"Form2"をさせて、2順目しましたが、プログラムは 動いています。 > MsgBox "アンロード" UnloadFlg = True DoEvents Unload Me 上記のように Form2でデバッグで確認しましたが、1順目以降常にはしっています。 >例もパブリック変数では? というか、うまくデータが反映しているものと反映しないものはどこが違うのですか? form1で With Form2 .Label3 = Me.pub1 .Label4 = Me.pub20 .Label2 = Me.pub12 .Label10 = Me.pub37 .Label11 = Me.pub29 .Label5 = Me.pub6 .Label6 = Me.pub8 .Label7 = Me.pub9 .Label8 = Me.pub10 .Label9 = Me.pub11 .Label14 = Val(Me.pub18) + Val(Me.pub28) .Text4 = Me.Bpub6 .Show (vbModal) End With と出来る部分はForm2で表示もうまくできその後のエクセルシートにも表示保存ができるが、 If Option11 = True Then opdir = "f" ElseIf Option13 = True Then opdir = "g" ElseIf Option15 = True Then opdir = "e" End If とopdir(パブリック変数宣言してある)はform1では変数に代入されても、Form2で If Form1.opdir = "e" Then moto = "e:\" & "XXX.xls" ElseIf Form1.opdir = "f" Then moto = "f:\" & "XXX.xls" ElseIf Form1.opdie = "g" Then moto = "g:\" & "XXX.xls" End If では、Form1.opdirになにも代入されておらず、素通りになってしまっている。 あともう1つ確認なのですが、あまりいい方法ではないのですが、どうすればいいのか、考え中ですが、 Form2 でアンロードの前で、Form1の変数の初期化をしています。 Form1. Form1.Text12.Text = "" Form1.Text7.Text = "" Set Form1 = Nothing というふうに、ここで、プログラムは走っているのですが、Form1の画面上に データが残っているようにみえています。 もう少しお知恵お貸し願えませんでしょうか?
お礼
その後何とか解決(?)して2度目3度目も続けて入力することができるようになりました。 (結果は全てモジュールを作成してパブリック宣言してしようしてみました) ただ、MARU4812さんの御意見では、パブリック宣言でも、イレギュラーが起きることもあるような・・・・・ いろいろありがとうございました。
補足
MARU4812さん回答ありがとうございます。 今から試してみたいとおもいます。 試す上で何点か質問したいのですが、 > For i = 1 To 3 このときの3はForm2をShowする回数になるのですか? たとえば、100回なら100とかになるのでしょうか? >'最後に操作しているフォームに命令 '※この時点で1つ目と2つ目の Form2 は f では操作できない f.Text1.Text = CStr(i) End Sub ここでのf.Text1.Textは、当然Formに非表示でもokで、TextXX.Text ”XX”は任意の数字でTextBox が必要なのですね 最後にモジュールにパブリック変数を設定して、うまくいっているように見えても、誤作動もしくはイタズラではないですが、今回のような症状が出る可能性があるということですか?