【ExcelVBA】Dir関数の使い方とは?実務で使うテクニックも解説

いつもの仕事を楽に
スポンサーリンク

こんにちは、VBAエンジニアのやすこれです。

みなさんは、VBAでDir関数を使ったことがありますか?

  • VBAで任意の名前のファイルがあるかどうか調べたい
  • VBAで任意のフォルダの全ファイル名を取得したい
  • VBAでのファイル一覧取得方法を知りたい!
という方もいるのではないでしょうか。

そこで今回は、Dir関数をファイル一覧取得の実例つきでご紹介します。

スポンサーリンク

Dir関数の使い方

Dir関数の基本的な使い方

Dir関数は、パス名で指定したファイルが存在した場合に、そのファイルのファイル名を返す関数です。

  1. 基本構文
Dir(パス名 [, 属性])
  • [, 属性]は省略可能(既定値は「標準ファイル」)
  • パス名を指定したDir関数を使った直後は「パス名」も省略可能
  1. コード例
Dir("C:\ドキュメント\SampleFile.xlsx")
「C:\ドキュメント\SampleFile.xlsx」が存在する場合、「Sample.xlsx」を返し、存在しない場合は「””」を返す。

01_VBADir関数返り値
コード例では「属性」を省略しており、「標準ファイル」からパスを検索している。

他にも、引数を指定することでファイルではなくフォルダ名を取得できたり、隠しファイルから検索ができたりするので、詳しく解説していきます。


Dir関数の「引数」について

「属性」に指定できる引数を紹介します。
定数詳細
vbNormal0標準ファイル(既定値)
vbReadOnly1読み取り専用ファイル
vbHidden2隠しファイル
vbSystem4システムファイル(Windowsのみ使用可)
vbVolume8ボリュームファイル(Windowsのみ使用可)
vbDirectory16フォルダ
vbAlias64エイリアスファイル(Macのみ使用可)

例えば、任意のフォルダ名を検索したい時には、次のように使用します。

  1. コード例
Dir("C:\ドキュメント\SampleFolder", vbDirectory)
「C:\ドキュメント\SampleFolder」フォルダが存在する場合、「SampleFolder」を返し、存在しない場合は「””」を返す。

02_VBADir関数フォルダ検索(vbDirectory)イメージ
その他の引数についても使い方は同じですので試してみてください。

対象ファイルまたはフォルダの「属性」は「GetAttr」関数で取得することができます。
  • GetAttr(“C:\ドキュメント\SampleFolder”)
上記コードは、「16(フォルダ)」を返します。


Dir関数の応用と注意点

引数を省略して同条件で検索

ここでは、「パス名」と「属性」の両方を省略する使い方を紹介します。

まず、「パス名」と「属性」の両方を省略したDir関数を使うためには、引数を指定したDir関数を実行する必要があります。

引数を指定したDir関数を使った直後に、引数を省略したDir関数を使用することで、同条件で次のファイル(フォルダ)を検索することができます。

03_VBADir関数引数省略検索フォルダ
例えば、上記画像のフォルダ「C:\ドキュメント\」内の標準ファイルのファイル名を返す「Dir(“C:\ドキュメント\”, vbNormal)」のあとに引数を省略した「Dir()」を使用した次のコードを書きます。

MsgBox Dir("C:\ドキュメント", vbNormal) & vbCrLf & _
       Dir() & vbCrLf & _
       Dir()

上記コード内の「Dir()」は、直前のDir関数で指定されている「パス名:”C:\ドキュメント\”」「属性:vbNormal」を引き継ぎ、直前に検索したファイルの次のファイルを検索するので、結果は画像の通りとなります。

04_VBADir関数引数省略検索結果イメージ
Dir関数のこの性質は非常に重要なので、しっかり覚えておきましょう。

Dir関数の注意点

便利なDir関数にも注意することがあります。それはエラーが起き、処理が中断されてしまうことです。

Dir関数のエラーは先ほど紹介した、引数を省略して直前の条件を引き継ぎ、次のファイルを検索する「Dir()」時に発生します。具体的には次の2つの場合にエラーが発生します。
  • 初めて使用するDir関数が引数を省略した「Dir()」の場合
  • 返り値が「””」となるDir関数の直後に「Dir()」を使用した場合

どちらも画像のように「プロシージャの呼び出し、または引数が不正です。」というエラーが発生します。

05_VBADir関数引数省略時エラーメッセージ
エラーが発生しないよう、引数を省略した「Dir()」を使う場合は、下記2点を確認してから使うようにしましょう。

  • 直前に引数を指定したDir関数があるか
  • 引数を省略した「Dir()」の直前のDir関数の返り値が「””」となっていないか

次に紹介する、ファイル一覧取得方法でも上記ポイントを含む部分があるので、しっかり理解しておきましょう。


