ファイル名に含まれる使用できない文字列を変換する。

VBS用に書いていたんだけど、
汎用性を持たせようと作り込み始めた辺りから段々と複雑化していって、
まんまと沼に嵌ってしまったので。
元々実現したかった部分のみ抽出して平坦に書き直してみた。

・やりたかったこと

・制御文字(&H0~&H1F)の半角空白化
・連続する半角空白は単一にまとめる
・前後の半角空白は削除
・使用不可文字(\ / : * ? " < > |)は全角化
・末尾半角ドットは全角化
・ファイル名が予約語なら全角化

予約語の処理までは不要かなーとも思ったが
備えあれば患いなしってことでこちらも対応。
StrConv がある VBA はラク出来て良いね。

なお、置換処理に RegExp オブジェクトを使ってないのは
1度の置換に2行の記述を必要とし、見辛くなってしまうから。

' ファイル名を正規化する
' 制御文字(&H0~&H1F)は半角空白に、連続する半角空白は単一にまとめ、ファイル名前後の半角空白は削除、
' ファイル使用不可文字(\ / : * ? " < > |)は全角変換する。
' 更に、ファイル名が予約語なら全角に、末尾半角ドットなら全角に変換する
Public Function FixedFileName(fileName As String) As String
    Dim tempName As String
    tempName = fileName
    
    ' 制御文字(&H0~&H1F)を半角空白に変換
    Dim index As Long
    For index = &H0 To &H1F
        tempName = Replace(tempName, Chr(index), " ")
    Next
    
    ' 連続した半角空白を一つにする
    Do While InStr(tempName, "  ") > 0
        tempName = Replace(tempName, "  ", " ")
    Loop
    
    ' 前後の半角空白を削除
    tempName = Trim(tempName)
    
    ' ファイル使用不可文字を全角に変換
    '  \ / : * ? " < > |
    tempName = Replace(tempName, "\", "¥") '円マーク
    tempName = Replace(tempName, ":", ":") 'コロン
    tempName = Replace(tempName, "*", "*") 'アスタリスク
    tempName = Replace(tempName, "?", "?") 'クエスチョンマーク
    tempName = Replace(tempName, """", Chr(-1449)) 'ダブルコーテーション
    tempName = Replace(tempName, "<", "<") '小なり
    tempName = Replace(tempName, ">", ">") '大なり
    tempName = Replace(tempName, "|", "|") 'ハット
    
    ' ファイル名が予約語なら全角に変換
    Dim RE As Object, reMatch As Object
    Set RE = CreateObject("VBScript.RegExp")
    RE.Pattern = "^(CON|PRN|AUX|NUL|COM[0-9]|LPT[0-9]|CLOCK\$)(\.|$)" ' 検索パターンを設定
    RE.IgnoreCase = True ' 大文字と小文字を区別しない
    RE.Global = True ' 文字列全体を検索する
    
    Set reMatch = RE.Execute(tempName)
    If reMatch.Count > 0 Then
        ' 予約語はアルファベットのみ全角に変換
        Dim tempMatch As String
        tempMatch = Replace(Replace(reMatch(0).Value, ".", ""), "$", "")
        tempName = Replace(tempName, tempMatch, StrConv(tempMatch, vbWide))
    End If
    Set reMatch = Nothing
    Set RE = Nothing
    
    ' 末尾半角ドットを全角に変換
    Dim tempLen As Long
    tempLen = Len(tempName)
    If tempLen > 0 Then
        If Right(tempName, 1) = "." Then
            If tempLen = 1 Then tempName = "."
            If tempLen >= 2 Then tempName = Left(tempName, tempLen - 1) & "."
        End If
    End If
    
    FixedFileName = tempName
End Function

参考
ファイル名に使用できない文字列が含まれていないか調べる - .NET Tips (VB.NET,C#...)
https://dobon.net/vb/dotnet/file/invalidpathchars.html

Naming Files, Paths, and Namespaces
https://social.msdn.microsoft.com/Search/ja-jp/?Query=Naming%20Files%2C%20Paths%2C%20and%20Namespaces