vba - 无法使用 ADO 从 CSV 读取数据,因为驱动程序认为我正在使用整数/数字并显示空值而不是文本

标签 vba excel ado adodb

我正在尝试使用 ADO 将一系列文本文件读入工作表中。当特定列中的大部分数据都是整数时,我遇到了问题。当它到达字符串时,它将给出空值(空白单元格)。

根据微软支持 ( Ado mixed data tyes ),这是很常见的事情,解决方案是设置 IMEX = 1。我尝试了这个,但没有成功。

我一直在搜索其他线程寻找答案,并发现了这个答案( other thread ),其中作者说将 TypeGuessRows 更改为“让 Jet 检测是否存在混合类型情况”并欺骗 Jet 检测某种数据类型。”然而,这也没有奏效。

下面是我的 VBA 代码。任何帮助将不胜感激

Sub query_text_file(WorkingSheet As String, Col As String, Row As Integer, fileName As String, firstOrLast As Integer)

Dim strPath As String
Dim ws As Worksheet

strToolWkbk = fileName
strPath = ThisWorkbook.Path & "\Excel_Barcode_Files"
Set ws = Worksheets(WorkingSheet)

'Need to reference the:
'   Microsoft ActiveX Data Objects 2.5 Library
Dim s_rst As ADODB.Recordset
Dim s_cnn As ADODB.Connection 's for sub connection
Dim intRow As Integer

Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H1

Set s_cnn = New ADODB.Connection

s_cnn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strPath & ";" _
& "Extended Properties=""text;HDR=Yes;IMEX=1;TypeGuessRows=12;FMT=Delimited"";"

s_cnn.Open
Set s_rst = New ADODB.Recordset


strSQL = "SELECT * FROM " & strToolWkbk


s_rst.Open strSQL, _
    s_cnn, adOpenStatic, adLockOptimistic, adCmdText

intRow = Row

s_rst.MoveFirst


Do Until s_rst.EOF
    ws.Range(Col & intRow) = s_rst(0)
    ws.Range(Chr(Asc(Col) + 1) & intRow) = s_rst(1)
    intRow = intRow + 1
    s_rst.MoveNext
Loop

s_rst.Close
s_cnn.Close

Set s_rst = Nothing
Set s_cnn = Nothing

End Sub

这是一个示例文本文件。该代码读取除“P”之外的所有内容

test test
P,0
1,1
5,2
6,3

最佳答案

基本上,不要依赖注册表项,如here on MSDN所述。

您需要创建一个 Schema.ini 文件并将其放在与所有文本文件相同的文件夹中。在 Schema.ini 中,您指定文本文件中可能拥有的所有列的类型 - 显式执行此操作比让驱动程序计算出列的正确类型更安全。 ..

假设您的桌面上有一些 txt 文件,请打开记事本并复制粘贴以下内容 - 确保调整 [test.txt] 部分以匹配实际 txt 文件的名称并保存它为:Schema.ini

[test.txt]
Format=CSVDelimited

Col1=Column1 Text
Col2=Column2 Text

确保在 strPath 中的部分末尾添加另一个斜杠(也在文章中指出)

strPath = ThisWorkbook.Path & "\Excel_Barcode_Files\"

*请记住,我在与您不同的位置工作 - 在本示例中我使用的是桌面,我的文本文件名为 test.txt

现在,您已经有了一个 Schema.ini,您可以修改连接字符串并取出一些不需要的参数,因为它们存在于 Schema.ini

因此,基于上述假设的 SSCCE 基本上是:

Sub Main()

    Cells.ClearContents

    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset

    Dim thePath As String
    thePath = "C:\Users\" & Environ("USERNAME") & "\Desktop\"


    cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & thePath & ";" _
                        & "Extended Properties=""text;HDR=No;"""

    cn.Open

    Dim sql As String
    sql = "SELECT * FROM test.txt"

    ' populate the recordset
    rs.Open sql, cn, adOpenStatic, adLockOptimistic, &H1

    ' copy the recordset starting at Range("A1") - assuming there are no headers - see HDR = No;
    Range("A1").CopyFromRecordset rs

    rs.Close
    Set rs = Nothing
    cn.Close
    Set cn = Nothing

End Sub

现在运行此命令后,您应该会看到所有值,包括缺少的 P:

enter image description here

关于vba - 无法使用 ADO 从 CSV 读取数据,因为驱动程序认为我正在使用整数/数字并显示空值而不是文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26537692/

相关文章:

sql - Access SQL : Inner Join with multiple tables

c# - 无法添加对 Outlook 2016 (Office 365) Interop (16.0.0.0) 的引用

vba - 如果值为空,则使用默认值

excel - 单击时清除文本框

excel - Excel中文本到列的数据分割

java - 使用 Java 编写 Excel 的选项

excel - 如何将函数 INDEX(MATCH... 转换为 VBA 代码

mysql - 多步操作产生错误。检查每个状态值

c++ - 如何确定 MSADO 命令参数的大小

javascript - VBA 抓取 JavaScript 生成的内容