VBAのDir関数を使ったファイル一覧取得方法

引数を省略したDir関数を利用してファイル一覧を取得

'対象となるシートを変数に定義
Dim trgtSh As Worksheet
Set trgtSh = ThisWorkbook.Worksheets("Dir関数")
'書き込み対象行の初期値を設定
Dim cnt As Long
cnt = 1

'引数を指定したDir関数の返り値を変数に定義
Dim buf As String
buf = Dir("C:\ドキュメント", vbNormal)
'同条件での検索結果がなくなるまで、ループ
Do Until buf = ""
    trgtSh.Cells(cnt, 1).Value = buf
    '書き込み対象行に1加算
    cnt = cnt + 1
    
    '同条件での次の検索結果を変数に格納
    buf = Dir()
Loop

まずはじめに、取得したファイル名を書き込むシートと対象行の初期値を変数に定義しています。
'対象となるシートを変数に定義
Dim trgtSh As Worksheet
Set trgtSh = ThisWorkbook.Worksheets("Dir関数")
'書き込み対象行の初期値を設定
Dim cnt As Long
cnt = 1

つづいて次の部分で、Dir関数に任意のパス(「C:\ドキュメント\」フォルダ内「標準ファイル」)を指定して取得したファイル名の初期値を変数「buf」に格納します。
'引数を指定したDir関数の返り値を変数に定義
Dim buf As String
buf = Dir("C:\ドキュメント", vbNormal)

最後のDoLoopでは、「Until buf = “”」つまり、同条件でのファイル名の返り値が「””」となるまでループを繰り返します。

ループ内では、対象シートの対象セルにファイル名を書き込み、対象行を「1」加算しています。その後、変数「buf」に「Dir()」つまり直前のDir関数と同条件で検索した次の結果を格納してループの初めに戻っています。
'同条件での検索結果がなくなるまで、ループ
Do Until buf = ""
    trgtSh.Cells(cnt, 1).Value = buf
    '書き込み対象行に1加算
    cnt = cnt + 1
    
    '同条件での次の検索結果を変数に格納
    buf = Dir()
Loop

06_VBADir関数ファイル一覧取得フォルダ内容DoLoop
指定したフォルダが上記画像の状態の時、実行結果は次の画像の通りとなります。

07_VBADir関数ファイル一覧取得実行結果DoLoop

Dir関数とワイルドカードを利用してファイル一覧を取得

'対象となるシートを変数に定義
Dim trgtSh As Worksheet
Set trgtSh = ThisWorkbook.Worksheets("Dir関数")
'書き込み対象行の初期値を設定
Dim cnt As Long
cnt = 1

'引数をワイルドカードで指定したDir関数の返り値を変数に定義
Dim buf As String
buf = Dir("C:\ドキュメント\*.xlsx", vbNormal)
'同条件での検索結果がなくなるまで、ループ
Do Until buf = ""
    trgtSh.Cells(cnt, 1).Value = buf
    '書き込み対象行に1加算
    cnt = cnt + 1
    
    '同条件での次の検索結果を変数に格納
    buf = Dir()
Loop

まずはじめに、取得したファイル名を書き込むシートと対象行の初期値を変数に定義しています。
'対象となるシートを変数に定義
Dim trgtSh As Worksheet
Set trgtSh = ThisWorkbook.Worksheets("Dir関数")
'書き込み対象行の初期値を設定
Dim cnt As Long
cnt = 1

つづいて次の部分で、Dir関数に任意のパス(「C:\ドキュメント\*.xlsx」に該当する「標準ファイル」)を指定して取得したファイル名の初期値を変数「buf」に格納します。
'引数をワイルドカードで指定したDir関数の返り値を変数に定義
Dim buf As String
buf = Dir("C:\ドキュメント\*.xlsx", vbNormal)

最後のDoLoopでは、「Until buf = “”」つまり、同条件でのファイル名の返り値が「””」となるまでループを繰り返します。

ループ内では、対象シートの対象セルにファイル名を書き込み、対象行を「1」加算しています。その後、変数「buf」に「Dir()」つまり直前のDir関数と同条件で検索した次の結果を格納してループの初めに戻っています。
'同条件での検索結果がなくなるまで、ループ
Do Until buf = ""
    trgtSh.Cells(cnt, 1).Value = buf
    '書き込み対象行に1加算
    cnt = cnt + 1
    
    '同条件での次の検索結果を変数に格納
    buf = Dir()
Loop

08_VBADir関数ファイル一覧取得フォルダ内容ワイルドカード
指定したフォルダが上記画像の状態の時、実行結果は次の画像の通りとなります。

09_VBADir関数ファイル一覧取得実行結果ワイルドカード

Dir関数とLike演算子を利用して任意の拡張子のファイル一覧を取得

