日程Fit|「いつ空いてますか?」の往復はもう不要。候補日を選んでURLを送るだけ|登録不要|今すぐ無料で使う →

Excel VBAを利用したファイル名の大文字・小文字一括変換方法

Excel VBAを利用したファイル名の大文字・小文字一括変換方法では、folder内mappingを作ってcollisionを全件検査し、Approvedの一件ごとにtemporary path経由でcaseを変更する。Windowsの一般的なcase-insensitive filesystemではcaseだけのName変更が直接反映されないことがあり、一意なtemporary名を経由する。UnicodeのLCase/UCaseはlocaleや文字で一対一でない場合もある。この記事はold path、desired case path、temporary path、binary comparison、approval statusをmapにするを判断軸にして、記事固有のコード、合否、停止条件、復元を順序立てて説明します。

内容やtagを変えず、base nameの大文字・小文字表記だけを安全に変換する。完了は「全approved fileがdesired caseで存在し、内容hashと拡張子、未承認file名が不変である」です。結果が空なら「oldとnewがbinaryでも同一なら変更不要とし、temporary fileを作らない」として調べ、エラーを0件へ置き換えません。

日程Fit。無料・登録不要。「いつ空いてる?」を、ひとつのリンクで。リンクを送って、○△×でかんたん日程調整。無料で日程を作る。
目次

case-insensitive filesystemを考慮

folder内mappingを作ってcollisionを全件検査し、Approvedの一件ごとにtemporary path経由でcaseを変更する。ファイル名の大小文字だけを一括変換では、単にコマンドが終了したことではなく「全approved fileがdesired caseで存在し、内容hashと拡張子、未承認file名が不変である」を完了条件にします。内容やtagを変えず、base nameの大文字・小文字表記だけを安全に変換する。

case-insensitive filesystemを考慮に入る前に、対象、実行場所、権限、入力の由来を確認します。oldとnewがbinaryでも同一なら変更不要とし、temporary fileを作らない。判定不能を成功へ丸めません。

folder内のold→new mapをpreview

folder内のold→new mapをpreviewでは「old path、desired case path、temporary path、binary comparison、approval statusをmapにする」という粒度で対象を特定します。Windowsの一般的なcase-insensitive filesystemではcaseだけのName変更が直接反映されないことがあり、一意なtemporary名を経由する。UnicodeのLCase/UCaseはlocaleや文字で一対一でない場合もある。表示名や先頭候補だけを採用しません。

ファイル名の大小文字だけを一括変換の対象が複数なら、候補数と除外理由を残します。ファイル名の大小文字だけを一括変換では実行ユーザー、OS・製品版、locale、カレントディレクトリも結果の解釈へ影響するため同時に記録します。

変換後名のcollisionを事前検査

変換後名のcollisionを事前検査は変更や出力生成より先に行う観測です。old path、desired case path、temporary path、binary comparison、approval statusをmapにするを含む形で現状を保存し、後段のコードが同じ対象へ向くか確認します。

Option Explicit

Private Type CaseRenameEntry
    SheetRow As Long
    OldPath As String
    NewPath As String
    TempPath As String
    OriginalSha256 As String
    Stage As Integer
End Type

Private CaseEntries() As CaseRenameEntry
Private CaseEntryCount As Long
Private CaseFolder As String
Private ProtectedInventory As Object
Private HashBaselineReady As Boolean

Private Function ExactLeafExists(ByVal folderPath As String, ByVal leafName As String) As Boolean
    Dim fso As Object, item As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    For Each item In fso.GetFolder(folderPath).Files
        If StrComp(item.Name, leafName, vbBinaryCompare) = 0 Then ExactLeafExists = True: Exit Function
    Next item
End Function

