【VBA】Dir関数の使い方と使用例
更新日:2024/01/15
VBAのDir関数を使用するとファイルシステム上のファイルやフォルダを確認できます。
ここでは、Dir関数の使い方と使用例を5つ紹介します。
Dir関数の構文
Dir関数の構文は、次のようになっています。
Dir関数の構文
文字列 = Dir( pathname , attributes )
Dir関数は pathname と attributes に一致するファイルまたはフォルダで最初に一致したものから、親フォルダを取り除いた文字列を返します。
- pathname:
親フォルダを含んだファイルパス。
ワイルドカード( "*":複数文字一致 、 "?":一文字一致)を使用できる。 - attributes:
検索するファイルの属性を指定する。
省略可能。規定値vbNormal。属性値 値 意味 vbNormal 0 通常のファイル vbReadOnly 1 通常+読み取り専用ファイル vbHidden 2 通常+隠しファイル vbSystem 4 通常+システムファイル vbVolume 8 ボリューム ラベル vbDirectory 16 通常ファイル+フォルダ vbArchive 32 通常ファイル+アーカイブ 複数の属性を指定するときは、+演算子で連結します。
' 通常ファイルと隠しファイルとフォルダを取得 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
実行すると、次のようなメッセージが表示されます。
例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
実行すると、次のようなメッセージが表示されます。
例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
今回はプロシージャ化していません。
プロシージャ化するなら配列で返したいのですが、そうするとあまり効率的でない処理になるからです。
実行すると、次のようなメッセージが表示されます。
少し結果がおかしいですね。
拡張子が一致しないものが含まれています。
原因と対象法は、こちら。
例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
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。