【エクセル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には他にもファイル(フォルダ)操作系の色々なメソッド(コピー、移動、削除、パスからファイル名の取得等)があるため覚えておくと便利です。

いいなと思ったら応援しよう!