【エクセルVBA】ファイルの存在チェックにDirを使用するのはやめましょう
こんにちは、自動化エンジニアをしています。kozuです。
VBAでファイル(フォルダ)が存在しているかをチェックするのにDir関数とFileSystemObjectの2つのやり方がありますが、どちらを使用しているでしょうか。
Dir関数の方がコード量が少なく簡単に使用できるため、こちらを用している人は少なくないと思います。私も最近まで使用していました。しかし、業務で開発しているときに謎の不具合が発生し、以降はFileSystemObjectを使うようにしています。
今回は、DirとFileSystemObjectを比較し、Dirを使ってはいけない理由を解説しようと思います。
1.コードの比較
まずはDirとFileSystemObjectでファイル(フォルダ)の存在チェックをするためのコードを比較してみます。
まずは、Dir関数を使用した場合のコードが以下になります。
'Dirを使ったファイル存在チェック
Dim filePath As String
filePath = "ファイルパス"
If Dir(filePath) = "" Then
MsgBox filePath & "は存在しません。"
Else
MsgBox filePath & "は存在します。"
End If
'Dirを使ったフォルダ存在チェック
Dim folderPath As String
folderPath = "フォルダパス"
If Dir(folderPath, vbDirectory) = "" Then
MsgBox folderPath & "は存在しません。"
Else
MsgBox folderPath & "は存在します。"
End If
Dir関数は引数にパスを設定し、空文字が返れば存在せずパスが返れば存在することがわかるため、簡単に使用できます。
次に、FileSystemObjectを使用した場合のコードが以下になります。
※参照設定「Microsoft Scripting Runtime」を追加していません。
'FileSystemObjectを使ったファイル存在チェック
Dim filePath As String
filePath = "ファイルパス"
With CreateObject("Scripting.FileSystemObject")
If .FileExists(filePath) Then
MsgBox filePath & "は存在します。"
Else
MsgBox filePath & "は存在しません。"
End If
End With
'FileSystemObjectを使ったフォルダ存在チェック
Dim folderPath As String
folderPath = "フォルダパス"
With CreateObject("Scripting.FileSystemObject")
If .FolderExists(folderPath) Then
MsgBox folderPath & "は存在します。"
Else
MsgBox folderPath & "は存在しません。"
End If
End With
CreateObjectでオブジェクトを生成する必要があるため、Dirよりコード量が多くなります。メソッド名がファイルとフォルダで分かれており、英語の意味のままであるため分かりやすいです。また、ファイル(フォルダ)のパスを指定し、パスが存在すればTrue、存在しなければFalseが返るため、返り値がBoolean型であるため分かりやすいです。
2.Dir関数の制限
Dir関数には制限の制限があります。
1.ファイル(フォルダ)パスが256バイトを超えるとエラーになる
2.拡張子が3文字の場合、3文字+1文字のものもヒットしてしまう(例:xlsを指定した場合、xlsx、xlsmもヒットする)
3.UNICODEファイル名(例:㉑)が判別できない
4.存在しないパスが存在する判定になることがある
1~3まではネットで調べれば見つかるものですが、私が経験した中で謎だったのが4でした。端末によって結果が変わることがあり、ネットで調べてもよくわからなかったためFileSystemObjectに変更したところ正常に動作しました。
最終的な原因は不明のままでしたが、この事象が発生してからはDirは使用しないと決めました。1~3についてもFileSystemObjectを使用すれば問題なく動作します。
3.まとめ
ファイル(フォルダ)存在チェックにおいてDir関数とFileSystemObjectを比較しましたが、不具合を避けるために手間を惜しまずDir関数ではなくFileSystemObjectを使うようにしましょう。
今回は解説しませんでしたが、FileSystemObjectには他にもファイル(フォルダ)操作系の色々なメソッド(コピー、移動、削除、パスからファイル名の取得等)があるため覚えておくと便利です。