У меня более 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
Как я могу получить номер последней строки (из текстового файла), чтобы избежать подсчета построчно?
@Black Cornail: Нет, это вопрос о подсчете количества строк в текстовом файле.
У вас уже есть: UBound(lines)





Попробуйте эту функцию. Он использует 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
что-то подобное не было бы быстрее?
Он по-прежнему читает каждую строку по очереди, в отличие от открытие всего файла сразу.
Файл 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"
Это работает довольно быстро.
Возможный дубликат EXCEL-VBA лучший способ найти последнюю строку