VBAでログ出力する方法|共有Excelでのトラブル防止に必須

Excel
この記事は約8分で読めます。

ログは、プログラムがエラーになったときの原因を調べるときに役立ちます。

VBAもエラーメッセージを表示しますが、もし自分以外が使用しているときにエラーが起きた場合に、「どんなメッセージだったか」、「どの処理で起きたか?」をこちらが知ることができません。

作っていない側からしたら、こんなエラーでたらびっくりして閉じてしまうかもしれません。(エラーの例↓)

そんな時に、エラーの前後でどんな処理を実行していたか、どこでエラーになったかなど、ログ出力処理を仕込んでおくことで、エラーの修正作業を時短することができます。

ログを出力する具体的な方法

ログ出力はエラー処理と組み合わせると便利ですが、まずはログを出力させるだけのやり方をお伝えします。

ログの出力は、専用ファイルを作成し、そこにメッセージを追記していく方法が一般的です。

作成の流れとしては以下のとおりです。

  • ログ用ファイルとフォルダの格納場所を決める
  • 参照設定を追加する
  • ログ出力処理を作成する
  • ログ出力したい場所で③を呼び出す

1.ログ用ファイルとフォルダの格納場所を決める

まずは、どこにログ出力用ファイルとそのファイルを格納するフォルダを設置するか決めます。

Excelファイルは、Cドライブ直下に作成したログテストフォルダに格納しています。

だいたいは、実行するVBAのExcelファイルと同じ階層にログ用フォルダを設置し、その中にログファイルを置きます。

C:\ログテスト\ログフォルダ\test.log

こんな感じの階層にします。ただし、この時点ではログフォルダとtest.logファイルは作成しなくて大丈夫です。

2.参照設定を追加する

別ファイルへの書き込みには、FileSystemObject オブジェクトを使用します。

FileSystemObject オブジェクト
VBA 言語リファレンス

VBAのエディターを開き、[ツール]→[参照設定]をクリックします。
ライブラリファイル一覧の中から、Microsoft Scripting Runtimeにチェックを入れて、OKをクリックします。

3.ログ出力処理を作成する

ログをファイルに書き込む処理を作成していきます。

色々な場所でこのログ書き込み処理を使用するため、標準モジュールにSubプロシージャを作成しその中に処理を書いていきます。

'ログファイルに書き込む処理
Public Sub WriteLog(msg As String)

  'Scripting.FileSystemObjectの定義
  Dim FSO As New Scripting.FileSystemObject


  'ログファイルがなければ作成
  If FSO.FileExists("C:\ログテスト\ログフォルダ\test.log") = False Then

      If FSO.FolderExists("C:\ログテスト\ログフォルダ") = False Then FSO.CreateFolder "C:\ログテスト\ログフォルダ"

      FSO.CreateTextFile "C:\ログテスト\ログフォルダ\test.log"

  End If

  '追記【ForAppending】を指定
  Dim Log As Object
  Set Log = FSO.OpenTextFile("C:\ログテスト\ログフォルダ\test.log", ForAppending)

  '「日時(空白)メッセージ」を書き込み
  Log.WriteLine Now & vbTab & msg


  '開放
  Set Log = Nothing
  Set FSO = Nothing

End Sub

以下の部分が最初にログ用ファイルやフォルダを作成しなかった理由です。

'ログファイルがなければ作成
If FSO.FileExists("C:\ログテスト\ログフォルダ\test.log") = False Then

    If FSO.FolderExists("C:\ログテスト\ログフォルダ") = False Then FSO.CreateFolder "C:\ログテスト\ログフォルダ"

    FSO.CreateTextFile "C:\ログテスト\ログフォルダ\test.log"

End If

もしフォルダやログファイルが消されたら、ログ出力時にエラーになってしまいます。それを防ぐために、ログ出力処理の中に、ログ用フォルダやファイルが存在するか、存在していなかったら作成する処理を記述しておきます。

あとはログファイルを指定してメッセージを書き込む処理を記述するだけ。

'追記【ForAppending】を指定
Dim Log As Object
Set Log = FSO.OpenTextFile("C:\ログテスト\ログフォルダ\test.log", ForAppending)

'「日時(空白)メッセージ」を書き込み
Log.WriteLine Now & vbTab & msg

