从 Excel VBA 中的大型文本文件中复制底行

Copy bottom rows from large text file in Excel VBA

我在网上搜索了 VBA 以下问题的解决方案,但无济于事。我的文本文件的数据范围在 3-5 百万行(这因文本文件而异),但我只需要提取最后 12 行实际数据并放入 Excel sheet , 最好用空格和制表符分隔。显然,我无法将文本文件直接加载到 Excel 中,行数限制为一百万左右,使用 DataTypes.Add 也没有任何好处。

有没有办法以分隔方式将最后几行数据导入 Excel?我的数据看起来像这样

来自文本文件:

Blah blah blah 东西我不需要 500 万行

第 5550203 行:

Line5550204: 这是这一段数据的标题

第 5550205 行:

Line5550206: 数据标题 1 数据标题 2 数据标题 3

第 5550207 行:

Line5550208: 数据单元 1 数据单元 2 数据单元 3

第 5550209 行:

第 5550210 行:数据 1 数据 2 数据 3

第 5550211 行:

Line5550212: 下一段数据的标题

第 5550213 行:

Line5550214:数据标题 1a 数据标题 2a 数据标题 3a

第 5550215 行:

Line5550216:数据单元 1a 数据单元 2a 数据单元 3a

第 5550217 行:

Line5550218:数据 1a 数据 2a 数据 3a

文件结束

显然,我不想导入空行,只导入数据。标题是可选的,我不需要单位。任何帮助或向我指出正确的方向将不胜感激。提前致谢!

这是一种方法:

Sub LastFewLines()
    
    Const BUFFER As Long = 15 'last how many lines
    
    Dim fso As Object, t, n As Long, ln, arr(0 To BUFFER), i As Long
    Set fso = CreateObject("scripting.filesystemobject")
    
    'create the dummy text file
'    Set t = fso.createtextfile("C:\Temp\dummy.txt")
'    For n = 1 To 4000000#
'        t.writeline "This is line " & n
'    Next n
'    t.Close

    Set t = fso.opentextfile("C:\Temp\dummy.txt", 1)
    
    n = 0
    Do While Not t.atendofstream
        ln = t.readline
        arr(n Mod BUFFER) = ln 'store lines, overwriting as we go
        n = n + 1
    Loop
    t.Close

    'read out last lines in correct order
    For i = (n - BUFFER) To n - 1
        Debug.Print arr(i Mod BUFFER)
    Next i
    
End Sub

出于速度原因,我们希望避免只读取整个文件才最终找到最后一行。

您可以使用seek-函数从文件的任何位置读取。然而,由于线条可能有不同的长度,我们不知道确切的位置。以下代码假定最大行长度并计算我们需要读取的最大字节数。这些字节被读入缓冲区,缓冲区被分成几行。现在我们可能需要很多行,但是很容易只得到最后 n 行:

Sub readfileTail(filename As String, Optional maxLines As Long = 12)

    Const maxLineLen = 256
    
    Dim f As Integer
    f = FreeFile
    Open filename For Binary As #f
    
    Dim fileLen As Long, filePos As Long
    fileLen = LOF(f)        ' Get size of file in bytes.
    filePos = fileLen - (maxLines * maxLineLen)
    
    Dim buffer As String
    Seek #f, filePos
    buffer = Input((maxLines * maxLineLen), #f) ' Read character.
    
    Dim lines() As String, i As Long, startline As Long
    lines = Split(buffer, vbCrLf)
        
    startline = UBound(lines) - maxLines + 1
    If startline < 0 Then startline = 0
    
    For i = startline To UBound(lines)
        Debug.Print i, lines(i)
    Next i
    Close #f
End Sub