excel 通过VBA打开CSV文件(性能)

9cbw7uwe  于 2023-02-05  发布在  其他
关注(0)|答案(7)|浏览(625)

显然,这个问题已经被问过很多次了,正常程序:
Workbooks.Open (ActiveWorkbook.Path & "\Test.csv")
无法正确解析CSV(一个单元格中包含多行)
多亏了Lernkurve,我才能用他的函数把它做对:Opening semicolon delimited CSV file

Sub ImportCSVFile(filepath As String)
Dim line As String
Dim arrayOfElements
Dim linenumber As Integer
Dim elementnumber As Integer
Dim element As Variant

linenumber = 0
elementnumber = 0

Open filepath For Input As #1 ' Open file for input
    Do While Not EOF(1) ' Loop until end of file
        linenumber = linenumber + 1
        Line Input #1, line
        arrayOfElements = Split(line, ";")

        elementnumber = 0
        For Each element In arrayOfElements
            elementnumber = elementnumber + 1
            Cells(linenumber, elementnumber).Value = element
        Next
    Loop
Close #1 ' Close file.
End Sub

但是这并不快(我有数千列的文件),我的问题是:
是否有任何本地方式打开CSV文件在Excel与正确的解析?

xxe27gdn

xxe27gdn1#

Workbooks.Open也确实起作用。
Workbooks.Open ActiveWorkbook.Path & "\Temp.csv", Local:=True
这作品/是必要的,因为我使用Excel在德国和excel确实使用“,”来分隔.csv默认,因为我使用一个英语安装的windows.即使你使用下面的代码excel强制的“,”分隔符.
Workbooks.Open ActiveWorkbook.Path & "\Test.csv", , , 6, , , , , ";"
Workbooks.Open ActiveWorkbook.Path & "\Temp.csv", , , 4+这个的变体不起作用(!)
为什么他们甚至有分隔符参数,如果它被本地参数阻止了?!这根本没有意义。但是现在它起作用了。

wecizke3

wecizke32#

这个函数读取一个15MB的CSV文件,并在大约3秒内将其内容复制到一个工作表中。在您的代码中可能花费了大量时间的是,您逐个单元格复制数据,而不是一次放置整个内容。

Option Explicit

Public Sub test()

  copyDataFromCsvFileToSheet "C:\temp\test.csv", ",", "Sheet1"

End Sub

Private Sub copyDataFromCsvFileToSheet(parFileName As String, parDelimiter As String, parSheetName As String)

  Dim data As Variant

  data = getDataFromFile(parFileName, parDelimiter)
  If Not isArrayEmpty(data) Then
    With Sheets(parSheetName)
      .Cells.ClearContents
      .Cells(1, 1).Resize(UBound(data, 1), UBound(data, 2)) = data
    End With
  End If

End Sub

Public Function isArrayEmpty(parArray As Variant) As Boolean
'Returns false if not an array or dynamic array that has not been initialised (ReDim) or has been erased (Erase)

  If IsArray(parArray) = False Then isArrayEmpty = True
  On Error Resume Next
  If UBound(parArray) < LBound(parArray) Then isArrayEmpty = True: Exit Function Else: isArrayEmpty = False

End Function

