こんにちは!Access VBAの世界へようこそ。
マクロの記録ボタンを押すだけの世界から一歩踏み出し、「自分の手でシステムをコントロールしたい」と願うあなたにとって、今日はとても大切な日になります。
現場でバリバリ動くAccessアプリを作っていると、避けて通れないのが「エラーとの戦い」です。
特に、他のデータベースやExcelファイルとリンクしているテーブルが、パスが変わったせいで「あれ?繋がらない!」となったり、処理の途中で「今から使いたい一時テーブルが、まだ作られていない!」なんていうアクシデントは日常茶飯事。
そんな時、エラーメッセージがいきなり画面にポップアップして、ユーザーをビビらせてしまう……そんなカッコ悪いコード、卒業したくありませんか?
今回は、「エラーが起きる前に、そっと存在を確かめてスマートに回避する」ための極意、`Application.CurrentData.AllTables`を使った堅牢なテーブル存在チェック術を伝授します。ここをクリアすれば、あなたの書くコードの「プロっぽさ」がグッと跳ね上がりますよ。一緒にマスターしていきましょう!
—
1. なぜ「いきなりアクセス」すると危険なのか?
プログラミング初心者がやりがちなのが、こんな書き方です。
‘ 【やってはいけない!危険な例】
DoCmd.OpenTable “T_売上集計_一時”
このコード、もし `T_売上集計_一時` というテーブルがたまたま存在していれば何事もなく動きます。しかし、存在しなかった瞬間、Accessは容赦なく実行時エラー(エラー番号:2450や3011など)を発生させ、VBAのコードを強制終了させます。
例えるなら、「鍵が閉まっているか確認せずに、いきなりドアに全速力で体当たりする」ようなものです。痛いですよね?
コードも同じです。ドアを叩く前に「今、鍵は開いているか?」を確認する優しさ(=堅牢性)が必要なのです。
—
2. 救世主登場:`Application.CurrentData.AllTables` とは?
そこで登場するのが、Accessが標準で用意してくれているオブジェクト、`Application.CurrentData.AllTables` です。
これは、あなたのAccessファイル(データベース)の中に存在しているすべてのテーブル(内部テーブルも、外部からのリンクテーブルも全部含みます!)の名前がリストアップされた「名簿(コレクション)」だと思ってください。
この名簿に向かって、
- 「ねえ、`T_売上集計_一時` って名前の生徒(テーブル)、この名簿に載ってる?」
と問いかけることで、エラーを出さずに「いる・いない」を事前に判定できるのです。
—
3. 実践!テーブルの存在を優しくチェックする関数
それでは、実際の現場でそのままコピー&ペーストして使える、スマートな関数を見てみましょう。
標準モジュールにこれを貼り付けておけば、いつでも呼び出して使えます。
‘ =================================指定したテーブルが存在するかを返す関数=================================
‘ 引数 : tableName (String) – チェックしたいテーブル名
‘ 戻り値: Boolean – 存在すれば True、存在しなければ False
‘ =======================================================================================================
Public Function CheckTableExists(ByVal tableName As String) As Boolean
Dim tbl As AccessObject
Dim isExist As Boolean
‘ 初期値は「いない(False)」としておく
isExist = False
p
‘ AllTables名簿の中に、お目当てのテーブル名があるか1つずつ総当たりで確認
For Each tbl In Application.CurrentData.AllTables
If tbl.Name = tableName Then
isExist = True K ‘ いた!
Exit For ‘ 見つかったのでループを抜け出す(効率化の技!)
End If
Next tbl
‘ 結果を返す
CheckTableExists = isExist
End Function
コードのここがポイント!
1. `For Each … In …` による全探索
Access内の全テーブルを順番に見ていき、名前が一致するかどうかを判定しています。
2. `Exit For` の美学
お目当てのテーブルが見つかった瞬間にループを即座に終了させています。無駄に最後まで探し続けない、こういう細かい気配りがプロのコードの証です。
—
4. この関数を実務でどう使うか?(実践コード例)
先ほど作った関数を使って、実際の業務処理を組み立ててみましょう。
例えば、「処理の前に一時テーブルの有無を確認し、もし無ければ新しく作る」という安全なフローです。
Public Sub RunMonthlyProcess()
Dim targetTbl As String
targetTbl = “T_売上集計_一時”
‘ 1. テーブルの存在チェックを呼び出す
If CheckTableExists(targetTbl) = True Then
MsgBox targetTbl & ” は存在します。処理を続行します。”, vbInformation, “確認”
‘ ここに通常の処理を書く(例:古いデータをクリアするなど)
‘ DoCmd.RunSQL “DELETE FROM ” & targetTbl
Else
‘ テーブルがない場合のフォールバック(代体処理や作成処理)
MsgBox targetTbl & ” が見つかりませんでした。新規作成します。”, vbExclamation, “注意”
‘ ここでテーブルを作る処理などを走らせる
‘ DoCmd.RunSQL “CREATE TABLE …”
End If
End Sub
これなら、万が一リンクが切れていたり、テーブルが削除されていても、ユーザーがパニックになるようなシステムエラー(デバッグ画面のポップアップ)を完全に回避できますよね。
—
5. 先輩エンジニアからのワンポイント・アドバイス
今回紹介した `AllTables` ですが、実はAccessオブジェクトモデルには似たような仲間がいくつかいます。
- `AllQueries` (クエリの有無を調べる)
- `AllForms` (フォームが開いているか・存在するか調べる)
- `AllReports` (レポートの有無を調べる)
使い方は今回の `AllTables` と全く同じです。「画面を開く前にフォームが存在するか確認したい」「クエリを実行する前に定義されているか確かめたい」という時にも、このパターンはそのまま応用できます。
まとめ
Access VBAにおけるエラー対策の本質は、「起きるかもしれないトラブルを予測し、コードの側で優しく包み込むこと」です。
- いきなりテーブルを操作してエラーを出すのはアマチュア。
- 事前に `Application.CurrentData.AllTables` で存在を確認してからスマートに分岐させるのがプロ。
ここをクリアしたあなたなら、もうマクロの記録の枠を超えて、実用に耐えうる堅牢なデータベースシステムを構築する基礎力が十分に身についています。
ぜひ、あなたの身の回りのAccessファイルでも試してみてくださいね。応援しています!
