はじめに
「ファイル名の連番の間に、新しいファイルを追加したい」「特定の番号以降の連番を、まとめて後ろにずらしたい」…。ファイル整理をしていると、このように連番を部分的に修正したくなることがあります。
一つずつ手作業で名前を変更するのは、ファイル数が増えるほど面倒で、ミスも起こりがちです。
VBAの FileSystemObject (FSO) を使えば、このような「連番のずらし処理」も、プログラムで一括実行できます。この記事では、指定した範囲の連番ファイル名を、指定した数だけ後ろにずらす(インクリメントする)方法を分かりやすく解説します。
連番をずらす際の注意点
連番をずらすとき、単純に番号の小さい方からリネームしていくと、名前が衝突してしまいます。
例えば、003.jpg を 005.jpg に、004.jpg を 006.jpg に変更したい場合、先に 003.jpg を 005.jpg にしてしまうと、もし 005.jpg が元々存在した場合に上書きされてしまいます(またはエラーになります)。
これを防ぐため、連番の大きい方から順番に処理するのが鉄則です。大きい番号からリネームすれば、名前の衝突は起こりません。
ファイル名の連番をずらすVBAコード
ここでは、Excelファイルと同じ階層にある「画像ファイル」フォルダを対象とします。その中にある IMG_005.jpg から IMG_010.jpg までのファイル名を、+10 した番号(IMG_015.jpg, IMG_020.jpg)にずらすコードを作成します。
完成コード
Sub ShiftSequentialFileNumbers()
'== 変数を定義します ==
Dim objFSO As Object
Dim folderPath As String
Dim currentFilePath As String
Dim i As Long
'== 設定項目 ==
Dim startNum As Long 'リネームを開始する番号
Dim endNum As Long 'リネームを終了する番号
Dim shiftAmount As Long '連番をいくつずらすか(加算する数)
Dim fileNameFormat As String 'ファイル名の書式(プレフィックスと拡張子)
'== FileSystemObjectを生成します ==
Set objFSO = CreateObject("Scripting.FileSystemObject")
'== 各種設定値を指定します ==
folderPath = ThisWorkbook.Path & "¥画像ファイル¥"
startNum = 5
endNum = 10
shiftAmount = 10 '連番を10増やす
' Format関数用の書式。"IMG_"がプレフィックス、"000"が3桁ゼロ埋め、".jpg"が拡張子
fileNameFormat = "'IMG_'000'.jpg'"
'== 連番の大きい方からループしてリネーム処理を行います ==
For i = endNum To startNum Step -1
'現在のファイルパスを生成
currentFilePath = folderPath & Replace(Format(i, fileNameFormat), "'", "")
'ファイルが存在すれば、リネームを実行
If objFSO.FileExists(currentFilePath) Then
Dim newFileName As String
newFileName = Replace(Format(i + shiftAmount, fileNameFormat), "'", "")
objFSO.GetFile(currentFilePath).Name = newFileName
'Debug.Print i & " -> " & i + shiftAmount 'イミディエイトウィンドウで処理の確認
End If
Next i
MsgBox "連番のずらし処理が完了しました。", vbInformation
'== オブジェクトを解放します ==
Set objFSO = Nothing
End Sub
コードの解説
設定項目コードの冒頭で、リネームのルールをまとめて設定できるようにしています。startNum,endNum: どの範囲の連番を対象にするかを決めます。shiftAmount: 連番をいくつ増やすかを指定します。fileNameFormat:Format関数でファイル名を生成するための書式です。'IMG_'のようにシングルクォーテーションで囲むと、それは固定の文字列(プレフィックス)として扱われます。000は3桁のゼロ埋めを意味します。
For i = endNum To startNum Step -1このコードの最も重要な部分です。ループをendNum(大きい数)からstartNum(小さい数)へ、Step -1で逆順に実行しています。これにより、前述したファイル名の衝突を防ぎます。currentFilePath = folderPath & Replace(Format(i, fileNameFormat), "'", "")ループ変数iとfileNameFormatを使って、IMG_010.jpgのようなファイルパスを組み立てています。Format関数でプレフィックスを扱うとシングルクォーテーションが付いてしまうため、Replace関数で取り除いています。If objFSO.FileExists(currentFilePath) Then ...連番の途中にファイルが存在しない場合(例:IMG_008.jpgがない)も考えられます。その場合にエラーが出ないよう、FileExistsでファイルの存在を確かめてからリネーム処理に進みます。objFSO.GetFile(currentFilePath).Name = newFileName実際にファイル名を変更する処理です。GetFileでファイルオブジェクトを取得し、その.Nameプロパティに新しいファイル名newFileNameを代入しています。
まとめ
今回は、FSOを使ってファイル名の連番を安全にずらす方法を解説しました。
- 大きい番号から小さい番号へループするのが衝突を避けるための鍵。
- ファイル名のルールを冒頭で設定できるようにしておくと、後々の修正が楽になる。
FileExistsで存在確認をすることで、より堅牢なプログラムになる。
このコードを応用すれば、連番の削除(別のフォルダに移動)や、逆に連番の間にスペースを空ける(若い番号をマイナスにずらす)といった処理も可能です。ぜひ、ご自身のファイル管理業務の自動化に役立ててください。
