OLEDB 将 CSV 导入 VB.NET 数据表,读取“-”为 0

OLEDB Import of CSV to VB.NET datatable reading '-' as 0

问候乐于助人的人,

我在读取 CSV 文件和转换为 VB.Net 中的数据表时遇到问题。 如果 CSV 文件包含一个充满“-”的列,那么在导入数据表时它们将显示为“0”并且整个列的格式为数字格式。

我写的代码是:

Public Function LoadCsvFile(filePath As String) As DataTable
    Try

        DTReadCSV = New DataTable

        Dim connection As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Microsoft.VisualBasic.Left(filePath, InStrRev(filePath, "\")) & ";Extended Properties=""text;HDR=Yes;FMT=Delimited""")

        Dim adapter As New OleDb.OleDbDataAdapter("SELECT * FROM [" + Microsoft.VisualBasic.Mid(filePath, InStrRev(filePath, "\") + 1) + "]", connection)
        'Dim table As New DataTable()
        adapter.Fill(DTReadCSV)

        'now thats its nicely in a datatable 
        IntAmountRows = DTReadCSV.Rows.Count
        IntAmountColumns = DTReadCSV.Columns.Count


        'System.Diagnostics.Debug.Print(DTReadCSV.Rows.Item(1)(1).ToString)
        Return DTReadCSV

        Exit Function
    Catch ex As Exception
        MsgBox(ex.ToString())

        MsgBox(Err.Number & " " & Chr(13) & Err.Description)
    End Try
End Function

除了通过将“-”作为空格删除来修改 CSV 文件之外,请更聪明的人找出解决此问题的方法,目前这似乎是导入这些 CSV 文件的唯一冗长的方法。

非常感谢

使用 Schema.INI 您可以向 OleDB 详细描述 CSV 的外观,包括生成的列名称和数据类型。例如,给定此数据:

"Country","Capital City","Population", "Fake"
"France","Paris","2.25","-----"
"Canada","Toronto","2.5","-----"
"Italy","Rome","2.8","-----"

在同一文件夹中创建一个Schema.ini文件;它可以有多个部分来定义该文件夹中的各种 CSV。如果在与 CSV 相同的文件夹中有一个 Schema.INI 并且 它有一个 CSV 条目,OleDB 将自动使用它(没有什么特别要做的)。

上述数据的 Schema.INI 条目可能如下所示:

[Capitals.CSV]
ColNameHeader=True
CharacterSet=1252
Format=CSVDelimited
TextDelimiter="
Col1="Country" Text Width 254
Col2="Capital City" Text Width 254
Col3="Population" Single
Col4="Fake" Text Width 254

OleDb 将在读取该文件时使用这些定义,从而在输出中为 "Fake" 列生成一串破折号:

使用 Schema.INI 的一个额外好处(在许多好处中)是您可以在那里命名列,而不是使用或别名 F1、F2、F3 等。该输出的 SQL 是只是 "SELECT * FROM Capitals.CSV"

提示(供其他人使用):要将 UTF8 指定为字符集,请在架构中使用 CharacterSet=65001

有关详细信息,请参阅
- Schema.ini Text File Driver
- Code Page Identifiers

您可以使用 Sebastien Lorion 的快速 CSV reader。我已经使用它近 10 年了(源代码可用,如果您只想加载它,可以使用 Nuget 包)。

我将在此处包含指向它的链接和一个代码片段,应该可以满足您的需求:

在这个例子中,我像你一样将文件名作为输入,你也可以有一个字符串,流,任何你需要的:

    ''' <summary>
''' Uses Lumenworks Fast CSV reader to load a DataTable
''' </summary>
''' <param name="fileName"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function CsvToDataTable(fileName As String) As DataTable
    Dim data As String = My.Computer.FileSystem.ReadAllText(fileName)
    Dim dt As New DataTable

    Using sr As New StringReader(data)
        ' The true indicates it has header values which can be used to access fields by their name, switch to
        ' false if the CSV doesn't have them
        Using csv As New LumenWorks.Framework.IO.Csv.CsvReader(sr, True)
            dt.Load(csv)
        End Using

        sr.Close()
    End Using

    Return dt

End Function