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
Related
I have an Excel sheet that pulls data from a folder full of .txt documents.
Last week Friday, it worked. Nothing changed. This week Monday, I get a Run-time error '53': File not found.
What's interesting, is that when I click "Debug" it highlights a line in my code, and when I mouse over the 'sFile' variable, it tells me the name of the file that it apparently can't find... but it could only know the name of it if it found it... And yes, I've verified, that file does exist.
The Excel sheet is in H:\My Documents\Loma CW3 Reports\
The data .txt files are in H:\My Documents\Loma CW3 Reports\Product Statistics\
The first 3 files that it should be pulling are:
- PR20180912T153019.txt
- PR20180913T070005.txt
- PR20180913T153002.txt
Like mentioned above, when I'm debugging the code and mouse-over "sFile" in the line "Open sFile For Input As #1", it tells me:
sFile = "PR20180912T153019.txt"
Which it could only know if it was successfully scanning the folder since I don't hardcode any of those file names in.
I have tried removing that file, renaming the file to a word like 'apple', checked to see if it became read-only (nope). I'm thrown for a loop here, because it worked as is last week, and nothing changed from when I opened it up this week and tried it.
Code below:
Private Sub CommandButton1_Click()
' Dim myFile As String
Dim text As String, textLine As String
Dim sFile As String, rowTarget As Long
rowTarget = 2
' myFile = Application.GetOpenFilename()
sFile = Dir("H:\My Documents\Loma CW3 Reports\Product Statistics\" & "*.txt*")
Do Until sFile = ""
Open sFile For Input As #1
Do Until EOF(1)
Line Input #1, textLine
text = text & textLine
Loop
Close #1
Do stuff here
rowTarget = rowTarget + 1
sFile = Dir()
text = ""
Loop
End Sub
I ended up specifying directory as a separate variable and appended the sFile name to it when opening the file.
Dim directory As String
directory = "H:\My Documents\Loma CW3 Reports\Product Statistics\"
sFile = Dir(directory & "*.txt*")
Do Until sFile = ""
Open (directory & sFile) For Input As #1
blah blah blah
Thanks #comintern
I really hope i can get your help.
Ive been searching high and low for what is probably a simple solution.
We have hundreds of txt files that all relate to cnc programs. Unfortunately there has been a historical lack of control in keeping a strict numbering system for parts and operations.
I have to extract the 3rd and 4th line of txt from each file into an excel doc so we can remunerate some and catalogue all for referencing.
So far the closest thing i've found to what i'm after is in the thread
Extract a single line of data from numerous text files and import into Excel
however i cannot make it work - my excel knowledge is good but not with macros.
the start of every txt file is
#1 <blank line>
#2 %
#3 O00000 (part description)
#4 (part descriptio)
#5 rest of program.
.
.
.
as requested ive included the code i'm trying to modify.
Private Sub CommandButton1_Click()
Dim filename As String, nextrow As Long, MyFolder As String
Dim MyFile As String, text As String, textline As String, prog As String
MyFolder = "M:\CNC Programs\Haas lathe programs\Haas ST30 programs\Programs\Programs in .txt format"
MyFile = Dir(MyFolder & "*.txt")
Do While MyFile <> ""
Open (MyFolder & MyFile) For Input As #1
Do Until EOF(1)
Line Input #3, textline
text = text & textline
Loop
Close #1
MyFile = Dir()
Debug.Print text
nextrow = Sheet1.Cells(Rows.Count, "A").End(xlUp).Row + 1
Sheet1.Cells(nextrow, "A").Value = Mid(text, prog)
text = "" 'reset text
Loop
End Sub
Since you don't have much experience with vba, here are some points you might want to google and put the results together
Open a Text File in Excel VBA (you should start with that, and try to read one file)
Loop through all files in a certain folder with Excel VBA
Your code needs to do the following.
get a list of all the files you want to load
open each file of that list
read the 3rd and 4th line from that file
copy the lines to excel.
There are lots of examples on the internet, once you learn how to search
after a few hours and some help from a friend we came up with this, does more or less what i needed.
I know how I want to improve it, I just need to figure that out now. Again, I'm sure its a simple trick. Perseverance!!!
What I want to do with this now, if you can, is take my directory
'M:\CNC Programs\Haas Mills programs\All Mill Programs .txt format\'
and scan all subsequent folders for said .txt files and extract the same info into a workbook.
If I figure it out I'll update the post again.
Thanks for setting me on the right path Mister 832.
Private Sub CommandButton1_Click()
Dim MyMask As String, nextrow As Long, MyFolder As String
Dim MyFile As String, text As String, textline As String
Dim posCommentStart As String, posCommentFinish
Dim iLine As Integer
MyFolder = "M:\CNC Programs\Haas Mills programs\All Mill Programs .txt format\HAAS MINI-MILL BALLPADS & BALLPINS\"
MyMask = MyFolder & "*.txt"
MyFile = Dir(MyMask)
Do While MyFile <> ""
iLine = 0
Open (MyFolder & MyFile) For Input As #1
Do Until EOF(1) Or iLine >= 4
iLine = iLine + 1
Line Input #1, textline
If iLine >= 3 Then
text = text & textline 'second loop text is already stored -> see reset text
End If
Loop
Close #1
MyFile = Dir()
Debug.Print text
posCommentStart = InStr(text, "(")
posCommentFinish = InStr(text, ")")
If posCommentStart > 0 Then
nextrow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row + 1
ActiveSheet.Cells(nextrow, "A").Value = Left(text, posCommentStart - 2)
ActiveSheet.Cells(nextrow, "B").Value = Mid(text, posCommentStart + 1, posCommentFinish - posCommentStart - 1)
End If
text = "" 'reset text
Loop
End Sub
I have the following code where I am trying to modify some Txt files in a specific folder. I first want to check that the Loop works. However when I run the macro the code can only read the first file and then there is a runtime 5 error at strFileName = Dir(). I am not sure what the problem is. The only issue I can think of is that I am moving the code between two module sheets. The folder location is being saved in a txt box in Sheet 1 of an excel workbook.
Sub Txt_File_Loop()
Public TextFile As String
Dim FolderLocation As String
Dim strFielName As String
Dim SaveLocation As String
'Location is present in a Text box
FolderLocation = Sheets(1).FolderLocationTXTBX.Text
strFileName = Dir(FolderLocation & " \ * ")
Do Until strFileName = ""
TextFile = FolderLocation & "\" & strFileName
Module2.Macro1
strFileName = Dir() 'ERROR is Here
Loop
End Sub
Sub Macro1()
Dim x As String
Open TextFile For Input As #1
Do Until EOF(1)
Line Input #1, textline
x = x & textline
Loop
Close #1
MsgBox x
End Sub
Have a look at these modifications. They seem to correct several things and run through well.
Option Explicit
Sub Txt_File_Loop()
Dim FolderLocation As String
Dim strFileName As String
Dim SaveLocation As String
'Location is present in a Text box
FolderLocation = Sheets(1).FolderLocationTXTBX.Text 'Environ("TMP")
strFileName = Dir(FolderLocation & "\*.txt")
Do Until strFileName = ""
Debug.Print FolderLocation & "\" & strFileName
Module2.Macro1 FolderLocation & "\" & strFileName
strFileName = Dir() 'ERROR is Here
Loop
End Sub
Sub Macro1(sFPFN As String)
Dim x As String, textline As String
Debug.Print sFPFN
Open sFPFN For Input As #1
Do Until EOF(1)
Line Input #1, textline
x = x & textline
Loop
Close #1
MsgBox x
End Sub
I passed the folder and filename name across as a string-type parameter. Also, I don't know why you had the extra spaces in (FolderLocation & " \ * " ; I tightened that up. There were a few misspellings and undeclared variables; these can be avoided with Option Explicit¹ at the top of the module code sheet. Get into the practise of standard indentation with your code. It certainly improves readability if nothing else.
¹ Setting Require Variable Declaration within the VBE's Tools ► Options ► Editor property page will put the Option Explicit statement at the top of each newly created code sheet. This will avoid silly coding mistakes like misspellings as well as influencing you to use the correct variable type in the variable declaration. Variables created on-the-fly without declaration are all of the variant/object type. Using Option Explicit is widely considered 'best practice'.
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 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