简体   繁体   English

Excel VBA - 在没有数据连接的情况下导入 CSV

[英]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.我希望使用这种连接样式的 VBA 代码来导入一些 CSV 文件。 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...当我使用连接向导时,它会以我需要的表格格式完全下载 CSV 等,所以我希望避免使用字符串阅读器......

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

I saw this on SO a few days ago .几天前我在 SO 上看到了这个。 . . . .

' 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

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).这不是最面向对象的解决方案(理想情况下,我们希望通过名称或作为 QueryTable 的属性指向该特定连接并将其删除)。

I noticed that when we create the Query Table the connection is added to the "Workbook.Connections" class as the last connection.我注意到当我们创建查询表时,连接被添加到“Workbook.Connections”类作为最后一个连接。 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).如果您想在以后出于某种原因删除连接,看起来连接名称是从 csv 工作簿名称派生的,因此您也可以始终以这种方式处理它(即将工作簿名称作为参数传递给连接类来引用它)。

Assuming we want to delete immediately , the solution works like this:假设我们想立即删除,解决方案是这样的:

  1. Get the count of connections ( ThisWorkbook.Connections.Count )获取连接数 ( ThisWorkbook.Connections.Count )
  2. Pass it as an index parameter to the connections class ( ThisWorkbook.Connections(ThisWorkbook.Connections.Count) )将其作为索引参数传递给连接类( ThisWorkbook.Connections(ThisWorkbook.Connections.Count)
  3. Call the .Delete method on the Connections class ( ThisWorkbook.Connections(ThisWorkbook.Connections.Count).Delete )调用 Connections 类的 .Delete 方法( 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 的末尾添加这行代码,如下所示:

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.我注意到您的代码使用工作簿指针ActiveWorksheet ,因此使用ActiveWorkbook或任何等效的工作簿可能与您的用例更相关。

Hope this helps!希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM