Vba ADO正在截断Excel数据
我有一个函数,它使用ADO从工作表的内容中获取ADODB记录集,如下所示: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
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”等。此外,列的名称也会随着工作表的变化而变化;它通常但不总是在同一列索引中。因此,我需要一种方法来获取每列的实际值(与显示值相反)。请注意,如果在工作簿打开时运行此操作,则会得到正确的值。但是我需要在书关上的时候运行它。