Private Function FileSha256(ByVal filePath As String) As String
    Dim fso As Object, stream As Object, hasher As Object
    Dim fileBytes As Variant, digest As Variant, i As Long, result As String, failureText As String
    On Error GoTo HashFailure
    Set fso = CreateObject("Scripting.FileSystemObject")
    If Not fso.FileExists(filePath) Then Err.Raise 53, , "hash対象fileがありません: " & filePath
    Set stream = CreateObject("ADODB.Stream")
    stream.Type = 1
    stream.Open
    stream.LoadFromFile filePath
    stream.Position = 0
    fileBytes = stream.Read
    stream.Close
    Set hasher = CreateObject("System.Security.Cryptography.SHA256Managed")
    digest = hasher.ComputeHash_2(fileBytes)
    For i = LBound(digest) To UBound(digest)
        result = result & LCase$(Right$("0" & Hex$(CLng(digest(i)) And &HFF&), 2))
    Next i
    If Len(result) <> 64 Then Err.Raise 5, , "SHA-256が64桁ではありません: " & filePath
    FileSha256 = result
    Exit Function
HashFailure:
    failureText = CStr(Err.Number) & " " & Err.Description
    On Error Resume Next
    If Not stream Is Nothing Then stream.Close
    On Error GoTo 0
    Err.Raise vbObjectError + 1840, "FileSha256", "SHA-256を読めないため停止します: " & filePath & ": " & failureText
End Function

Private Function FileMetadataFingerprint(ByVal filePath As String) As String
    Dim fso As Object, item As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set item = fso.GetFile(filePath)
    FileMetadataFingerprint = CStr(item.Size) & "|" & Format$(item.DateLastModified, "yyyymmddhhnnss")
End Function

Private Function HashMatches(ByVal filePath As String, ByVal expectedSha256 As String) As Boolean
    HashMatches = (StrComp(FileSha256(filePath), expectedSha256, vbBinaryCompare) = 0)
End Function

Private Sub AssertExactPathAndHash(ByVal expectedPath As String, ByVal expectedSha256 As String, ByVal role As String)
    Dim fso As Object, parentPath As String, leafName As String
    Set fso = CreateObject("Scripting.FileSystemObject")
    parentPath = fso.GetParentFolderName(expectedPath)
    leafName = fso.GetFileName(expectedPath)
    If Not ExactLeafExists(parentPath, leafName) Then Err.Raise 53, , role & "のpath/nameがcase exactではありません: " & expectedPath
    If Not HashMatches(expectedPath, expectedSha256) Then Err.Raise 5, , role & "のSHA-256がbaselineと異なります: " & expectedPath
End Sub

Private Sub AssertProtectedInventory()
    Dim key As Variant, fso As Object, protectedPath As String
    If ProtectedInventory Is Nothing Then Err.Raise 5, , "protected SHA-256 inventoryがありません"
    Set fso = CreateObject("Scripting.FileSystemObject")
    For Each key In ProtectedInventory.Keys
        protectedPath = fso.BuildPath(CaseFolder, CStr(key))
        AssertExactPathAndHash protectedPath, CStr(ProtectedInventory(key)), "未対象file"
    Next key
End Sub

Private Sub WriteFixtureAscii(ByVal filePath As String, ByVal payload As String)
    Dim fso As Object, writer As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set writer = fso.CreateTextFile(filePath, True, False)
    writer.Write payload
    writer.Close
End Sub

