はじめに
「商品コードと商品名のリストはあるが、実際の画像ファイル名が商品コードのままで分かりにくい…」「Excelで管理しているファイルリスト通りに、ファイル名を一括で修正したい」
このような、Excelシートの情報を使って、大量のファイル名を一括で変更したいというニーズは、多くの業務で発生します。
VBAの FileSystemObject (FSO) を使えば、こうした作業をボタン一つで自動化できます。この記事では、Excelシートに作成した「現在のファイル名」と「新しいファイル名」の一覧表に沿って、実際にファイル名を一括リネームする、安全で確実な方法をご紹介します。
リネーム用の一覧表を準備する
まず、VBAを実行するための準備として、以下のような一覧表をExcelシートに作成します。ここでは、シート名を「リネームリスト」とします。
A列 (現在のファイル名) | B列 (新しいファイル名) | C列 (処理結果) |
product_001.jpg | 新商品A(夏モデル).jpg | |
product_002.jpg | 人気商品B(限定色).jpg | |
product_003.jpg | 定番商品C.jpg | |
IMG_9999.jpg | (削除予定).jpg | |
… | … |
- A列: 変更したいファイルの、現在の名前を入力します。
- B列: 変更後の、新しい名前を入力します。
- C列: VBAが処理結果(成功、失敗など)を書き込むための空の列です。
安全なリネーム処理(2段階リネーム)とは?
一覧表通りに上から順番にリネームすると、「A
をB
にリネームしたいが、B
という名前はリストの下の方でリネーム元として使われている」といった名前の衝突が発生し、エラーの原因となります。
これを防ぐため、元コードでも採用されている**「2段階リネーム」**という手法を使います。
- 第1段階(一時リネーム): まず、リストにある全ての元ファイルを、絶対に重複しない「一時的な名前」に一斉に変更します。
- 第2段階(最終リネーム): その後、「一時的な名前」にしたファイルを、リスト通りの「新しい名前」に一斉に変更します。
この手順を踏むことで、処理の途中でファイル名が衝突する危険性を完全になくすことができます。
一覧表に沿ってファイル名を変更するVBAコード
ここでは、「リネームリスト」シートのA2セルから始まる一覧表を使い、「対象ファイル」フォルダ内にあるファイルをリネームします。
完成コード
Sub RenameFilesBasedOnList()
'== 変数を定義します ==
Dim objFSO As Object
Dim ws As Worksheet
Dim nameList As Range
Dim targetRow As Range
Dim folderPath As String
Dim currentFilePath As String
Dim tempName As String
'== 基本設定 ==
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set ws = ThisWorkbook.Worksheets("リネームリスト")
folderPath = ThisWorkbook.Path & "¥対象ファイル¥"
' リストの範囲をA2セルから最終行まで自動取得
Set nameList = ws.Range("A2", ws.Cells(ws.Rows.Count, "A").End(xlUp)).Resize(, 3)
' 処理結果列をクリア
nameList.Columns(3).ClearContents
'== 第1段階:一時的な名前にリネーム ==
For Each targetRow In nameList.Rows
currentFilePath = folderPath & targetRow.Cells(1, 1).Value '現在のファイルパス
If objFSO.FileExists(currentFilePath) Then
' 重複しない一時的な名前を生成
tempName = "temp_" & Format(Now, "yyyymmddhhmmss") & "_" & targetRow.Row & ".tmp"
' FSOで一時リネームを実行
objFSO.GetFile(currentFilePath).Name = tempName
' 一時ファイル名をC列(処理結果列)に記録しておく
targetRow.Cells(1, 3).Value = tempName
Else
' ファイルが存在しない場合
targetRow.Cells(1, 3).Value = "ファイルなし"
End If
Next targetRow
'== 第2段階:新しい名前にリネーム ==
For Each targetRow In nameList.Rows
tempName = targetRow.Cells(1, 3).Value
' 一時リネームに成功したファイルのみ対象
If tempName <> "ファイルなし" Then
currentFilePath = folderPath & tempName '一時ファイルのパス
' FSOで最終リネームを実行
objFSO.GetFile(currentFilePath).Name = targetRow.Cells(1, 2).Value 'B列の新しいファイル名
' 処理結果を「成功」に更新
targetRow.Cells(1, 3).Value = "リネーム成功"
End If
Next targetRow
MsgBox "処理が完了しました。", vbInformation
'== オブジェクトを解放します ==
Set objFSO = Nothing
Set ws = Nothing
End Sub
コードの解説
Set nameList = ...
リネーム対象のリスト範囲をA2セルからA列の最終データ行まで自動で取得しています。これにより、リストの行数が変わってもコードを修正する必要がありません。- 第1段階ループ
For Each targetRow In nameList.Rows
: 一覧表を一行ずつ処理します。If objFSO.FileExists(...)
: A列に書かれたファイルが実際に存在するかを確認します。tempName = ...
:Format(Now, ...)
で現在時刻(秒単位まで)と行番号を組み合わせ、絶対に重複しない一時ファイル名を生成します。objFSO.GetFile(...).Name = tempName
: 実際に一時ファイル名へのリネームを実行します。targetRow.Cells(1, 3).Value = tempName
: 後で使うため、どのファイルをどの一時名前にしたか、C列にメモしておきます。
- 第2段階ループ
If tempName <> "ファイルなし" Then
: C列のメモを見て、一時リネームに成功したファイルだけを対象に処理を進めます。objFSO.GetFile(...).Name = targetRow.Cells(1, 2).Value
: 一時ファイル名のファイルを、B列に書かれている本来の「新しいファイル名」にリネームします。targetRow.Cells(1, 3).Value = "リネーム成功"
: C列の処理結果を「成功」に書き換えて、ユーザーに処理結果が分かるようにします。
まとめ
今回は、Excelの一覧表という「設計図」に基づいて、FSOでファイル名を一括変更する、非常に実用的な方法をご紹介しました。
- Excelでリストを作ることで、複雑なリネームルールも簡単に管理できる。
- **「2段階リネーム」**の手法を用いることで、ファイル名の衝突を気にすることなく安全に処理できる。
- 処理結果をExcelシートに書き出すことで、どのファイルが成功し、どのファイルが存在しなかったのかを後から簡単に確認できる。
この方法は、商品管理、文書管理、写真整理など、様々な場面で応用が可能です。ぜひ、定型的なリネーム作業の自動化にお役立てください。