
[プログラミング: VBA] Dir関数で環境依存文字のフォルダ名は正しく扱えない
お疲れ様です ( 'ω')ノ
VBAでフォルダやファイルの列挙をするときにどのようにしていますか?
もし、Dir関数 を使っていると環境依存文字が使われているフォルダやファイル名は正しく取得することができません。
環境依存文字が使われている可能性があれば、FSO(FileSystemObject)を使いましょう・・・というのが今回のテーマです。
このテーマは僕が知らないで小一時間ハマってしまったため、知らな人には知って欲しいという思いで設定しました。
それでは、Dir関数 で環境依存文字のフォルダ名取得するとどうなるのか? FSOだとどうなるか? を解説してきます。
< まず、フォルダの列挙をしてみよう >
まず、フォルダを列挙してみます。
恐らく、フォルダを列挙する際に使われるのが、Dir関数かFSO(FileSystemObject)のどちらかだと思います。
そこで、Dir関数とFSOでフォルダを列挙するためのコードをそれぞれ書いていきます。
< Dir関数でフォルダを列挙するコード >
Option Explicit
Sub フォルダ検索_Dir関数()
'===== 変数宣言 ==========================================================
Dim strTmpFolder As String
Dim i As Long
'========================================================================
strTmpFolder = Dir("D:\", vbDirectory)
i = 1
Do Until strTmpFolder = ""
i = i + 1
Cells(i, 1) = strTmpFolder
strTmpFolder = Dir
Loop
End Sub
< FSO(FileSystemObject)でフォルダを列挙するコード >
Sub フォルダ検索_FSO()
'===== 変数宣言 ==========================================================
Dim varTmp As Variant
Dim i As Long
Dim objFSO As Object
'========================================================================
Set objFSO = CreateObject("Scripting.FileSystemObject")
i = i + 1
With objFSO
For Each varTmp In .GetFolder("D:\").SubFolders
i = i + 1
Cells(i, 2) = varTmp.Name
Next
End With
Set objFSO = Nothing
End Sub
コードは両方ともDドライブ直下のフォルダを列挙して、シートに出力するだけのコードになります。
< 実行する前にフォルダをエクスプローラで見てみる >
コードを実行する前にフォルダが置かれている場所がどのようになっているか、エクスプローラで見てみましょう。
僕の場合はDドライブ直下はこのようになっています。同じフォルダ名があるように見えますが、よく見ると違います。
上から2つ目のフォルダが、フォルダ名の先頭に通常の "_(アンダースコア)” を使い、3つ目がアンダースコアを間違って環境依存文字 ”‗" に変換してしまったフォルダです( これは僕が素で間違って作った時のものです(汗) )。
なお、半透明のフォルダが二つ存在していますが、OSの設定で隠しファイルを表示するようにしているだけです。
< 実行結果 >
Dir関数の場合、通常のアンダースコアのフォルダ名は正確に取得できていますが、環境依存文字が含まれたフォルダ名の方は ”?" に変換されています。
FSOの方は正確に取得できています。
これがDir関数では環境依存文字が正しく扱えなかったことを示す結果です。
ちなみにFSOの方は、何も設定しなければ勝手に隠しフォルダも拾ってしまいます。
< 環境依存文字にハマった理由 >
僕はこの現象にハマってしまい、「いつからVBAでアンダースコアが拾えなくなったんだ?」「ついにVBAが壊れた。」「これがVBAを使う宿命なのか?」なんてわけわからないことを考えていましたが、ただ単に環境依存文字に間違って変換してしまっていて、Dir関数が環境依存文字を正しく拾えなかったというだけの話でした。
しかし、その結果にたどり着くまでにより深くハマる原因を作っていたのが、VBEでした。
どういうことかというと、、、
↑ こういうことです。
FSOでフォルダを取得するコードをステップインしている時のスクリーンショットです。
変数varTmp には環境依存文字が含まれたサブフォルダーオブジェクトが格納されていますが、ローカルウィンドウではそのフォルダ名が正しく表示されていません。
しかし、前述のシート出力結果では正しく表示されています。
これが原因で、僕はより一層ハマることになったわけです。
< VBEは環境依存文字やShift-JISに無い文字に対応していない >
どうやらVBEはシート上やOS上で扱えるUnicode文字にあってShift-JISに無い文字は ”?” と表示されてしまうらしい。
そのため、Shift-JISに無い環境依存文字をフォルダ名に使った場合、FSOでもローカルウィンドウやイミディエイトウィンドウでは、表示だけが ”?" に変換されてしまうようです。
ただし、あくまで表示上の話であって、変数に格納されている値は別ということです。
Dir関数がダメだったのでFSOで試してステップイン実行中にもローカルウィンドウにこんな感じ("?")で表示されたら「FSOでもダメということは本当にVBAがおかしくなったのか。」って思ってしまいます。本当に知らなければ。
つまり、このようなこともあるので、ローカルウィンドウでおかしいと思っても一度シート上に出力したり、テキストファイル等に出力して、確認してみましょう。ということです。
< まとめ >
・フォルダ検索で、環境依存文字が使われている可能性があればFSOを使う
・シートはUnicode対応、VBEはShift-JISしか対応していない
・変数の値を確認するときはシートにも出力してみよう
この3つです。
この記事を最後まで読んでいただき、ありがとうございます。
宜しければ ”スキ” をしてもらえると僕のモチベーションが上がります。
どうぞよろしくお願いします!
それじゃ ('ω')ノ