Private Sub AssertSameSizeSameSecondMtimeChangeIsRejected()
    Dim fso As Object, fixtureFolder As String, fixturePath As String
    Dim beforeMetadata As String, afterMetadata As String, beforeHash As String, afterHash As String
    Dim attempt As Long, fixturePassed As Boolean, failureText As String
    On Error GoTo FixtureFailure
    Set fso = CreateObject("Scripting.FileSystemObject")
    Randomize
    fixtureFolder = fso.BuildPath(fso.GetSpecialFolder(2), ".ittrip-seq184-hash-fixture-" & Format$(Now, "yyyymmddhhnnss") & "-" & CStr(Int(Rnd() * 1000000)))
    If fso.FolderExists(fixtureFolder) Or fso.FileExists(fixtureFolder) Then Err.Raise 58, , "fixture pathが既にあります"
    fso.CreateFolder fixtureFolder
    fixturePath = fso.BuildPath(fixtureFolder, "same-metadata.bin")
    For attempt = 1 To 20
        WriteFixtureAscii fixturePath, "AAAA"
        beforeMetadata = FileMetadataFingerprint(fixturePath)
        beforeHash = FileSha256(fixturePath)
        WriteFixtureAscii fixturePath, "BBBB"
        afterMetadata = FileMetadataFingerprint(fixturePath)
        afterHash = FileSha256(fixturePath)
        If beforeMetadata = afterMetadata Then Exit For
    Next attempt
    If beforeMetadata <> afterMetadata Then Err.Raise 5, , "same-size/same-second-mtime fixtureを準備できません"
    If StrComp(beforeHash, afterHash, vbBinaryCompare) = 0 Then Err.Raise 5, , "fixtureの異なる内容が同じSHA-256になりました"
    If HashMatches(fixturePath, beforeHash) Then Err.Raise 5, , "hash gateがsame-size/same-second-mtime内容変更を誤って受理しました"
    Debug.Print "same-size/same-second-mtime fixture rejected=True", beforeHash, afterHash
    fixturePassed = True
FixtureCleanup:
    On Error Resume Next
    If Len(fixtureFolder) > 0 And fso.FolderExists(fixtureFolder) Then fso.DeleteFolder fixtureFolder, True
    On Error GoTo 0
    If fixturePassed Then Exit Sub
    Err.Raise vbObjectError + 1841, "AssertSameSizeSameSecondMtimeChangeIsRejected", failureText
FixtureFailure:
    failureText = CStr(Err.Number) & " " & Err.Description
    Resume FixtureCleanup
End Sub

Windowsの一般的なcase-insensitive filesystemではcaseだけのName変更が直接反映されないことがあり、一意なtemporary名を経由する。UnicodeのLCase/UCaseはlocaleや文字で一対一でない場合もある。ファイル名の大小文字だけを一括変換では取得不能、対象なし、値が空という三状態を分け、stderrや終了コードを捨てません。

一時名を経由して一件変更

一時名を経由して一件変更ではfolder内mappingを作ってcollisionを全件検査し、Approvedの一件ごとにtemporary path経由でcaseを変更する。ファイル名の大小文字だけを一括変換のサンプルにあるパス、セル、ユーザー、時刻は検証用なので、直前に確認した承認値へ置き換えます。

