我有 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
如何获取最后一行的编号(来自文本文件)以避免逐行计数?
最快的方法取决于您正在处理的文件的大小:
行数 | 文件大小 | 声明 |
|
|
---|---|---|---|---|
一个巨大的文件 | 170万 | 40mb × 1 | ❌ 25.2 秒 | ✔️ 2.1 秒 |
很多sᴍᴀʟʟ文件 | 6 | 14b × 10,000 | ✔️ 1.3 秒 | ❌ 18.9 秒 |
更适合 sᴍᴀʟʟ 文件 | 更适合大文件 |
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 `For Binary Access Read As #1:ReDim...Get #1,,bytes
线路输入/LineInput (4.44s) Kill=1.11s . . . Open F For Input As #iFile...Line Input #1,st
Early Bind/ReuseObj (5.25s) Del=1.12s 。 . .设置 o=New Scripting.FileSystemObject':st=o.OpenTextFile(F).ReadAll()
早期绑定/FreshObj (11.98s) Del=1.35s 。 . .设置 o=New Scripting.FileSystemObject':st=o.OpenTextFile(F).ReadAll()
LateBind/ReuseObj (6.25s) Del=1.47s 。 . .设置 o=CreateObject("Scripting.FileSystemObject")
LateBind/FreshObj (13.59s) Del=2.29s 。 . .使用 CreateObject("Scripting.FileSystemObject")
试试这个功能。它使用
FileSystemObject
。应该比读取整个文件并将其分成单行更快。灵感来自嘿,脚本专家
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(获取和转换数据):
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"
这工作得非常快。
我不认为你可以只用一种方法来阅读最后一行。
Do While fso.AtEndOfStream <> True
fso.SkipLine
Loop
lines = fso.Line-1
这样的事情不会更快吗?