EXCEL VBAメモ - DIR関数のハマりどころ
デバッグで少々ハマったのでメモ。
指定したフォルダの下のファイルを一つずつ取り出して処理する場合や、特定のファイルが存在するかを判断したい場合には、DIR関数で簡潔に記述できるのでよく使用します。こんな感じで
Dim path As String Dim file As String path = "c:\foo" file = Dir(path & "\*.xml") Do Until file = "" Debug.Print file file = Dir() Loop
ところがDIR関数を使用したループ内では、そのループ用途以外ではDIR関数が使用できないという問題があります。
下の例では、DIR関数を使用したループ内で、更にファイルの存在確認にDIR関数を使用しています。このような使い方をした場合には、実行時にループの最後の
file = Dir()
で、「プロシージャの呼び出し、または、引数が不正です」というエラーが発生します。
Dim path As String Dim file As String path = "c:\foo" file = Dir(path & "\*.xml") Do Until file = "" If Dir("c:\foo.txt") <> "" Then Debug.Print "Exist" End If Debug.Print file file = Dir() 'ここでエラー Loop
上の例の様にループの中で、別の用途のDIR関数を直接記述した場合には直ぐにわかります。
ところがループの中でプロシージャを呼び出していて、そのプロシージャの中(または更に呼び出されるプロシージャの中)でDIR関数を使用した場合には、呼び出されるプロシージャの単体のテストでは問題なく動作してしまう為、見つけるのが難しくなってしまいます。
その様なことを防止するためにも指定フォルダの下のファイルを一つずつ処理するような場合には、少々記述が面倒になりますが FileSystemObject を使用した方が良いと思われます。
Dim fso As Object Dim file As Object Dim path As String path = "c:\foo" Set fso = CreateObject("Scripting.FileSystemObject") For Each file In fso.GetFolder(path).Files If Right(file.Name, 4) <> ".xml" Then GoTo Continue If Dir("c:\foo.txt") <> "" Then Debug.Print "Exist" End If Debug.Print file.Name Continue: Next