VB6で2つのフォームを使ってプログラムについて

このQ&Aのポイント
  • Windows XP VB6(SP?)の環境で2つのフォーム(1と2)を使用してプログラムを作成しています。1からエクセルのデータを呼び込んで表示し、さらにデータを追加し、コマンドボタンを押すと2が表示されます。一部のデータはラベルに表示し、さらにデータを追加できます。1と2のデータをエクセルの帳票に登録・保存します。2のフォームは登録・保存の際にアンロードします。
  • 1順目ではうまくデータが表示されますが、2順目ではパブリック変数を使用して表示されたデータのみが正しく反映されます。フォーム上では表示されていますが、デバッグプリントするとデータが空欄になっているため、登録・保存できません。どうすれば解決するかわかりません。
  • VB6を半年ほど学んでいます。これについてわからないことができれば、教えていただきたいです。
回答を見る
  • ベストアンサー

VB6で2つのFormを使ってプログラムについて

環境:WindowsXp VB6(SP?) 操作:2つのフォーム(1と2)1からエクセルのデータを呼び込み⇒表示⇒さらにデーター追加⇒     コマンドボタンを押して2を表示⇒一部1のデータをラベルに表示してさらにデータ追加⇒     コマンド」ボタンを押して1と2のデータをエクセルの帳票に登録・保存     以上のことを繰り返す。     この間2フォームの登録・保存で2のフォームはアンロードする。 質問:1順目はうまくいくのですが、2順目になると、パブリック変数を使用して、テキストやラベルに表    示された、ものはうまくデーターが反映されるが、それ以外は、フォーム上では表示されていて     もdebug.printすると、データーが空欄になっているため、登録・保存できない。     例:'****Form1***** Public ex As String Form2.Show End Sub '******Form2******** Private Sub Form_Load() Label1 = Form1.ex End Sub このとき、2順目のForm1.exは””でもForm2のLabel1にはデーターが表示されている。             なにがいけないのかが、いろいろネットで調べてもよくわからないので、どなたか教えてくだ      さい。(initilizeとかをせっていすべきなのか?)      ただ、まだVB6をはじめて半年ほどですので、よろしくおねがいいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.2

