VBA / ADO: чтение смешанных типов данных из источника данных .csv - PullRequest
0 голосов
/ 21 февраля 2012

У меня проблема с чтением смешанных типов данных из источника данных .csv: строки возвращаются как нулевые, когда у меня есть столбец со смешанными строковыми / числовыми значениями. Я установил IMEX = 1 и изменил запись реестра TypeGuessRows с 8 на 0 (но даже если я смешал типы данных в первых 8 строках, строки по-прежнему отображаются как пустые). Также ImportMixedTypes = Текст в реестре.

Что мне не хватает ?? Любые идеи высоко ценится.

Вот моя строка подключения:

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

Ответы [ 2 ]

1 голос
/ 21 февраля 2012

Вот еще один пример кода , в котором не используется ADO , аналогично тому, что опубликовал Fink, с немного большей гибкостью и обработкой ошибок.Производительность неплохая (считывает и анализирует CSV-файл размером 20 МБ менее чем за 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
0 голосов
/ 21 февраля 2012

Вы заблокированы для чтения CSV с ADO? Кажется, я всегда сталкиваюсь с проблемами, пытаясь читать текстовые файлы с помощью 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
...