お世話になります。
VB6で指定フォルダ以下(サブフォルダ、複数階層も)にある
ファイル名を取得したいと思っています。
検索してみたところ、いろいろなやり方や抽出条件指定がありました。
単純に、簡単に、フルパスのファイル名を列挙する方法を教えてください。
以上、よろしくお願いいたします。
Dir 関数の場合、入れ子で呼び出す機能が無いので、階層を辿る場合には
少々工夫が必要になりますね(と言いつつ、私も Dir を使う事が多いですが)。
> 単純に、簡単に、
階層を再帰的に走査する場合には、FileSystemObject を使う事も
検討してみてください。高機能な分、Dir よりも若干低速ですが、その分、
取り扱いは Dir よりも簡単になるかと思います。単純かは別として。
> フルパスのファイル名を列挙する方法を教えてください。
別案として、DIR コマンドで列挙するとか。
Option Explicit
Private Sub Form_Load()
Text1.Text = "C:\Program Files\Microsoft Visual Studio\VB98"
Command1.Caption = "列挙"
End Sub
Private Sub Command1_Click()
Dim files() As String
files = GetFiles(Text1.Text)
'確認用
Dim v As Variant
For Each v In files
Debug.Print v
Next
End Sub
Public Function GetFiles(ByVal directory As String) As String()
Dim wk As String
wk = Environ("TMP") & "\" & Format(Now, "yyyyMMddhhmmss")
CreateObject("WScript.Shell").Run """" & Environ("COMSPEC") _
& """ /C DIR """ & directory & """ /S /B > """ & wk & """", _
vbNormalFocus, True
With CreateObject("Scripting.FileSystemObject").OpenTextFile(wk)
Dim s As String
If Not .AtEndOfLine Then s = .ReadAll()
GetFiles = Split(Left(s, Len(s & ":*") - 2), vbNewLine)
.Close
End With
Kill wk
End Function
オショウさん、魔界の仮面弁士さん、ありがとうございます。
> Dir 関数の場合、入れ子で呼び出す機能が無いので、階層を辿る場合には
> 少々工夫が必要になりますね(と言いつつ、私も Dir を使う事が多いですが)。
これが良く理解できなかったので、もっとスマートな方法がないかと思いました。
ご提示いただいたコードはスマートで機能実現できました。
FileSystemObjectについて調べて中身を理解してみたいと思います。
> FileSystemObjectについて調べて中身を理解してみたいと思います。
FileSystemObject 版のサンプルを提示しておきます。
Option Explicit
Private Sub Form_Load()
Text1.Text = "C:\Program Files\Microsoft Visual Studio\VB98"
Command1.Caption = "列挙"
End Sub
Private Sub Command1_Click()
Dim Files() As Variant
Files = GetFiles(Text1.Text, True)
'確認用
Dim v As Variant
For Each v In Files
Debug.Print v
Next
End Sub
Public Function GetFiles(ByVal directory As String, Optional includeDirName As Boolean = False) As Variant()
Dim Files As Object, FSO As Object
Set Files = CreateObject("Scripting.Dictionary")
Set FSO = CreateObject("Scripting.FileSystemObject")
With FSO.GetFolder(directory)
If includeDirName Then
'ディレクトリ名も出力
Files.Add Files.Count, .Path & IIf(.IsRootFolder, "", "\")
End If
Dim subItem As Object, fileName As Variant
'サブディレクトリを再帰
For Each subItem In .SubFolders
For Each fileName In GetFiles(subItem.Path, includeDirName)
Files.Add Files.Count, fileName
Next
Next
'直下のファイル群を列挙
For Each subItem In .Files
Files.Add Files.Count, subItem.Path
Next
End With
GetFiles = Files.Items()
End Function
>> Dir 関数の場合、入れ子で呼び出す機能が無いので、階層を辿る場合には
>> 少々工夫が必要になりますね(と言いつつ、私も Dir を使う事が多いですが)。
> これが良く理解できなかったので、もっとスマートな方法がないかと思いました。
Dir/Dir$ 関数バージョンです。
列挙中に、別のディレクトリを走査する事は出来ませんので、
列挙後に、別のディレクトリを走査するようにしています。
-----
Option Explicit
Private Sub Form_Load()
Text1.Text = "C:\Program Files\Microsoft Visual Studio\VB98"
Command1.Caption = "列挙"
End Sub
Private Sub Command1_Click()
Dim Files() As String
Files = GetFiles(Text1.Text, True)
'確認用
Dim v As Variant
For Each v In Files
Debug.Print v
Next
End Sub
Public Function GetFiles(ByVal directory As String, Optional includeDirName As Boolean = False) As String()
directory = directory & IIf(directory Like "*\", "", "\")
'下位要素を列挙する
Dim directories As Collection, Files As Collection
Set directories = New Collection
Set Files = New Collection
Dim dirName As String
dirName = Dir$(directory, vbDirectory Or vbSystem Or vbHidden Or vbReadOnly)
Do Until dirName = ""
If dirName <> "." And dirName <> ".." Then
If (GetAttr(directory & dirName) And vbDirectory) = vbDirectory Then
directories.Add directory & dirName
Else
Files.Add directory & dirName
End If
End If
dirName = Dir$()
Loop
Dim result As Object
Set result = CreateObject("Scripting.Dictionary")
If includeDirName Then
'ディレクトリ名も出力
result.Add result.Count, directory & IIf(directory Like "*\", "", "\")
End If
'このディレクトリのファイルを出力
Dim filePath As Variant
For Each filePath In Files
result.Add result.Count, filePath
Next
'列挙した下位ディレクトリに対して再帰
Dim dirPath As Variant
For Each dirPath In directories
For Each filePath In GetFiles(dirPath, includeDirName)
result.Add result.Count, filePath
Next
Next
'Variant 配列から String配列に変換
GetFiles = Split(Join(result.Items(), vbNullChar), vbNullChar)
End Function
魔界の仮面弁士さん、非常にわかりやすい
サンプルコードをありがとうございました。
また、何かあればよろしくお願いいたします。
本件、解決とさせていただきます。
ツイート | ![]() |