'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:

  1. Get the count of connections (ThisWorkbook.Connections.Count)
  2. Pass it as an index parameter to the connections class (ThisWorkbook.Connections(ThisWorkbook.Connections.Count))
  3. 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