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

时间:2018-06-11 12:24:19

标签: excel vba excel-vba row counter

我有超过100个文本文件,我必须计算每个文件的行数。 Column A列出文件名,位于E1中指定的文件夹中。有几个文件有超过100万行,导致脚本运行的时间非常长。

screenshot

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

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

4 个答案:

答案 0 :(得分:6)

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

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个小文本文件)
二进制访问/获取(4.32s)Kill = 1.17s。 。 。打开F进行二进制访问读取为#1:ReDim ...获取#1 ,,, bytes
线路输入/线路输入(4.44s)Kill = 1.11s。 。 。打开F输入为#iFile ...行输入#1,st
Early Bind / ReuseObj (5.25s)Del = 1.12s。 。 。设置o = New Scripting.FileSystemObject&#39;:st = o.OpenTextFile(F).ReadAll()
Early Bind / FreshObj (11.98s)Del = 1.35s。 。 。设置o = New Scripting.FileSystemObject&#39;:st = o.OpenTextFile(F).ReadAll()
LateBind / ReuseObj (6.25s)Del = 1.47s。 。 。设置o = CreateObject(&#34; Scripting.FileSystemObject&#34;)
LateBind / FreshObj (13.59s)Del = 2.29s。 。 。使用CreateObject(&#34; Scripting.FileSystemObject&#34;)

答案 1 :(得分:1)

尝试使用此功能。它使用FileSystemObject。应该比读取整个文件更快并将其拆分为单行。灵感来自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

答案 2 :(得分:1)

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

这非常快。

答案 3 :(得分:-1)

我认为你不能用一种方法阅读最后一行。

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

lines = fso.Line-1

这样的事情会不会更快?