0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【VBA】Excelでファイル名を一括変更するマクロを作ってみた【バリデーション付き】

0
Posted at

目次

  1. はじめに
  2. 完成コード
  3. コードの解説
  4. バリデーションの仕組み
  5. 参照設定について
  6. 実際に動かしてみる
  7. まとめ

はじめに

複数のファイル名を一括で変更したいとき、手作業では時間がかかります。Excelシートにファイルパスと新しい名前を一覧で記載しておき、VBAで一括変換できると便利です。今回は、事前にしっかりバリデーション(データが適切かどうかを確認)を行い、安全にファイル名を変更するマクロを紹介します。

完成コード

まずは完成したコードをご覧ください。A列にファイルのフルパス、B列に変更後のファイル名を入力し、このマクロを実行すると一括でファイル名が変更されます。

Sub RenameFiles()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim i As Long
    Dim oldPath As String
    Dim newName As String
    Dim parentPath As String
    Dim newPath As String
    Dim fso As Scripting.FileSystemObject
    Dim errorCount As Long
    Dim successCount As Long
    Dim validationErrors As String
    Dim emptyRowCount As Long
    
    Set fso = New Scripting.FileSystemObject
    Set ws = ActiveSheet
    
    errorCount = 0
    successCount = 0
    validationErrors = ""
    emptyRowCount = 0
    
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    
    If lastRow < 2 Then
        MsgBox _
         "データが見つかりません。A列にファイルパス、B列に新しい名前を入力してください。", _
         vbExclamation
        Exit Sub
    End If
    
    For i = 2 To lastRow
        oldPath = Trim(ws.Cells(i, 1).Value)
        newName = Trim(ws.Cells(i, 2).Value)
        
        If oldPath = "" Then
            If newName <> "" Then
                validationErrors = validationErrors & "行" & i & _
                    ": A列(ファイルパス)が空です" & vbCrLf
            Else
                emptyRowCount = emptyRowCount + 1
            End If
        ElseIf newName = "" Then
            validationErrors = validationErrors & "行" & i & _
                ": B列(新しい名前)が空です" & vbCrLf
        ElseIf Not (Mid(oldPath, 2, 2) = ":\" Or Left(oldPath, 2) = "\\") Then
            validationErrors = validationErrors & "行" & i & _
                ": A列がフルパスではありません(例: C:\Folder\file.txt)" & vbCrLf
        ElseIf ContainsInvalidChars(newName) Then
            validationErrors = validationErrors & "行" & i & _
                ": B列に使用できない文字が含まれています(\ / : * ? "" < > |)" & _
                vbCrLf
        End If
    Next i
    
    If emptyRowCount = lastRow - 1 Then
        MsgBox _
         "データが入力されていません。A列にファイルパス、B列に新しい名前を入力してください。", _
         vbExclamation
        Exit Sub
    End If
    
    If validationErrors <> "" Then
        MsgBox _
         "以下のエラーを修正してください:" & vbCrLf & validationErrors, _
         vbExclamation, "入力エラー"
        Exit Sub
    End If
    
    If MsgBox( _
            lastRow - 1 & "個のファイル名を変更します。よろしいですか?", _
            vbYesNo + vbQuestion _
        ) = vbNo Then Exit Sub
    End If
    
    For i = 2 To lastRow
        oldPath = Trim(ws.Cells(i, 1).Value)
        newName = Trim(ws.Cells(i, 2).Value)
        
        If oldPath <> "" And newName <> "" Then
            If fso.FileExists(oldPath) Then
                parentPath = fso.GetParentFolderName(oldPath)
                
                If Right(parentPath, 1) = "\" Then
                    newPath = parentPath & newName
                Else
                    newPath = parentPath & "\" & newName
                End If
                
                If fso.FileExists(newPath) Then
                    ws.Cells(i, 3).Value = "エラー: 同名のファイルが既に存在"
                    errorCount = errorCount + 1
                Else
                    On Error Resume Next
                    fso.MoveFile oldPath, newPath
                    
                    If Err.Number = 0 Then
                        ws.Cells(i, 3).Value = "成功"
                        successCount = successCount + 1
                    Else
                        ws.Cells(i, 3).Value = "エラー: " & Err.Description
                        errorCount = errorCount + 1
                        Err.Clear
                    End If
                    On Error GoTo 0
                End If
            Else
                ws.Cells(i, 3).Value = "エラー: ファイルが見つかりません"
                errorCount = errorCount + 1
            End If
        End If
    Next i
    
    MsgBox "処理完了" & vbCrLf & _
           "成功: " & successCount & "個" & vbCrLf & _
           "エラー: " & errorCount & "個" & vbCrLf & vbCrLf & _
           "結果はC列に記載されています。", vbInformation
    
    Set fso = Nothing
    Set ws = Nothing
End Sub

Private Function ContainsInvalidChars(fileName As String) As Boolean
    Dim invalidChars As Variant
    Dim i As Long
    
    invalidChars = Array("\", "/", ":", "*", "?", """", "<", ">", "|")
    
    For i = LBound(invalidChars) To UBound(invalidChars)
        If InStr(fileName, invalidChars(i)) > 0 Then
            ContainsInvalidChars = True
            Exit Function
        End If
    Next i
    
    ContainsInvalidChars = False
End Function

コードの解説

このマクロは大きく3つのフェーズ(段階)に分かれています。それぞれのフェーズを順番に見ていきます。

【フェーズ1】データの取得と初期チェック

最初に、Excelシートからデータの範囲を取得します。lastRow変数で最終行を特定し、2行目以降にデータがあるかを確認しています。

lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

If lastRow < 2 Then
    MsgBox "データが見つかりません。", vbExclamation
    Exit Sub
End If

1行目は見出し行と想定しているため、2行目未満ならデータなしと判断します。End(xlUp)は、ExcelでCtrl + ↑を押したときと同じ動作で、データがある最後の行を見つけてくれます。

【フェーズ2】全行のバリデーション

実際にファイル名を変更する前に、すべての行をチェックして問題がないか確認します。これにより、処理の途中で予期しないエラーが起きるのを防げます。

For i = 2 To lastRow
    oldPath = Trim(ws.Cells(i, 1).Value)
    newName = Trim(ws.Cells(i, 2).Value)
    
    If oldPath = "" Then
        If newName <> "" Then
            validationErrors = validationErrors & "行" & i & _
                                ": A列(ファイルパス)が空です" & vbCrLf
        Else
            emptyRowCount = emptyRowCount + 1
        End If
    ElseIf newName = "" Then
        validationErrors = validationErrors & "行" & i & _
                            ": B列(新しい名前)が空です" & vbCrLf
    End If
Next i

空行(A列もB列も空)は無視し、片方だけ入力されている場合はエラーとして記録します。Trim関数で前後の空白を削除しているので、スペースだけの入力も空欄として扱われます。

【フェーズ3】ファイル名の変更処理

バリデーションを通過したら、実際にファイル名を変更します。FileSystemObjectMoveFileメソッドを使用しており、これは名前変更だけでなく移動にも使えるメソッドです。

fso.MoveFile oldPath, newPath

処理結果はC列に記録されるため、後から確認できます。成功した行とエラーが出た行が一目で分かります。

バリデーションの仕組み

このマクロでは4種類のバリデーションを行っています。それぞれの仕組みを詳しく見ていきます。

【空欄チェック】

A列とB列のどちらかが空の場合、エラーとして記録されます。両方空の場合は単なる空行として扱い、エラーにはなりません。

If oldPath = "" Then
    If newName <> "" Then
        validationErrors = validationErrors & "行" & i & _
                            ": A列が空です" & vbCrLf
    Else
        emptyRowCount = emptyRowCount + 1
    End If

この処理により、「B列だけ入力してA列を忘れた」といったミスを防げます。emptyRowCountで空行の数を数えておき、全行が空行だった場合は専用のメッセージを表示します。

【フルパスチェック】

相対パス(例: Folder\file.txt)ではなく、絶対パス(例: C:\Folder\file.txt)が入力されているかをチェックします。

ElseIf Not (Mid(oldPath, 2, 2) = ":\" Or Left(oldPath, 2) = "\\") Then
    validationErrors = validationErrors & "行" & i & _
                            ": フルパスではありません" & vbCrLf

C:\のような形式か、\\server\のようなUNCパス(ネットワークパス)であるかを判定しています。Mid(oldPath, 2, 2)で2文字目から2文字分、つまり:\の部分を取り出して確認しています。

【無効な文字チェック】

Windowsのファイル名には使用できない文字があります。これらが含まれていないか、専用の関数ContainsInvalidCharsでチェックしています。

invalidChars = Array("\", "/", ":", "*", "?", """", "<", ">", "|")

For i = LBound(invalidChars) To UBound(invalidChars)
    If InStr(fileName, invalidChars(i)) > 0 Then
        ContainsInvalidChars = True
        Exit Function
    End If
Next i

これらの文字が1つでも含まれていればTrueを返し、エラーとして記録されます。InStr関数は文字列の中に特定の文字が含まれているかを調べる関数で、見つかった位置を返します。見つからない場合は0を返すので、> 0で判定しています。

【ファイルの存在チェックと重複チェック】

実際の変更処理の中で、変更元のファイルが存在するか、変更先に同名のファイルが既にないかをチェックしています。

If fso.FileExists(oldPath) Then
    If fso.FileExists(newPath) Then
        ws.Cells(i, 3).Value = "エラー: 同名のファイルが既に存在"
    Else
        fso.MoveFile oldPath, newPath
    End If
Else
    ws.Cells(i, 3).Value = "エラー: ファイルが見つかりません"
End If

これにより、誤って既存のファイルを上書きしてしまうことを防げます。FileExistsメソッドは、指定したパスにファイルが存在するかをTrueまたはFalseで返してくれます。

参照設定について

このコードではScripting.FileSystemObjectを使用しています。これを使うには参照設定が必要です。

参照設定を行うメリットは、コードの実行速度が速くなることと、IntelliSense(入力補完機能)が使えることです。CreateObjectを使う方法もありますが、参照設定の方が型の安全性が高く、初心者には分かりやすいです。

参照設定の方法は以下の記事で解説しています。

参照設定を行うと、fso.と入力したときに使えるメソッドの一覧が自動で表示されます。これがあると、どんな機能が使えるのかが分かりやすくなります。

まとめ

ファイルの一括リネームでは、事前のバリデーションが重要です。全行をチェックしてからまとめて処理することで、途中でエラーが起きて中途半端な状態になるのを防げます。参照設定を使ったFileSystemObjectは、ファイル操作を安全に行うための便利なツールです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?