Access上級者向け:モーダルダイアログの動的生成と設計思想

Access

こんにちは、Access歴30年のなかぜんです。
今回は、ちょっと上級者向けの内容として「モーダルダイアログの動的生成と設計思想」について解説します。

「また固定フォームか…」と感じたあなたへ

Accessでユーザーからの入力を受け取るとき、つい固定レイアウトのフォームで済ませていませんか?

たとえば、条件入力、詳細編集、確認メッセージなど…。実務で柔軟に対応したい場面、たくさんありますよね。

そんなときに便利なのが「モーダルダイアログを動的に生成する技術」です。これを習得すれば、1つの汎用フォームで複数用途に対応でき、メンテも楽になります。

モーダルダイアログとは?

まずは基本から。

モーダルダイアログとは、ユーザーがそのダイアログに応答するまで、他の画面操作をロックするフォームのことです。たとえば「確認してください」「選択してください」といった処理に適しています。

VBAでは以下のようにモーダル表示ができます。

DoCmd.OpenForm "F_条件入力", WindowMode:=acDialog

このように acDialog を指定するだけで、フォームがモーダル動作になります。

なぜ「動的生成」が必要なのか?

固定のフォームだと「パターンの追加=フォームの追加」になり、メンテナンスが大変です。

しかし、動的に項目を切り替えることで、1つの汎用フォームを使い回すことが可能になります。

ポイントは次のとおりです:

  • 開く前にフォームへ「何を表示するか」を指示
  • フォーム側はその指示に従ってコントロールの表示・非表示を調整
  • 入力された値はグローバル変数やTempVarsなどで取得

実例:3種類の用途に対応する汎用ダイアログ

目的

以下の3パターンの入力に、同じフォームを使います。

  1. 日付入力(From/To)
  2. 1つの選択肢(コンボボックス)
  3. 複数テキスト入力

フォーム側の設計

フォーム名: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を使ったダイアログ定義の自動構築」について解説予定です。

お楽しみに!

それでは、また次の記事でお会いしましょう。

\楽天ポイント4倍セール!/
楽天市場
\商品券4%還元!/
Yahooショッピング