100を超えるテキストファイルがあり、それぞれの行数を数える必要があります。 Column A
は、E1
で指定されたフォルダーにあるファイル名をリストします。いくつかのファイルには100万行を超える行があり、スクリプトの実行に非常に長い時間がかかります。
Sub counter()
Dim fso As New FileSystemObject
Dim ts As TextStream
Dim longtext As String
Dim lines As Variant
Dim GoToNum As Integer
Dim Start As Integer
GoToNum = 2
Start = 3
Do Until IsEmpty(Cells(Start, 1))
GoToNum = GoToNum + 1
Start = Start + 1
Loop
For i = 3 To GoToNum
If Cells(i, 2).Value <= Cells(2, 5).Value Then
ConOrg = Cells(1, 4).Value & "\" & Cells(i, 1).Value
Set ts = fso.OpenTextFile(ConOrg, ForReading, False)
longtext = ts.ReadAll
ts.Close
lines = Split(longtext, vbLf)
Cells(i, 3) = UBound(lines) - LBound(lines) - 1
End If
Next i
End Sub
行ごとにカウントされないように、最後の行の番号(をテキストファイルから)を取得するにはどうすればよいですか?
40 MBファイル(170万行)
-CountLF
= 25.2秒
-CountLines
= 2.1秒
14 Bファイル(6行)x 10,000回
-CountLF
= 1.3秒
-CountLines
= 18.9秒
Function countLF(fName As String) As Long
Dim st As String
Open fName For Input As #1: st = Input(LOF(1), 1): Close #1
countLF = Len(st) - Len(Replace(st, vbLf, "")) + 1
End Function
使用例:
Debug.Print countLF("c:\test.txt")
Function countLines(fName As String) As Long
countLines = CreateObject("Scripting.FileSystemObject").OpenTextFile(fName, 8, True).Line
End Function
使用例:
Debug.Print countLines("c:\test.txt")
その他のベンチマーク:(2500個の小さなテキストファイル)
Binary Access/Get(4.32s)Kill = 1.17s。 。 。バイナリアクセス用にFを開く#1:ReDimとして読み取る...#1 , bytesを取得する
Line Input/LineInput(4.44s)Kill = 1.11s。 。 。入力としてFを開く#iFile ... Line Input#1、st
Early Bind/ReuseObj(5.25s)Del = 1.12s。 。 。 Set o = New Scripting.FileSystemObject ':st = o.OpenTextFile(F).ReadAll()
Early Bind/FreshObj(11.98s)Del = 1.35s。 。 。 Set o = New Scripting.FileSystemObject ':st = o.OpenTextFile(F).ReadAll()
LateBind/ReuseObj(6.25s)Del = 1.47s。 。 。 Set o = CreateObject( "Scripting.FileSystemObject")
LateBind/FreshObj(13.59s)Del = 2.29s。 。 。 CreateObject( "Scripting.FileSystemObject")を使用
この関数を試してみてください。 FileSystemObject
を使用します。ファイル全体を読み取って1行に分割するよりも高速である必要があります。からインスピレーションを受けた Hey、Scripting guy
Function countLines(fName As String) As Long
Const ForReading = 1
Dim objFSO As Object, objTextFile As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile(fName, ForReading)
objTextFile.ReadAll
countLines = objTextFile.Line
End Function
別のアプローチは、Power Query(Get&Transform Data)を使用することです。
let
Source = Folder.Files("C:\Users\me\MyFolder"),
#"Filtered Rows" = Table.SelectRows(Source, each [Extension] = ".txt"),
#"Added Row Count" = Table.AddColumn(#"Filtered Rows", "Rows In File", each Table.RowCount(Table.FromColumns({Lines.FromBinary([Content])})), Int64.Type),
#"Removed Columns" = Table.SelectColumns(#"Added Row Count",{"Name", "Rows In File"})
in
#"Removed Columns"
これはかなり高速に動作します。