【Access VBA】DoCmd.RunSQLはもう古い?「警告なし」でスマートにクエリを実行する極意
こんにちは。Accessの迷宮へようこそ。
もしあなたが今、「マクロの記録」や「DoCmd.RunSQL」という言葉に頼り切っているなら、今日でその卒業証書を授与しましょう。
Access VBAを操る上で、「クエリ実行時のあの警告ダイアログ」に振り回されるのは、もう終わりです。なぜなら、真のプロフェッショナルは`DoCmd.SetWarnings`という「諸刃の剣」を使わないからです。
今回は、現場で愛用される「CurrentDb.Execute」という強力な武器の使い方を、その本質から解説します。
—
1. なぜ「DoCmd.SetWarnings False」は使うべきではないのか?
初心者の多くは、アクションクエリを実行する際、以下のようなコードを書きます。
‘ 【非推奨】よくある「諸刃の剣」スタイル
DoCmd.SetWarnings False
DoCmd.RunSQL “DELETE FROM T_売上明細 WHERE 処理済み = True”
DoCmd.SetWarnings True ‘ 戻し忘れるとAccess全体が警告を無視し続ける事故に!
これには2つの大きな欠点があります。
1. エラーハンドリングの脆弱性: 途中でエラーが発生し、プログラムが止まると、`SetWarnings True`が実行されず、Accessの警告機能が死んだままになります。
2. パフォーマンスと重さ: `DoCmd`系はAccessのUI層(マクロエンジン)を介するため、オブジェクトの生成・破棄に無駄なオーバーヘッドが生じます。
2. 伝説のメソッド:CurrentDb.Execute の真価
「CurrentDb.Execute」は、AccessのUIをバイパスして、データベースエンジン(DAO)に直接命令を下すための手法です。UIへの影響がないため、そもそも「警告をオフにする」という設定すら不要なのです。
スマートな実装例
Public Sub DeleteProcessedData()
Dim db As DAO.Database
Set db = CurrentDb
‘ dbFailOnError を付けるのがプロの作法
‘ エラーが起きたら即座にロールバック(取り消し)してくれる保険です
On Error GoTo ErrHandler
db.Execute “DELETE FROM T_売上明細 WHERE 処理済み = True”, dbFailOnError
MsgBox “削除が完了しました。”
Exit Sub
ErrHandler:
MsgBox “エラーが発生しました: ” & Err.Description
End Sub
なぜこれが「最強」なのか?
- 警告が出ない: UIを介さないため、最初から「警告」という概念が存在しません。
- dbFailOnErrorの恩恵: もし何らかの理由で削除が失敗しても、データベースに中途半端な変更が残ることを防ぎます。
- 高速: 余計なGUIの描画やイベントを飛ばすので、数万件のレコード処理でも体感速度がまるで違います。
—
3. 初学者が陥る「引数の罠」と対策
`CurrentDb.Execute`を使う際、一つだけ注意点があります。それは「文字列の中に変数やコントロールの値を埋め込むとき」です。
よくあるエラーとして、文字列の連結ミスがあります。
‘ 悪い例:変数が文字列として認識されずエラーになる
db.Execute “DELETE FROM T_売上 WHERE ID = ” & Me.txtID & “”
これを防ぐための「鉄則」は以下の通りです。
1. SQL文を一度変数に入れる: デバッグ時に`Debug.Print`でSQLの中身を確認できるようにする。
2. 型を意識する: 数値ならそのまま、文字列なら `'” & strVal & “‘` とシングルクォーテーションで囲む。
現場で使える「デバッグ・テンプレート」
Dim strSQL As String
strSQL = “DELETE FROM T_売上 WHERE 担当者 = ‘” & Me.txt担当者名 & “‘”
‘ 確認用(イミディエイトウィンドウに出力)
Debug.Print strSQL
db.Execute strSQL, dbFailOnError
—
まとめ:ここをクリアすれば、あなたはもう脱初心者!
今回お伝えした内容は、単なる小手先のテクニックではありません。
- UI(見た目)とデータ(内部処理)を分離して考えること
- エラー発生時に「中途半端な状態」を残さないこと
この2つは、業務システムを構築する上で最も重要な「アーキテクチャの精神」です。
`DoCmd`は便利ですが、Accessの深い部分を操るなら`CurrentDb`(DAOオブジェクト)を使いこなしましょう。ここを突破すれば、あなたのAccess開発スキルは劇的に安定し、保守性が格段に向上します。
ぜひ、今書いているコードの`DoCmd`を、`CurrentDb.Execute`に書き換えてみてください。その瞬間に、あなたのAccessが少しだけ「賢く」なっていることに気づくはずです。
応援していますよ。困ったことがあれば、またいつでも聞きに来てくださいね。
