差分表示


VisualBasic 5における,フォームの扱い方についてのメモ
//parent=VisualBasic
&include_htmlfile(comp/vbmemo1,http://kamoland.com/comp/);
*Visual Basicのメモ 〜Formの扱いかた〜

**1.Formを表示する方法
 VBにおいて,Formほど基本的かつ難解なものはないと思います.
生成したFormを解放し忘れたため,プログラムを終了したつもりでもそれが残っていて,
結局タスクマネージャで終了させるはめになるのは,よくあることです.

Formを表示するには,大きく分けて3つの方法があります

***A.暗黙の生成による方法
 よく使われる方法です.frmMainという名前のFormがプロジェクトにあるとき,
--(
frmMain.Show
--)

として表示します.破棄するには,
--(
Unload frmMain
--)

とします.
簡単なのですが,frmMainを複数表示させようとすると,扱いが難しくなります.
そのため,frmMainを1枚だけしか表示しない場合に用います.
----


***B.明示的に生成する方法 #1(コンパイル時確定)
--(
Dim frmInst As frmMain

Set frmInst = New frmMain
frmInst.Show
--)

同様に,破棄するには,
--(
Unload frmInst
Set frmInst = Nothing
--)

とします.
少し手数が増えます.しかし,frmMainを複数表示してそれぞれを管理するには,
この方法をとります.
----


***C.明示的に生成する方法 #2(実行時確定)

--(
Dim frmInst As Form

Set frmInst = Forms.Add("frmMain")
Load frmInst
frmInst.Show
--)

破棄するには,

--(
Unload frmInst
Set frmInst = Nothing
--)

とします.
生成するForm名が,実行時に確定する場合に使用します.かなり特殊な用法です.

----


**2.Form間でデータを受け渡しする方法
 前回,Formを表示する方法を説明しましたが,Formを表示する際に,
何か変数の値をそのFormに渡してやりたいことがよくあります.
例えば,典型的なのは

+マスタ一覧Form
+マスタ詳細Form

の2枚のFormがあり,1.で特定のレコードが選択されると,
2.でそのレコード内容を表示して編集させるという構成でみられます.
この場合,2.のFormを表示する直前に,選択されているレコードの情報(行番号,
主キー値など)を 1.の Formから2.のFormに渡す必要があります.

この方法について,

-frmFirst - 呼び出し元
-frmSecond - 呼び出し先

として説明します.
----

***A.Global変数を使う方法 (×)
 例えば,BASモジュールで
--(
Global lngSelectedRow As Long
--)

とでも記述しておいて,frmFirstではこれに値を代入してからfrmSecondをShowするという方法です.
frmFirst内からでも,frmSecond内からでも,この変数にアクセスできるということを利用しており,
記述は非常に簡単です.
しかしこの方法を使ってしまうと,後でバグ対応をする人が泣きをみるので,使うべきではありません.

Global変数は,そのプロジェクト内のどこからでも操作でき,値の変化を追跡するのが困難なので,
例えばシステム起動時に特定の場所で値がセットされて,それが終了まで変化しないという場合以外には,
使用してはいけません.
----


***B.frmSecondのPublic変数を使う方法
 frmSecondのコードを以下のように記述します.
--(
Public lngParam As Long

Private Sub Form_Load()
    MsgBox Me.lngParam  'frmFirstから受け取ったlngParamを表示
    Me.lngParam = 1  'lngParamの値を変更
End Sub

そして,frmFirstにはコマンドボタンを貼り付けて,以下のように記述します

Private Sub Command1_Click()
    Dim frmT As frmSecond

    Set frmT = New frmSecond   'インスタンス生成
    frmT.lngParam = 2   'lngParamをセット
    Load frmT   'フォームのロード
    frmT.Show 1  'フォームの表示(モーダル)
    MsgBox frmT.lngParam  'lngParamを表示(frmSecondで変更された値になる)
    Set frmT = Nothing  '参照破棄.この時インスタンスが消滅する
End Sub
--)

このコードでは,frmSecondのPublic変数 lngParamを用いて,

-frmFirst から frmSecond への値渡し
-frmSecond から frmFirst への値返し

の両方を行っています.

 FormのPublic変数は,FormのLoad,Unloadの影響を受けないことに注意してください.
このあたり,Formの生成メカニズムの複雑なところですが,
今後説明する機会があると思います

Public変数はGlobal変数と似ていますが,この方法の方が保守しやすいと思い,
私はもっぱらこの方法を使っています.
----


***C.frmSecondのイベントを使う方法
 これは,frmSecondがモードレス表示の時に,
frmSecondからfrmFirstに任意のタイミングで値を転送するという場合に使用する方法です.
複数のFormを連携動作させるようなシステムではこういう仕掛けが必要です.

実際に以下のコードを実行してみれば,すぐに動作はわかると思いますが,
frmSecondでコマンドボタンをクリックすると,frmFirstでMsgboxが表示されます.

&ltitle(frmFirstのコード);
--(
Private WithEvents mfrmT As frmSecond

Private Sub Form_Load()
    Set mfrmT = New frmSecond
    mfrmT.lngParam = 2
    Load mfrmT
    mfrmT.Show
End Sub

Private Sub Form_Unload(Cancel As Integer)
    On Error Resume Next 'Unload失敗をトラップするため

    Unload mfrmT
    Set mfrmT = Nothing
End Sub

Private Sub mfrmT_evtClick(ByVal lngParam As Long)
    MsgBox lngParam
End Sub
--)

&ltitle(frmSecondのコード - コマンドボタンを貼ってください);
--(
Public lngParam As Long
Public Event evtClick(ByVal lngParam As Long)

Private Sub Command1_Click()
    Me.lngParam = Me.lngParam - 1
    RaiseEvent evtClick(Me.lngParam)
End Sub
--)


© 2020 KMIソフトウェア