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

スポンサーリンク

こんにちは!Accessでのフォーム開発、日夜お疲れ様です。

「画面に入力してボタンを押したはずなのに、データが保存されていなかった……」
「VBAで別の処理に移行した瞬間、意図しないタイミングでエラーが出た……」

Accessのフォームを作っていて、こんな不可解な現象に頭を悩ませたことはありませんか?
実はこれ、Accessが持つ「入力データがいつ確定するのか(バッファの仕組み)」という本質を理解していないと、必ずハマる罠なんです。

今回は、プログラミング初学者の方や「マクロの記録」から一歩抜け出して本格的なシステムを作りたい方に向けて、Access VBAの命とも言える「レコードの強制保存(`DoCmd.RunCommand acCmdSaveRecord`)」を徹底解説します。

ここをクリアすれば、あなたの作るAccessアプリの信頼性は劇的に跳ね上がりますよ。一緒にマスターしていきましょう!

1. なぜ「保存」でつまずくのか?(Accessの裏側を知る)

私たちがフォームのテキストボックスに文字を入力したとき、データは即座にデータベース(テーブル)に書き込まれているわけではありません。

実は、入力中のデータは「フォームという一時的な作業台(バッファ)」の上にフワフワと浮いている状態です。この状態のまま別の処理(例えば、印刷ボタンを押す、別のフォームを開く、VBAで集計処理をするなど)を実行しようとすると、Accessはパニックを起こします。

「まだ確定していないデータ」が引き起こす悲劇

  • 入力したはずなのに、VBAの処理が古いデータのままスルーしてしまう。
  • 必須入力のチェック(バリデーション)がすり抜けて、空っぽのデータが保存されてしまう。

これを防ぐためには、VBA側から「今すぐその作業台の上のデータを、テーブルにガッチリ書き込みなさい!」と命令してあげる必要があります。その最強の呪文が、今回紹介する `DoCmd.RunCommand acCmdSaveRecord` です。

2. 解決の切り札:`DoCmd.RunCommand acCmdSaveRecord` とは?

このコードは、一言でいうと「現在フォーカスがある(=ユーザーが編集している)レコードの変更を、強制的にディスク(テーブル)に保存する」命令です。

画面上の「保存」ボタンを、プログラムが代わりにビシッと押してくれるイメージですね。

基本的な使い方(実戦コード例)

例えば、「登録完了」ボタンがクリックされたときに、必ず入力内容を保存し、その直後に独自のチェックを行いたい場合のコードを見てみましょう。

Private Sub btnSave_Click()
On Error GoTo ErrorHandler

‘ 【最重要】VBA側から強制的にレコードの保存を実行する
‘ これにより、入力された値が確定し、テーブルへの書き込みプロセスが走ります。
If Me.Dirty Then ‘ フォームが編集中(汚染されている)の場合のみ
DoCmd.RunCommand acCmdSaveRecord
End If

‘ — ここから独自のバリデーション(入力チェック) —

‘ 顧客名が空っぽだったら怒る
If IsNull(Me.txtCustomerName) Or Me.txtCustomerName = “” Then
MsgBox “顧客名が入力されていません!”, vbExclamation, “入力エラー”
Me.txtCustomerName.SetFocus ‘ 該当箇所へカーソルを戻す
Exit Sub
End If

MsgBox “データの保存とチェックが正常に完了しました!”, vbInformation, “成功”

Exit Sub

ErrorHandler:
‘ 予期せぬエラーで保存できなかった場合
MsgBox “保存中にエラーが発生しました: ” & Err.Description, vbCritical, “システムエラー”
End Sub

コードのここがポイント!

1. `Me.Dirty` の判定
フォームに変更が加わっていない状態で保存命令を出すと、エラーになることがあります。`Me.Dirty = True`(変更あり)の時だけ保存を実行するのが、プロのテクニックです。
2. 保存のタイミングを完全にコントロール
この `DoCmd.RunCommand acCmdSaveRecord` が実行された瞬間、Accessの標準機能である「更新前処理(BeforeUpdate)」イベントが裏側で発動します。ここでテーブルの入力規則や重複チェックに引っかかれば、自動的に保存がキャンセルされ、エラーをトラップできるようになります。

3. 陥りやすい罠とエラー回避の知恵

この強力な `acCmdSaveRecord` ですが、実務の現場では初心者が陥りがちな「あるあるエラー」が存在します。ここを知っておくだけで、開発スピードが3倍変わります。

罠①:「フォーカスがない」怒られエラー

  • エラー内容: 「実行時エラー 2046: 現在、このコマンドは実行できません。」
  • 原因: レコードが存在しない状態(新規追加でまだ何も入力していない状態など)や、テキストボックス以外にフォーカスがある状態で無理やり保存命令を出してしまいました。
  • 対策: 先ほど紹介したように `If Me.Dirty Then` で囲むか、エラーハンドラ(`On Error GoTo`)を必ず実装してエラーを優しく受け止めてあげましょう。

罠②:バリデーションの二重苦

Accessには、テーブルプロパティでの「入力規則」や、フォームの「BeforeUpdate」イベントなど、チェック機能が多段構えになっています。
`acCmdSaveRecord` を実行すると、これらのチェックが一斉に、かつ強制的に走り出します。
「どのエラーメッセージが、どのタイミングでユーザーに表示されるか」を事前にテストし、エラーメッセージが重複してポップアップしないよう、設計を整理しておきましょう。

まとめ:ここをクリアすれば、あなたもAccess中級者!

今回は、Access VBAにおけるデータの生命線である「レコードの強制保存」について解説しました。

  • Accessのデータは、そのままでは作業台(バッファ)の上に浮いている。
  • 確実に保存・チェックしたいときは `DoCmd.RunCommand acCmdSaveRecord` を使って地面に足を着けさせる。
  • `Me.Dirty` と組み合わせて、スマートにエラーを防ぐ。

この概念を理解できれば、単なる「マクロの貼り付け」から卒業し、ユーザーの入力ミスを完全にガードできる堅牢な業務システムが作れるようになります。

「動くだけのコード」から「意図通りにコントロールできるコード」へ。
今回のテクニックをあなたのAccessアプリに組み込んで、ワンランク上のエンジニアを目指しましょう!応援しています!

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