Sub BuildApprovedCaseMap()
    Dim ws As Worksheet, fso As Object, oldKeys As Object, targetKeys As Object
    Dim lastRow As Long, r As Long, oldPath As String, newPath As String, oldLeaf As String
    Dim newLeaf As String, item As Object, key As String, i As Long
    Set ws = ThisWorkbook.Worksheets("CaseMap")
    Set fso = CreateObject("Scripting.FileSystemObject")
    HashBaselineReady = False
    CaseEntryCount = 0
    Set ProtectedInventory = Nothing
    CaseFolder = fso.GetAbsolutePathName(Trim$(CStr(ws.Range("B1").Value2)))
    If Not fso.FolderExists(CaseFolder) Then Err.Raise 76, , "対象folderがありません"
    AssertSameSizeSameSecondMtimeChangeIsRejected
    lastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
    If lastRow < 2 Then Err.Raise 5, , "mapping行がありません"
    ReDim CaseEntries(1 To lastRow - 1)
    Set oldKeys = CreateObject("Scripting.Dictionary"): oldKeys.CompareMode = vbTextCompare
    Set targetKeys = CreateObject("Scripting.Dictionary"): targetKeys.CompareMode = vbTextCompare
    For r = 2 To lastRow
        If StrComp(Trim$(CStr(ws.Cells(r, "D").Value2)), "Approved", vbBinaryCompare) = 0 Then
            oldPath = fso.GetAbsolutePathName(Trim$(CStr(ws.Cells(r, "B").Value2)))
            newPath = fso.GetAbsolutePathName(Trim$(CStr(ws.Cells(r, "C").Value2)))
            If StrComp(fso.GetParentFolderName(oldPath), CaseFolder, vbTextCompare) <> 0 Or StrComp(fso.GetParentFolderName(newPath), CaseFolder, vbTextCompare) <> 0 Then Err.Raise 5, , "同じ承認folder直下だけを変換します: row=" & r
            If StrComp(oldPath, newPath, vbTextCompare) <> 0 Or StrComp(oldPath, newPath, vbBinaryCompare) = 0 Then Err.Raise 5, , "caseだけが異なるold/newを指定します: row=" & r
            oldLeaf = fso.GetFileName(oldPath): newLeaf = fso.GetFileName(newPath)
            If Not ExactLeafExists(CaseFolder, oldLeaf) Then Err.Raise 53, , "old名をcase exactで確認できません: " & oldLeaf
            If oldKeys.Exists(oldPath) Then Err.Raise 5, , "old名が重複しています: " & oldPath
            If targetKeys.Exists(newPath) Then Err.Raise 5, , "変換後名がcase-fold衝突しています: " & newPath
            oldKeys.Add oldPath, True: targetKeys.Add newPath, True
            CaseEntryCount = CaseEntryCount + 1
            With CaseEntries(CaseEntryCount)
                .SheetRow = r
                .OldPath = oldPath
                .NewPath = newPath
                .OriginalSha256 = FileSha256(oldPath)
                .Stage = 0
            End With
        End If
    Next r
    If CaseEntryCount = 0 Then Err.Raise 5, , "Approved mappingがありません"
    For Each item In fso.GetFolder(CaseFolder).Files
        key = fso.GetAbsolutePathName(item.Path)
        If targetKeys.Exists(key) And Not oldKeys.Exists(key) Then Err.Raise 58, , "未対象fileと変換後名が衝突します: " & item.Name
    Next item
    Set ProtectedInventory = CreateObject("Scripting.Dictionary"): ProtectedInventory.CompareMode = vbBinaryCompare
    For Each item In fso.GetFolder(CaseFolder).Files
        key = fso.GetAbsolutePathName(item.Path)
        If Not oldKeys.Exists(key) Then ProtectedInventory.Add item.Name, FileSha256(item.Path)
    Next item
    For i = 1 To CaseEntryCount
        CaseEntries(i).TempPath = fso.BuildPath(CaseFolder, ".ittrip-case-stage-" & Format$(Now, "yyyymmddhhnnss") & "-" & CStr(i))
        If fso.FileExists(CaseEntries(i).TempPath) Or targetKeys.Exists(CaseEntries(i).TempPath) Then Err.Raise 58, , "temporary名が衝突しています"
        AssertExactPathAndHash CaseEntries(i).OldPath, CaseEntries(i).OriginalSha256, "Approved source"
    Next i
    AssertProtectedInventory
    For i = 1 To CaseEntryCount
        ws.Cells(CaseEntries(i).SheetRow, "E").Value2 = "Validated"
        ws.Cells(CaseEntries(i).SheetRow, "F").NumberFormat = "@"
        ws.Cells(CaseEntries(i).SheetRow, "F").Value2 = CaseEntries(i).OriginalSha256
        Debug.Print CaseEntries(i).OldPath, CaseEntries(i).NewPath, CaseEntries(i).TempPath, CaseEntries(i).OriginalSha256
    Next i
    HashBaselineReady = True
End Sub

case-fold後に同名となる複数file、Unicode不定、open fileがあればbatchを止める。ファイル名の大小文字だけを一括変換で変更が発生する場合は、新規出力、no-clobber、WhatIf、下書き表示など利用可能な安全機構を先に使います。

Approved mapだけ反映

Approved mapだけ反映では入力と出力を別々に再取得します。ファイル名の大小文字だけを一括変換の合格は、全approved fileがdesired caseで存在し、内容hashと拡張子、未承認file名が不変であることです。件数だけでなく識別値と内容も照合します。

