5

我目前正在编写一些代码,可以通过 ADODB 连接访问单独的工作簿。由于速度的原因,我选择了这个而不是其他方法。下面是我的代码:

    Sub GetWorksheetData(strSourceFile As String, strSQL As String, TargetCell As      range)
    Dim cn As ADODB.Connection, rs As ADODB.Recordset, f As Integer, r As Long
    If TargetCell Is Nothing Then Exit Sub
    Set cn = New ADODB.Connection
    On Error Resume Next
    cn.Open "DRIVER={Microsoft Excel Driver (*.xls)};DriverId=790;ReadOnly=True;" & _
    "DBQ=" & strSourceFile & ";"
    ' DriverId=790: Excel 97/2000
    ' DriverId=22: Excel 5/95
    ' DriverId=278: Excel 4
    ' DriverId=534: Excel 3
    On Error GoTo 0
    If cn Is Nothing Then
    MsgBox "Can't find the file!", vbExclamation, ThisWorkbook.Name
    Exit Sub
    End If

    ' open a recordset
    Set rs = New ADODB.Recordset
    On Error Resume Next
    rs.Open strSQL, cn, adOpenForwardOnly, adLockReadOnly, adCmdText
    ' rs.Open "SELECT * FROM [SheetName$]", _
    cn, adOpenForwardOnly, adLockReadOnly, adCmdText
    ' rs.Open "SELECT * FROM [SheetName$]", _
    cn, adOpenStatic, adLockOptimistic, adCmdText
    ' rs.Open "SELECT * FROM [SheetName$] WHERE [Field Name] LIKE 'A%'", _
    cn, adOpenStatic, adLockOptimistic, adCmdText
    ' rs.Open "SELECT * FROM [SheetName$] WHERE [Field Name] LIKE 'A%' ORDER BY [Field                 Name]", _
    cn, adOpenStatic, adLockOptimistic, adCmdText

    ' optional ways of retrieving a recordset
    ' Set rs = cn.Execute("[A1:Z1000]") ' first worksheet
    ' Set rs = cn.Execute("[DefinedRangeName]") ' any worksheet

    On Error GoTo 0
    If rs Is Nothing Then
    MsgBox "Can't open the file!", vbExclamation, ThisWorkbook.Name
    cn.Close
    Set cn = Nothing
    Exit Sub
    End If

    'RS2WS rs, TargetCell
    TargetCell.CopyFromRecordset rs ' optional approach for Excel 2000 or later

    If rs.State = adStateOpen Then
    rs.Close
    End If
    Set rs = Nothing
    cn.Close
    Set cn = Nothing
    End Sub

现在,这段代码大部分都有效,但是当一行包含混合数据类型时,查询将跳过一些值。例如:

原始数据:

    3844774 12505604
    3844794 12505604
    4266113 3281271
    4295817 1307HX

返回数据:

    3844774 12505604
    3844794 12505604
    4266113 3281271
    4295817 

注意最后一位数据是如何被跳过的。这适用于多个条目,但仅限于包含字母的条目(使其成为文本)。原始表格也将所有内容都设置为文本。有什么建议让它不会跳过这些行吗?

提前致谢!

4

2 回答 2

6

那是因为您缺少 IMEX :)

请参阅此链接(将数据视为文本部分

http://connectionstrings.com/excel-2007

从那个链接引用。

将数据视为文本

当您想将文件中的所有数据视为文本时使用此选项,覆盖 Excels 列类型“常规”以猜测列中的数据类型。

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1";

如果要将列标题读入结果集中(即使有标题也使用 HDR=NO)并且列数据是数字,请使用 IMEX=1 以避免崩溃。

始终使用 IMEX=1 是检索混合数据列数据的更安全方法。考虑这样一种情况:一个 Excel 文件可能工作正常,导致该文件的数据导致驱动程序猜测一种数据类型,而另一个包含其他数据的文件导致驱动程序猜测另一种数据类型。这可能会导致您的应用崩溃。

对于 XLS 文件,请参阅此链接

http://connectionstrings.com/excel

高温高压

于 2012-05-08T20:58:38.843 回答
1

你应该使用这个。

OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyExcel.xls;Extended Properties="Excel 8.0;HDR=Yes;IMEX=1";

"IMEX=1;" tells the driver to always read "intermixed" (numbers, dates, strings etc) data columns as text. Note that this option might affect excel sheet write access negative.

For more reading please read it.

于 2012-05-08T20:59:20.317 回答