【入門編】DoCmd.RunCommand acCmdSaveRecordの強制実行による入力値の確定とバリデーション – Access VBA解析バイブル

スポンサーリンク

こんにちは! Accessでのシステム開発、お疲れ様です。

「フォームに入力したはずのデータが保存されないまま次の処理に進んでしまい、エラーが出る……」
「入力規則に違反しているのに、なぜかVBAがそのまま突き進んでしまう……」

現場でバリバリとAccessアプリを作っていると、こうした「レコードの保存タイミング」の壁に必ずぶつかりますよね。マクロの記録から一歩抜け出し、自分の手でロジックをコントロールしたいあなたへ。今回は、Access VBAの心臓部とも言える「レコードの強制保存と入力値の確定(`DoCmd.RunCommand acCmdSaveRecord`)」について、プロの視点から徹底的に分かりやすく解説していきます。

ここをクリアすれば、Access VBAのフォーム制御の基本はバッチリですよ! 一緒にマスターしていきましょう。

1. なぜ「レコードの強制保存」が必要なのか?

まずは、Accessが裏側でどうやってデータを保存しているのか、その「お作法」を知る必要があります。

私たちがフォームのテキストボックスに文字を入力している時点では、そのデータはまだ画面上の「仮置き場(バッファ)」にある状態です。Accessが「よし、テーブルに書き込もう」と判断するのは、以下のようなタイミングです。

  • ユーザーが別のレコードに移動したとき
  • ユーザーがレコード移動ボタンを押したとき
  • フォームを閉じようとしたとき

「まだ保存されていない状態」でVBAを走らせる危険性

例えば、「登録完了ボタン」をクリックしたときに、VBAで「入力されたデータが正しいかチェックし、別のテーブルにログを書き込む」という処理を作ったとします。

このとき、「まだ画面上の仮置き場にあるデータ」は、テーブルから見ると「まだ存在しない(または古い)データ」です。そのため、VBAが意図しない古いデータを掴んでしまい、バグやデータの食い違いを引き起こす原因になります。

ここで登場するのが、今回主役の`DoCmd.RunCommand acCmdSaveRecord`です。

2. コードの意味と使い方:確実にデータを「確定」させる

では、実際にコードを見てみましょう。ボタンクリック時などのイベントに、以下のように記述します。

Private Sub 登録ボタン_Click()
On Error GoTo ErrorHandler

‘ 1. 現在のレコードの変更を強制的に保存(ディスク/テーブルへ確定)
If Me.Dirty Then ‘ フォームに未保存の変更があるかチェック
DoCmd.RunCommand acCmdSaveRecord
End If

‘ 2. 保存が成功した前提で、次のバリデーション(入力チェック)や処理へ
MsgBox “レコードが正常に保存され、入力が確定しました!”, vbInformation, “確認”

Exit Sub

ErrorHandler:
‘ ユーザーが入力規則に違反して入力をキャンセルした場合などのエラーをキャッチ
MsgBox “保存中にエラーが発生しました。入力内容を確認してください。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “保存エラー”
End Sub

コードのポイント解説

1. `Me.Dirty` のチェック

  • `Me.Dirty` は、「現在フォーカスがあるレコードに、まだ保存されていない変更があるか?」を `True` / `False` で返すプロパティです。変更がないのに保存コマンドを発行すると無駄な処理が走るため、これを挟むのがプロのスマートな書き方です。

2. `DoCmd.RunCommand acCmdSaveRecord`

  • これが実行された瞬間、Accessは強制的に「レコードの更新前処理(BeforeUpdate)」を走らせ、入力内容をテーブル(または背後のレコードソース)に書き込もうとします。

3. 実務でよくある「罠」と、その回避策

この `acCmdSaveRecord` ですが、強力であるがゆえに、初心者の方がハマりやすい「罠」がいくつかあります。現場で泣きを見ないために、次の2つだけは覚えておいてください。

罠そのもの:入力規則にひっかかると「実行時エラー」になる

もしユーザーが「必須入力のフィールドを空欄のまま」にしていたり、テーブルの入力規則に違反したデータを入力していた場合、`DoCmd.RunCommand acCmdSaveRecord` が実行された瞬間に、Access標準のエラーメッセージがポップアップし、VBAのコードがその場でストップ(デバッグ画面へ突入)してしまいます。

これでは、親切なエラーメッセージを自分でコントロールできません。

対策:エラーハンドリングを必ずセットで書く

先ほどのサンプルコードのように、`On Error GoTo ErrorHandler` を必ず記述してください。
これにより、Access標準の冷たいエラー画面の代わりに、自分たちが意図した分かりやすいメッセージボックスをユーザーに表示させることができます。

‘ エラー番号 2501(キャンセル)などは、アクションが取り消された時のものですが、
‘ 基本的な入力規則違反はエラーハンドラーで捕捉できます。

4. バリデーション(入力値検証)の完璧なフロー

実務で求められる「入力値の確定から保存、そして独自のチェック」を行う理想的なコードの全体像をプレゼントします。そのままコピペして、ご自身のフォームのボタンイベントなどに活用してください。

Private Sub btnSave_Click()
On Error GoTo Err_Process

‘ — Step 1: 独自のマニュアル・バリデーション(VBAによる事前チェック) —
If IsNull(Me.txtCustomerName) Or Trim(Me.txtCustomerName) = “” Then
MsgBox “顧客名は必須入力です。”, vbExclamation, “入力漏れ”
Me.txtCustomerName.SetFocus ‘ 該当箇所へフォーカスを移動
Exit Sub
End If

‘ — Step 2: レコードの強制保存と確定 —
‘ 画面上の入力を確実にデータベース側のバッファに書き込ませます
If Me.Dirty Then
DoCmd.RunCommand acCmdSaveRecord
End If

‘ — Step 3: 保存完了後の処理 —
MsgBox “データを正常に保存しました。”, vbInformation, “完了”

Exit Sub

Err_Process:
‘ — エラーハンドリング —
‘ 入力規則(テーブル設計側)に違反した場合などのフォールバック
MsgBox “データを保存できませんでした。” & vbCrLf & _
“入力内容に誤りがないか確認してください。” & vbCrLf & _
“【詳細】 ” & Err.Description, vbCritical, “保存エラー”
End Sub

5. まとめ

いかがでしたでしょうか? 今回のポイントをギュッと凝縮して振り返ります。

  • 「保存」のタイミングを制する者がAccess VBAを制す。 処理を進める前にデータを確定させたいときは `DoCmd.RunCommand acCmdSaveRecord` を使う。
  • 無駄な実行を防ぐために、`If Me.Dirty Then` で変更があるか確認してから呼ぶのがスマート。
  • 入力規則違反などでエラーが起きるため、必ず `On Error GoTo` とセットで実装する

この基本を押さえるだけで、あなたが作るAccessアプリの「データ堅牢性」はプロのレベルにグッと近づきます。エラーに怯える日々から脱却し、意図通りに動く美しいコードを書いていきましょう。

あなたのAccess開発ライフが、より快適でクリエイティブなものになりますように。チーフアーキテクトより、応援しています!

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