Sub RenameAllApprovedCaseMappings()
    Dim ws As Worksheet, fso As Object, i As Long, primaryError As String, rollbackErrors As String
    Set ws = ThisWorkbook.Worksheets("CaseMap")
    Set fso = CreateObject("Scripting.FileSystemObject")
    If Not HashBaselineReady Or CaseEntryCount = 0 Then Err.Raise 5, , "先にBuildApprovedCaseMapで全SHA-256 baselineを確定してください"
    AssertProtectedInventory
    For i = 1 To CaseEntryCount
        If CStr(ws.Cells(CaseEntries(i).SheetRow, "D").Value2) <> "Approved" Then Err.Raise 5, , "承認状態が変わりました"
        If StrComp(CStr(ws.Cells(CaseEntries(i).SheetRow, "F").Value2), CaseEntries(i).OriginalSha256, vbBinaryCompare) <> 0 Then Err.Raise 5, , "保存SHA-256が変わりました"
        AssertExactPathAndHash CaseEntries(i).OldPath, CaseEntries(i).OriginalSha256, "実行直前Approved source"
        If fso.FileExists(CaseEntries(i).TempPath) Then Err.Raise 58, , "temporary名が実行直前に衝突しました"
    Next i
    On Error GoTo Rollback
    For i = 1 To CaseEntryCount
        AssertExactPathAndHash CaseEntries(i).OldPath, CaseEntries(i).OriginalSha256, "phase1直前Approved source"
        Name CaseEntries(i).OldPath As CaseEntries(i).TempPath
        CaseEntries(i).Stage = 1
    Next i
    For i = 1 To CaseEntryCount
        AssertExactPathAndHash CaseEntries(i).TempPath, CaseEntries(i).OriginalSha256, "phase2直前temporary"
        Name CaseEntries(i).TempPath As CaseEntries(i).NewPath
        CaseEntries(i).Stage = 2
    Next i
    For i = 1 To CaseEntryCount
        AssertExactPathAndHash CaseEntries(i).NewPath, CaseEntries(i).OriginalSha256, "二相rename後Approved target"
    Next i
    AssertProtectedInventory
    For i = 1 To CaseEntryCount
        ws.Cells(CaseEntries(i).SheetRow, "E").Value2 = "RenamedAndHashVerified"
    Next i
    Exit Sub
Rollback:
    primaryError = CStr(Err.Number) & " " & Err.Description
    On Error Resume Next
    For i = CaseEntryCount To 1 Step -1
        Err.Clear
        If CaseEntries(i).Stage = 2 Then
            AssertExactPathAndHash CaseEntries(i).NewPath, CaseEntries(i).OriginalSha256, "rollback直前new"
            If Err.Number = 0 Then Name CaseEntries(i).NewPath As CaseEntries(i).TempPath
        End If
        If Err.Number = 0 And (CaseEntries(i).Stage = 1 Or CaseEntries(i).Stage = 2) Then
            AssertExactPathAndHash CaseEntries(i).TempPath, CaseEntries(i).OriginalSha256, "rollback直前temporary"
            If Err.Number = 0 Then Name CaseEntries(i).TempPath As CaseEntries(i).OldPath
        End If
        If Err.Number <> 0 Then rollbackErrors = rollbackErrors & " row=" & CaseEntries(i).SheetRow & " move=" & Err.Description
    Next i
    For i = 1 To CaseEntryCount
        Err.Clear
        AssertExactPathAndHash CaseEntries(i).OldPath, CaseEntries(i).OriginalSha256, "rollback後Approved source"
        If Err.Number <> 0 Then
            rollbackErrors = rollbackErrors & " row=" & CaseEntries(i).SheetRow & " verify=" & Err.Description
            ws.Cells(CaseEntries(i).SheetRow, "E").Value2 = "RollbackHashFailed"
        Else
            CaseEntries(i).Stage = 0
            ws.Cells(CaseEntries(i).SheetRow, "E").Value2 = "RolledBackAndHashVerified"
        End If
    Next i
    Err.Clear
    AssertProtectedInventory
    If Err.Number <> 0 Then rollbackErrors = rollbackErrors & " protected=" & Err.Description
    On Error GoTo 0
    HashBaselineReady = False
    If Len(rollbackErrors) > 0 Then Err.Raise vbObjectError + 184, , "rename失敗=" & primaryError & "; rollback/hash検証失敗=" & rollbackErrors
    Err.Raise vbObjectError + 185, , "rename失敗。全対象のold path/name/SHA-256と未対象SHA-256をrollback確認済み: " & primaryError