そもそもクラス(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 命令を 出してみて下さい。別のフォームが表示される場合は、命令の 対象が別になってしまっているという事です。

muuuug
質問者

お礼

その後何とか解決(?)して2度目3度目も続けて入力することができるようになりました。 (結果は全てモジュールを作成してパブリック宣言してしようしてみました) ただ、MARU4812さんの御意見では、パブリック宣言でも、イレギュラーが起きることもあるような・・・・・ いろいろありがとうございました。

muuuug
質問者

補足

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 が必要なのですね 最後にモジュールにパブリック変数を設定して、うまくいっているように見えても、誤作動もしくはイタズラではないですが、今回のような症状が出る可能性があるということですか?

その他の回答 (2)

  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.3

メモリ上でのインスタンス(実体)の生成から破棄までの タイミングのイメージがつかめていないと同じ事は起こる でしょう。 モジュールにしたら全て解決する問題ではありませんし。 (例えば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)
回答No.1

2順目のときform2のForm_Load()は動いていますか? 注: msgbox("動いた") とかをform2のForm_Load()に加えて確認できます。 書いてある例なら、form2のForm_Load()が2順目に動いていないと思いますが。 >この間2フォームの登録・保存で2のフォームはアンロードする。 というのは、本当にunloadしてますか? hideでも画面から消えますけど。 hideされた状態なら、showしても、Form_load()は動きません。 >2順目になると、パブリック変数を使用して、テキストやラベルに表 >示された、ものはうまくデーターが反映されるが 例もパブリック変数では? というか、うまくデータが反映しているものと反映しないものはどこが違うのですか?

muuuug
質問者

補足

さっそくの回答ありがとうございます。 >書いてある例なら、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の画面上に     データが残っているようにみえています。 もう少しお知恵お貸し願えませんでしょうか?

関連するQ&A

  • VB2008 Form間の計算について

    VB勉強中のものです。 次のようにプログラムを作成したいですので よろしくお願いします。 要望: 1 From2のTextbox1 or Textbox2に"2001/05/05"ような書式で日付を入力 2 RadioButton1かRadioButton2の選択して 3 Form1の「DateTimePicker」を利用して、日数の差を計算し、 Form2の label3に結果を表示させる 例: From2のTextbox1 = 2001/01/01 Form1の「DateTimePicker」 = 2002/01/01 RadioButton1を選択したら、 Label3内に " 誕生日から生まれて365日となりました" という結果が出れば、問題がないです。 ------------ Form 1 --------------------- Public Class Form1 Private Sub Label2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label2.Click 'labelをクリックして、form2を開く Dim frmTmp As New Form2 frmTmp.ShowDialog() End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim intdate As Integer intdate = DateDiff(DateInterval.Day, DateTimePicker1.Value, Now) Label1.Text = "誕生日から生まれて" & intdate & "日となりました" End Sub End Class -------------------------------------------- -------------Form 2 ------------------------ Public Class Form2 Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged If RadioButton1.Checked = True Then Label3.Text = "*******わからない部分*******" End If End Sub End Class ----------------------------------------------------- 以上

  • VBで動的に作成したパネルの上にラベルを乗せるには?

    VB6にてプログラムで動的に作成したフレーム(Frame)の上に、動的に作成したラベル(Label)を乗せることが出来ません。 どうすれば、ラベルをフレームの上に乗せることが出来るようになるでしょうか? どなたか分かる方がいらっしゃいましたら、ご教授願います。 なお、フレームとラベルの作成は以下のようなやり方で行っています。 ' Form1 : 表示フォーム Private lbl As New LabelClass ' ラベル作成クラス Private frm As New FrameClass ' フレーム作成クラス Private Sub Form_Load() Call lbl.LabelMake(Form1, "lbl1") With lbl.makelbl .Caption = "テストラベル" .AutoSize = True .Top = 500 .Left = 500 .Visible = True End With Call frm.FrameMake(Form1, "frm1") With frm.makefrm .Caption = "テストフレーム" .Width = 2000 .Height = 2000 .Visible = True End With End Sub ' LabelClass : ラベル作成クラス Public WithEvents makelbl As Label Public Sub LabelMake(form As Object, name As String) Set makelbl = form.Controls.Add("VB.Label", name) End Sub ' FrameClass : フレーム作成クラス Public WithEvents makefrm As Frame Public Sub FrameMake(form As Object, name As String) Set makefrm = form.Controls.Add("VB.Frame", name) End Sub ※nameはオブジェクト名です

  • VB、教えてください。

    VB、教えてください。 5つのラベルが縦に並んでいます。 label0 label1 label2 label3 label4 あらかじめ、 Dim m as integer=0 を宣言し、 どうにかして "label"という文字列とmという数字をくっつけ、 label0 label1… という風にできないでしょうか。 そして label"m".text=10*m というような表示を作りたいのですが。 下記のようなイメージです。分かりにくかったらごめんなさい。 Public Class Form1 Dim m As Integer = 0 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click lblmessage(+("m").Text = 10*m m = m + 1 End Sub End Class

  • VB2005で、動的にコントロールを作成出来ない件

    MDIのフォームで、 子フォーム1にコントロール(ラベルなど)を追加したい場合、 子フォーム2のボタンクリックで追加しようとすると 追加されません。 (子フォーム1のボタンで同一フォームへコントロールを  追加しようとすると追加できました。) どのようにすれば追加できるでしょうか? 子フォーム2の追加ボタン関数のコード Private Sub Add_click()  AddLabel(子フォーム1, "hogehoge") End Sub モジュール(関数群)のコード Private Sub AddLabel(Byval objForm As Form, ByVal strText As String)  Dim ctlAddLabel As New Label()  With ctlAddLabel   .AutoSize = False   .Location = New Point(0, 0)   .Size = New Size(200, 40)   .Name = "Label" & Counter 'Counter は追加の度に1ずつ増えます   .Text = strText  End With  objForm.Controls.Add(ctrlAddLabel) End Sub

  • VB.NET Form1からForm2を開いたり閉じたりする方法

    VB.NET2005でForm1にあるCheckBoxをTrueにするとform2をモードレスフォームとして開き、CheckBoxをFalseにするとform2を閉じる方法がわかりません。また、form2の[×]で閉じた時にはForm1にあるCheckBoxをFalseにする方法がわかりません。 '----------------------------------- Private Sub CheckBox2_CheckedChanged ・・・   Dim f_cnt As Integer   Dim form2 As New Form2()   f_cnt = My.Application.OpenForms.Count   If CheckBox1.Checked = True Then     If f_cnt = 1 Then form1.Show() 'モードレスフォームとして表示する   Else    form2.Close() ←閉じない   End If End Sub '-----------------------------------

  • VB6のform Load

    Private Sub Form_Load() Form1.ScaleMode = 0 Form1.Scale (-10, 10)-(10, -10) Form1.Line (-10, 0)-(10, 0) Form1.Line (0, -10)-(0, 10) End Sub とやって座標画面を作ろうとしましたが Lineが表示されません。 仕方が無いので Private Sub Form_Load() Form1.ScaleMode = 0 Form1.Scale (-10, 10)-(10, -10) End Sub Private Sub Form_Activate() Form1.Line (-10, 0)-(10, 0) Form1.Line (0, -10)-(0, 10) End Sub とやりました。 そういうものだとあきらめるしかないのでしょうか?

  • Form1.vbに書いた定数をModule1.vbでも使うには?

    Form1.vbには Public Class Form1Form Public Const 横幅 As Long = 1200 と書いています。 そして、 Module1.vbに Sub 共通_横幅() Form1Form.Width = 横幅 End Sub と書くと、 「名前 '横幅' は宣言されていません。」 となります。 Form1.vbの Public Class Form1Formの上に 「Public Const 横幅 As Long = 1200」 を移動しても 「名前空間のステートメントが無効です。」 となります。 どうすれば Form1.vbで宣言した定数をModule1.vbで使用することができるのでしょうか? スコープを「Public」にしただけではだめなのでしょうか? Class Form1Form.Width = 横幅 にしてもだめでした。 よろしくお願い致します。

  • Form1からForm2へ変数を送る

    VBの初心者です。 下のようにコードを記述してみました。 ・Form1のdNameをForm2へ送り、ラベルに表示。 ・変数dNameは標準モジュールで定義。 **Form1** dName = delname.Text Form2.Show **Form2** Label.Caption = dName **標準モジュール** Dim dName As String しかし、ラベルにdNameの値が表示されません。 なにか良い解決策を教えてください。 あと、標準モジュールについてわかりやすく教えて下さい。

  • Formオブジェクトについて

    Formオブジェクトに関する質問です。 ある関数にフォームオブジェクトを引数として渡してやりたいのですが、何かよい方法はありますでしょうか? 例) Private Sub cmdTest_Click(Index as Integer) Dim frm as Form If Index = 0 then Load_Test(Form 2) Else Load_Test(Form 3) End if End Sub Private Sub Load_Test(frm as Form) frm.Show frm.Label1.Caption = "TEST” End Sub

  • VB2010の、Formを開く動作に関する質問です

    VB2010のFormについてお聞きしたいことがあります。 例えばForm1とForm2の2つがあるとして、 ・Form1上のボタンをクリック後Form2が表示される ・Form2を表示後Form1は自動で閉じられる。 この様な事をするにはどの様に行えばよろしいでしょうか? 試しに、 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click   Form2.Show()   Me.Close() End Sub と、してみたのですが Form2が表示された直後に1と2両方消えてしまいました。 改善方法を教えていただけると嬉しいです。 よろしくお願いいたします。

専門家に質問してみよう