'Excel VBA - Import CSV without data connection
I'm hoping to use this bit of connection style VBA code to import a number of CSV files. When I used the connection wizard, it downloads the CSV exactly in the table format I need it in etc, so I'm hoping to avoid doing a string reader...
Is there a way to do something like the following, but without creating a permanent connection?
Sub Macro1()
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;T:\XYZ\KCross\Output\alpha.csv", Destination:=range("$B$2" _
))
.name = "alpha_1"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub
Solution 1:[1]
I saw this on SO a few days ago . . .
' Merge data from multiple sheets into seperate sheets
Sub R_AnalysisMerger2()
Dim WSA As Worksheet
Dim bookList As Workbook
Dim SelectedFiles As Variant
Dim NFile As Long
Dim FileName As String
Dim Ws As Worksheet, vDB As Variant, rngT As Range
Dim vFn, myFn As String
Application.ScreenUpdating = False
SelectedFiles = Application.GetOpenFilename(filefilter:="Excel Files (*.csv*), *.csv*", MultiSelect:=True)
If IsEmpty(SelectedFiles) Then Exit Sub
For NFile = LBound(SelectedFiles) To UBound(SelectedFiles)
FileName = SelectedFiles(NFile)
vFn = Split(FileName, "\")
myFn = vFn(UBound(vFn))
myFn = Replace(myFn, ".csv", "")
Set bookList = Workbooks.Open(FileName, Format:=2)
Set WSA = bookList.Sheets(1)
vDB = WSA.UsedRange
bookList.Close (0)
Set Ws = Sheets.Add(after:=Sheets(Sheets.Count))
ActiveSheet.Name = myFn
Ws.Range("a1").Resize(UBound(vDB, 1), UBound(vDB, 2)) = vDB
Next
Application.ScreenUpdating = True
End Sub
' Merge data from multime files into one sheet.
Sub R_AnalysisMerger()
Dim WSA As Worksheet
Dim bookList As Workbook
Dim SelectedFiles() As Variant
Dim NFile As Long
Dim FileName As String
Dim Ws As Worksheet, vDB As Variant, rngT As Range
Application.ScreenUpdating = False
Set Ws = ThisWorkbook.Sheets(1)
Ws.UsedRange.Clear
'change folder path of excel files here
SelectedFiles = Application.GetOpenFilename(filefilter:="Excel Files (*.csv*), *.csv*", MultiSelect:=True)
For NFile = LBound(SelectedFiles) To UBound(SelectedFiles)
FileName = SelectedFiles(NFile)
Set bookList = Workbooks.Open(FileName, Format:=2)
Set WSA = bookList.Sheets(1)
With WSA
vDB = .UsedRange
Set rngT = Ws.Range("a" & Rows.Count).End(xlUp)(2)
If rngT.Row = 2 Then Set rngT = Ws.Range("a1")
rngT.Resize(UBound(vDB, 1), UBound(vDB, 2)) = vDB
bookList.Close (0)
End With
Next
Application.ScreenUpdating = True
Ws.Range("A1").Select
End Sub
Solution 2:[2]
It's not the most Object-Oriented solution (ideally we'd want to point at that specific connection by name or as an attribute of the QueryTable and delete it).
I noticed that when we create the Query Table the connection is added to the "Workbook.Connections" class as the last connection. This lets us take a count of the connections, pass it back to the connections class to point at this connection, then delete it.
This solution will only work if you want to delete the connection immediately with the creation of the Query Table. If you want to delete the connection at a later time for some reason, it looks like the connection name is derived from the csv workbook name, so you could always approach it that way too (ie pass the workbook name as an parameter to the connections class to reference it).
Assuming we want to delete immediately, the solution works like this:
- Get the count of connections (
ThisWorkbook.Connections.Count) - Pass it as an index parameter to the connections class (
ThisWorkbook.Connections(ThisWorkbook.Connections.Count)) - Call the .Delete method on the Connections class (
ThisWorkbook.Connections(ThisWorkbook.Connections.Count).Delete)
Using your provided code, I'd add this line of code at the end of the sub like so:
Sub Macro1()
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;T:\XYZ\KCross\Output\alpha.csv", Destination:=range("$B$2" _
))
.name = "alpha_1"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
ThisWorkbook.Connections(ThisWorkbook.Connections.Count).Delete
End Sub
Another way to understand the solution would be writing it like this:
Dim wb as Workbook: set wb = ThisWorkbook
Dim conns as Connections: set conns = wb.Connections
conns(conns.Count).Delete
Note: I'm also assuming this macro will only operate on the workbook it lives in; I noticed your code uses the workbook pointer ActiveWorksheet so using ActiveWorkbook or whatever the workbook equivalent is might be more relevant in your use case.
Hope this helps!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ASH |
| Solution 2 | James Andrew Bush |