End Sub

oldとnewがbinaryでも同一なら変更不要とし、temporary fileを作らない。ファイル名の大小文字だけを一括変換の結果が期待と違えば追加変更を重ねず、入力、対象範囲、locale・時刻、権限、製品仕様の順に戻って調べます。

caseだけで同一扱いになる場合

case-fold後に同名となる複数file、Unicode不定、open fileがあればbatchを止める。caseだけで同一扱いになる場合に当てはまるときは中止理由、対象識別子、終了コードまたはErr.Number、直前に成功した段階を保存します。

oldとnewがbinaryでも同一なら変更不要とし、temporary fileを作らない。ファイル名の大小文字だけを一括変換の再試行は原因を直し、同じ入力と対象を再確認してから行います。警告抑止や強制上書きで通しません。

reverse mapで元表記へ戻す

old/new reverse mapでcollisionを再確認し、同じtemporary経由で元caseへ戻す。復元にも「old path、desired case path、temporary path、binary comparison、approval statusをmapにする」を用い、類似名の別対象へ処理しません。

  • ファイル名の大小文字だけを一括変換の開始前状態
  • 採用対象: old path、desired case path、temporary path、binary comparison、approval statusをmapにする
  • 復元後の確認: 全approved fileがdesired caseで存在し、内容hashと拡張子、未承認file名が不変である
  • 復元を止める条件: case-fold後に同名となる複数file、Unicode不定、open fileがあればbatchを止める

Unicode case foldの限界

全件成功するまでstatusを個別記録し、途中失敗時に残りへ続行するか承認を分ける。ファイル名の大小文字だけを一括変換を反復するときは、正常、差分なし、対象なし、要承認、失敗を別の状態として記録します。

Unicode case foldの限界の主キーold path、desired case path、temporary path、binary comparison、approval statusをmapにする
採用条件全approved fileがdesired caseで存在し、内容hashと拡張子、未承認file名が不変である
空結果oldとnewがbinaryでも同一なら変更不要とし、temporary fileを作らない
中止条件case-fold後に同名となる複数file、Unicode不定、open fileがあればbatchを止める

case-insensitive filesystemを考慮から証跡化する変換後名のcollisionを事前検査

ファイル名の大小文字だけを一括変換の証跡は「old path、desired case path、temporary path、binary comparison、approval statusをmapにする」を主キーにします。case-insensitive filesystemを考慮で確認した値と、実行直前・実行直後の値を同じ作業番号に保存し、表示名が似ている別対象や前回の結果を混ぜません。

folder内のold→new mapをpreviewで空結果を判定する一時名を経由して一件変更

ファイル名の大小文字だけを一括変換の空結果は「oldとnewがbinaryでも同一なら変更不要とし、temporary fileを作らない」として扱います。folder内のold→new mapをpreviewで入力自体が存在するか、権限で見えていないか、条件に一致しないだけかを分け、0件という表示だけで成功・失敗を決めません。

Unicode case foldの限界から復旧可否を測るcase-insensitive filesystemを考慮

ファイル名の大小文字だけを一括変換の復旧判断では「old/new reverse mapでcollisionを再確認し、同じtemporary経由で元caseへ戻す」を採用します。Unicode case foldの限界を再確認し、復旧後に「全approved fileがdesired caseで存在し、内容hashと拡張子、未承認file名が不変である」へ戻ったかを別の読み取り処理で測定します。

