こんにちはblueです。
VBAでファイルの保存を行う時、文字列の問題で「不正な文字です」といったエラーが出ることがありませんか?
これはファイル名に使えない文字を使用していることによるものです。
\ | 円マーク |
---|---|
/ | スラッシュ |
: | コロン |
* | アスタリスク |
? | クエスチョンマーク、疑問符 |
“ | ダブルクォーテーション |
<> | 不等号 |
| | 縦棒 |
これらを禁則文字といいます。
この現象はセルの値や各種プロパティなどの文字列からファイル名を作成する場合に起こります。
この場合は禁則文字を一つ一つ変換(Replace関数)するのが一番簡単ですが、9個もある禁則文字をすべて記載するのは面倒です。
FileName=Replace(FileName, "/", "/")
FileName=Replace(FileName, "\", "¥")
・
・
・
ただ今回Twitterで処理方法について教えていただいたのでまとめておきたいと思います。
↓教えていただいたのはりゅうりゅう先生です。一つ一つの方法について丁寧に教えていただきました☺。
なおダブルコーテーションについては同じ処理ができないので別におまけに追加しています。
処理方法
今回方法として3つの方法を説明します。
- 禁則文字列をLike演算子で処理し、半角を全角にする(Like演算子+StrConv)
- 禁則文字列をInstr関数で処理し、半角を全角にする(Instr関数+StrConv)
- 禁則文字列をReplace関数で処理し、半角を全角にする(Replace関数)
これらの方法で禁則文字を半角から全角にします。
こうすることでファイル名にした場合のエラー回避ができるようになります。
それぞれについて紹介します。
Like演算子+StrConv
以下は禁則文字列をLike演算子の文字リストに入れて処理し、StrConv関数で全角に変換するサンプルマクロです。
Private Sub NGwordConversion()
'Like演算子+SrConv関数を使う方法
Dim FileName As String
Dim NGword As String
Dim i As Long
FileName = "山田太郎/Yamada Taro<情報>.xlsx"
NGword = "[\,/,:,*,?,<,>,|]"
For i = 1 To Len(FileName)
If Mid(FileName, i, 1) Like NGword Then
Mid(FileName, i, 1) = StrConv(Mid(FileName, i, 1), vbWide)
End If
Next i
End Sub
各コードの詳細は以下になります。
If Mid(FileName, i, 1) Like NGword Then
Mid関数を使用してファイル名を一つずつ取り出して禁則文字と比較します。
Like演算子については以下のように[]でくくってひとまとめにして利用することができます。
なお一文字一文字は,で区切る必要があります
この中で[\,/,:,*,?,<,>,|]として禁則文字リストを作っています。
Mid(FileName, i, 1) = StrConv(Mid(FileName, i, 1), vbWide)
右辺は該当した文字に関してStrConv関数を使って全角に変換しています。
左辺はMid関数ではなくMidステートメントです。Mid関数は一部を取り出すものですが、Midステートメントは文字列の一部を置換します。
Midステートメントについては以下のエクセルの神髄先生のサイトが非常にわかりやすかったです。
Instr関数+StrConv
以下の方法では禁則文字列をInstr関数の第一引数に入れて処理し、StrConv関数で全角に変換するサンプルマクロです。
Private Sub NGwordConversion2()
'Instr関数+SrConv関数を使う方法
Dim FileName As String
Dim NGword As String
Dim i As Long
FileName = "山田太郎/Yamada Taro<情報>.xlsx"
NGword = "\/:*?<>|"
For i = 1 To Len(FileName)
If InStr(NGword, Mid(FileName, i, 1)) > 0 Then
Mid(FileName, i, 1) = StrConv(Mid(FileName, i, 1), vbWide)
End If
Next i
End Sub
各コードの詳細は以下になります。
If InStr(NGword, Mid(FileName, i, 1)) > 0 Then
上記と同様にMid関数を使用してファイル名を一つずつ取り出して禁則文字と比較します。
Instr関数の場合は第一引数に禁則文字列を入れて、第二引数と比較しています。
Mid(FileName, i, 1) = StrConv(Mid(FileName, i, 1), vbWide)
上記と同様に右辺は該当した文字に対してStrConv関数を使って全角に変換しています。
左辺も上記と同様にMidステートメントで取得した文字列を置換しています。
Replace関数
以下は禁則文字列について半角のまとまりと全角のまとまりを作り、全角に変換するサンプルマクロです。
Private Sub NGwordConversion3()
'Replace関数を使う方法
Dim FileName As String
Dim NGwordWide As String
Dim NGwordNarrow As String
Dim i As Long
FileName = "山田太郎/Yamada Taro<情報>.xlsx"
NGwordNarrow = "\/:*?<>|"
NGwordWide = "¥/:*?<>|"
For i = 1 To Len(NGwordNarrow)
FileName = Replace(FileName, Mid(NGwordNarrow, i, 1), Mid(NGwordWide, i, 1))
Next
End Sub
各コードの詳細は以下になります。
For i = 1 To Len(NGwordNarrow)
Like演算子やInstr関数はファイル名に対してループを実行しましたが、この場合は禁則文字列に対してループ処理を実行します。
FileName = Replace(FileName, Mid(NGwordNarrow, i, 1), Mid(NGwordWide, i, 1))
禁則文字を一つずつ抜き出してファイル名に存在する場合に全角の禁則文字に変換しています。
この場合は以下のように半角と全角でリストにしておき、対応する番号で変換するという形をとっています。対応表が作れるような場合は良い方法です。
1 | \ | ¥ |
---|---|---|
2 | / | / |
3 | : | : |
4 | * | * |
5 | ? | ? |
6 | < | < |
7 | > | > |
8 | | | | |
おまけ
以下はダブルコーテーションを変換するサンプルマクロです。
Private Sub NGwordConversion4()
'”(ダブルコーテーション)の処理方法
Dim FileName As String
FileName = "山田太郎/Yamada Taro""<情報>.xlsx"
FileName = Replace(FileName, """", Chr(&HFA57))
End Sub
ダブルコーテーションはVBEではそのままでは入らないので半角は「””」の2度記入、全角は文字コードで記入しています。
まとめ
以上が禁則文字を処理するマクロでした。
一つ一つをReplace関数で処理してもよいのですがこちらのほうがスマートです。
文字列操作においてLike演算子やInstr関数、Replace関数は基本なので両方使えるようになっておくと応用範囲が広がると思います。
脱初心者の為のVBAの書籍は以下がお勧めです。リーダブルコードやエラー処理などできるVBAを書くための技術が満載です。
VBAを一通りすべて学びたい方は以下がお勧めです。分量は多いですがVBAで必要な知識がすべて盛り込まれているのでこの一冊でほぼすべてが理解できます。
VBAでのファイル操作にFileSystemObjectを使ってみませんか?初心者からでも可能なまとめ記事としていますので参考にしていただければ幸いです。
コメント