PR

エラー処理とログ記録を実践的に実装する方法 ~保守性の高いデータベースを作るための必須テクニック~

VBA

Microsoft Accessで業務システムを運用する場合、最も重要なのは「エラーが発生しないこと」ではなく、「エラーが発生しても原因を把握し、迅速に復旧できること」です。

そのためには、VBAで適切なエラー処理を実装し、ログを記録する仕組みを整えることが欠かせません。本記事では、Access VBAにおける実践的なエラー処理とログ記録の方法を逆引き形式で解説します。日々の保守運用に役立つテクニックを紹介しますので、ぜひ自社システムの品質向上にお役立てください。


Access VBAでエラー処理が重要な理由

Accessで構築された業務システムでは、以下のようなエラーが日常的に発生します。

  • データ入力ミス
  • ネットワーク切断
  • テーブルのロック
  • SQL実行エラー
  • ファイル参照エラー
  • 想定外のNull値

開発時には問題なく動作していても、本番運用ではさまざまな要因によってエラーが発生します。

エラーが発生した際に、

  • 原因が分からない
  • どこで止まったか分からない
  • ユーザーから連絡が来ても再現できない

という状況になると、調査に多くの時間を費やすことになります。

そのため、開発段階からエラー処理とログ出力を組み込むことが重要です。


VBAの基本的なエラー処理

スポンサーリンク

エラー発生時に処理を移動する

最も基本的なエラー処理です。

Private Sub Command1_Click()

    On Error GoTo Err_Handler

    MsgBox 1 / 0

Exit_Handler:

    Exit Sub

Err_Handler:

    MsgBox Err.Number & " : " & Err.Description

    Resume Exit_Handler

End Sub

ポイント

  • On Error GoToでエラー処理へ移動
  • Err.Numberでエラー番号取得
  • Err.Descriptionで内容取得
  • Exit_Handlerを作る

この形はAccess VBAの定番です。


よく使うエラー情報を取得する

エラー番号を取得する

Debug.Print Err.Number

番号内容
13型が一致しません
53ファイルが見つかりません
91オブジェクト変数未設定
3022重複データ

エラー内容を取得する

Debug.Print Err.Description

表示例

ファイルが見つかりません


発生したプロシージャ名を記録する

定数を使用すると分かりやすくなります。

Const PROC_NAME As String = “更新処理”

エラー発生時

MsgBox PROC_NAME


逆引き① SQL実行エラーを捕捉したい

Accessアプリでは最も多いケースです。

サンプル

On Error GoTo Err_Handler

CurrentDb.Execute _

"UPDATE T_社員 SET 氏名='山田' WHERE ID=1", _

dbFailOnError

Exit Sub

Err_Handler:

    MsgBox Err.Number & vbCrLf & _

           Err.Description

dbFailOnErrorを付ける理由

以下ではエラーが検知されない場合があります。

CurrentDb.Execute strSQL

推奨

CurrentDb.Execute strSQL, dbFailOnError


逆引き② 重複データの登録を防ぎたい

主キーやユニークインデックス違反です。

エラー番号3022を判定

If Err.Number = 3022 Then

    MsgBox "既に登録されています"

Else

    MsgBox Err.Description

End If

利用例

  • 社員番号
  • 顧客コード
  • 管理番号

の重複防止に活用できます。


逆引き③ Nullエラーを防ぎたい

AccessではNullによるエラーが非常に多く発生します。


Nz関数を使う

悪い例

Me.売上 * 1.1

売上がNullの場合

無効なNull値です

改善例

Nz(Me.売上, 0) * 1.1

結果

結果
10001100
Null0

実務では必須テクニックです。


逆引き④ ファイル存在チェックをしたい

Excel出力やCSV処理で利用します。

If Dir(strFile) = "" Then

    MsgBox "ファイルが存在しません"

    Exit Sub

End If

If Dir(“C:\test.xlsx”) = “” Then


逆引き⑤ フォームが開いているか確認したい

よくある実行時エラーを回避できます。

If CurrentProject.AllForms("F_顧客").IsLoaded Then

    Forms!F_顧客.Requery

End If

ログ記録機能を作成する

ここからが本題です。

エラー内容をテーブルへ記録する仕組みを作ります。


ログテーブル作成

T_エラーログ

