问题
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.
回答1:
try the below for your objRecordset features and query (tested in 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
so, here the JET SQL format Function is forcing ADO's SQL Parser to output a string formatted as 0.00
ALso, I have set the CursorTLocation
property to adUseClient
so you won't need to use MoveLast
and MoveFirst
let us know how you get on
Philip
回答2:
Unfortuately I had the same problem once before and the reason is that the ACE driver only looks at the first value in a column to decide the data type for that entire column. So, you can try to sort the data with the numeric values on top.
The "Gold Standard" way to create joined tables in Excel is with vLookup. I would suggest doing this even though it may seem a bit "amateur."
Also, it appears that setting IMEX to 1 basically forces ACE to return the text representations so that alpha-numeric values in a numeric column are not returned as null.
来源:https://stackoverflow.com/questions/16681618/ado-is-truncating-excel-data