【入門編】【上級】DoCmd.OpenFormの「WindowMode」を駆使した、ダイアログ形式でのデータ入力設計と制御 – Access VBA解析バイブル

スポンサーリンク

Access VBAを極める:`DoCmd.OpenForm`で実現する「同期型ダイアログ」の極意

こんにちは。現場で泥臭い実装から高尚なアーキテクチャまで叩き込んできたエンジニアです。

Access開発において、多くの人が最初にぶつかる壁が「画面遷移とデータの受け渡し」です。特に、「子画面で入力した値を親画面に戻す」という処理。これ、適当に作るとコードがスパゲッティ化し、メンテナンス不可能な「負の遺産」が爆誕します。

今日は、`DoCmd.OpenForm`の`WindowMode`引数を使いこなし、まるでOSの標準機能のようにスムーズな「ダイアログ制御」を実装する極意を伝授します。ここをマスターすれば、AccessのGUI構築は一気にプロの領域へ足を踏み入れられますよ。

1. なぜ「ダイアログモード」を使うのか?

通常、フォームを開くときには「非同期」的な挙動が基本です。しかし、マスターメンテナンスや一時的な値入力では、「子画面の処理が終わるまで、親画面を操作不能にする(同期させる)」という挙動が不可欠です。

ここで登場するのが `acDialog` です。これを指定すると、VBAのコード実行は一時停止し、子画面が閉じられるか非表示になるまで、呼び出し元のコードは次の行へ進まない「同期モード」になります。

基本の構文

DoCmd.OpenForm FormName:=”frm子画面”, _
WindowMode:=acDialog

この一行だけで、Accessは「この子画面を閉じるまで待機する」という制約を自律的に引き受けます。非常に強力ですが、ここからが本番です。

2. 【核心】呼び出し元へ値を返す「スマートな連携術」

初心者が陥りやすい罠は、「子画面から直接、親画面のコントロールを書き換える」という密結合な設計です。これは絶対に避けてください。

正解は、「子画面は値を保持したまま非表示(Visible = False)になり、親画面がその値を拾い上げる」というフローです。

実装のステップ

1. 子画面: 閉じる直前に自分自身を非表示にする(`Me.Visible = False`)。
2. 親画面: `OpenForm`の次の行で、子画面のコントロールから値を取得する。
3. 親画面: 値を取得し終わったら、子画面を完全に閉じる(`DoCmd.Close`)。

【サンプルコード:子画面側(frmSelector)】

‘ 子画面:決定ボタンのクリックイベント
Private Sub btnOK_Click()
‘ データを閉じるのではなく、非表示にして待機させる
Me.Visible = False
End Sub

【サンプルコード:親画面側(frmMain)】

‘ 親画面:呼び出し処理
Public Sub btnOpenDialog_Click()
‘ ダイアログモードで開く
DoCmd.OpenForm FormName:=”frmSelector”, WindowMode:=acDialog

‘ — ここでコード実行は一旦停止(子画面が閉じられるか非表示になるまで) —

‘ 子画面が非表示になったら、ここから再開
If CurrentProject.AllForms(“frmSelector”).IsLoaded Then
‘ 子画面から値を取得
Me.txtResult = Forms(“frmSelector”).txtInputData

‘ 役目を終えたので閉じる
DoCmd.Close acForm, “frmSelector”
End If
End Sub

3. 陥りやすいエラーと回避策

この設計をするときに必ず直面する「落とし穴」を先回りして潰しておきましょう。

罠1:子画面を「×」ボタンで閉じられた場合

ユーザーが「×」ボタンでキャンセルすると、`Me.Visible = False` を通らずに画面が消滅します。このとき親画面で値を拾いに行くと、「フォームが見つかりません」というエラーになります。

対策: `OnClose`イベントではなく、`OnUnload`で判定するか、親画面で`IsLoaded`を必ずチェックしてください。

罠2:オブジェクトのライフサイクル管理

`DoCmd.OpenForm`で開いたフォームは、`acDialog`であってもメモリ上に残り続けます。上記の通り、最後に必ず `DoCmd.Close` を呼ぶ習慣をつけてください。メモリリークは地味ですが、長期間運用するAccessアプリでは致命傷になります。

まとめ:ここをクリアすれば「プロの設計」です

今回のポイントを整理します。

  • `acDialog`はコードを同期停止させるスイッチ
  • 子画面は`Visible = False`で値を保持したまま待機させる
  • 親画面は「開く→待つ→拾う→閉じる」のサイクルを徹底する

この「値を受け渡すための同期制御」をマスターすれば、Accessの画面設計は自由自在です。マクロの記録から卒業し、こうした「オブジェクトの状態」を意識したコーディングができるようになると、あなたの作るアプリは格段に堅牢で使いやすいものになります。

「ここが少し難しかった」という部分があれば、遠慮なく教えてくださいね。一つずつクリアして、最高のAccess開発者を目指しましょう!

タイトルとURLをコピーしました