Private Function getDataFromFile(parFileName As String, parDelimiter As String, Optional parExcludeCharacter As String = "") As Variant
'parFileName is supposed to be a delimited file (csv...)
'parDelimiter is the delimiter, "," for example in a comma delimited file
'Returns an empty array if file is empty or can't be opened
'number of columns based on the line with the largest number of columns, not on the first line
'parExcludeCharacter: sometimes csv files have quotes around strings: "XXX" - if parExcludeCharacter = """" then removes the quotes

  Dim locLinesList() As Variant
  Dim locData As Variant
  Dim i As Long
  Dim j As Long
  Dim locNumRows As Long
  Dim locNumCols As Long
  Dim fso As Variant
  Dim ts As Variant
  Const REDIM_STEP = 10000

  Set fso = CreateObject("Scripting.FileSystemObject")

  On Error GoTo error_open_file
  Set ts = fso.OpenTextFile(parFileName)
  On Error GoTo unhandled_error

  'Counts the number of lines and the largest number of columns
  ReDim locLinesList(1 To 1) As Variant
  i = 0
  Do While Not ts.AtEndOfStream
    If i Mod REDIM_STEP = 0 Then
      ReDim Preserve locLinesList(1 To UBound(locLinesList, 1) + REDIM_STEP) As Variant
    End If
    locLinesList(i + 1) = Split(ts.ReadLine, parDelimiter)
    j = UBound(locLinesList(i + 1), 1) 'number of columns
    If locNumCols < j Then locNumCols = j
    i = i + 1
  Loop

  ts.Close

  locNumRows = i

  If locNumRows = 0 Then Exit Function 'Empty file

  ReDim locData(1 To locNumRows, 1 To locNumCols + 1) As Variant

  'Copies the file into an array
  If parExcludeCharacter <> "" Then

    For i = 1 To locNumRows
      For j = 0 To UBound(locLinesList(i), 1)
        If Left(locLinesList(i)(j), 1) = parExcludeCharacter Then
          If Right(locLinesList(i)(j), 1) = parExcludeCharacter Then
            locLinesList(i)(j) = Mid(locLinesList(i)(j), 2, Len(locLinesList(i)(j)) - 2)       'If locTempArray = "", Mid returns ""
          Else
            locLinesList(i)(j) = Right(locLinesList(i)(j), Len(locLinesList(i)(j)) - 1)
          End If
        ElseIf Right(locLinesList(i)(j), 1) = parExcludeCharacter Then
          locLinesList(i)(j) = Left(locLinesList(i)(j), Len(locLinesList(i)(j)) - 1)
        End If
        locData(i, j + 1) = locLinesList(i)(j)
      Next j
    Next i

  Else

    For i = 1 To locNumRows
      For j = 0 To UBound(locLinesList(i), 1)
        locData(i, j + 1) = locLinesList(i)(j)
      Next j
    Next i

  End If

  getDataFromFile = locData

  Exit Function

error_open_file:             'returns empty variant
unhandled_error:             'returns empty variant

End Function
dbf7pr2w

dbf7pr2w3#

这可能会对你有帮助,也取决于你的CSV文件是如何格式化的。
1.打开您的Excel工作表,然后进入菜单DataImport External DataImport Data
1.选择您的CSV文件。
1.原始数据类型:选择Fixed width,然后选择Next
1.它会自动分隔您的columns。然后,您可以检查Data preview面板中的拆分列。
1.然后Finish &参见。
注意:你也可以用Delimited作为原始数据类型。在这种情况下,你需要键入你的定界符。
啊!

jchrr9hc

jchrr9hc5#

我也遇到了同样的问题,我无法在Excel中打开CSV文件。我已经找到了一个解决方案,适合我在这个问题Opening a file in excel via Workbooks.OpenText
这个问题帮助我找到了一个适合我的代码,代码大致如下所示:

Private Sub OpenCSVFile(filename as String)
    Dim datasourceFilename As String
    Dim currentPath As String

    datasourceFilename = "\" & filename & ".csv"
    currentPath = ActiveWorkbook.Path

    Workbooks.OpenText Filename:=currentPath & datasourceFilename, _
                       Origin:=xlWindows, _
                       StartRow:=1, _
                       DataType:=xlDelimited, _
                       TextQualifier:=xlDoubleQuote, _
                       ConsecutiveDelimiter:=False, _
                       Tab:=False, _
                       Semicolon:=False, _
                       Comma:=True, _
                       Space:=False, _
                       Other:=False, _
                       FieldInfo:=Array(Array(1, 1), Array(2, 1)), _
                       DecimalSeparator:=".", _
                       ThousandsSeparator:=",", _
                       TrailingMinusNumbers:=True
End Sub

至少,它帮助我了解了很多可以在Workbooks.OpenText方法中使用的参数。

w8f9ii69

w8f9ii696#

有时候,不管设置多少参数,www.example.com的所有解决方案Workbooks.open都不起作用。对我来说,最快的解决方案是在区域和语言设置中更改列表分隔符。区域窗口/附加设置.../列表分隔符。
如果csv没有以正确的方式打开,您可能已经将",“设置为列表分隔符。只需将其更改为”;“而一切都解决了。只是当“一切都对你不利”时最简单的方法:P

yqkkidmi

yqkkidmi7#

我只是通过如下设置Workbook.Open方法中的 Local 参数来解决(我的)问题:

xtrct_wb = Workbooks.Open(filePath, Local:=True)

每一个信息都在它适当的列中。希望它对你也有效。

相关问题