Access VBAの深淵へ:DoCmd.OpenFormで「同期処理」を操り、データ入力を制御する極意
こんにちは。Accessの現場で幾多のシステムを構築してきたアーキテクトです。
Access VBAを触っていると、「フォームを開いて、何かを入力してもらい、その結果を待ってから次の処理を動かしたい」という要求によく出会います。しかし、何も考えずにフォームを開くと、コードは待ってくれず、入力が終わる前に次の命令が実行されてしまい、データ整合性が崩れる……。これが多くの初心者が最初にぶつかる「非同期の壁」です。
今日は、`DoCmd.OpenForm`の`WindowMode`引数を駆使し、「呼び出し元を一時停止させて、入力完了を待つ」という同期的なデータ入力フローを実装する極意を伝授します。ここをマスターすれば、あなたのアプリケーションは「不安定なスクリプト」から「堅牢な業務システム」へと進化します。
—
なぜ「ダイアログ形式」が必要なのか?
通常、VBAでフォームを開くと、コードは即座に次の行へ進みます。しかし、マスターメンテナンスや一時的な入力用ダイアログの場合、「入力が終わるまで後ろの処理を進めてはいけない」という場面があります。
ここで登場するのが、`DoCmd.OpenForm`メソッドの第6引数、`WindowMode`です。
魔法の定数:acDialog
この引数に `acDialog` を指定すると、Accessは「モーダルモード」でフォームを開きます。
- モーダル(Modal)とは?:そのフォームを閉じるまで、他のウィンドウや背後のコード操作を一切受け付けない状態のこと。
まさに、業務アプリケーションにおいて「入力完了まで待機する」ための専用モードです。
—
実践:同期型データ入力のコード設計
では、実際に現場で使えるコードを見てみましょう。呼び出し元(親)の処理が、入力完了を待ってから再開される様子を確認してください。
1. 呼び出し側のコード(親フォーム)
Public Sub OpenEntryForm_Click()
‘ フォームをダイアログモードで開く
‘ 呼び出し元のコードは、この行で一時停止する
DoCmd.OpenForm FormName:=”frm_InputData”, _
WindowMode:=acDialog
‘ — ここから下は、frm_InputDataが閉じられるまで実行されない —
‘ フォームが閉じられた後、正しくデータが更新されたかチェックする
If IsLoaded(“frm_InputData”) = False Then
MsgBox “入力が完了しました。最新のデータを反映します。”, vbInformation
Me.Requery ‘ 親フォームのリストを最新の状態に更新
End If
End Sub
2. 入力完了時のコード(子フォーム)
Private Sub btn_Close_Click()
‘ 入力チェック等のロジック
If IsNull(Me.txt_TargetValue) Then
MsgBox “値を入力してください!”, vbExclamation
Exit Sub
End If
‘ フォームを閉じる(これで呼び出し元のコードが再開される)
DoCmd.Close acForm, Me.Name
End Sub
—
陥りやすい罠と「プロの知恵」
この設計を使う際、初心者がよくハマるポイントが2つあります。
① 「値」をどうやって親に渡すか?
`acDialog`でフォームを閉じると、そのフォームオブジェクト自体が破棄されます。そのため、閉じられた後に「子フォームのテキストボックスの値」を参照しようとすると、エラーが発生します。
- 解決策:データをテーブルに保存し、親フォーム側で `Requery` するのが最も安全です。あるいは、親フォームの変数を `Public` にしておき、子フォームから直接値を書き込む手法も現場ではよく使われます。
② エラーハンドリングの欠如
ユーザーが「×」ボタンでフォームを閉じた場合、入力が完了していない可能性があります。
- プロの知恵:`Form_Unload` イベントを使い、「保存せずに閉じてよいか?」のフラグ管理を行うか、あるいは「保存ボタンを押すまで×ボタンを無効化する」といった制御を組み合わせると、より堅牢になります。
—
最後に:Accessオブジェクトモデルを味方につける
`DoCmd`はAccessの動作を司る強力な道具です。しかし、ただ闇雲に使うのではなく、「このフォームは今、どのようなライフサイクルにあるのか?」を意識してみてください。
- `acWindowNormal`: 通常の開かれ方(非同期)
- `acDialog`: ユーザーの入力を待つ(同期)
このたった一つの引数を使い分けるだけで、アプリケーションの挙動は劇的に整然としたものになります。
「コードを止める」ことは、決して悪いことではありません。むしろ、ユーザーの操作フローをしっかり制御し、データの安全性を守るための「エンジニアの優しさ」です。ぜひ、次回の開発からこの手法を導入してみてくださいね。
ここをクリアしたあなたは、もうAccess VBAの入門者ではありません。次は、より高度なイベント駆動の世界でお会いしましょう。
