一行のコードで終わらせる ②-1 指定フォルダ内のファイルパス取得
昨日は、特定列の空白セルを行ごと削除するマクロについて紹介した。
infoment.hatenablog.com
今日は指定フォルダ内にある全ファイルの、ファイルパス取得について紹介する。
例えば「C:\Temp」フォルダに、以下4つのファイルがあるとする。
Dir関数で取得
このようなケースで私が最初に学んだのは、Dir関数を用いた方法だった。
Dir 関数 (Visual Basic for Applications) | Microsoft Docs
例えば、こんな感じだ。ユーザー定義関数で、ファイルパスを配列に格納する。
Function GetFilePathes(folder_path As String) As Variant Dim FileName As String ' 指定パスの最初にあるファイルについて、 ' Dir関数でファイル名を取得する。 FileName = Dir(folder_path & "\*.*") ' 取得したファイルパス格納用コレクション。 Dim TempCol As Collection Set TempCol = New Collection ' 指定フォルダ内の全てのファイル(※)について、 ' ファイルパスをコレクションに格納する。 ' ※サブフォルダ下のファイルを除く。 Do While FileName <> "" TempCol.Add folder_path & "\" & FileName FileName = Dir Loop ' 空っぽのフォルダだった場合、空配列を返して終了。 If TempCol.Count = 0 Then GetFilePathes = Array() Exit Function End If ' コレクションを配列に変換する。 Dim TempSeq() As Variant ReDim TempSeq(1 To TempCol.Count) Dim i As Long: i = 1 Dim c As Variant For Each c In TempCol TempSeq(i) = c i = i + 1 Next GetFilePathes = TempSeq End Function
こちらのマクロでテストしてみよう。
Sub hogeTest() Dim seq As Variant seq = GetFilePathes("C:\Temp") End Sub
結果、ファイルパスを取得することが出来た。
FileSystemObject で取得
次に学んだのは、FileSystemObjectだった。
FileSystemObject オブジェクト
例えば、こんな感じだ。※事前にMicrosoft Scripting Runtimeを参照設定済み。
Function GetFilePathes(folder_path As String) As Variant ' FileSystemObject用変数の宣言と初期化。 Dim FSO As FileSystemObject Set FSO = New FileSystemObject ' ファイルが存在しない場合、空配列を返す。 Dim iMax As Long iMax = FSO.GetFolder(folder_path).Files.Count If iMax = 0 Then GetFilePathes = Array() Exit Function End If ' 指定フォルダ内の全ファイルパスを、配列に格納する。 ' ※サブフォルダ下のファイルを除く。 Dim i As Long: i = 1 Dim TempSeq() As Variant ReDim TempSeq(1 To iMax) Dim myFile As File For Each myFile In FSO.GetFolder(folder_path).Files TempSeq(i) = myFile.Path i = i + 1 Next GetFilePathes = TempSeq End Function
Dir関数が高速でお手軽である一方、FileSystemObjectは遅いが高機能、ということらしい。個人的には、FileSystemObjectの方が好みだ。
3番目の方法
主に今までの二つを用いつつ、新たなファイル検索の方法を探していた私はつい先日、以下のコードに出会ってしまった。
Function Function_FileList(FolderLocation As String) Function_FileList = Filter(Split(CreateObject("wscript.shell").exec("cmd /c Dir """ & FolderLocation & """ /b /a-d").stdout.readall, vbCrLf), ".") End Function
出典は↓ こちら。
stackoverrun.com
グルグルとループさせることなく、一行で、一撃で処理を完了させている。衝撃だった。全てのケースに適用できる訳では無いようだが、それでも凄いと思った。
それにしても、この一行で、一体何をやっているんだろう?慣れた人には馴染み深いものばかりなのだろうが、私の場合、初めて見るものが幾つもある。
そこで明日は、勉強のために、これを読み解くことに挑戦してみます。
参考まで。