ADO 读取Excel文件数据, 丢失数据或数据错误问题。

在用ADO读取Excel文件数据,常容易发生丢失数据的现象。

例如,用ADO打开一个Excel文件的代码如下:
 Dim objConn As ADODB.Connection
    Dim objRS As ADODB.Recordset
    Dim objRSTable As ADODB.Recordset
   
    Set objConn = New ADODB.Connection
    Set objRS = New ADODB.Recordset
    objRS.CursorLocation = adUseClient
   
    With objConn
        .Provider = "Microsoft.Jet.OLEDB.4.0"
        .ConnectionString = "Data Source=" & Me.ExcelPath & ";Extended Properties=""Excel 8.0;HDR=NO;"""
        .CursorLocation = adUseClient
        .Open
    End With
   
    ' Check whether there is a sheet named "master" in the excel file
    Set objRSTable = objConn.OpenSchema(adSchemaTables)
blnMasterSheet = False
    For i = 1 To objRSTable.RecordCount
        If UCase(CStr(objRSTable.Fields("TABLE_NAME").Value)) = "MASTER$" Then
            blnMasterSheet = True
            Exit For
        End If
        objRSTable.MoveNext
    Next i
       
    Set objRSTable = Nothing
    If Not blnMasterSheet Then
        MsgBox ("Master Worksheet Is Not Found")
        Set objConn = Nothing
        Set objRS = Nothing
        GetExcelData = False
        Exit Function
    End If
   
    strExcuteScript = "select * from [Master$A1:F]"
    objRS.Open strExcuteScript, objConn, adOpenStatic, adLockOptimistic
运行后发现第一列的某些行数据丢失了。这发生在第一行是数字,第二行是文字的情况。
因为在读取excel的时候,ODBC会根据第一行的文字来设定返回的recordset的字段类型,当第一行是数字时,就会认为整列都是数字的。结果后面的字符无法读出。

这时,需要把连接字符串改为.ConnectionString = "Data Source=" & Me.ExcelPath & ";Extended Properties=""Excel 8.0;HDR=NO;IMEX=1;"""

其中,IMEX=1;这个属性的意思是,以文本方式读取excel表。 那么就算第一行是数字,后面的字符串也可以正常读出了。

问题好像是解决了。但过一段时间后,又出现了问题,读取某个列的某个行时,会出现错误。错误现象为

我们读取Excel表格后,会把数据传到另一个recordset (假定为R2)再进行处理的。在给另一个recordset付值时出错。根据错误信息,得知如果把一个超长的或者错误的数据付给一个字段时会出现这样的错误。但在R2中,我们设定了对于的字段的长度是1000的,而要付值的数据长度是628,为什么还会出错呢。这个R1的字段出来的值后面也带有很多的乱码。就是说,本来从Excel中读出来的数据已经是乱码了。

      我们把怀疑产生乱码的所有空格去掉,结果错误到了下一行。再把正常的数据复制变成很长,结果也会产生错误。再尝试把前面的正常行去掉,居然错误就不见了。
        把断点设在错误的那行,查数据的长度,是628, 再看rs.fileds(11).defineSize, 发现只有255. 那就说明,它实际字段是认为长255的,但把数据都读出来了,结果是乱码,再把这些乱码付值给另一个recordset时才报错。
        把产生错误的数据放在第一行时,是不会有这个错误的,查看它的defineSize, 发现不再是255了,而是很大的数字。
        再尝试把错误的数据放在1-8行,都不会产生问题,在9行以上就会产生。

        原来,ODBC在读取Excel时,会有个值设置TypeGuessRows=8, 意思是ODBC会先在前8行的数据中去比较,如果所有的数据都在255或以下,那这个字段长度就是varchar(255),否则,这个字段将是text类型。

      于是,我们加上TypeGuessRow=100,再试,结果错误依然存在。

      原来,虽然可以设置这个属性,但ODBC是不会去用它的,要使这个属性有效,必须修改注册表。对于注册表键是

Excel 97
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Jet/3.5/Engines/Excel
Excel 2000 and later versions
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Jet/4.0/Engines/Excel


修改了里面的TypeGuessRow后,这个问题暂时解决了。

但是,如果大的数据在表的后面位置的话,这个问题还是有可能发生的。所以要彻底的解决的话,在打开一个recordset前,就要先定义好它的字段长度了。

 

 

来源:http://www.excelhome.net/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用 VBA 中的 ADO 连接 Excel 数据表获取数据需要以下步骤: 1. 引用 Microsoft ActiveX Data Objects 库。 在 VBA 编辑器中,依次点击菜单栏中的“工具”→“引用”,勾选“Microsoft ActiveX Data Objects 2.x 库”(其中的“x”表示版本号,您可以选择您电脑上已安装的版本)。 2. 创建 ADO 连接对象。 在 VBA 代码中,使用 `CreateObject` 方法创建 ADO 连接对象,并设置连接字符串。例如,以下代码创建了一个连接到 Excel 工作簿的连接对象: ``` Dim cn As Object Set cn = CreateObject("ADODB.Connection") cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\excel\workbook.xlsx;Extended Properties=""Excel 12.0;HDR=YES"";" ``` 其中 `Provider` 参数指定了使用的 OLE DB 提供程序,这里使用的是 Microsoft.ACE.OLEDB.12.0,它可以连接 Excel 文件。`Data Source` 参数指定了 Excel 文件的路径和文件名,`Extended Properties` 参数指定了 Excel 文件的属性,例如 `HDR=YES` 表示第一行是标题行。 3. 打开连接。 使用 `Open` 方法打开连接: ``` cn.Open ``` 4. 创建 ADO 命令对象。 在 VBA 代码中,使用 `CreateObject` 方法创建 ADO 命令对象,并设置 SQL 语句。例如,以下代码创建了一个查询 Excel 数据表的命令对象: ``` Dim cmd As Object Set cmd = CreateObject("ADODB.Command") cmd.ActiveConnection = cn cmd.CommandText = "SELECT * FROM [Sheet1$]" ``` 其中 `ActiveConnection` 属性指定了连接对象,`CommandText` 属性指定了 SQL 语句,这里查询了名为“Sheet1”的数据表的所有数据。 5. 执行命令并获取数据。 使用 `Execute` 方法执行命令,并使用 `Recordset` 属性获取查询结果。例如,以下代码执行命令并将结果保存到 `rs` 变量中: ``` Dim rs As Object Set rs = cmd.Execute ``` 您可以使用 `rs` 变量中的方法和属性获取查询结果,例如 `rs.Fields` 获取所有字段名,`rs.GetRows` 获取所有数据行。 6. 关闭连接。 使用 `Close` 方法关闭连接: ``` cn.Close ``` 完整的示例代码如下: ``` Sub GetExcelData() Dim cn As Object Dim cmd As Object Dim rs As Object '创建连接对象 Set cn = CreateObject("ADODB.Connection") cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\excel\workbook.xlsx;Extended Properties=""Excel 12.0;HDR=YES"";" '打开连接 cn.Open '创建命令对象 Set cmd = CreateObject("ADODB.Command") cmd.ActiveConnection = cn cmd.CommandText = "SELECT * FROM [Sheet1$]" '执行命令并获取数据 Set rs = cmd.Execute Debug.Print rs.Fields(0).Name Debug.Print rs.GetRows(10) '关闭连接 cn.Close End Sub ``` 注意,以上代码仅供参考,您需要根据您的实际情况进行修改

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值