Dir関数を使用して特定のフォルダに保存されているファイルの一覧の取得、特定のファイルの一覧の取得、フォルダ内のcsvファイル等のテキストファイルを1ファイルずつ読み込んで特定の処理をするなど、Dir関数を使用したサンプルプログラムを覚書。
Dir関数はかなり古いバージョンから用意されていてやり方としては古いかもしれないけれど、たくさんあるcsvファイルのデータを読み込んでAccessのデータベースのテーブルに追加するプログラムとかを今でもよく書いたりします。
意外にもDir関数を中心としたサンプルプログラムの覚書がなかったりするので覚書きしておく。
他の記事のサンプルプログラムで使われていてちょいちょい出てきてはいるんだけれど、Dir関数を中心とした記事はなかったりします。
サンプルプログラムは、全てExcelで作っているけれど、AccessのVBAでも同じように使えます。
Dir関数の概要
Dir関数は、ファイルが存在するかどうかのチェック(検索)をしてくれる関数で、対象が存在すると対象のフィル名を返してくれます。
例えば、指定したフォルダに拡張子が".exe"のファイルがあるかどうかチェックするだけであれば、以下の様なプログラムになります。
拡張子が".exe"のファイルが存在するかどうかチェックするサンプルプログラム
Sub example_dir01()
Dim strFileName As String
'C:¥Windowsフォルダに拡張子が.exeのファイルがあるか
strFileName = Dir("c:¥windows¥*.exe")
'見つかったファイルをメッセージボックスで表示
MsgBox strFileName
End Sub
もし複数".exe"を拡張子に持つファイルが複数あったとしてもDir関数が返してくるのは最初に見つかった1つのファイルだけです。
ファイルが存在しない場合、Dir関数は長さ 0 の文字列 ("") が返します。
つまり、Dir関数の戻り値が""だった場合、ファイルが存在しないことになるので、指定したファイルがあるかどうかをチェックする場合以下の様なプログラムになります。
Sub example_dir02()
Dim strFileName As String
'C:¥Windowsフォルダにhogehoge.txtというファイルがあるか
strFileName = Dir("c:¥windows¥hogehoge.txt")
If strFileName = "" Then
MsgBox "ファイルがありません。"
Else
MsgBox strFileName & "が見つかりました。"
End If
End Sub
Dir関数を使って複数のファイルを処理する
Dir関数を使って複数のファイルを扱うサンプルプログラムです。
指定したフォルダに拡張子".exe"のファイルのファイル数を数えるサンプルプログラム
Sub example_dir03()
Dim strFileName As String, Counter As Integer
'C:¥Windowsフォルダに*.exeファイルがあるか
strFileName = Dir("c:¥windows¥*.exe")
'ファイル数を数える変数Counterを0で初期化
Counter = 0
'拡張子.exeのファイルが見つからなくなるまで繰り返し
'実行させるためにDo Until(指定した条件まで繰り返す)を使う
Do Until strFileName = ""
'ファイルが見つかるたびに1加算
Counter = Counter + 1
'同じ条件で次のファイル(.exe)を探す
strFileName = Dir()
Loop
MsgBox "ファイルの数は" & Counter & "個です。"
End Sub
このサンプルプログラムのポイントですが、まずDo Untilループを使用しているところになります。
Do Untilは、指定した条件が成立するまでDo~Loopの中の処理を繰り返し実行する命令になります。
Dir関数はファイルが見つからなくなると長さ0の文字列、すなわち""を返しますので、Dir関数によって返された値が代入されている変数 StrFileName の値が""になるまで処理を繰り返すようになっています。
Do~Loopの中では、ファイルが見つかるたびにCounter変数に1が加算されるようになっています。
もう一つ重要なポイントとして、"strFileName = Dir()"の部分です。
これは、Dir関数に最初に指定した条件と同じ条件でファイルの有無をチェックさせることを意味しています。
当然最初に見つかったファイルは除外されますので、最初に見つかったファイル以外に".exe"ファイルがあればそのファイル名を、なければ長さ0の文字列""を返します。
ちなみに、最初のDir関数の条件を*.*にすると全てのファイルが対象になるので、C:\Windowsフォルダに保存されている全ファイルの数がカウントされます。
ただし、非常に残念ですがサブフォルダの中までは見てくれません。
ファイルの属性を指定してファイルを検索する方法
Dir関数の第2引数に特定の値を指定することでファイルの属性を条件にすることができます。
Dir関数に指定できるオプション値は以下のとおりです。
定数 | 値 | 説明 |
---|---|---|
vbNormal | 0 | (既定値) 属性のないファイル。 |
vbReadOnly | 1 | 属性のないファイルと読み取り専用のファイル。 |
vbHidden | 2 | 属性のないファイルと隠しファイル。 |
VbSystem | 4 | 属性のないファイルとシステム ファイル。Macintosh では使用できません。 |
vbVolume | 8 | ボリューム ラベル。他の属性を指定した場合は、vbVolume?は無視されます。Macintosh では使用できません。 |
vbDirectory | 16 | 属性のないファイルとディレクトリまたはフォルダー。 |
vbAlias | 64 | 指定したファイル名がエイリアスとして設定されているファイル。Macintosh でのみ使用できます。 |
Dir関数の第2引数にこれらの名前付き引数(定数)もしくは、指定されている数値を使用することで指定した条件に当てはまるファイルを検索することができます。
Dir関数を使用する際の注意点です。
- ファイル名は特定の順序で取得されるわけではありません。
- Dir関数により返されるファイル名は、ファイル名の昇順や新しい順など、特定の条件によって並び替えられた順で返すわけではありません。
- Dir関数で指定したファイルにサブフォルダが存在する場合でもそのサブフォルダ内は対象とはなりません。
Dir関数を使用したサンプルプログラム応用編
Dir関数を使用して特定の条件に合致した複数のファイルに対して1ファイルずつ同じ処理を実行させることができます。
以下のVBAのサンプルプログラムは、Dir関数を使用して指定したフォルダ内にあるcsv形式(*.csv)を探して、存在したらそのcsvファイルの中身をExcelのセルに展開するというDir関数を利用した応用プログラムです。
このプログラムを動作させると見つかった全てのcsvファイルデータがExcelのシートにどんどん追記されていきます。
Sub Sample_Dir04()
Dim strFileName As String, FNo As Long, strLineText As String
Dim strPath As String, strTextArr
Dim i As Integer, strRngAddress As String
ThisWorkbook.Worksheets("Sheet1").Range("a1").Select
'Dir関数でファイルを探すフォルダのパス
strPath = "c:¥temp¥"
'C:¥temp¥*.csvに該当するすべてのファイルを対処として以降の処理
'を繰り返し実行する
strFileName = Dir(strPath & "*.csv")
Do Until strFileName = ""
FNo = FreeFile
'Dir関数で見つかったファイルを開く
Open strPath & strFileName For Input As #FNo
'ファイルの終端まで(EOF)データを1行ずつ取り出す
Do Until EOF(FNo)
Line Input #FNo, strLineText
'取り出したカンマで区切られた行のデータを配列に代入する
strTextArr = Split(strLineText, ",")
'データを貼り付ける直前のアクティブセルのアドレスを取っておく
strRngAddress = ActiveCell.Address
'配列に入っているデータを1つずつセルに代入していく
For i = 0 To UBound(strTextArr)
ActiveCell.Value = strTextArr(i)
ActiveCell.Offset(0, 1).Select
Next i
'アクティブセルを1行下に移動する。
Range(strRngAddress).Offset(1, 0).Select
Loop
'ファイルを閉じる
Close #FNo
'条件に該当する次のファイルを探す
strFileName = Dir()
Loop
End Sub
VBAのDir関数を使用したサンプルプログラムまとめ
1つの特定のフォルダ内の複数のファイルから条件に合致したファイルのファイル名を取得する場合にはDir関数を使うほうがシンプルで良いと思いますが、基本的に処理速度は遅いです。
サブフォルダも含めて条件に合致したファイルを探す場合や速度を求めるならDir関数では難しくなるので、FileSearchオブジェクトを使用するなど、別の方法をおすすめします。
業務上、膨大な数のcsvファイルから一行ずつデータを取り出して処理をする場合が結構あって、よく使うプログラムの1つです。
フォルダ選択に[ファイルを開く]ダイアログボックスを使用してもっと使いやすくしたりすると更によいかもしれません。
コメント