こんにちは、Access歴30年のなかぜんです。
今回は、ちょっと上級者向けの内容として「モーダルダイアログの動的生成と設計思想」について解説します。
「また固定フォームか…」と感じたあなたへ
Accessでユーザーからの入力を受け取るとき、つい固定レイアウトのフォームで済ませていませんか?
たとえば、条件入力、詳細編集、確認メッセージなど…。実務で柔軟に対応したい場面、たくさんありますよね。
そんなときに便利なのが「モーダルダイアログを動的に生成する技術」です。これを習得すれば、1つの汎用フォームで複数用途に対応でき、メンテも楽になります。
モーダルダイアログとは?
まずは基本から。
モーダルダイアログとは、ユーザーがそのダイアログに応答するまで、他の画面操作をロックするフォームのことです。たとえば「確認してください」「選択してください」といった処理に適しています。
VBAでは以下のようにモーダル表示ができます。
DoCmd.OpenForm "F_条件入力", WindowMode:=acDialog
このように acDialog
を指定するだけで、フォームがモーダル動作になります。
なぜ「動的生成」が必要なのか?
固定のフォームだと「パターンの追加=フォームの追加」になり、メンテナンスが大変です。
しかし、動的に項目を切り替えることで、1つの汎用フォームを使い回すことが可能になります。
ポイントは次のとおりです:
- 開く前にフォームへ「何を表示するか」を指示
- フォーム側はその指示に従ってコントロールの表示・非表示を調整
- 入力された値はグローバル変数やTempVarsなどで取得
実例:3種類の用途に対応する汎用ダイアログ
目的
以下の3パターンの入力に、同じフォームを使います。
- 日付入力(From/To)
- 1つの選択肢(コンボボックス)
- 複数テキスト入力
フォーム側の設計
フォーム名:F_ダイアログ汎用
あらかじめ以下のコントロールを非表示で配置しておきます:
- txtFromDate, txtToDate
- cmb選択肢
- txt入力1, txt入力2, txt入力3
- btnOK, btnCancel
呼び出し元(VBA)
Public Function ShowDateDialog() As Boolean
TempVars("DialogType") = "DateRange"
DoCmd.OpenForm "F_ダイアログ汎用", WindowMode:=acDialog
If TempVars("DialogResult") = "OK" Then
MsgBox "開始日:" & TempVars("FromDate") & vbCrLf & _
"終了日:" & TempVars("ToDate")
ShowDateDialog = True
Else
ShowDateDialog = False
End If
End Function
ここで重要なのは、TempVars
を使ってフォームへ「目的」を渡していることです。
フォーム側:フォームモジュール
Private Sub Form_Load()
Select Case TempVars("DialogType")
Case "DateRange"
Me.txtFromDate.Visible = True
Me.txtToDate.Visible = True
Case "SelectOne"
Me.cmb選択肢.Visible = True
Case "TextMulti"
Me.txt入力1.Visible = True
Me.txt入力2.Visible = True
Me.txt入力3.Visible = True
End Select
End Sub
Private Sub btnOK_Click()
Select Case TempVars("DialogType")
Case "DateRange"
TempVars("FromDate") = Me.txtFromDate
TempVars("ToDate") = Me.txtToDate
Case "SelectOne"
TempVars("選択値") = Me.cmb選択肢
Case "TextMulti"
TempVars("入力1") = Me.txt入力1
TempVars("入力2") = Me.txt入力2
TempVars("入力3") = Me.txt入力3
End Select
TempVars("DialogResult") = "OK"
DoCmd.Close acForm, Me.Name
End Sub
Private Sub btnCancel_Click()
TempVars("DialogResult") = "Cancel"
DoCmd.Close acForm, Me.Name
End Sub
このようにすると、1つのフォームで複数の入力パターンに対応できます。
注意点とよくあるミス
- TempVarsの消し忘れ:不要になったら
TempVars.RemoveAll
を使いましょう。 - コントロール名の混乱:Visible切替の対象が増えると、名称の統一が重要になります。
- ダイアログでレコードソースを持たせない:ダイアログフォームは基本的に非連結にする方がトラブルが少ないです。
応用ポイント:フィールド情報から動的にレイアウト構築
さらに発展させると、「渡された構造データ」に応じて、テキストボックスやラベルをCreateControl
で動的に作ることも可能です。
たとえばJSON文字列やテンポラリテーブルから構造を読み取り、表示項目を決定することで、柔軟なレイアウト対応が実現します。
Dim ctl As Control
Set ctl = CreateControl("F_ダイアログ汎用", acTextBox, , , , 100, 500, 200, 300)
ctl.Name = "txtDynamic"
ctl.Visible = True
実務では、「エラー項目だけ入力」「設定値だけ編集」といった場面に便利です。
まとめ:モーダルフォームを味方にしよう
今回ご紹介した技術で、Accessのフォーム設計に新たな可能性が生まれます。
- モーダルフォームの仕組み
- TempVarsによる値の受け渡し
- 1つのフォームで複数用途に対応する設計
「フォーム=1用途」の固定観念から脱却して、動的なダイアログ設計にぜひチャレンジしてみてください。
次のステップ
次回は、「JSONを使ったダイアログ定義の自動構築」について解説予定です。
お楽しみに!
それでは、また次の記事でお会いしましょう。
