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開発者を目指しましょう!