ファイル名の大小文字だけを一括変換の事前確認では、old path、desired case path、temporary path、binary comparison、approval statusをmapにするを画面表示や標準出力だけで済ませず、実行日時と一緒に作業記録へ写します。Windowsの一般的なcase-insensitive filesystemではcaseだけのName変更が直接反映されないことがあり、一意なtemporary名を経由する。UnicodeのLCase/UCaseはlocaleや文字で一対一でない場合もあるという仕様があるため、似た名前の別対象、前回実行時の値、キャッシュされた表示を今回の対象と取り違えないことが重要です。

ファイル名の大小文字だけを一括変換のコードを実行した直後は、まず終了状態を保存し、その後に別の読み取り処理で「全approved fileがdesired caseで存在し、内容hashと拡張子、未承認file名が不変である」を確認します。ファイル名の大小文字だけを一括変換では同じコードの表示だけを合否判定に使うと部分成功や遅延反映を見逃すため、識別値、件数、内容の三点を照合します。

ファイル名の大小文字だけを一括変換で結果が得られない場合は、oldとnewがbinaryでも同一なら変更不要とし、temporary fileを作らない。ファイル名の大小文字だけを一括変換ではこの状態と、権限拒否、入力形式の不一致、接続先や時刻の違いを一緒にしません。ファイル名の大小文字だけを一括変換の対象候補数、除外された候補、最後に成功した確認処理を残すと、再試行で同じ失敗を重ねずに済みます。

ファイル名の大小文字だけを一括変換を元へ戻す必要があるときは、old/new reverse mapでcollisionを再確認し、同じtemporary経由で元caseへ戻す。ファイル名の大小文字だけを一括変換の復元前にも変更後の識別値を再取得し、別担当者の更新が入っていないか確認します。ファイル名の大小文字だけを一括変換の復元結果も通常処理と同じ完了条件で測り、戻したつもりという報告だけで閉じません。

ファイル名の大小文字だけを一括変換を引き継ぐ記録には、全件成功するまでstatusを個別記録し、途中失敗時に残りへ続行するか承認を分ける。特に「case-fold後に同名となる複数file、Unicode不定、open fileがあればbatchを止める」に該当した場合は、実行を止めたこと自体を正しい結果として扱います。ファイル名の大小文字だけを一括変換の次回担当者が承認範囲と未処理対象を区別できるよう、作業番号と対象識別子を対応付けます。

ファイル名の大小文字だけを一括変換の作業記録には、開始前の対象候補、採用した識別値、実行したコード、終了後の実測、除外理由を同じ作業番号で保存します。「old path、desired case path、temporary path、binary comparison、approval statusをmapにする」を省くと別対象との比較になり得るため、日時、実行場所、製品版と一緒に残します。

Excel VBAを利用したファイル名の大文字・小文字一括変換方法を定期運用へ組み込む場合も初回は対話的に確認します。正常は「全approved fileがdesired caseで存在し、内容hashと拡張子、未承認file名が不変である」、空結果は「oldとnewがbinaryでも同一なら変更不要とし、temporary fileを作らない」、停止は「case-fold後に同名となる複数file、Unicode不定、open fileがあればbatchを止める」として報告し、次の担当者が同じ条件で追試できるようにします。

caseだけの変更は一時名を経由する

WindowsのFileExists/Dirは通常case-insensitiveなので、新旧がcaseだけ違うと新名の存在確認が元ファイル自身に一致します。同じ親フォルダかつvbTextCompareでは同一、vbBinaryCompareでは相違する組合せだけを受け付けます。

一意な一時名へ移してから希望caseへ移し、二段目が失敗した場合は一時名から旧名へ戻します。別フォルダへの移動や文字case以外の変更はこの手順の対象外です。

公式情報・参考資料

ファイル名の大小文字だけを一括変換のコマンド、API、対応範囲は次の公式一次資料で確認しました。確認日は2026年7月17日です。ファイル名の大小文字だけを一括変換の実行環境にあるman、–help、VBA Object Browser、Get-Helpも併用してください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次