Excel VBAのDir関数の使い方をお探しですね。
広告
Excel VBAのDir関数でファイル・フォルダの存在確認をする方法
Excel VBAでブックを保存したり、CSVを読み込んだり、指定フォルダへファイルを書き出したりする処理では、対象のファイルやフォルダが存在しないだけでエラーになることがあります。
そんなときに便利なのが**Dir関数**です。
Dir関数を使えば、ファイルやフォルダの存在を事前にチェックできます。
存在する場合だけ処理を続ける、存在しない場合はメッセージを出す、といった安全な分岐を作れるので、エラーに強いマクロが作れるようになります。
この記事では、Excel VBAのDir関数でファイルやフォルダの存在確認をする基本から、実務でつまずきやすい注意点まで分かりやすく解説します。
Dir関数で存在確認する基本
Dir関数は、指定したパスに一致するファイル名またはフォルダ名を返すVBA関数です。
存在確認で使う場合の考え方はとてもシンプルで、**対象が存在すれば名前が返り、存在しなければ空文字「””」が返ります**。
つまり、Dir関数そのものがTrueやFalseを返すわけではなく、戻り値が空かどうかをIf文で判定するのが基本です。
この仕組みを理解しておくと、ファイルの読み込み前、保存前、フォルダ作成前などにエラーを防ぐ処理を書きやすくなります。
基本の書き方は次のとおりです。
“`vb
Dir(パス名 [, 属性])
“`
**第1引数**には確認したいファイルやフォルダのパスを文字列で指定します。
たとえば「C:\Temp\sample.xlsx」のようなフルパスを指定するのが一般的です。
カレントディレクトリ内であればファイル名だけでも動きますが、実務ではどの場所を見ているのかが曖昧になりやすいため、できるだけフルパスで書くことをおすすめします。
**第2引数**の属性は省略できますが、フォルダを判定する場合は**vbDirectory**を指定するのが定番です。
Dir関数の戻り値は、フルパスではなく**「ファイル名」または「フォルダ名」のみ**です。
たとえば「C:\Temp\sample.xlsx」を指定して存在していた場合、返るのは「sample.xlsx」だけです。
存在確認だけなら問題ありませんが、戻り値を使って別の処理を行う場合は、必要に応じてフォルダパスと結合してフルパスを作る必要があります。
また、ファイル名やフォルダ名に**ワイルドカード**を使える点もDir関数の特徴です。
「*.xlsx」や「売上*」のように指定すれば、条件に一致する対象を探すこともできます。
Dir関数でファイルの有無を判定する
ファイルの存在確認は、Dir関数のもっとも基本的な使い方です。
指定したファイルが存在する場合はファイル名が返り、存在しない場合は空文字が返るため、If文で「<> “”」または「= “”」を判定します。
Excel VBAでは、外部ファイルを開く前や、CSVを取り込む前、同名ファイルへの上書きを避けたい場面でよく使います。
事前にファイルの有無を判定しておけば、「ファイルが見つかりません」などの実行時エラーを避け、ユーザーに分かりやすいメッセージを表示できます。
ファイルが存在するかどうかを確認する基本コードは次のとおりです。
“`vb
Sub CheckFileExists()
Dim filePath As String
filePath = “C:\Temp\sample.xlsx”
If Dir(filePath) <> “” Then
MsgBox “ファイルは存在します。
”
Else
MsgBox “ファイルは存在しません。
”
End If
End Sub
“`
この例では、指定したパスに「sample.xlsx」があれば「ファイルは存在します。
」と表示されます。
存在しなければDir関数は空文字を返すため、Else側の処理に進みます。
実務ではMsgBoxを表示するだけでなく、存在する場合はWorkbooks.Openで開く、存在しない場合は処理を終了する、といった使い方が多くなります。
特に自動処理では、ファイルがないまま次の処理に進むと原因が分かりにくいエラーにつながるため、最初にチェックしておくことが重要です。
読み込み前のチェックとして使うなら、次のように**Exit Sub**を組み合わせると処理の流れが明確になります。
“`vb
Sub OpenFileAfterCheck()
Dim filePath As String
filePath = “C:\Temp\sample.xlsx”
If Dir(filePath) = “” Then
MsgBox “指定されたファイルが見つかりません。
” & vbCrLf & filePath, vbExclamation
Exit Sub
End If
Workbooks.Open filePath
End Sub
“`
この書き方では、ファイルが存在しない場合にメッセージを出して処理を終了し、存在する場合だけブックを開きます。
正常時の処理をIf文の中に深く入れずに済むため、コードが読みやすくなるのも利点です。
なお、**拡張子の指定ミス**には注意が必要です。
「sample.xlsx」と「sample.xlsm」は別ファイルとして扱われるため、実際のファイル形式に合わせてパスを指定してください。
複数の拡張子を対象にしたい場合は、ワイルドカードを使うか、候補ごとに判定する設計にします。
Dir関数でフォルダの存在確認をする
フォルダの存在確認を行う場合は、Dir関数の第2引数に**vbDirectory**を指定します。
vbDirectoryは「ディレクトリ、つまりフォルダも対象にする」という意味の定数です。
ファイル確認と同じく、対象フォルダが存在すればフォルダ名が返り、存在しなければ空文字が返ります。
Excel VBAでは、出力先フォルダが存在するか確認してからファイルを保存する、フォルダがなければ作成する、といった場面でよく使います。
基本コードは次のとおりです。
“`vb
Sub CheckFolderExists()
Dim folderPath As String
folderPath = “C:\Temp\Output”
If Dir(folderPath, vbDirectory) <> “” Then
MsgBox “フォルダは存在します。
”
Else
MsgBox “フォルダは存在しません。
”
End If
End Sub
“`
このように、フォルダを調べるときは「**Dir(folderPath, vbDirectory)**」と書きます。
ただし、フォルダパスの末尾に「\」を付けるかどうかは処理によって挙動が分かりにくくなることがあるため、特定フォルダの存在確認では「C:\Temp\Output」のように**末尾の区切り文字を付けない形**で統一すると安全です。
一方で、フォルダ内のファイル一覧を取得するときは「C:\Temp\Output\*.xlsx」のように、フォルダパスと検索条件を結合するため末尾の「\」が必要になります。
フォルダがなければ作成してから保存する処理は、実務で特によく使われます。
“`vb
Sub CreateFolderIfNotExists()
Dim folderPath As String
folderPath = ThisWorkbook.Path & “\出力”
If Dir(folderPath, vbDirectory) = “” Then
MkDir folderPath
End If
ThisWorkbook.SaveCopyAs folderPath & “\backup.xlsm”
End Sub
“`
このコードでは、現在のブックと同じ場所に「出力」フォルダがなければ**MkDir**で作成し、その中にブックのコピーを保存します。
すでに同名フォルダがある状態でMkDirを実行するとエラーになるため、事前にDir関数で存在確認している点が重要です。
ただし、MkDirは一度に深い階層をまとめて作ることはできません。
たとえば「C:\Temp\A\B」を作りたいときに「A」が存在しない場合、いきなり「B」まで作成しようとするとエラーになります。
深い階層を扱う場合は、上位フォルダから順に作成するか、FileSystemObjectの利用も検討するとよいです。
なお、厳密に「フォルダだけ」を判定したい場合は注意が必要です。
vbDirectoryを指定しても、条件やパスの指定によっては通常ファイルも検索対象に含まれることがあります。
通常の業務マクロでは「指定した名前のフォルダがあるか」を確認する用途で問題になりにくいものの、同名のファイルが存在する可能性がある場所では、GetAttr関数で属性を確認するか、後述するFileSystemObjectのFolderExistsを使うとより明確です。
Dir関数を使うときの注意点と使い分け
Dir関数は短く書けて便利ですが、**内部状態を保持する特殊な関数**である点に注意が必要です。
Dir関数は、最初にパスやワイルドカードを指定して呼び出すと、その検索条件を記憶します。
その後、**引数なしのDir()**を呼ぶと、同じ条件に一致する次のファイル名を返します。
この仕組みによってフォルダ内のファイル一覧を取得できますが、処理の途中で別のDir関数を呼ぶと検索状態が上書きされ、元の一覧取得が途中で崩れることがあります。
たとえば、次のようなファイル一覧取得では、最初だけ検索条件を指定し、2回目以降はDir()で次のファイルを取得します。
“`vb
Sub ListExcelFiles()
Dim folderPath As String
Dim fileName As String
Dim row As Long
folderPath = “C:\Temp\”
fileName = Dir(folderPath & “*.xlsx”)
row = 1
Do While fileName <> “”
Cells(row, 1).Value = fileName
Cells(row, 2).Value = folderPath & fileName
row = row + 1
fileName = Dir()
Loop
End Sub
“`
このループの途中で「If Dir(別のフォルダ, vbDirectory) = “” Then」のような存在確認を挟むと、Dir関数が保持している検索条件が別のものに切り替わります。
その結果、次のDir()が本来のファイル一覧の続きではなく、直前に実行した存在確認の続きとして扱われることがあります。
これは初心者だけでなく、ある程度VBAを書ける人でも見落としやすいポイントです。
**Dir関数で一覧取得をしている最中は、別のDir関数を呼ばない**設計にするのが安全です。
FileSystemObjectとの使い分け
この問題を避けたい場合や、ファイルとフォルダの判定結果をTrueまたはFalseで分かりやすく扱いたい場合は、**FileSystemObject**を使う方法もあります。
FileSystemObjectでは、ファイルは**FileExists**、フォルダは**FolderExists**で判定できます。
Dir関数のように戻り値の空文字を比較するのではなく、存在すればTrue、存在しなければFalseが返るため、意図が読み取りやすいコードになります。
“`vb
Sub CheckByFSO()
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
If fso.FileExists(“C:\Temp\sample.xlsx”) Then
MsgBox “ファイルは存在します。
”
End If
If fso.FolderExists(“C:\Temp\Output”) Then
MsgBox “フォルダは存在します。
”
End If
End Sub
“`
Dir関数とFileSystemObjectの使い分けは、処理の複雑さで考えると分かりやすいです。
– **単純に1つのファイルやフォルダの有無を確認するだけ**なら、Dir関数は短く書けて十分実用的です。
– **Dir関数でファイル一覧を取得している最中に別の存在確認も行う場合**、属性を厳密に判定したい場合、フォルダ作成や削除などのファイル操作をまとめて扱う場合は、FileSystemObjectを使ったほうが安全で読みやすくなります。
どちらか一方だけを覚えるのではなく、Dir関数の手軽さとFileSystemObjectの明確さを場面に応じて選ぶことが、実務で安定したVBAを書くコツです。
汎用関数にしておくと便利
最後に、存在確認の処理は**汎用関数**にしておくと再利用しやすくなります。
毎回If Dir(…)と書いてもよいですが、処理名として意味が分かる関数にしておくと、後からコードを読んだときに意図が伝わりやすくなります。
“`vb
Function FileExistsByDir(ByVal filePath As String) As Boolean
FileExistsByDir = (Dir(filePath) <> “”)
End Function
Function FolderExistsByDir(ByVal folderPath As String) As Boolean
FolderExistsByDir = (Dir(folderPath, vbDirectory) <> “”)
End Function
“`
まとめ
Excel VBAのDir関数でファイルやフォルダの存在確認をする方法は、基本だけなら難しくありません。
重要なのは次の3点です。
1. **Dir関数の戻り値はTrue/Falseではなく名前または空文字**であること
2. **フォルダ判定ではvbDirectoryを指定**すること
3. **一覧取得中に別のDirを呼ぶと状態が上書きされる**こと
これらを押さえておけば、ファイルの読み込み、保存、フォルダ作成などの処理をエラーに強くできます。
業務マクロでは「存在する前提」で処理を書くのではなく、**「存在しない場合も想定して分岐する」**ことで、利用者にとって扱いやすい安定したツールになります。
ぜひDir関数を活用して、エラーに強いVBAを書いてみてください。
広告