OpenTextFileメソッドは、開いたファイルの読み取り、書き込み、追加書き込みができます。

OpenTextFile メソッド (Visual Basic for Applications)
VBA 言語リファレンス

ログの書き込み処理では、処理の履歴を出力していくため、【追記=ForAppending(または8)】を指定します。

そのほか、ファイルを読み取り専用として開く場合は【ForReading(または1)】
ファイルを書き込み専用として開く場合には【ForWriting(または2)】を指定します。

ログ出力したい場所で③を呼び出す

ログ書き込みのSubプロシーシャを作成したら、それを呼びだす記述をしていくだけです。

今回はsheet1にボタンを3つ設置し、それを押したときにログが書き込まれるという流れにします。

Sub ボタン1_Click()

  MsgBox ("ボタン1が押されました")

  'ログに書き込み
  WriteLog ("【INFO】ボタン1が押されました。")

End Sub

Sub ボタン2_Click()

  MsgBox ("ボタン2が押されました")

  'ログに書き込み
  WriteLog ("【INFO】ボタン2が押されました。")

End Sub

Sub ボタン3_Click()

  MsgBox ("ボタン3が押されました")

  'ログに書き込み
  WriteLog ("【INFO】ボタン3が押されました。")

End Sub

これで、ログの出力処理の実装は完了です。
テストしてみます。

ボタン1を押すと、メッセージが表示され、ログが書き込まれます。

フォルダを確認すると、ログフォルダが作成されています。

その中にtest.logファイルが作成されています。

中身を見ると、ちゃんとログ出力されていますね。


ログは出力日時も自動で書き込まれるので、いつ、何が処理されたかの履歴をいつでも確認できるので便利です。

補足

ログのメッセージの書き方や、エラー処理との組み合わせについてです。

メッセージの書き方

このログはエラーか?警告か?案内か?を一目で判断するために、インデックスを入れておくといいです。

【INFO】は、おしらせや案内をしたいときに使用。ログインしたよとか、処理が完了したよなどを出力したいときに記述。
【WARN】は、warning=警告したいときに使用。 緊急性はないが注意しておくとこを出力したいときに記述。
【ERROR】エラーにより正常動作しないためすぐに対応が必要な時に記述。

例: 【INFO】ログインが完了しました
   【WARN】このファイルは最新ではありません
   【ERROR】インデックスが有効範囲にありません

エラー処理との組み合わせ

エラー処理を入れれば、エラーが起きたときだけログ出力するよう実装できます。

エラー処理は、エラーが起こる可能性があるコードの直前に、

On Error GoTo FirstErr

と追加します。FirstErrの箇所は自由にラベル名をつけます。エラーとわかるラベル名(Err○○とか、ERROR_○○など)がいいです。

そして、エラーが起きたときは、エラー時に実行するコードの直前に、命名したエラーラベル名を記述するだけです。

FierstError:
ここにエラーの時に実行したい処理

以下は例です。

Sub ボタン1_Click()

  '要素数3のリストを宣言
  Dim list(3) As String

  'エラー処理
  On Error GoTo FirstErr

  '要素10に格納しようとして、わざとエラーを起こす
  list(10) = "これはエラーになるよ"    ←ここでFirstErr:にジャンプ

  MsgBox (list(10))

'エラーになった場合はここにジャンプします
FirstErr:
  MsgBox "内部でエラーが発生しました。OKをクリックし○○までご連絡ください"

  'ログに書き込み
  WriteLog ("【ERROR】ボタン1_Click()内で要素格納時にエラーが発生しました")

End Sub

このエラー時に実行するコード内にログ出力を入れれば、エラーが発生した時にエラーに関するログを出力することができます。

エラー時にはメッセージを出してあげれば、利用しているユーザーも慌てず対処することができます。

こんな感じでエラー時のログ出力が確認できます。

まとめ

VBAでログを出力する方法をお伝えしました。

社内で共有するExcelファイルは、VBAの中にログ出力を仕込んでおくことで、修正作業の効率化につながります。ひと手間かかりますが、簡単に実装できるので、おすすめです。

すでに作成されたVBAにも、簡単にログ出力を組み込むことができるので、開発初期や終盤に関わらず今からでもログ出力処理を実装してみてください。

その他にも、業務効率化についておすすめの記事は次のとおりです。参考にしていただけると嬉しいです。