こんにちは!Access VBAの世界へようこそ。チーフアーキテクトの私です。
マクロの記録から一歩抜け出し、「いざ本格的な業務システムを作ろう!」と意気込んだものの、こんな壁にぶつかったことはありませんか?
- 「フォームを開いたはいいが、裏で動いているはずの後続処理が先に走ってしまい、データが空っぽのまま進んでしまう……」
- 「入力画面を開いたまま、元の画面をいじれてしまうせいで、ユーザーが変な操作をしてエラーになる……」
これ、Access開発の現場で初心者が100%通る「同期ズレ」の罠なんです。
今回は、`DoCmd.OpenForm` の秘めたる力、`WindowMode:=acDialog` を徹底解説します。ここをクリアすれば、あなたの作るAccessアプリは一気に「プロのシステム」へと生まれ変わりますよ。さあ、一緒に扉を開きましょう!
—
1. なぜ「同期」が必要なのか?(データのすれ違いを防ぐ)
通常のフォームを開くコードを書いてみてください。
‘ 通常の開き方
DoCmd.OpenForm “frm_Input”
MsgBox “入力処理が終わりました!”
これだと、`DoCmd.OpenForm` でフォームが開いた瞬間に、待ってくれることなく次の `MsgBox` が実行されてしまいます。人間がフォームに文字を入力している最中にもかかわらず、VBAは猛スピードで先に進んでしまうのです。これでは「入力されたデータを使って次の処理をする」という連携ができませんよね。
ここで登場するのが、モーダル(Modal)制御という概念です。
`acDialog` がもたらす「神のタイムストップ」
`DoCmd.OpenForm` の引数に `WindowMode:=acDialog` を指定すると、Accessの神様が降臨したかのように、呼び出し元のVBAの実行がピタッと一時停止します。
1. 入力用フォームが開く
2. 【ここでVBAは完全にフリーズ(待機)状態になる】
3. ユーザーがフォームにデータを入力し、保存して閉じる(あるいはキャンセルする)
4. フォームが閉じられた瞬間、止まっていたVBAが目覚め、後続の処理を再開する
この「入力完了を完全に待ち受ける(同期する)」動きこそが、堅牢なデータ入力設計のキモなのです。
—
2. 実践!ダイアログ形式でのデータ入力設計
では、実際の業務でそのまま使えるコードで見ていきましょう。
今回は、「社員情報入力フォーム(`frm_EmployeeInput`)」をダイアログで呼び出し、入力された結果に応じて処理を分岐させるシナリオです。
ステップ①:呼び出し元のコード(メイン側)
まずは、メニュー画面やボタンから入力フォームを呼び出すプロシージャです。
‘ =================================================================
‘ 担当者コード:メイン画面のボタンなどに紐づけるプロシージャ
‘ =================================================================
Sub OpenEmployeeDialog()
On Error GoTo ErrorHandler
Dim lngEmployeeID As Long
‘ 【重要】ここで WindowMode に acDialog を指定する!
‘ これにより、この行でVBAの処理が一時停止します。
DoCmd.OpenForm FormName:=”frm_EmployeeInput”, _
View:=acNormal, _
WindowMode:=acDialog
‘ —————————————————————-
‘ ★ ここから下は、「frm_EmployeeInput」が閉じられるまで絶対に実行されません!
‘ —————————————————————-
‘ フォームが閉じられた後、入力されたデータがちゃんと存在するかチェック
If CurrentProject.AllForms(“frm_EmployeeInput”).IsLoaded = False Then
MsgBox “社員情報の入力画面が閉じられました。”, vbInformation, “確認”
‘ 必要であれば、入力されたデータを元にした後続処理をここに書く
‘ 例: RefreshDataGrid など
End If
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
End Sub
ステップ②:入力フォーム側の閉じ方(ここがミソ!)
ダイアログとして開いたフォームは、ただ `DoCmd.Close` するだけでは、呼び出し元に「どういう結果で閉じたか(保存したのか、キャンセルしたのか)」をうまく伝えられないことがあります。
プロの現場では、ダイアログフォームを閉じる際、「フォームを非表示(Visible = False)」にしてから、呼び出し元に制御を返すというテクニックを使います。
‘ =================================================================
‘ 入力フォーム側の「保存して閉じる」ボタンのコード
‘ =================================================================
Private Sub cmdSave_Click()
‘ 1. 入力チェック(バリデーション)
If IsNull(Me.txtEmployeeName) Then
MsgBox “氏名を入力してください。”, vbExclamation, “入力エラー”
Me.txtEmployeeName.SetFocus
Exit Sub
End If
‘ 2. データの確定(テーブルへ書き込み)
If Me.Dirty Then
Me.Dirty = False
End If
‘ 3. 【重要テクニック】
‘ フォームを「閉じる」のではなく「非表示」にする。
‘ これにより、フォームが消えても、呼び出し元からコントロールの値を参照し続けられます。
Me.Visible = False
End Sub
‘ =================================================================
‘ 入力フォーム側の「キャンセル」ボタンのコード
‘ =================================================================
Private Sub cmdCancel_Click()
‘ キャンセルされた場合は、入力を破棄して非表示にする
If Me.Dirty Then
Me.Undo
End If
Me.Visible = False
End Sub
そして、フォーム自体が完全にメモリから消えるタイミング(`Form_Close` イベントなど)で、`DoCmd.Close` を実行するように整理します。
—
3. 初心者がハマる!陥りやすい罠とエラー回避の知見
ここで、現場でよくある「やらかしポイント」をシェアしておきます。ここを知っているだけで、デバッグの時間が何時間も浮きますよ。
罠その1:ダイアログを開いている最中に、別のAccessウィンドウを触ろうとしてフリーズと勘違いする
`acDialog` を指定すると、そのフォームが「モーダル(排他制御)」状態になります。つまり、そのフォームを閉じるまで、Access内の他のフォームやメニューを一切操作できなくなります。
「あれ?Accessが固まった!?」と焦るユーザー続出ポイントですので、操作マニュアルや画面設計の段階で「この画面を閉じるまで他は触れません」というデザインにしておく配慮が必要です。
罠その2:閉じられた後にフォームのコントロール値を見ようとしてエラー
先ほどのコード解説で「フォームを非表示(Visible = False)にする」というテクニックを紹介しました。
もし、フォームを完全にアンロード(メモリから完全消去)してしまうと、呼び出し元に戻った瞬間に `Forms!frm_EmployeeInput!txtEmployeeName` のような参照が「オブジェクトが見つかりません」エラー(実行エラー 2450など)を引き起こします。
- 知見: ダイアログフォームの結果を参照したい場合は、「閉じる」直前にフォームを非表示(`Me.Visible = False`)にし、呼び出し元で値を取得し終わってから、最後に `DoCmd.Close acForm, “frm_EmployeeInput”` で完全にメモリから解放してあげましょう。
—
まとめ:ここをクリアすれば、Access VBAの基本はバッチリ!
今回は `DoCmd.OpenForm` の `WindowMode:=acDialog` を用いた、同期的なデータ入力設計について解説しました。
- 通常のOpenForm は「放りっぱなし(非同期)」。
- `acDialog` を使ったOpenForm は「お互いの手を取り合って進む(同期)」。
この違いをマスターするだけで、あなたが作るAccessアプリケーションの品質は、アマチュアレベルから一気にプロのアーキテクトレベルへと飛躍します。
「画面を開く → ユーザーの入力を待つ → 結果を受け取って次に進む」。
この黄金フローをあなたの武器にして、ぜひ次の開発現場で使ってみてください。
それでは、次回の極限の知見でお会いしましょう!バッチリ使いこなしてくださいね!
