63

I'm trying to parse a text document using VBA and return the path given in the text file. For example, the text file would look like:

*Blah blah instructions
*Blah blah instructions on line 2
G:\\Folder\...\data.xls
D:\\AnotherFolder\...\moredata.xls

I want the VBA to load 1 line at a time, and if it starts with a * then move to the next line (similar to that line being commented). For the lines with a file path, I want to write that path to cell, say A2 for the first path, B2 for the next, etc.

The main things I was hoping to have answered were:

  1. What is the best/simple way to read through a text file using VBA?
  2. How can I do that line by line?
John Smith
  • 7,243
  • 6
  • 49
  • 61
dancran
  • 721
  • 2
  • 9
  • 12

5 Answers5

80

for the most basic read of a text file, use open

example:

Dim FileNum As Integer
Dim DataLine As String

FileNum = FreeFile()
Open "Filename" For Input As #FileNum

While Not EOF(FileNum)
    Line Input #FileNum, DataLine ' read in data 1 line at a time
    ' decide what to do with dataline, 
    ' depending on what processing you need to do for each case
Wend

#Author note - Please stop adding in close #FileNum - it's addressed in the comments, and it's not needed as an improvement to this answer

SeanC
  • 15,695
  • 5
  • 45
  • 66
  • 10
    I'm a little late to the party, but Line Input has problems with anything other than strictly a CR or CRLF combination (i.e. LF on its own) - FSO has no such problems (but yeah, is probably a little bit slower) – Cor_Blimey Aug 20 '13 at 21:28
  • 27
    Remember Close #FileNum at the end! – Magnus Smith May 26 '14 at 11:15
  • 5
    For anyone else wondering: `DataLine` excludes the terminating `CR` or `CRLF` ([source](https://msdn.microsoft.com/en-us/library/aa243392%28v=vs.60%29.aspx)) – Felipe May 11 '15 at 15:35
  • ON ERROR is required. – NoChance Jul 15 '17 at 21:32
  • @NoChance, not if the file is just as expected, but programming styles were not what the question is about. – SeanC Jul 16 '17 at 13:14
  • um, from what I understand, it's a really bad idea to leave out the `CLOSE` command. – ashleedawg Jan 09 '19 at 23:17
  • depends. all files are closed on exit, but it's much better form to close the files when you expect them to be closed - saves trouble later. As @MagnusSmith mentioned this, I upvoted that comment rather than edit my answer – SeanC Jan 10 '19 at 05:20
52

I find the FileSystemObject with a TxtStream the easiest way to read files

Dim fso As FileSystemObject: Set fso = New FileSystemObject
Set txtStream = fso.OpenTextFile(filePath, ForReading, False)

Then with this txtStream object you have all sorts of tools which intellisense picks up (unlike using the FreeFile() method) so there is less guesswork. Plus you don' have to assign a FreeFile and hope it is actually still free since when you assigned it.

You can read a file like:

Do While Not txtStream.AtEndOfStream
    txtStream.ReadLine
Loop
txtStream.Close

NOTE: This requires a reference to Microsoft Scripting Runtime.

Robino
  • 4,530
  • 3
  • 37
  • 40
Brad
  • 11,934
  • 4
  • 45
  • 73
  • thanks for the reply Brad. I think this also will accomplish what I wanted just fine – dancran Jul 17 '12 at 21:29
  • 9
    Actually, without dimensioning `txtStream` as a `TextStream` object, there will be no intellisense – ElRudi Apr 22 '16 at 09:11
  • 1
    You can also do this without checking the Microsoft Scripting Runtime box by using `Set fso = CreateObject("Scripting.FileSystemObject")` instead of `Dim fso As FileSystemObject: Set fso = New FileSystemObject`, you just lose the intellisense – user7868 Apr 19 '23 at 05:10
40

For completeness; working with the data loaded into memory;

dim hf As integer: hf = freefile
dim lines() as string, i as long

open "c:\bla\bla.bla" for input as #hf
    lines = Split(input$(LOF(hf), #hf), vbnewline)
close #hf

for i = 0 to ubound(lines)
    debug.? "Line"; i; "="; lines(i)
next
Alex K.
  • 171,639
  • 30
  • 264
  • 288
2

You Can use this code to read line by line in text file and You could also check about the first character is "*" then you can leave that..

Public Sub Test()

    Dim ReadData as String

    Open "C:\satheesh\myfile\file.txt" For Input As #1

    Do Until EOF(1) 
       Line Input #1, ReadData 'Adding Line to read the whole line, not only first 128 positions
    If Not Left(ReadData, 1) = "*" then
       '' you can write the variable ReadData into the database or file
    End If 

    Loop

    Close #1

End Sub
GJK
  • 37,023
  • 8
  • 55
  • 74
satheesh kumar
  • 139
  • 1
  • 2
  • 8
-2

The below is my code from reading text file to excel file.

Sub openteatfile()
Dim i As Long, j As Long
Dim filepath As String
filepath = "C:\Users\TarunReddyNuthula\Desktop\sample.ctxt"
ThisWorkbook.Worksheets("Sheet4").Range("Al:L20").ClearContents
Open filepath For Input As #1
i = l
Do Until EOF(1)
Line Input #1, linefromfile
lineitems = Split(linefromfile, "|")
        For j = LBound(lineitems) To UBound(lineitems)
            ThisWorkbook.Worksheets("Sheet4").Cells(i, j + 1).value = lineitems(j)
        Next j
    i = i + 1 
Loop
Close #1
End Sub
Daniel L. VanDenBosch
  • 2,350
  • 4
  • 35
  • 60
Tarun Reddy
  • 2,123
  • 2
  • 11
  • 6