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:
What is the best/simple way to read through a text file using VBA?
How can I do that line by line?
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
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.
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
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
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
Related
I have the following macro that is should write new data onto a new line in a text/csv file, however it overwriting the existing text in the file, I thought that write wrote to a new line as opposed to print. I am not sure what I am doing wrong
Sub picking()
Range("d14").NumberFormat = "mm/dd/yyyy"
Range("d14").Value = Now
Range("e14").NumberFormat = "hh:mm"
Range("e14").Value = Now
Range("e17").Value = "Picking"
Call outputcsv
End Sub
Sub outputcsv()
Dim Fullpath As String
Dim outputstring As String
Fullpath = Worksheets("Maintence").Range("c5")
Open Fullpath For Output As #1
outputstring = Worksheets("CSV").Range("A1")
Write #1, outputstring
Close #1
End Sub
You just need to change...
Open Fullpath For Output As #1
...to...
Open Fullpath For Append As #1
Note that "Output" changes to "Append."
Also note that "Append" will create the file - just as Output does - if it doesn't already exist. No need to pre-create it.
I am trying to read a text file of numbers into excel VBA and the code keeps reading everything in all at once, not line by line.
With this code, a regular test file (test.txt) reads line by line whereas the file I want (TJS-3_43874_Generated_TLE.txt) does not. I can cut the individual lines of TJS-3_43874_Generated_TLE.txt into a clean text file, line by line, and it will read properly but I have a large list of files and this isn't a great use of time. Is there a hidden character or something I'm missing?
I am hoping someone can shed light on what I'm doing wrong. Thanks!
This is the format of basically every code I have read:
Sub testread()
Dim myFile As String, text As String, textline As String, posLat As Integer, posLong As Integer
myFile = "C:\Users\TJS-3_43874_Generated_TLE.txt"
'myFile = "C:\Users\test.txt"
Open myFile For Input As #1
Do Until EOF(1)
Line Input #1, textline
text = text & textline
Loop
Close #1
End Sub
test.txt
Some information here..
latitude: 72n31
longitude: 15w27
Some information here..
TJS-3_43874_Generated_TLE.txt
1 43874U 18110A 20124.62500000 .00000092 00000-0 34605-0 0 00001
2 43874 000.0554 290.8570 0002993 254.0264 075.0858 01.00270444005065
Line Input # looks for either a Chr(13) character or a Chr(13)Chr(10) sequence to identify where one line stops and the next line starts. Some operating systems or programs generate files which only use Chr(10) to separate each line and Line Input # will read the contents of those files into one long line.
To check if this is the case for your file, try:
Line Input #1, textline
If InStr(textline, Chr$(10)) > 0 Then
MsgBox "Line contains embedded Chr(10) characters"
End If
Assuming that there are indeed embedded Chr(10) characters, then we can split textline into an array to recover the individual lines:
Dim sLines() As String
Dim vLine As Variant
sLines = Split(textline, Chr$(10))
For Each vLine In sLines
MsgBox vLine
Next vLine
Note that vLine had to be a Variant to be used in the For Each...Next loop. Replace the MsgBox vLine part with whatever processing you need to perform on each line
When reading a text file in VBA, the newlines are stripped on each line. When saving the line, append vbCrLf.
Try this code:
Sub testread()
Dim myFile As String, text As String, textline As String, posLat As Integer, posLong As Integer
myFile = "C:\Users\TJS-3_43874_Generated_TLE.txt"
'myFile = "C:\Users\test.txt"
Open myFile For Input As #1
Do Until EOF(1)
Line Input #1, textline
Debug.Print textline
text = text & textline & vbCrLf
Loop
Debug.Print text
Close #1
End Sub
I need help in modifying the CSV file using VBA. I did research and came up with this solution. However, I can't get the expected output. So, for example, I have a CSV file:
ProductID,ProductName,SupplierName,CategoryID,Unit,Price
,,,,,
1,Chais,John Ray,1,10 boxes x 20 bags,18.00093483
2,Chang,Michael,1,24 - 12 oz bottles,19.66890343
I want to change all the values under the productname and suppliername. And change something like the combination of ProductID and the Column Name. My expected output should look like:
ProductID,ProductName,SupplierName,CategoryID,Unit,Price
,,,,,
1,1 ProductName,1 SupplierName,1,10 boxes x 20 bags,18.00093483
2,2 ProductName,2 SupplierName,1,24 - 12 oz bottles,19.66890343
It can occur multiple times and can change the column location. This is my code:
Sub test()
Dim FilePath As String, LineFromFile As Variant, LineItems() As String, strFile As Variant
FilePath = "C:\Users\mestrivo\Documents\Files\MyFirstProg\test.csv"
Open FilePath For Input As #1
Do Until EOF(1)
Line Input #1, LineFromFile
LinteItems = Split(LineFromFile, ",")
LineItems(1) = LineItems(0) & " ProductName"
LineItems(2) = LineItems(0) & " SupplierName"
strFile = Join(LineItems, ",")
Loop
Open "C:\Users\mestrivo\Documents\Files\MyFirstProg\test - 2.csv" For Output As #1
Print #1, strFile
Close #1
End Sub
Please help me check my code. I got an error on this part:
Open "C:\Users\mestrivo\Documents\Files\MyFirstProg\test - 2.csv" For Output As #1
it says that the file is already open.
NEVER hard-code file handles, they aren't for you to grab, they're for VBA to query what's available and give you a free, usable file handle. Use the FreeFile function to do this.
Dim fileHandle As Long
fileHandle = FreeFile
Then replace all hard-coded #1 handles with #fileHandle.
You cannot open two different files using the same handle. You've already opened the file for input:
Open FilePath For Input As #1
So when you try to use the same handle for output...
Open "C:\Users\mestrivo\Documents\Files\MyFirstProg\test - 2.csv" For Output As #1
That's when you get an error; you haven't closed the #1 handle yet, and now you're trying to reuse it to open another file - you can't do that.
You're dealing with two files, so either you open the first one, read it, then close it before you open the second one, write to it and then close it - or, you open both, and write to one as you read the other, then close both.
Either way, you shouldn't hard-code file handles. Use FreeFile to get a free file handle. Always.
Try this:
Sub test()
Dim FilePath As String, LineFromFile As Variant, _
LineItems() As String, strFile As Variant
FilePath = "mycsv.csv"
Open FilePath For Input As #1
Do Until EOF(1)
Line Input #1, LineFromFile
LineItems() = Split(LineFromFile, ",")
'I suggest to add the following 'If' statements
If LineItems(0) <> "" Then
LineItems(1) = LineItems(0) & " ProductName"
LineItems(2) = LineItems(0) & " SupplierName"
End If
If strFile <> "" Then strFile = strFile & Chr(10)
'-------------------------------------------------
strFile = strFile & Join(LineItems, ",")
Loop
'In the next 'Open' statement you are trying to
'assign an object over another that's already opened,
'therefore you must close the previous object first
'and / or declare the second one with another name
Close #1
Open "mycsv2.csv" For Output As #1
Print #1, strFile
Close #1
End Sub
I have a text file with file addresses listed line by line.
Sometimes, however, the users go in there and accidentally add a space or a blank line between the addresses and that crashes the entire code.
How could I avoid this when reading the file using VBA?
This is the current block used to open the text file and read addresses line by line:
Set ActiveBook = Application.ActiveWorkbook
PathFile = ActiveWorkbook.Path & "\FilePaths.txt"
Open PathFile For Input As #1
Do Until EOF(1)
Line Input #1, SourceFile
Set Source = Workbooks.Open(SourceFile)
You will add two lines which will ignore blank lines and spaces like this:
Line Input #1, SourceFile
SourceFile = Trim(SourceFile) '~~> This will trim all the spaces
If Not SourceFile = "" Then '~~> This will check if lines is empty
Set Source = Workbooks.Open(SourceFile)
Suggest you add further code to
test if the file actually exists
test if the file is of a valid type for excel to open
code
Dim SourceFile As String
Dim PathFile As String
Set ActiveBook = Application.ActiveWorkbook
PathFile = ActiveWorkbook.Path & "\FilePaths.txt"
Open PathFile For Input As #1
Do Until EOF(1)
Line Input #1, SourceFile
SourceFile = Trim$(SourceFile)
If Len(Dir(ActiveWorkbook.Path & "\" & SourceFile)) > 0 Then
Select Case Right$(SourceFile, Len(SourceFile) - InStrRev(SourceFile, "."))
Case "xls", "xls*"
Set Source = Workbooks.Open(ActiveWorkbook.Path & "\" & SourceFile)
Case Else
Debug.Print "source not valid"
End Select
End If
Loop
Thanks for the code.
I did some small changes so I can reuse it in many different cases and call at any point of the code, using up to 3 different args (you may increase if you wish). like this below example.
note: you may change "totalBananas,EN2003" to anything you find impossible to exist in your files... I used it this way because I am not sure how to declare the args as optional :-p I don't think they are really possible to be optional anyway.
...
Call FixTextFile(file_name, "blabla", "0000", "")
...
Sub FixTextFile(inFile As Variant, fixArg1 As String, fixArg2 As String, fixArg3 As String)
Dim resArg1, resArg2, resArg3 As Long
Dim outFile As String
Dim data As String
If fixArg1 = "" Then fixArg1 = "totalBananas,EN2003"
If fixArg2 = "" Then fixArg2 = "totalBananas,EN2003"
If fixArg3 = "" Then fixArg3 = "totalBananas,EN2003"
Open inFile For Input As #1
outFile = inFile & ".alt"
Open outFile For Output As #2
Do Until EOF(1)
Line Input #1, data
resArg1 = InStr(1, data, fixArg1)
resArg2 = InStr(1, data, fixArg2)
resArg3 = InStr(1, data, fixArg3)
If Trim(data) <> "" And resArg1 < 1 And resArg2 < 1 And resArg3 < 1 Then
Print #2, data
End If
Loop
Close #1
Close #2
Kill inFile
Name outFile As inFile
MsgBox "File alteration completed!"
End Sub
I'm working on a project in excel and I am taking a text file, reading the text file, and trying to remove the stop words from the text file. But I'm getting stuck on removing the stop words in excel VBA. From the research I've seen it's possible in Java and PHP but I haven't been able to find one specifically to excel VBA. Is there a function that will remove stop words in excel VBA?
Const InputTxtFile As String = "C:\Temp\InTxt.txt"
Const OutputTxtFile As String = "C:\Temp\OutTxt.txt"
Const ListOfStopWords As String = ";CAT;DOG;FOX;"
Sub main()
Dim DataLine As String
Dim strTempLine As String
Open InputTxtFile For Input As #1 'Or FreeFile()
Open OutputTxtFile For Append As #2
While Not EOF(1)
Line Input #1, DataLine
Dim LineTab() As String
LineTab = Split(DataLine, " ") 'Split readed line on space
If UBound(LineTab) > 0 Then
For i = 0 To UBound(LineTab)
If (InStr(ListOfStopWords, ";" + LineTab(i) + ";") = 0) Then 'Look if not in Stop Words list
strTempLine = strTempLine + LineTab(i) + " "
End If
Next
Print #2, strTempLine 'Print to output file
strTempLine = ""
End If
Wend
Close #1
Close #2
End Sub
'Ref: Read/Parse text file line by line in VBA