項目名
IDオートナンバー
発生日日時
エラー番号数値
エラー内容長いテキスト
プロシージャ名短いテキスト
ユーザー名短いテキスト

ログ書込み用関数を作成

Public Sub WriteErrorLog( _

    ByVal ProcName As String)

    Dim strSQL As String

    strSQL = ""

    strSQL = strSQL & _

    "INSERT INTO T_エラーログ("

    strSQL = strSQL & _

    "発生日,"

    strSQL = strSQL & _

    "エラー番号,"

    strSQL = strSQL & _

    "エラー内容,"

    strSQL = strSQL & _

    "プロシージャ名,"

    strSQL = strSQL & _

    "ユーザー名)"

    strSQL = strSQL & _

    "VALUES("

    strSQL = strSQL & _

    "#" & Format(Now(), _

    "yyyy/mm/dd hh:nn:ss") & "#,"

    strSQL = strSQL & _

    Err.Number & ",'"

    strSQL = strSQL & _

    Replace(Err.Description, "'", "''") & "','"

    strSQL = strSQL & _

    ProcName & "','"

    strSQL = strSQL & _

    Environ("USERNAME") & "')"

    CurrentDb.Execute _

    strSQL, _

    dbFailOnError

End Sub

実際に呼び出す方法

Private Sub cmdUpdate_Click()

Const PROC_NAME As String = _

"cmdUpdate_Click"

On Error GoTo Err_Handler

CurrentDb.Execute _

"UPDATE T_社員 SET 有効=1"

Exit_Handler:

    Exit Sub

Err_Handler:

    Call WriteErrorLog(PROC_NAME)

    MsgBox _

    "エラーが発生しました。" & _

    vbCrLf & _

    "管理者へ連絡してください。"

    Resume Exit_Handler

End Sub

ログ記録のメリット

トラブル調査が容易になる

ユーザーから

エラーが出ました

と言われても原因は分かりません。

ログがあれば

  • 発生日時
  • エラー内容
  • 発生箇所

を確認できます。


利用状況が見える

頻繁に発生するエラーが分かります。

  • 入力ミスが多い
  • ネットワーク切断が多い
  • 特定機能だけ問題が発生

改善ポイントの発見につながります。


保守コスト削減

属人的な調査を減らせます。

担当者が変わっても

  • ログ参照
  • 原因調査
  • 修正

の流れが明確になります。


実践でおすすめの標準テンプレート

筆者がAccess開発でよく使用する構成です。

Private Sub Sample()

Const PROC_NAME As String = _

"Sample"

On Error GoTo Err_Handler

'==================

'メイン処理

'==================

MsgBox "処理開始"

Exit_Handler:

    Exit Sub

Err_Handler:

    Call WriteErrorLog(PROC_NAME)

    MsgBox _

    "エラーが発生しました。" & _

    vbCrLf & _

    Err.Number

    Resume Exit_Handler

End Sub

このテンプレートを標準化するだけでも保守性が大きく向上します。


Access運用で押さえておきたいポイント

MsgBoxだけで終わらない

悪い例

MsgBox Err.Description

これでは履歴が残りません。

必ずログを残しましょう。


エラーを無視しない

以下は極力避けるべきです。

On Error Resume Next

便利ですが原因不明の不具合が発生しやすくなります。

使用する場合は必要最小限にしましょう。


エラーを利用者へそのまま表示しない

悪い例

MsgBox Err.Description

利用者には意味が分からないことがほとんどです。

推奨

MsgBox _

“処理中にエラーが発生しました。”

詳細はログへ保存します。


まとめ

Access VBAの開発では、機能実装ばかりに目が向きがちですが、本当に重要なのは運用開始後の保守性です。

今回紹介した内容を整理すると、

  • On Error GoToでエラー処理を実装する
  • Err.NumberとErr.Descriptionを取得する
  • dbFailOnErrorを活用する
  • Null対策にNz関数を利用する
  • エラーログテーブルを作成する
  • 発生日時・内容・ユーザーを記録する
  • 利用者向けメッセージと管理者向けログを分ける

これらを徹底することで、障害発生時の調査時間を大幅に短縮できるようになります。

Accessは今でも多くの企業で業務システムとして利用されています。だからこそ、「動くシステム」だけでなく、「保守しやすいシステム」を目指すことが重要です。ぜひ今回のエラー処理テンプレートを自社のAccess開発へ取り入れてみてください。

コメント

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