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でフォルダ名を一括変更するマクロ【バリデーション機能で安全に実行】

0
Posted at

目次

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

はじめに

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

完成コード

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

Sub RenameFolders()
    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 Integer
    Dim successCount As Integer
    Dim validationErrors As String
    Dim emptyRowCount As Integer
    
    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)" & 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.FolderExists(oldPath) Then
                parentPath = fso.GetParentFolderName(oldPath)
                
                If Right(parentPath, 1) = "\" Then
                    newPath = parentPath & newName
                Else
                    newPath = parentPath & "\" & newName
                End If
                
                If fso.FolderExists(newPath) Then
                    ws.Cells(i, 3).value = "エラー: 同名のフォルダが既に存在"
                    errorCount = errorCount + 1
                Else
                    On Error Resume Next
                    fso.MoveFolder 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(folderName As String) As Boolean
    Dim invalidChars As Variant
    Dim i As Integer
    
    invalidChars = Array("\", "/", ":", "*", "?", """", "<", ">", "|")
    
    For i = LBound(invalidChars) To UBound(invalidChars)
        If InStr(folderName, 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行目未満ならデータなしと判断します。

【フェーズ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列も空)は無視し、片方だけ入力されている場合はエラーとして記録します。このように段階的にチェックすることで、どの行に問題があるのかが明確になります。

【フェーズ3】フォルダ名の変更処理

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

fso.MoveFolder oldPath, newPath

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

バリデーションの仕組み

このマクロでは4種類のバリデーションを行っています。

【空欄チェック】

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

【フルパスチェック】

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

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

C:\のような形式か、\\server\のようなUNCパス(ネットワークパス)であるかを判定しています。

【無効な文字チェック】

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

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

これらの文字が1つでも含まれていればTrueを返し、エラーとして記録されます。

【フォルダの存在チェックと重複チェック】

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

If fso.FolderExists(oldPath) Then
    ' 存在する場合の処理
Else
    ws.Cells(i, 3).Value = "エラー: フォルダが見つかりません"
End If

これにより、誤って既存のフォルダを上書きしてしまうことを防げます。

参照設定について

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

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

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

まとめ

フォルダの一括リネームでは、事前のバリデーションが重要です。全行をチェックしてからまとめて処理することで、途中でエラーが起きて中途半端な状態になるのを防げます。参照設定を使った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?