Vba ADO正在截断Excel数据

Vba ADO正在截断Excel数据,vba,excel,ado,jet-sql,Vba,Excel,Ado,Jet Sql,我有一个函数,它使用ADO从工作表的内容中获取ADODB记录集,如下所示: 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 adOp

我有一个函数,它使用ADO从工作表的内容中获取ADODB记录集,如下所示:

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
我在导入数字数据时遇到了一个问题,其中数字的格式为1位小数,但实际上有2位小数。只有数据类型在列中混合时才会发生这种情况。例如,这些值:

0.03
0.05
0.08
0.13
当我在此表中将它们设置为小数点后1位时:

+-------+-----------+
| value | something |
+-------+-----------+
| 0.0   | a         |
| 0.1   | a         |
| 0.1   | sda       |
| 0.1   | sdf       |
+-------+-----------+
+---------+-----------+
|  value  | something |
+---------+-----------+
| asdfasd | asdfas    |
| 0.0     | a         |
| 0.1     | a         |
| 0.1     | sda       |
| 0.1     | sdf       |
+---------+-----------+
然后记录集获得正确的2位小数值。但当我把它们放在这张桌子上时:

+-------+-----------+
| value | something |
+-------+-----------+
| 0.0   | a         |
| 0.1   | a         |
| 0.1   | sda       |
| 0.1   | sdf       |
+-------+-----------+
+---------+-----------+
|  value  | something |
+---------+-----------+
| asdfasd | asdfas    |
| 0.0     | a         |
| 0.1     | a         |
| 0.1     | sda       |
| 0.1     | sdf       |
+---------+-----------+
然后记录集只获取1位小数的值,例如,它选择“0.0”而不是“0.03”。我认为这是因为第一行中的字符串导致ADO将列中的所有值视为显示的字符串

有没有一种方法,我仍然可以拿起文本字符串,但也得到正确的小数位数的数字值


编辑:只是注意到一些奇怪的事情。当我在工作簿打开时运行此操作时,记录集将获得正确的小数位数。如果我在工作簿关闭时运行它,它只会获取显示的小数。

请尝试以下功能和查询(在MS query中使用Excel进行测试):

因此,这里强制ADO的SQL解析器输出格式为
0.00

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

让我们知道你进展如何


Philip

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

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


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

是否从工作簿或任何其他应用程序调用代码?如果是Excel VBA,为什么不考虑利用Excel对象模型,只打开源工作簿?您可以将光标变成沙漏,并在执行此操作时关闭屏幕更新,这样用户就不会“看到”工作簿被打开然后关闭。在所有退出路径上重新打开屏幕更新-尤其是错误退出路径,以避免支持用户说“我的Excel刚刚冻结”。@Santosh,这是从另一个工作簿调用的。15000个工作簿,真的吗+祝你好运!正如@Santosh刚刚提到的,问题在于ADO需要将数据当作数据表来处理,给定列中只允许使用一种数据类型。如果将列格式化为显示2或3个小数,该怎么办?然后,您可以将所有内容视为字符串,并根据需要使用
TryParse
。但是超过15000本工作手册,你可能会得到一个你不感兴趣的性能冲击…@sigil你可能会发现这个链接很有用,但没有起作用。它所做的只是在截断值的末尾添加一个0:“0.00”、“0.10”等。此外,列的名称也会随着工作表的变化而变化;它通常但不总是在同一列索引中。因此,我需要一种方法来获取每列的实际值(与显示值相反)。请注意,如果在工作簿打开时运行此操作,则会得到正确的值。但是我需要在书关上的时候运行它。