以前、エラーログ出力の方法を書きましたが、こういうログ処理というのはクラスにまとめてしまうと使い勝手がよくなります。
LogClass
今回、VBEでクラスモジュールを追加し、名前をLogClassとしました。プロパティでログファイルの最大サイズやローテーション世代数を設定出来るようにしています。
'定数
Private Const MAX_FILE_SIZE As Long = 4096 'ログファイルサイズ(KB)
Private Const LOG_FILE_NAME As String = "error" 'ログファイル名
Private Const LOG_FILE_EXT As String = "log" '拡張子名
Private Const LOG_FOLDER As String = "Log" 'フォルダ名
Private Const ROTATE_NUM As Integer = 3 'ログローテーション世代数
'メンバ変数
Private mMaxFileSize As Long '最大ログファイルサイズ(KB)
Private mLogFileName As String 'ログファイル名
Private mLogFileExt As String '拡張子名
Private mLogFolderName As String 'ログフォルダ名
Private mLogRotateNum As Integer 'ログローテーション世代数
'Win32API
Private Declare Sub GetLocalTime Lib "kernel32" (lpSystem As SYSTEMTIME)
'構造体
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
'プロパティ
Public Property Let MaxFileSize(ByVal Value As Long)
mMaxFileSize = Value
End Property
Public Property Let LogFileName(ByVal Value As String)
mLogFileName = Value
End Property
Public Property Let LogFileExt(ByVal Value As String)
mLogFileExt = Value
End Property
Public Property Let LogFolderName(ByVal Value As String)
mLogFolderName = Value
End Property
Public Property Let LogRotateNum(ByVal Value As Integer)
mLogRotateNum = Value
End Property
'クラス初期化処理
Private Sub Class_Initialize()
'デフォルト値を設定
mMaxFileSize = MAX_FILE_SIZE
mLogFileName = LOG_FILE_NAME
mLogFileExt = LOG_FILE_EXT
mLogFolderName = LOG_FOLDER
mLogRotateNum = ROTATE_NUM
End Sub
'エラーログ作成
Public Sub MakeErrorLog(ByRef errObj As ErrObject, _
ByVal procName As String)
Dim errNumber As Long
Dim errDescription As String
Dim messageLog As String
'エラー情報を保管
errNumber = errObj.Number
errDescription = errObj.Description
'エラーを消去
errObj.Clear
messageLog = "【エラー番号】" & errNumber & _
" 【詳細】" & errDescription & _
" 【発生場所】" & procName
'書き込み
Call WriteLog(messageLog)
'メッセージボックス表示
MsgBox errNumber & Space(2) & errDescription, vbCritical, "エラー"
End Sub
'ログ出力
Private Sub WriteLog(ByVal message As String)
On Error GoTo ErrorTrap
Dim ts, fso As FileSystemObject
Dim projectPath As String
Dim logFolder As String
Dim logFile As String
Dim LogFileName As String
Dim sysLocalTime As SYSTEMTIME
'現在時刻を取得
GetLocalTime sysLocalTime
'ログファイル名
LogFileName = "error.log"
'プロジェクトパスを取得
projectPath = CurrentProject.Path
'ログ格納フォルダ
logFolder = projectPath & "\" & mLogFolderName
'FileSystemObjectオブジェクトを作成する
Set fso = CreateObject("Scripting.FileSystemObject")
'ログ格納フォルダの確認(なければ作成)
If fso.FolderExists(logFolder) = False Then
'フォルダを作成する
Call fso.CreateFolder(logFolder)
End If
'ログファイルフルパス名
logFile = logFolder & "\" & LogFileName
'ログローテート
Call LogRotate(logFile)
'ファイルオープン
Set ts = fso.OpenTextFile(logFile, ForAppending, True)
'書き込み
Call ts.WriteLine("[" & sysLocalTime.wYear & "/" & _
Format(sysLocalTime.wMonth, "00") & "/" & _
Format(sysLocalTime.wDay, "00") & " " & _
Format(sysLocalTime.wHour, "00") & ":" & _
Format(sysLocalTime.wMinute, "00") & ":" & _
Format(sysLocalTime.wSecond, "00") & "." & _
Format(sysLocalTime.wMilliseconds, "000") & "] " & message)
'ファイルクローズ
ts.Close
Set ts = Nothing
Set fso = Nothing
Exit Sub
ErrorTrap:
MsgBox Err.Number & Space(2) & Err.Description, vbCritical, "エラー"
End Sub
'ログローテート
Private Sub LogRotate(ByVal fileName As String)
On Error GoTo Err_Trap
Dim fso As FileSystemObject
Dim i As Integer
Dim r As Integer
Dim folderPath As String
Dim srcFile As String
Dim destFile As String
Dim oldestFile As String
Dim checkFile As String
Dim fileSize As Long
'FileSystemObjectオブジェクトを作成する
Set fso = CreateObject("Scripting.FileSystemObject")
'ファイルが存在するかチェック
If fso.FileExists(fileName) = False Then
Exit Sub
End If
'ファイルサイズを取得する
fileSize = fso.GetFile(fileName).Size
'ファイルサイズをチェック
If fileSize < mMaxFileSize * 1024 Then
'最大サイズを超えてなければ処理を抜ける
Exit Sub
End If
'フォルダパスを取得
folderPath = fso.GetParentFolderName(fileName)
'最古ファイルパス
oldestFile = folderPath & "\" & mLogFileName & mLogRotateNum & "." & mLogFileExt
'最古ファイルが存在すれば削除
If fso.FileExists(oldestFile) Then
Call fso.DeleteFile(oldestFile)
r = mLogRotateNum - 1
Else
'ローテーション世代数を調べる
For r = (mLogRotateNum - 1) To 0 Step -1
If r = 0 Then
checkFile = folderPath & "\" & mLogFileName & "." & mLogFileExt
Else
checkFile = folderPath & "\" & mLogFileName & r & "." & mLogFileExt
End If
If fso.FileExists(checkFile) Then
Exit For
End If
Next
End If
'ファイル名をローテーションする
For i = r To 0 Step -1
If i = 0 Then
srcFile = folderPath & "\" & mLogFileName & "." & mLogFileExt
Else
srcFile = folderPath & "\" & mLogFileName & i & "." & mLogFileExt
End If
destFile = folderPath & "\" & mLogFileName & i + 1 & "." & mLogFileExt
If fso.FileExists(srcFile) Then
'ファイル名変更
Call fso.MoveFile(srcFile, destFile)
End If
Next
Exit_Trap:
Set fso = Nothing
Exit Sub
Err_Trap:
MsgBox Err.Number & Space(2) & Err.Description, vbCritical, "エラー"
Resume Exit_Trap
End Sub
使用例
下記にLogClassの使用例を示します。まず、LogClassの変数を宣言したあと、SetステートメントのNewキーワードでLogClassオブジェクトのインスタンスを作成します。
インスタンスを作成したら、各プロパティの値を設定しています。このプロパティを設定しなかった場合は、コンストラクタで設定した初期値が使われます。
Public Sub LogClassTest()
On Error GoTo Err_Trap
Dim log As LogClass
Set log = New LogClass
'ログクラスプロパティ設定
log.MaxFileSize = 4096
log.LogFileName = "error"
log.LogFileExt = "log"
log.LogFolderName = "Log"
log.LogRotateNum = 3
Dim a As Long
a = 30 / 0
MsgBox "a = " & a
Exit Sub
Err_Trap:
Call log.MakeErrorLog(Err, "LogClassTest")
End Sub
スポンサーリンク