Как быстро подсчитать количество строк в нескольких текстовых файлах?

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

Как быстро подсчитать количество строк в нескольких текстовых файлах?

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

Как я могу получить номер последней строки (из текстового файла), чтобы избежать подсчета построчно?

Возможный дубликат EXCEL-VBA лучший способ найти последнюю строку

Samuel Hulla 11.06.2018 14:33

@Black Cornail: Нет, это вопрос о подсчете количества строк в текстовом файле.

FunThomas 11.06.2018 14:37

У вас уже есть: UBound(lines)

Patrick Honorez 11.06.2018 17:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
3
6 887
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

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

lines = fso.Line-1

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

Он по-прежнему читает каждую строку по очереди, в отличие от открытие всего файла сразу.

ashleedawg 11.06.2018 15:24
Ответ принят как подходящий

Как подсчитать строки в текстовом файле с помощью 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")

More Benchmarking: (2500 tiny text files)
Binary Access/Get (4.32s) Kill=1.17s . . . 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 . . . Set o=New Scripting.FileSystemObject':st=o.OpenTextFile(F).ReadAll()
LateBind/ReuseObj (6.25s) Del=1.47s . . . Set o=CreateObject("Scripting.FileSystemObject")
LateBind/FreshObj (13.59s) Del=2.29s . . . With CreateObject("Scripting.FileSystemObject")

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

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

Другие вопросы по теме