【问题标题】:Import csv with quoted newline using QueryTables in Excel在 Excel 中使用 QueryTables 导入带有引号的换行符的 csv
【发布时间】:2014-10-02 12:35:09
【问题描述】:

我编写了一个 Visual Basic 宏来将一个 csv 文件加载到我经常使用的 Excel 中。

不幸的是,如果 csv 文件包含带引号的换行符,则结果与直接使用 excel 打开 csv 文件时得到的结果不同。与通常的导入工具不同,QueryTables.add() 假定它遇到的任何换行符(无论是否引用)都是行尾。

有没有办法解决这个问题?我更喜欢不涉及预先修改传入的 csv 文件以删除换行符的解决方案,但我也愿意接受这方面的建议。不过,我确实希望在生成的 excel 文件单元格中有换行符。

我的宏的相关部分:

Sub LoadMyFile()
    ' Query the table of interest
    With ActiveSheet.QueryTables.Add(Connection:="TEXT;" _
      & ThisWorkbook.Path & "\" & Range("A1").Value & ".csv", _
      Destination:=Range("$A$2"))
        .Name = ActiveSheet.Name
        .FieldNames = True
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .RefreshStyle = xlOverwriteCells
        .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)
        .TextFileTrailingMinusNumbers = True
        .Refresh BackgroundQuery:=False
    End With
End Sub

这是一个带有引号的换行符示例 csv 文件

"firstCol","secondCol"
"name1","data
one"
"name 
2","data two"

宏从单元格 A1 读取文件名(减去 .csv 扩展名),并假定 csv 文件与包含宏的 excel 文件位于同一目录中。

我在 Windows 7 机器上使用 32 位 Office Professional 2010。

【问题讨论】:

    标签: vba excel csv import


    【解决方案1】:

    此类 CSV 文件(数据点中的换行符)的导入仅适用于 Workbooks。打开且仅适用于区域设置格式(分隔符、文本分隔符)的 CSV,使用 Excel。

    Set wb = Workbooks.Open(Filename:="C:\Users\axel\Desktop\test.csv", Local:=True)
    
    aData = wb.Worksheets(1).UsedRange.Value
    lRows = UBound(aData, 1)
    lCols = UBound(aData, 2)
    
    With ActiveSheet
     .Range(.Cells(1, 1), .Cells(lRows, lCols)).Value = aData
    End With
    
    wb.Close
    

    问候

    阿克塞尔

    【讨论】:

    • 感谢您的建议。看起来很有希望。我星期一回办公室试试看。
    • 正如所写,此解决方案在新工作簿中打开文件(并且还用 NA 填充了一堆单元格)。不过,我也许可以使用它。谢谢
    • 可爱。 Local:=True 是我想要的。没有这个,列就会损坏。
    【解决方案2】:

    编辑:之前提供的代码实际上是根据您提供的具体示例设计的,源 CSV 中有 2 列和相对较少的数据。我已经查看了下面的代码以适应其他可能的场景 - 还包括一些运行时效率的优化。

    请注意,我不习惯使用与我在这里依赖的 Open 方法相关的搜索工具,而且我仍然对它们在某些情况下的实际工作方式存在一些疑虑,但是在运行了几次测试之后代码看起来工作得很好。

    Sub csvImportbis()
    
        Dim s As String
        Dim i As Long
        Dim j As Long
        Dim a() As String
    
        myfile = FreeFile
        i = 1
        j = 1
    
        'ENTER YOUR PATH/FILE NAME HERE
        Open "YOUR_PATH/FILENAME" For Input As #myfile
    
            Do Until EOF(myfile)
    
                Do
                    Input #myfile, s
                    cur = Seek(myfile)
                    Seek myfile, cur - 1
                    i = i + 1
                Loop While input(1, #myfile) <> vbLf
    
                ReDim a(1 To i - 1, 1 To 10000)
    
                i = 1
    
                Seek #myfile, 1
    
                Do Until EOF(myfile)
    
                    Input #myfile, a(i, j)
                    i = i + 1
    
                    If i > UBound(a, 1) Then
                        i = 1
                        j = j + 1
                    End If
    
                    If j > UBound(a, 2) Then
                        ReDim Preserve a(1 To UBound(a, 1), 1 To UBound(a, 2) + 10000)
                    End If
    
                Loop
    
            Loop
    
        Close #myfile
    
        sup = j
    
        ReDim Preserve a(1 To UBound(a, 1), 1 To sup)
    
        'QUALIFY THE RANGE WITH YOUR WORKBOOK & WORKSHEET REFERENCES
        Range("A1").Resize(sup, UBound(a, 1)) = WorksheetFunction.Transpose(a)
    
    End Sub
    

    【讨论】:

    • 感谢您的建议。目前,我实际上是在导入之前使用不同的工具删除这些换行符作为解决方法。不幸的是,它们是数据的一部分,应在导入后保留。我考虑过用导入后改回换行符的代码替换它们,不过......
    • 好的 - 您可以使用上面的代码在字符串中保留换行符,只需摆脱替换函数并将 s1 和 s2 字符串变量直接分配给范围值即可。我只是假设不应保留这些换行符
    • 啊,很好。谢谢。另外,是否需要提前知道使用这种方法的 csv 文件中有多少列?我加载的文件种类繁多。谢谢你的帮助,顺便说一句!
    • 不用担心。查看我的回复 - 我提供了一些新代码和信息。希望这会有所帮助
    • 我遇到了这个问题。我的原始输入文件有这些烦人的字段,如下所示:"=""1994""" 作为一种解决方法,以确保 excel 将数字读取为文本并且它会被破坏。我认为按照其他答案中的建议,从Workbooks.Open() 工作可能会更容易。
    猜你喜欢
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    相关资源
    最近更新 更多