2016年7月27日水曜日

ExcelVBAでファイルの一覧を取得する方法の速度を比較

Excelでファイルの一覧を取得する方法はいくつかあります。ソースのシンプルさを考えるとDir関数一択ですが、速度的にはどうなのか、試してみました。




比較用プログラム
Sub test()
path_ = "C:\a\b\"
準備 path_
Cells.Clear
計測 1, True
a path_
計測 1, False
計測 2, True
b path_
計測 2, False
計測 3, True
c path_
計測 3, False
End Sub
Sub 準備(path_)
Dim fs As Object, ws As Object
Set fs = CreateObject("Scripting.FileSystemObject")
For i = 1 To 1000000
fs.CreateTextFile(path_ & i).Close
Next
End Sub
Sub 計測(行, sw開始)
Dim 列
If sw開始 Then 列 = 2 Else 列 = 3
Cells(行, 列) = Time()
If sw開始 <> True Then Cells(行, 4).FormulaR1C1Local = "=second(R[0]C[-1]-R[0]C[-2])"
End Sub
Sub a(path_)
name_ = Dir(path_)
i = 1
Do While name_ <> ""
Cells(i, 1) = name_
i = i + 1
name_ = Dir()
Loop
End Sub
Sub b(path_)
Dim fs As Object, shell As Object
Set fs = CreateObject("Scripting.FileSystemObject")
Set shell = CreateObject("WScript.Shell")
pathTMP = fs.GetSpecialFolder(2) & "\" & fs.GetTempName()
shell.Run "cmd /C dir /A-D /B " & path_ & " > " & pathTMP, 0, True
Dim rs As Object
Set rs = fs.OpenTextFile(pathTMP)
arr = Split(rs.ReadAll, vbCr & vbLf)
rs.Close
len_ = UBound(arr)
For i = 0 To len_
Cells(i + 1, 1) = arr(i)
Next
End Sub
Sub c(path_)
Dim f As Object, cnt As Long
With CreateObject("Scripting.FileSystemObject")
For Each f In .GetFolder(path_).Files
cnt = cnt + 1
Cells(cnt, 1) = f.Name
Next f
End With
End Sub


結果
ファイル数:1000000
メディア:内蔵SSD

Dir関数 15秒
Dirコマンド 21秒
Filesコレクション 42秒


速度的にもDir関数で良いようですが、ScreenUpdatingをfalseにしたりCalculation = xlCalculationManualにしたりしなくても、ファイル数100万個で6秒程度の差しか出ないので速度での優位性はそんなに無さそうです。

0 件のコメント:

コメントを投稿