【问题标题】:How to quickly count the number of lines in multiple text files?如何快速统计多个文本文件的行数?
【发布时间】:2018-11-20 16:51:18
【问题描述】:

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


【解决方案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】:

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

    Do While fso.AtEndOfStream <> True
        fso.SkipLine
    Loop
    
    lines = fso.Line-1
    

    这样的事情不会更快吗?

    【讨论】:

    【解决方案3】:

    如何使用 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.32 秒)杀死=1.17 秒。 . . Open F For Binary Access Read As #1:ReDim...Get #1,,bytes
    Line Input/LineInput (4.44s) Kill=1.11s 。 . . Open F For Input As #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 . . .设置 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")

    【讨论】:

      【解决方案4】:

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

      这工作得很快。

      【讨论】:

        猜你喜欢
        • 2012-07-07
        • 1970-01-01
        • 2017-12-20
        • 1970-01-01
        • 2023-03-27
        • 2014-11-21
        • 2010-11-28
        • 2017-01-09
        相关资源
        最近更新 更多