4

I have a function that gets an ADODB recordset from the contents of a worksheet using ADO, as follows:

Function WorksheetRecordset(workbookPath As String, sheetName As String) As adodb.Recordset

Dim objconnection As New adodb.Connection
Dim objrecordset As New adodb.Recordset

On Error GoTo errHandler

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

objconnection.CommandTimeout = 99999999

objconnection.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
    "Data Source=" & workbookPath & ";" & _
        "Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";"

objrecordset.Open "Select * FROM [" & sheetName & "$]", _
    objconnection, adOpenStatic, adLockOptimistic, adCmdText

If objrecordset.EOF Then
    Set WorksheetRecordset = Nothing
    Exit Function
End If

objrecordset.MoveLast
objrecordset.MoveFirst

Set WorksheetRecordset = objrecordset
Exit Function

errHandler:
Set WorksheetRecordset = Nothing

End Function

I'm having a problem importing number data where the numbers are formatted to 1 decimal place but they actually have 2 decimal places. This only happens if the datatype is mixed in the column. For example, these values:

0.03
0.05
0.08
0.13

When I set them to 1 decimal place in this table:

+-------+-----------+
| value | something |
+-------+-----------+
| 0.0   | a         |
| 0.1   | a         |
| 0.1   | sda       |
| 0.1   | sdf       |
+-------+-----------+

then the recordset gets the correct 2 decimal place values. But when I put them in this table:

+---------+-----------+
|  value  | something |
+---------+-----------+
| asdfasd | asdfas    |
| 0.0     | a         |
| 0.1     | a         |
| 0.1     | sda       |
| 0.1     | sdf       |
+---------+-----------+

then the recordset only gets the 1 decimal place values, e.g. it picks up "0.0" instead of "0.03". I think this is because the string in the first row is causing ADO to treat all values in the columns as strings as displayed.

Is there a way I can still pick up the text string, but also get the correct number of decimal places in the number values?

EDIT: Just noticed something odd. When I run this while the workbook is open, the recordset gets the correct decimal places. If I run it while the workbook is closed, it only gets the displayed decimals.

4

2 回答 2

1

为您的objRecordset功能和查询尝试以下操作(在 MS Query with Excel 中测试):

With objrecordset
    .CursorLocation = adUseClient
    .LockType = adLockOptimistic
    .CursorType = adOpenStatic
    .ActiveConnection = objconnection
    .Open "Select format(`" & sheetName & "$`.value,'0.00') as [value], something FROM [" & sheetName & "$]"
End With

所以,这里的JET SQL 格式函数是强制 ADO 的 SQL 解析器输出一个格式化为的字符串0.00

另外,我已将CursorTLocation属性设置为,adUseClient因此您无需使用MoveLastMoveFirst

让我们知道您的身体情况如何

菲利普

于 2013-05-22T13:36:14.623 回答
0

不幸的是,我以前遇到过同样的问题,原因是 ACE 驱动程序只查看列中的第一个值来决定整个列的数据类型。因此,您可以尝试使用顶部的数值对数据进行排序。

在 Excel 中创建连接表的“黄金标准”方法是使用 vLookup。我建议这样做,即使它看起来有点“业余”。

此外,似乎将 IMEX 设置为 1 基本上会强制 ACE 返回文本表示形式,以便数字列中的字母数字值不会返回为 null。

于 2014-09-19T17:27:29.657 回答