I'm new to VBA and therefore need some help. I'm trying to import data from a CSV file using a method where I can chose the csv of a list using the following piece of code:
Private Sub commandbuttonimport_click()
Dim fd As Office.FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.Filters.Clear
.Title = "Select a CSV File"
.Filters.Add "CSV", "*.csv", 1
.AllowMultiSelect = False
Dim sfile As String
If .Show = True Then
sfile = .SelectedItems(1)
End If
End With
'import csv from filedialog
If sfile <> "" Then
Open sfile For Input As #1
row_number = 1
Do Until EOF(1)
Line Input #1, LineFromFile
LineItems = Split(LineFromFile, ";")
Application.Range("FC_Range_Final").Cells(row_number, 1).Value = LineItems(0)
Application.Range("FC_Range_Final").Cells(row_number, 2).Value = LineItems(1)
Application.Range("FC_Range_Final").Cells(row_number, 3).Value = LineItems(2)
row_number = row_number + 1
Loop
Close #1
End If
End Sub
But the thing is, I would only like to import the data from the chosen csv file starting from row 2 and skip the first one. If I manually delete the first row from the CSV file (which contains the headers) and then use the code above everything works, but if the headers remain no luck.
Help would be appreciated as I'm kinda stuck right now.
Try the following...
'import csv from filedialog
Dim LineItems() As String
Dim LineFromFile As String
Dim line_number As Long
Dim row_number As Long
line_number = 1
row_number = 1
Open sfile For Input As #1
Do Until EOF(1)
Line Input #1, LineFromFile
If line_number > 1 Then
LineItems = Split(LineFromFile, ";")
Application.Range("FC_Range_Final").Cells(row_number, 1).Value = LineItems(0)
Application.Range("FC_Range_Final").Cells(row_number, 2).Value = LineItems(1)
Application.Range("FC_Range_Final").Cells(row_number, 3).Value = LineItems(2)
row_number = row_number + 1
End If
line_number = line_number + 1
Loop
Close #1
EDIT
Based on your comments, it looks like a line feed (vbLf) is used as the end of line marker. Assuming that this is the case, you'll need to change your code to the following...
'import csv from filedialog
Dim DataFromFile As String
Dim LinesFromData() As String
Dim LineItems() As String
Dim row_number As Long
Open sfile For Input As #1
DataFromFile = Input(LOF(1), 1) ' get contents from entire file
LinesFromData = Split(DataFromFile, vbLf) ' split data into separate lines assuming line feed as end of file marker
For row_number = LBound(LinesFromData) + 1 To UBound(LinesFromData) ' +1 to start with second line of data
LineItems = Split(LinesFromData(row_number), ";") ' split the line into separate items
If UBound(LineItems) <> -1 Then
Application.Range("FC_Range_Final").Cells(row_number, 1).Resize(, 3).Value = LineItems
End If
Next row_number
Close #1
Related
This continues on from a previous question I have asked actually. I am desperate to find a way to remove the trailing blank lines from text files when generated from an excel file to which I have been unsuccessful so far. I have found the below code just now and when I execute it, I can see that it has the basis for what I want (I think) but I don't have the skill to amend it so that ignores any line with data in it and just deletes the blank spaces. Can anyone help me amend this so that it can delete those pesky white spaces please?
Sub AltText()
Dim File As String
Dim VecFile() As String, Aux As String
Dim i As Long, j As Long
Dim SizeNewFile As Long
File = Application.GetOpenFilename
'Import file lines to array excluding first 3 lines and
'lines starting with "-"
Open File For Input As 1
i = 0
j = 0
Do Until EOF(1)
j = j + 1
Line Input #1, Aux
If j > 3 And InStr(1, Aux, "-") <> 1 Then
i = i + 1
ReDim Preserve VecFile(1 To i)
VecFile(i) = Aux
End If
Loop
Close #1
SizeNewFile = i
'Write array to file
Open File For Output As 1
For i = 1 To SizeNewFile
Print #1, VecFile(i)
Next i
Close #1
MsgBox "File alteration completed!"
End Sub
To remove lines that are blank, try the following code:
Sub AltText()
Dim inFile As String
Dim outFile As String
Dim data As String
inFile = Application.GetOpenFilename
Open inFile For Input As #1
outFile = inFile & ".alt"
Open outFile For Output As #2
Do Until EOF(1)
Line Input #1, data
If Trim(data) <> "" Then
Print #2, data
End If
Loop
Close #1
Close #2
Kill inFile
Name outFile As inFile
MsgBox "File alteration completed!"
End Sub
you need to look for blank spaces and carriage return characters, so after you read the line, check for content:
dim temp as string
temp = Replace (aux, chr(10), "")
temp = Replace (temp,chr(13),"")
temp = Rtrim(Ltrim(temp)) ' remove just blank stuff
now check for the length:
if j > 3 and Len(temp) <> 0 then
......
add the lines
so your code should look like this:
Sub AltText()
Dim File As String
Dim VecFile() As String, Aux As String
Dim i As Long, j As Long
Dim SizeNewFile As Long
File = Application.GetOpenFilename
'Import file lines to array excluding first 3 lines and
'lines starting with "-"
Open File For Input As 1
i = 0
j = 0
Do Until EOF(1)
j = j + 1
Line Input #1, Aux
'=====
dim temp as string
temp = Replace (aux, chr(10), "")
temp = Replace (temp,chr(13),"")
temp = Rtrim(Ltrim(temp)) ' remove just blank stuff
'======
If j > 3 And Len(temp) <> 0 Then
i = i + 1
ReDim Preserve VecFile(1 To i)
VecFile(i) = Aux
End If
Loop
Close #1
SizeNewFile = i
'Write array to file
Open File For Output As 1
For i = 1 To SizeNewFile
Print #1, VecFile(i)
Next i
Close #1
MsgBox "File alteration completed!"
End Sub
I am using VBA to import data from .txt files into a table of my spreadsheet which I am using for further pivot charts. The network directory that I am importing the files from contains ~5500 files and will grow over time at about 2000 files per year currently. The entries in the table are sorted by date (oldest to newest).
I have a macro which checks the date of the most recent entry, then uses DIR to search the network location and iterate through the files in that directory. For each file, if the file is newer than the most recent entry, I want to import the data and add it to the table. If the file is older, I want DIR to move to the next file. Below is the code I am currently using.
Sub NewFilesFromNetwork()
Dim myDatabase As Worksheet
Set myDatabase = Sheets("Database")
Dim TotalRows As Long, LastDate As Date
TotalRows = myDatabase.ListObjects("Table1").Range.Rows.Count
LastDate = Cells(TotalRows + 48, 6).Value 'the "+48" here is important because there are 48 hidden rows at the top of the spreadsheet before the table starts
Dim MyFolder As String, MyFile As String
On Error Resume Next
Application.ScreenUpdating = False
MyFolder = "*path to my network location*"
MyFile = Dir(MyFolder & "*.txt")
Dim t As Integer, k As Integer
t = 0 'counter for calculating total files imported
k = 0 'counter for calculating total files checked
Do While MyFile <> ""
TxtFile = MyFolder & MyFile
If FileDateTime(TxtFile) > LastDate Then
Open TxtFile For Input As #1
Do Until EOF(1)
Line Input #1, textline
text = text & textline
Loop
Close #1
Call CommonImportCode 'separate sub which picks out information from the .txt file string and adds it to the table as a new entry
k = k + 1
t = t + 1
MyFile = Dir()
End If
k = k + 1
MyFile = Dir()
Loop
Application.ScreenUpdating = True
MsgBox "Number of files searched = " & k & vbNewLine & "Number of files imported = " & t
End Sub
The issue I am having is this:
I can check the network location and see that there are 10 new files. However, the macro only imports 5 of them, and seems to be importing only every other file of the new files. Is there a reason the macro is skipping files when they meet the conditions of the IF statement?
k = k + 1
MyFile = Dir()
That code is duplicated. If your "If" just above is true, you are jumping one file. Your loop should be :
Do While MyFile <> ""
TxtFile = MyFolder & MyFile
If FileDateTime(TxtFile) > LastDate Then
Open TxtFile For Input As #1
Do Until EOF(1)
Line Input #1, textline
text = text & textline
Loop
Close #1
Call CommonImportCode 'separate sub which picks out information from the .txt file string and adds it to the table as a new entry
t = t + 1
End If
k = k + 1
MyFile = Dir()
Loop
or something approaching.
I need to extract data from a set of text files inside a folder. I tried several times without success, I hope that someone can help me.
All the files I have to read are inside the folder C:/test. The data I need to extract from the text files is located after the key word Read BRT Luminance.
The data should be placed in an excel file, every data extracted from a single text file inside a different cell.
I tried with this macro, but it doesn't work:
Dim myFile As String, myFolder As String, text As String, textline As String, originatorName As String, entryDescription As String, amount As Long
Sub Button1_Click()
Dim fs, f, f1, fc
Dim cella
cella = A2
'Add column headers
Range("A1").Value = "Brightness"
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFolder("C:\test")
Set fc = f.Files
For Each f1 In fc
If InStr(1, f1.Name, ".txt") Then
'Open file
Open f1 For Input As #1
Do Until EOF(1)
Line Input #1, textline
text = text & textline
Loop
'Close file
Close #1
ReadBRTLuminance = InStr(text, "Read BRT Luminance")
ActiveCell.Offset(cella, 1).Value = Mid(text, ReadBRTLuminance + 31, 9)
cella = cella + 1
End If
Next
End Sub
My macro to extract the data I need from a single file works fine:
Dim myFile As String, myFolder As String, text As String, textline As String, originatorName As String, entryDescription As String
Dim amount As Long
Sub Button1_Click()
'Add column headers
Range("A1").Value = "Brightness"
'Show open file dialog box
myFile = Application.GetOpenFilename()
'Open file
Open myFile For Input As #1
Do Until EOF(1)
Line Input #1, textline
text = text & textline
Loop
'Close file
Close #1
ReadBRTLuminance = InStr(text, "Read BRT Luminance")
Range("A2").Value = Mid(text, ReadBRTLuminance + 31, 9)
End Sub
You're not clearing the value of text between files, so that's why you always get the value from the first file...
Stackbros
I have some VBA which I'm using to import a .csv file from a specified folder into Excel. Once imported the script performs some other transformations such as delimiting and offsetting. See below.
Sub OpenTextFile ()
Dim FilePath As String
FilePath = "C:\Foldername\Foldername\Foldername\File_name.CSV"
Open FIlePath For Input As #1
row_number = 0
Do Until EOF(1)
Line Input #1, LineFromFile
LineItems = Split(LineFromFile, ",")
ActiveCell.Offset (row_number, 0).Value = LineItems (2)
ActiveCell.Offset (row_number, 1).value = LineItems (1)
ActiveCell.Offset (row_number, 2).Value = LineItems (0)
row_number = row_number + 1
Loop
Close #1
End Sub
What I really want to do is modify this so that when I run this I'm alsways importing the latest file from the folder, based on the date property of the file in the folder.
Thanks in advance.
Have a look at this routine. It is rather old but I think it does what you want. If not, it should give you some ideas.
Function NewestFileName(ByVal Path As String, ByVal FileTemplate As String) As String
' * Path Folder in which to search for files
' * FileTemplate File name specification of the file required. For example:
' MyFile*.xls
' * Finds, and returns the name of, the newest file in folder Path with a name
' that matches FileTemplate. Returns "" if no matching file is found.
' 25Jul11 Copied from RiskRegisterControl V43.xls.
' 22Nov11 Name changed from NewestFile to NewestFileName to match NextFileName.
' 20Apr12 Minor improvements
Dim FileDateCrnt As Date
Dim FileDateNewest As Date
Dim FileNameCrnt As String
Dim FileNameNewest As String
If Right(Path, 1) <> "\" Then
Path = Path & "\"
End If
FileNameCrnt = Dir$(Path & FileTemplate)
If FileNameCrnt = "" Then
NewestFileName = ""
Exit Function
End If
FileNameNewest = FileNameCrnt
FileDateNewest = FileDateTime(Path & FileNameCrnt)
Do While True
FileNameCrnt = Dir$
If FileNameCrnt = "" Then Exit Do
FileDateCrnt = FileDateTime(Path & FileNameCrnt)
If FileDateCrnt > FileDateNewest Then
FileNameNewest = FileNameCrnt
FileDateNewest = FileDateCrnt
End If
Loop
NewestFileName = FileNameNewest
End Function
I want to show 7000 files content that are in a folder and in excel?
I have a found a piece of code that helped me but its only reading one by one. However, I want to read 7000 all in one go. Please help.
Option Explicit
Sub Import_TXT_File()
Dim strg As Variant
Dim EntireLine As String
Dim FName As String
Dim i As String
Application.ScreenUpdating = False
FName = Application.GetOpenFilename("Text Files (*.txt), *.txt", , "Choose File to Import")
Open FName For Input Access Read As #1
i = 1
While Not EOF(1)
Line Input #1, EntireLine
strg = EntireLine
'Change "Sheet1" to relevant Sheet Name
'Change "A" to the relevant Column Name
Sheets("Sheet1").Range("A" & i).Value = strg
i = i + 1
Wend
EndMacro:
On Error GoTo 0
Application.ScreenUpdating = True
Close #1
End Sub
user1185158
The code which you are using will be very slow when you are reading 7000 files. Also there is no code which can read 7000 files in 1 go. You will have to loop through the 7000 files. However there is one good news :) Instead of looping through every line in the text file, you can read the entire file into an array and then write it to excel. For example see this code which is very fast as compared to the code that you have above.
TRIED AND TESTED
Sub Sample()
Dim MyData As String, strData() As String
Open "C:\MyFile.Txt" For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
strData() = Split(MyData, vbCrLf)
End Sub
Now using the same code in a loop we can write it into an Excel File
'~~> Change this to the relevant path
Const strPath As String = "C:\Temp\"
Sub Sample()
Dim ws As Worksheet
Dim MyData As String, strData() As String
Dim WriteToRow As Long, i As Long
Dim strCurrentTxtFile As String
Set ws = Sheets("Sheet1")
'~~> Start from Row 1
WriteToRow = 1
strCurrentTxtFile = Dir(strPath & "*.Txt")
'~~> Looping through all text files in a folder
Do While strCurrentTxtFile <> ""
'~~> Open the file in 1 go to read it into an array
Open strPath & strCurrentTxtFile For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
strData() = Split(MyData, vbCrLf)
'~~> Read from the array and write to Excel
For i = LBound(strData) To UBound(strData)
ws.Range("A" & WriteToRow).Value = strData(i)
WriteToRow = WriteToRow + 1
Next i
strCurrentTxtFile = Dir
Loop
MsgBox "Done"
End Sub
What the above code does is that it reads the contents of the 7000 text files in sheet 1 (one below the other). Also I have not included error handling. Please do that.
CAUTION: If you are reading heavy text files, say, each file has 10000 lines then you will have to tweak the code in the above scenario as you will get errors. for example
7000 Files * 10000 lines = 70000000 lines
Excel 2003 has 65536 rows and Excel 2007/2010 has 1048576 rows.
So once the WriteRow reaches the maximum row, you might want to read the text file contents into Sheet 2 and so on...
HTH
Sid
Taking Siddharth's solution a little further. You probably don't want to write each row one at a time, calls to the worksheet are extremely slow in Excel, it is better to do any looping in memory and write back in one fell swoop :)
Sub Sample()
Dim ws As Worksheet
Dim MyData As String, strData() As String, strData2() As String
Dim WriteToRow As Long, i As Long
Dim strCurrentTxtFile As String
Set ws = Sheets("Sheet1")
'~~> Start from Row 1
WriteToRow = 1
strCurrentTxtFile = Dir(strPath & "*.Txt")
'~~> Looping through all text files in a folder
Do While strCurrentTxtFile <> ""
'~~> Open the file in 1 go to read it into an array
Open strPath & strCurrentTxtFile For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
strData = Split(MyData, vbCrLf)
'Resize and transpose 1d array to 2d
ReDim strData2(1 To UBound(strData) + 1, 1 To 1)
For i = 1 To UBound(strData)
strData2(i, 1) = strData(i - 1)
Next i
Sheet1.Range("A1").Offset(Sheet1.Rows.Count - 1, 0).End(xlUp).Offset(1).Resize(UBound(strData), 1).Value = strData2
strCurrentTxtFile = Dir
Loop
MsgBox "Done"
End Sub