Как быстро посчитать количество строк в нескольких текстовых файлах? - PullRequest
0 голосов
/ 11 июня 2018

У меня есть более 100 текстовых файлов, и я должен посчитать строки для каждого из них.Column A указывает имя файла, расположенного в папке, указанной в E1.Несколько файлов имеют более 1 миллиона строк, что приводит к тому, что скрипт запускается ужасно долго.

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 голосов
/ 11 июня 2018

Альтернативным подходом было бы использование 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"

Это работает довольно быстро.

0 голосов
/ 11 июня 2018

Я не думаю, что вы можете прочитать последнюю строку только с помощью метода.

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

lines = fso.Line-1

что-то подобное не будет быстрее?

0 голосов
/ 11 июня 2018

Как подсчитать строки в текстовом файле с использованием VBA:

40 МБ файла (1,7 миллиона строк)
- CountLF = 25,2секунд
- CountLines = 2,1 секунды

14 файлов B (6 строк) x 10000 раз
- 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,32 с) Kill = 1,17 с.,,Открыть F для двоичного доступа Читайте как # 1: ReDim ... Get # 1,, байты
Линейный вход / LineInput (4,44 с) Kill = 1,11 с.,,Открыть F для ввода в виде #iFile ... Линейный вход # 1, st
Раннее связывание / повторное использованиеObj (5,25 с) Del = 1,12 с.,,Установите o = New Scripting.FileSystemObject ': st = o.OpenTextFile (F) .ReadAll ()
Раннее связывание / FreshObj (11,98 с) Del = 1,35 с.,,Установите o = New Scripting.FileSystemObject ': st = o.OpenTextFile (F) .ReadAll ()
LateBind / ReuseObj (6,25 с) Del = 1,47 с.,,Установите o = CreateObject ("Scripting.FileSystemObject")
LateBind / FreshObj (13,59 с) Del = 2,29 с.,,С CreateObject ("Scripting.FileSystemObject")

0 голосов
/ 11 июня 2018

Попробуйте эту функцию.Он использует 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
...