如何读取文本文件中的第二行

我想在VBA中读取一个大文件,并在线看到这个代码:

Dim MyChar As String, Pointer As Long, LastLine As String Open "MyTextFile.Txt" For Binary As #1 Pointer = LOF(1) - 2 MyChar = Chr$(32) Do Get #1, Pointer, MyChar If MyChar = vbCr Or MyChar = vbLf Then Exit Do Else: Pointer = Pointer - 1 LastLine = MyChar & LastLine End If Loop MsgBox "Last Line is " & LastLine 

如何更改此代码以获得第二个最后一行? 需要一些帮助。

想到这个:

 Set objFSO = CreateObject("Scripting.FileSystemObject") Set objTextFile = objFSO.OpenTextFile _ "MyTextFile.Txt", 1) objTextFile.ReadAll MsgBox objTextFile.Line 

但我不能走到第二线。

取决于你的方法。 但是,如果文件真的很大,那么你可能不希望Excel加载整个文件。 所以,你可能会打开文件并逐行阅读,而不知道文件有多大,有多less行。 在这种情况下,最简单的做法是将两行一次存储在两个单独的stringvariables中。 只要你打到最后一行,你可以退出你的循环 – 如上面的代码所示 – 不仅输出最后一行(如代码中已经完成的那样),而且还输出该文件中倒数第二行的内容。

 Public Sub GetSecondLastRow() Dim strSecondLastLine As String Dim strFileToImport As String Dim strLastLine As String Dim intPointer As Integer Dim lngCounter As Long strFileToImport = ThisWorkbook.Path & IIf(InStr(1, ThisWorkbook.Path, "\") > 0, "\", "/") & "MyTextFile.txt" intPointer = FreeFile() Open strFileToImport For Input Access Read Lock Read As #intPointer lngCounter = 0 Do Until EOF(lngCounter) strSecondLastLine = strLastLine Line Input #intPointer, strLastLine lngCounter = lngCounter + 1 Loop Close intPointer Debug.Print "Content of the second last row:" Debug.Print "---------------------------------------" Debug.Print strSecondLastLine Debug.Print "---------------------------------------" Debug.Print "Content of the last row:" Debug.Print "---------------------------------------" Debug.Print strLastLine End Sub 

另一种方法是首先查询文件的行数,然后使用ADO获取该文件中的第二个logging。 但我怀疑这会更快。 ADO的问题是你得到一个巨大的recordset包含整个文本文件。 这是由于你在SELECT * from MyTextFile.txt子句中没有限制。 所以,整个文本文件进入内存之前,你可以做任何事情。 然后 – 当然,您可以检查RecordCount并通过光标快速前进的所有logging重新进行操作,直至find最后一行。 不幸的是,ADO不支持

row_number()over(按@@ ROWCOUNTsorting)。

否则,您可以首先select count(1) from MyTextFile.txt获取select count(1) from MyTextFile.txt的行数,然后再获取适用的行。

所以,无论如何,我几乎可以肯定(没有经过testing)ADO的performance将低于标准,而第一个解决scheme就是如果文本文件大小如你所说的那样。 如果你仍然喜欢ADO,那么这是代码(基于以下问题/答案: 复制文本从.txt文件在Excel中使用ADO忽略第一行 )。

  Sub ImportTextFile() 'Imports text file into Excel workbook using ADO. 'If the number of records exceeds 65536 then it splits it over more than one sheet. Dim strFilePath As String, strFilename As String, strFullPath As String Dim lngCounter As Long Dim oConn As ADODB.Connection Dim oRS As ADODB.Recordset Dim oFSObj As Object 'Get a text file name strFullPath = Application.GetOpenFilename("Text Files (*.txt),*.txt", , "Please select text file...") If strFullPath = "False" Then Exit Sub 'User pressed Cancel on the open file dialog 'This gives us a full path name eg C:\temp\folder\file.txt 'We need to split this into path and file name Set oFSObj = CreateObject("SCRIPTING.FILESYSTEMOBJECT") strFilePath = oFSObj.GetFile(strFullPath).ParentFolder.Path strFilename = oFSObj.GetFile(strFullPath).Name 'Open an ADO connection to the folder specified Set oConn = New ADODB.Connection oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & strFilePath & ";" & _ "Extended Properties=""text;HDR=No;FMT=Delimited""" Set oRS = New ADODB.Recordset 'Now actually open the text file and import into Excel oRS.Open "SELECT count(1) FROM [" & strFilename & "]", oConn, 3, 1, 1 Range("A1").CopyFromRecordset oRS Set oRS = New ADODB.Recordset 'Now actually open the text file and import into Excel oRS.Open "SELECT * FROM [" & strFilename & "]", oConn, 3, 1, 1 While Not oRS.EOF And Not oRS.BOF If oRS.AbsolutePosition = Range("A1").Value2 Then Range("A2").Value = oRS.Fields(0).Value End If oRS.MoveNext Wend oRS.Close oConn.Close End Sub 

你提供的代码工作如下:

  1. 它设置一个指向文件最后一个字符的指针
  2. 然后向后读取该文件,直到find换行符
  3. 它将所有读取的内容作为最后一行返回。

为了对你的需要进行修改,我添加了一个Boolean secondRun ,它让代码再次运行第2步,从而logging第2行:

 Dim MyChar As String, Pointer As Long, LastLine As String Open "MyTextFile.Txt" For Binary As #1 Pointer = LOF(1) - 2 MyChar = Chr$(32) Dim secondRun As Boolean Do ' Read character at position "Pointer" into variable "MyChar" Get #1, Pointer, MyChar If MyChar = vbCr Or MyChar = vbLf Then ' Linebreak = line read completely If Not secondRun Then ' Run again if we've read only one line so far secondRun = True LastLine = "" Pointer = Pointer - 2 Else Exit Do End If Else: Pointer = Pointer - 1 ' Add character to result String LastLine = MyChar & LastLine End If Loop MsgBox " 2nd last line is " & LastLine 

你可以试试这个:

 Public Function GetSecondLastLine(sFileName As String, Optional sLineDelimiter As String = vbCrLf) As String Dim sContent As String Dim aLines() As String sContent = TextFromFile(sFileName) aLines = Split(sContent, sLineDelimiter) GetSecondLastLine = aLines(UBound(aLines) - 1) End Function Public Function TextFromFile(sFileName As String) As String Dim lFile As Long lFile = FreeFile Open sFileName For Input As #lFile TextFromFile = Input$(LOF(lFile), lFile) Close #lFile End Function 

如有必要,您可以更改行分隔符(例如vbLF的vbCR)