首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用ACE OLEDB引擎读取csv数据,如何检测数据中的错误

用ACE OLEDB引擎读取csv数据,如何检测数据中的错误
EN

Stack Overflow用户
提问于 2019-11-14 22:43:13
回答 1查看 455关注 0票数 1

在Excel中,我尝试使用和一个schema.ini文件读取CSV文本文件。这是可行的,但是当数据出现错误时,我希望ACE OLEDB引擎会抛出一个异常。

但是,它只是将数据中的错误值读入为null,并将它们作为空值传递,并且它只是继续,没有任何错误消息。特别是对于大型数据集,这是不可行的,因为没有办法轻松地发现任何手工错误。

下面是一个选项卡分隔的数据集,并有一些有意复制的错误。

代码语言:javascript
复制
OrderID OrderDate   Amount  Price   ArtNo   
40361   07/09/2019  2   59.95   4006633374668   
40362   07/10/2019  2   42,95   4006633146647   
40363   07/11/2019  1   69.75   4016987119501   
40364   07/12/2019  4   4.99    4082300264630   
40365   07/13/2019  1   39.95   4026736081348   
40366   07/14/2019  1   230.00  4013872786831   
40367   07/29/2019  1   42.95   4006633294256   
40368   07/30/2019  1   3,299.00    GTIN:0191215072422  
40369   07/31/2019  1   86.95   4010858791506   
40370   07/32/2019  10  8.99    4029416288686   

以及相应的schema.ini文件

testdata.txt DateTimeFormat=m/d/yyyy DecimalSymbol=。 Format=TabDelimited Col1=OrderID整数宽度5 Col2=OrderDate日期宽度10 Col3=Amount整数宽度2 Col4=Price浮子宽度10 Col5=ArtNo文本宽度13

使用ACE OLEDB连接到文本文件并执行SELECT * FROM textfile后,结果如下:

有些单元格是空的,尽管数据文件中有值。

B:值"42,95“是DecimalSymbol设置为点的错误。

D:值"3,299.00“是一个错误,因为有1000个逗号

E:值"07/32/2019“是一个不正确的日期

F*:值"GTIN:0191215072422“太长,E9在13个字符处被切断(*没有在图像中标记)

(顺便说一句,日期值A也被错误地解释了,即使设置DateTimeFormat=m/d/yyyy是正确的,但是C是正确的--可能仅仅是因为日期大于12,但是Excel总是对日期格式感到烦躁,所以我在这里忽略它们)

下面是使用ACE OLEDB引擎加载文本数据文件的VBA代码。

代码语言:javascript
复制
Sub ReadCsvTest(sPath As String, sFile As String, sBOM As String)

    Dim Wsh As Worksheet
    Dim AdoConnect As ADODB.Connection ' Tools > References > select "Microsoft ActiveX Data Objects x.x Library"
    Dim AdoRcrdSet As ADODB.Recordset
    Dim strSQL As String
    Dim sField As String
    Dim sValue As String
    Dim i As Integer
    Dim iRow As Integer
    ' not sure what it does, but just set sBOM = "\xEF\xBB\xBF"

    ' Add a new sheet
    With ActiveWorkbook
        Set Wsh = .Sheets.Add(After:=.Sheets(.Sheets.Count))
        'Wsh.Name = NewSheetName        'rename new Sheet
    End With

    Set AdoConnect = New ADODB.Connection
    AdoConnect.Provider = "Microsoft.ACE.OLEDB.12.0"
    AdoConnect.ConnectionString = "Data Source=" & sPath & ";Extended Properties='text';"
    AdoConnect.Open

    strSQL = "select * from " & sFile
    Set AdoRcrdSet = New ADODB.Recordset
    AdoRcrdSet.Open strSQL, AdoConnect

    ' header column names
    For i = 0 To AdoRcrdSet.Fields.Count - 1
        sField = WorksheetFunction.Substitute(AdoRcrdSet.Fields(i).Name, sBOM, "")
        Wsh.Cells(1, i + 1).Value = sField
    Next

    ' row values
    iRow = 2
    AdoRcrdSet.MoveFirst
    While Not AdoRcrdSet.EOF
        For i = 0 To AdoRcrdSet.Fields.Count - 1
            sValue = IIf(IsNull(AdoRcrdSet.Fields(i).Value), "", AdoRcrdSet.Fields(i).Value)
            Wsh.Cells(iRow, 1 + i).Value = sValue
        Next

        AdoRcrdSet.MoveNext
        iRow = iRow + 1
    Wend

End Sub

顺便说一句,我知道我也可以使用Open对话框,手动为每一列设置数据类型和格式,但这完全忽略了schema.ini。另外,对于其他应用程序,使用ACE OLEDB引擎也是一项要求。

所以我的问题是,有可能检测到这些类型的数据错误吗?我能以某种方式区分数据错误和实际的空/空值吗?或者我可以在连接字符串中使用额外的设置来使ACE OLEDB引擎抛出错误,或者使它将错误值设置为null以外的值?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-27 07:39:01

对于任何对这个问题感兴趣的人,我最终创建了一个用于Notepad++的CSV Lint插件

插件可以自动检测csv的类型(逗号、制表符等)。以及列的数据类型。此数据定义基于schema.ini格式。然后,插件可以根据此元数据验证数据。

自动列检测大部分时间都是工作的,它并不总是正确地检测数据类型。但是,您可以在验证数据文件之前手动编辑元数据,这样就不会有问题了。它也适用于固定宽度的数据文件,它包括一个语法高亮选项,如您在屏幕截图中所见。

我希望用额外的特性来更新这个Notepad++插件,但是它对于检测csv文件中的数据错误非常有用。

你可以在这里找到插件:

http://github.com/BdR76/CSVLint

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58867643

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档