如何快速统计多个文本文件的行数?

问题描述 投票:0回答:4

我有 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

如何获取最后一行的编号(来自文本文件)以避免逐行计数?

vba excel row counter
4个回答
12
投票

如何使用 VBA 计算文本文件中的行数:

最快的方法取决于您正在处理的文件的大小:

行数 文件大小
Open
声明
FileSystemObject
一个巨大的文件 170万 40mb × 1 ❌ 25.2 秒 ✔️ 2.1 秒
很多sᴍᴀʟʟ文件 6 14b × 10,000 ✔️ 1.3 秒 ❌ 18.9 秒
更适合 sᴍᴀʟʟ 文件 更适合文件

→ 更适合 small 文件:

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")


3
投票

试试这个功能。它使用

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

2
投票

另一种方法是使用 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"

这工作得非常快。


-1
投票

我不认为你可以只用一种方法来阅读最后一行。

Do While fso.AtEndOfStream <> True
    fso.SkipLine
Loop

lines = fso.Line-1

这样的事情不会更快吗?

© www.soinside.com 2019 - 2024. All rights reserved.