【VBA】Dir関数の使い方と使用例

更新日:2024/01/15

VBAのDir関数を使用するとファイルシステム上のファイルやフォルダを確認できます。
ここでは、Dir関数の使い方と使用例を5つ紹介します。

 

Dir関数の構文

Dir関数の構文は、次のようになっています。

Dir関数の構文

文字列 = Dir( pathname , attributes )

Dir関数は pathname と attributes に一致するファイルまたはフォルダで最初に一致したものから、親フォルダを取り除いた文字列を返します。

  • pathname:

    親フォルダを含んだファイルパス。
    ワイルドカード( "*":複数文字一致 、 "?":一文字一致)を使用できる。

  • attributes:

    検索するファイルの属性を指定する。
    省略可能。規定値vbNormal。

    属性値意味
    vbNormal0通常のファイル
    vbReadOnly1通常+読み取り専用ファイル
    vbHidden2通常+隠しファイル
    vbSystem4通常+システムファイル
    vbVolume8ボリューム ラベル
    vbDirectory16通常ファイル+フォルダ
    vbArchive32通常ファイル+アーカイブ

    複数の属性を指定するときは、+演算子で連結します。

    ' 通常ファイルと隠しファイルとフォルダを取得
    name = Dir( filename , vbHidden + vbDirectory )
    

    アーカイブは、バックアップ済みかどうかなどについてのフラグです。
    ファイルの特性ではありません。

 

引数なしの呼び出し

Dir関数の引数なしの呼び出しは、ワイルドカードで複数のファイルを取得させるときに使用します。

Dir関数呼び出しの初回は、一つ目の引数を省略できません。
省略するとエラーになります。

2回目以降は、Dir関数が "" を返すまで引数を省略できます。
ただし初回に "" が返ってきた場合は、2回目はエラーになります。

 

ワイルドカードは拡張子に注意

ファイル名に ワイルドカードの "*" を使用すると、拡張子のチェックが4文字以降はおこなわれません。

例えば検索したいファイル名を data*.txt としたとき、data3.txt-old などが含まれます。
これはDir関数の特徴ではなくて、Windowsコマンドのdirの仕様です。

拡張子が異なる結果を除外したいときは、Dir関数の戻り値がファイル名パターンに一致しているかを確認します。

' ワイルドカードで一致するファイルの名前を取得(改良版)
Sub DirSample3()
    Const filename = "data*.txt"
    Const fullfilename As String = "C:\data\" & filename
    
    Dim name As String
    Dim result As String
    
    name = Dir(fullfilename)
    Do While name <> ""
        If LCase(name) Like filename Then
            result = result & name & vbCrLf
        End If
        name = Dir()
    Loop
    MsgBox result
End Sub

Like演算子は、ワイルドカードでの比較を行います。
そのため、Dir関数に渡した引数のファイル名の部分をLike比較することで、パターン一致判定できます。

なお、LCase関数で文字列中のアルファベットを小文字に統一しています。
like比較するファイル名も小文字である必要があります。

 

Dir関数の使用例

Dir関数の使用例をいくつか紹介します。
コードは次のフォルダ構造での実行を想定しています。

c:\data <DIR>
    ┣ data1.txt
    ┣ data1-1.txt
    ┣ data2.txt
    ┣ data3.txt-old
    ┗ subdir <DIR>

例1:ファイルが存在するか確認

Dir(filename)の結果が "" ならファイルが存在しない、または隠しファイル、またはディレクトリです。
ファイルが存在するかの確認は、結果が "" でないかどうかを判定します。

' ファイルかどうかを確認するプロシージャ
Function isFile(filename) As Boolean
    isFile = Dir(filename) <> ""
End Function
' isFileのテスト
Sub DirSample1()
    Const filename As String = "C:\data\data1.txt"
    Const dirname As String = "C:\data\subdir"
    
    Dim result1 As Boolean
    Dim result2 As Boolean
    
    result1 = isFile(filename)
    result2 = isFile(dirname)
    
    MsgBox "ファイル確認:" & result1 & vbCrLf & "フォルダ確認:" & result2
End Sub

実行すると、次のようなメッセージが表示されます。

実行結果 ファイル確認:true フォルダ確認:false

例2:ファイルが存在するか確認(隠しファイル含む)

隠しファイルを含めてファイルの存在を確認するときは、Dir関数の第二引数に vbHidden を指定します。
前項のコードのDir関数を次のように変更します。

isFile = Dir(filename, vbHidden) <> ""

vbHiddenのみで通常ファイルと隠しファイルが確認されます。

例3:フォルダが存在するか確認

Dir関数の第二引数に vbDirectory を指定すると、ファイル(隠しファイル除く)またはフォルダが存在するとき "" 以外の結果になります。
結果にファイルを含まない時は、AND条件を使用します。

' ファイルが存在するかどうか確認するプロシージャ
Function isFolder(foldername) As Boolean
    isFolder = (Dir(foldername, vbDirectory) <> "" And Dir(foldername) = "")
End Function
' isFolderのテスト
Sub DirSample2()
    Const filename As String = "C:\data\data1.txt"
    Const dirname As String = "C:\data\subdir"
    
    Dim result1 As Boolean
    Dim result2 As Boolean
    
    result1 = isFolder(filename)
    result2 = isFolder(dirname)
    
    MsgBox "ファイル確認:" & result1 & vbCrLf & "フォルダ確認:" & result2
    
End Sub

実行すると、次のようなメッセージが表示されます。

実行結果 ファイル確認:false フォルダ確認:true

例4:ワイルドカードで一致するファイル名を取得

Dir関数はファイル名を一つだけ返します。
ワイルドカードでファイル名を指定すると、残りのファイルは引数なしのDir関数で取得できます。

' ワイルドカードで一致するファイルの名前を取得
Sub DirSample3()
    Const filename As String = "C:\data\data*.txt"
    
    Dim name As String
    Dim result As String
    
    name = Dir(filename)
    Do While name <> ""
        result = result & name & vbCrLf
        name = Dir()
    Loop
    MsgBox result
End Sub

今回はプロシージャ化していません。
プロシージャ化するなら配列で返したいのですが、そうするとあまり効率的でない処理になるからです。

実行すると、次のようなメッセージが表示されます。

実行結果 data1.txt data1-1.txt data2.txt data3.txt-old

少し結果がおかしいですね。
拡張子が一致しないものが含まれています。
原因と対象法は、こちら

例5:ファイルの属性ごとに処理をおこなう

ワイルドカードで取得したファイルに対して、属性別の処理をおこなう例です。

' ワイルドカードで一致するファイルの名前を取得
Sub DirSample3()
    Const filename = "*"
    Const dirname As String = "C:\data\"

    Dim name As String
    Dim attr As Long

    name = Dir(dirname & filename, vbDirectory + vbHiddenThen)
    Do While name <> ""
        attr = GetAttr(dirname & name)

        If (attr And vbHidden) = vbHiddenThen
             ' 隠しファイルの時の処理
        End If

        If (attr And vbDirectory) = vbDirectory Then
             ' フォルダの時の処理
        End If

        name = Dir()
    Loop

End Sub

GetAttr関数は、dir関数の第二引数で使用できる値と同じ値を返します。

更新日:2024/01/15

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。