目次
はじめに
複数のフォルダ名を一括で変更したいとき、手作業では時間がかかります。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】フォルダ名の変更処理
バリデーションを通過したら、実際にフォルダ名を変更します。FileSystemObjectのMoveFolderメソッドを使用しており、これは名前変更だけでなく移動にも使えるメソッドです。
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は、ファイル操作を安全に行うための便利なツールです。