wanna.jp VBAリファレンス
Top > VBA関数リファレンス > VBA Killの使い方

【情シス必見】VBA Killで古いログファイルを自動削除!Permission Deniedエラーも完全攻略

情シス担当者の皆さん、サーバーのストレージ容量逼迫に頭を悩ませていませんか?特に、日々蓄積されるログファイルやバックアップファイルは、あっという間にディスクを圧迫し、重要な業務システムの安定稼働を脅かします。手動での定期削除は手間がかかる上にミスも起こりがち。そんな悩みをVBAでスマートに解決しましょう!本記事では、VBAのKill関数を使って古いログファイルを自動で削除する方法を、情シス目線で徹底解説します。

コピペで動く!古いログファイルを自動削除するVBAコード

まずは、指定したフォルダ内の古いログファイル(例: Log_2023.txt のようなファイルを含むパターン)を自動で検索し、削除する基本的なVBAコードです。お使いの環境に合わせて、strFolderPathstrFileNamePatterndteThreshold を設定してください。

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の強力なエラーハンドリング機能である 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環境の維持に役立ててください。

VBAでの業務効率化、悩み解決します

「このマクロ、もっと速くならないかな?」「エラーが消えない…」
Access/VBA専門のwanna.jpにご相談ください。

無料相談はこちら