【问题标题】:VBA/ADO: reading mixed data types from a .csv datasourceVBA/ADO:从 .csv 数据源读取混合数据类型
【发布时间】:2012-03-11 19:21:12
【问题描述】:

我在从 .csv 数据源读取混合数据类型时遇到问题:当我有一个包含混合字符串/数字值的列时,字符串作为空值返回。我设置了 IMEX=1 并将注册表项 TypeGuessRows 从 8 更改为 0(但即使我在前 8 行中混合了数据类型,字符串仍然以 Null 的形式出现)。注册表中还有 ImportMixedTypes=Text。

我错过了什么?任何想法都非常感谢。

这是我的连接字符串:

ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;" _
    & "Data Source=" & Folder & ";" _
    & "Extended Properties='text;HDR=YES;FMT=CSVDelimited;IMEX=1';" _
    & "Persist Security Info=False;"

【问题讨论】:

  • 你读过这个吗(关于邮政编码和添加注册表键的底部部分:ImportMixedTypes = Text):blog.lab49.com/archives/196

标签: sql vba csv ado


【解决方案1】:

这是另一个不使用 ADO 的代码示例,与 Fink 发布的类似,具有更多的灵活性和错误处理。性能还不错(在我的机器上读取和解析一个 20 MB 的 csv 文件不到 3 秒)。

Public Function getDataFromFile(parFileName As String, parDelimiter As String, Optional parExcludeCharacter As String = "") As Variant
'parFileName is supposed to be a delimited file (csv...)'
'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 quotes are removed'

  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 New FileSystemObject
  Dim ts As TextStream
  Const REDIM_STEP = 10000

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

  'Counts the number of lines and finds 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
      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

【讨论】:

  • 嗨,谢谢,但必须使用 ADO,需要能够对文件运行 SQL 查询
  • 根据查询,可能很容易迭代返回的数组并检查一些条件,但我知道在这种情况下您想使用 ADO 来完成。
【解决方案2】:

您是否习惯于使用 ADO 读取 CSV?我似乎总是遇到像您遇到的那样尝试使用 ADO 读取文本文件的问题。我通常只是放弃 ADO 端,直接用文本阅读器读取文件以获得更多控制权。

Public Sub TestIt()

    Dim path As String

    path = "C:\test.csv"

    ReadText path
End Sub

Public Sub ReadText(path As String)
'requires reference to 'Microsoft Scripting Runtime' scrrun.dll OR use late binding

    Const DELIM As String = ","
    Dim fso As New Scripting.FileSystemObject
    Dim text As Scripting.TextStream
    Dim line As String
    Dim vals() As String

    Set text = fso.OpenTextFile(path, ForReading)

    Do While Not text.AtEndOfStream

        line = text.ReadLine

        vals = Split(line, DELIM)

        'do something with the values
    Loop

    text.Close
End Sub

【讨论】:

    猜你喜欢
    • 2012-09-06
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 2020-09-17
    • 1970-01-01
    相关资源
    最近更新 更多