'対象となるシートを変数に定義
Dim trgtSh As Worksheet
Set trgtSh = ThisWorkbook.Worksheets("Dir関数")
'書き込み対象行の初期値を設定
Dim cnt As Long
cnt = 1

'引数を指定したDir関数の返り値を変数に定義
Dim buf As String
buf = Dir("C:\ドキュメント", vbNormal)
'同条件での検索結果がなくなるまで、ループ
Do Until buf = ""
    '拡張子が「.xlsx」のファイルの場合、処理を実行
    If buf Like "*.xlsx" Then
        trgtSh.Cells(cnt, 1).Value = buf
        '書き込み対象行に1加算
        cnt = cnt + 1
    End If
    
    '同条件での次の検索結果を変数に格納
    buf = Dir()
Loop

まずはじめに、取得したファイル名を書き込むシートと対象行の初期値を変数に定義しています。
'対象となるシートを変数に定義
Dim trgtSh As Worksheet
Set trgtSh = ThisWorkbook.Worksheets("Dir関数")
'書き込み対象行の初期値を設定
Dim cnt As Long
cnt = 1

つづいて次の部分で、Dir関数に任意のパス(「C:\ドキュメント\」フォルダ内「標準ファイル」)を指定して取得したファイル名の初期値を変数「buf」に格納します。
'引数を指定したDir関数の返り値を変数に定義
Dim buf As String
buf = Dir("C:\ドキュメント", vbNormal)

最後のDoLoopでは、「Until buf = “”」つまり、同条件でのファイル名の返り値が「””」となるまでループを繰り返します。

ループ内では「If」文と「Like」演算子を使い、「buf」に格納されたファイル名の拡張子が「.xlsx」の場合のみ処理を実行させています。

条件に合致した場合は、対象シートの対象セルにファイル名を書き込み、対象行を「1」加算しています。最後に、変数「buf」に「Dir()」つまり直前のDir関数と同条件で検索した次の結果を格納してループの初めに戻っています。
'同条件での検索結果がなくなるまで、ループ
Do Until buf = ""
    '拡張子が「.xlsx」のファイルの場合、処理を実行
    If buf Like "*.xlsx" Then
        trgtSh.Cells(cnt, 1).Value = buf
        '書き込み対象行に1加算
        cnt = cnt + 1
    End If
    
    '同条件での次の検索結果を変数に格納
    buf = Dir()
Loop

10_VBADir関数ファイル一覧取得フォルダ内容Like演算子
指定したフォルダが上記画像の状態の時、実行結果は次の画像の通りとなります。

11_VBADir関数ファイル一覧取得実行結果Like演算子

FileSystemObjectを使ったファイル名取得方法

ここまでは、Dir関数を使ってファイル名を取得してきましたが、次のように「FileSystemObject」を使ってもファイル名を取得することができます。

'FileSystemObjectを生成
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

MsgBox fso.GetFileName("C:\ドキュメント\SampleFile.xlsx")

'FileSystemObjectを解放
Set fso = Nothing

結果は次の画像の通りとなります。
12_VBAFileSystemObjectでファイル名取得
順にコードを解説します。

'FileSystemObjectを生成
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
「FileSystemObject」を使う際には、まずはじめに、オブジェクトを生成する必要があります。2~3行目の部分ですが、決まり文句なのでそのまま覚えてしまいましょう。

MsgBox fso.GetFileName("C:\ドキュメント\SampleFile.xlsx")
続く5行目の部分では生成した「FileSystemObject」の「GetFileName」メソッドを使用してファイル名を取得します。パスが存在する・しないに関わらず、引数に指定したパスのファイル名にあたる文字列を返すので注意しましょう。

FileSystemObjectを解放
Set fso = Nothing
最後に、生成した「FileSystemObject」を解放しています。このコードを実行しないと、メモリにオブジェクトが残ったままとなり、無用な負荷をかけてしまいます。生成文と同様、決まり文句ですので、こちらも覚えてしまいましょう。

このように、Dir関数以外の方法でもファイル名を取得することができるので、あわせて覚えておきましょう。


VBAのDir関数まとめ

今回はVBAのDir関数の使い方をご紹介いたしました。

Dir関数を使えば、任意のパス名からファイル名や、フォルダ名を取得できるので、使いこなせば非常に便利です。

また、今回紹介したファイル一覧の取得方法も使いこなせるようにしておきましょう。

ファイル一覧取得方法

  • 引数を省略したDir関数を利用してファイル一覧を取得
  • Dir関数とワイルドカードを利用してファイル一覧を取得
  • Dir関数とLike演算子を利用して任意の拡張子のファイル一覧を取得

注意点としても紹介した、引数を省略した「Dir()」で起きるエラーも覚えておきましょう。まずは実例通り使ってみると、理解が深まり応用が効くのでおすすめです。

ぜひ、使ってみてくださいね!