【情シス必見】VBA Killで古いログファイルを自動削除!Permission Deniedエラーも完全攻略
情シス担当者の皆さん、サーバーのストレージ容量逼迫に頭を悩ませていませんか?特に、日々蓄積されるログファイルやバックアップファイルは、あっという間にディスクを圧迫し、重要な業務システムの安定稼働を脅かします。手動での定期削除は手間がかかる上にミスも起こりがち。そんな悩みをVBAでスマートに解決しましょう!本記事では、VBAのKill関数を使って古いログファイルを自動で削除する方法を、情シス目線で徹底解説します。
コピペで動く!古いログファイルを自動削除するVBAコード
まずは、指定したフォルダ内の古いログファイル(例: Log_2023.txt のようなファイルを含むパターン)を自動で検索し、削除する基本的なVBAコードです。お使いの環境に合わせて、strFolderPath、strFileNamePattern、dteThreshold を設定してください。
Sub DeleteOldLogFilesVBAKill()
'------------------------------------------------------------
' 関数名: DeleteOldLogFilesVBAKill
' 概要 : 指定されたフォルダ内の古いログファイルを削除します。
' ファイルが他のプロセスで開かれているとエラーになる可能性があります。
' (エラーハンドリングなしのシンプルなバージョン)
'------------------------------------------------------------
Dim strFolderPath As String ' ログファイルが保存されているフォルダパス
Dim strFileNamePattern As String ' 削除対象のファイル名パターン (例: "Log_*.txt")
Dim dteThreshold As Date ' 削除対象とするファイルの最終更新日時の閾値
' ★★★ ここを環境に合わせて変更してください ★★★
strFolderPath = "C:\ServerLogs\" ' 例: "C:\inetpub\logs\LogFiles\" やネットワークパスも可
strFileNamePattern = "Log_*.txt" ' 例: "Log_2023.txt", "Log_20231026.txt" などに一致
dteThreshold = Date - 30 ' 今日の日付から30日前の日付 (30日以上前のファイルを削除)
' ★★★ ここまで ★★★
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim fName As String
Dim lngDeletedCount As Long ' 削除したファイル数カウント用
' FileSystemObjectを生成
Set objFSO = CreateObject("Scripting.FileSystemObject")
' フォルダが存在するかチェック
If Not objFSO.FolderExists(strFolderPath) Then
MsgBox "エラー: 指定されたログフォルダが見つかりません。" & vbCrLf & strFolderPath, vbCritical, "処理中断"
Exit Sub
End If
Set objFolder = objFSO.GetFolder(strFolderPath)
lngDeletedCount = 0
' フォルダ内の全ファイルをループ
For Each objFile In objFolder.Files
fName = objFile.Name
' ファイル名がパターンに一致し、かつ最終更新日時が閾値より古い場合
If LCase(fName) Like LCase(strFileNamePattern) Then
If objFile.DateLastModified < dteThreshold Then
' 削除処理を実行
' 注意: ここではエラーハンドリングを行っていません。
' Permission Denied エラーが発生すると停止します。
Kill objFile.Path
Debug.Print "削除しました: " & objFile.Path & " (最終更新日: " & objFile.DateLastModified & ")"
lngDeletedCount = lngDeletedCount + 1
End If
End If
Next objFile
' オブジェクトを解放
Set objFile = Nothing
Set objFolder = Nothing
Set objFSO = Nothing
MsgBox "古いログファイルの削除処理が完了しました。" & vbCrLf & _
"削除したファイル数: " & lngDeletedCount & "件", vbInformation, "処理完了"
End Sub
【重要】Permission Deniedエラーを回避せよ!実務で役立つ堅牢化テクニック
上記のシンプルなコードは、実務環境では思わぬ落とし穴にはまることがあります。
もし削除しようとしているファイルが、別のプロセス(例えば、ログを書き込んでいるアプリケーション、ネットワーク上の他のユーザー、ウィルス対策ソフトなど)によって開かれている場合、VBAは「実行時エラー'70': Permission Denied(アクセス拒否)」で停止してしまいます。
これは自動化スクリプトとしては致命的です。この問題を回避し、堅牢なシステム運用を実現するためのテクニックをご紹介します。
このエラーを回避する最も実用的な方法は、VBAの強力なエラーハンドリング機能である
On Error Resume Next と、発生したエラーを適切にログに記録する仕組みを組み合わせることです。これにより、特定のファイルの削除に失敗してもスクリプト全体が停止することなく、次のファイル処理へと進むことができます。
Permission Denied回避 & エラーログ出力対応コード
以下のコードは、前述のコードにエラーハンドリングとエラーログ出力機能を追加したものです。これにより、システムがより堅牢になります。
Sub DeleteOldLogFilesVBAKill_Robust()
'------------------------------------------------------------
' 関数名: DeleteOldLogFilesVBAKill_Robust
' 概要 : 指定されたフォルダ内の古いログファイルを削除します。
' Permission Denied (アクセス拒否) エラーを回避し、
' エラーが発生した場合はログファイルに記録します。
'------------------------------------------------------------
Dim strFolderPath As String ' ログファイルが保存されているフォルダパス
Dim strFileNamePattern As String ' 削除対象のファイル名パターン
Dim dteThreshold As Date ' 削除対象とするファイルの最終更新日時の閾値
Dim strErrorLogPath As String ' エラーログの出力先パス
' ★★★ ここを環境に合わせて変更してください ★★★
strFolderPath = "C:\ServerLogs\" ' 例: "C:\inetpub\logs\LogFiles\"
strFileNamePattern = "Log_*.txt" ' 例: "Log_2023.txt", "Log_20231026.txt"
dteThreshold = Date - 30 ' 今日の日付から30日前の日付
strErrorLogPath = "C:\ServerLogs\DeleteError.log" ' エラーを記録するログファイルのパス
' ★★★ ここまで ★★★
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim fName As String
Dim lngDeletedCount As Long
Dim intFileNumber As Integer ' エラーログ書き込み用ファイル番号
' FileSystemObjectを生成
Set objFSO = CreateObject("Scripting.FileSystemObject")
' フォルダが存在するかチェック
If Not objFSO.FolderExists(strFolderPath) Then
MsgBox "エラー: 指定されたログフォルダが見つかりません。" & vbCrLf & strFolderPath, vbCritical, "処理中断"
Exit Sub
End If
Set objFolder = objFSO.GetFolder(strFolderPath)
lngDeletedCount = 0
' フォルダ内の全ファイルをループ
For Each objFile In objFolder.Files
fName = objFile.Name
' ファイル名がパターンに一致し、かつ最終更新日時が閾値より古い場合
If LCase(fName) Like LCase(strFileNamePattern) Then
If objFile.DateLastModified < dteThreshold Then
On Error Resume Next ' ここからエラーが発生しても処理を中断せず次へ進む
Kill objFile.Path ' ファイルを削除
If Err.Number <> 0 Then
' エラーが発生した場合 (例: Permission Denied エラー70)
Debug.Print "エラー: " & objFile.Path & " を削除できませんでした。 " & _
"(コード: " & Err.Number & ", 説明: " & Err.Description & ")"
' エラーログに書き込む
intFileNumber = FreeFile
Open strErrorLogPath For Append As #intFileNumber
Print #intFileNumber, Now & " - ERROR: Failed to delete '" & objFile.Path & "' - " & Err.Description & " (Err No: " & Err.Number & ")"
Close #intFileNumber
Err.Clear ' エラー情報をクリア
Else
' 削除に成功した場合
Debug.Print "削除しました: " & objFile.Path & " (最終更新日: " & objFile.DateLastModified & ")"
lngDeletedCount = lngDeletedCount + 1
End If
On Error GoTo 0 ' エラーハンドリングを通常に戻す
End If
End If
Next objFile
' オブジェクトを解放
Set objFile = Nothing
Set objFolder = Nothing
Set objFSO = Nothing
MsgBox "古いログファイルの削除処理が完了しました。" & vbCrLf & _
"削除したファイル数: " & lngDeletedCount & "件" & vbCrLf & _
"エラーログ: " & strErrorLogPath & " をご確認ください。", vbInformation, "処理完了"
End Sub
まとめ:VBA Killで情シス業務をスマートに、そして堅牢に
VBAのKill関数は、シンプルな機能ながら、情シス業務におけるファイル管理の強力な味方となります。本記事でご紹介したように、古いログファイルを自動で削除することで、サーバー容量の圧迫を防ぎ、手動による管理負荷を大幅に軽減できます。
さらに、On Error Resume Nextによるエラーハンドリングとログ出力の実装は、システムを堅牢にし、予期せぬトラブル発生時にも迅速な対応を可能にします。このVBAスクリプトをWindowsのタスクスケジューラと組み合わせれば、完全に自動化されたログファイル管理システムが完成します。ぜひ、皆さんの現場で活用し、よりスマートで安定したIT環境の維持に役立ててください。