I'm trying to get datatables from different Excel worksheets. I get the datatables correctly using a OleDbConnection
. However, some columns are wrongly read as String
, but some of them are Double
or DateTime
type.
The Excel I'm reading I already created it from an Access file and it is written with correct datatypes. I also verified that no "Number stored as text" cell message in the Excel sheet is shown. The problem rise up when I try to read a column in this Excel file which most of the rows are empty.
From this post I get that ADO.NET chooses the data type based on the majority of the values in the column. So I don't know if the fact that most of the entries are empty in these fields could affect while reading it.
But, I repeat, this does not happen when reading the datatable content from the Access because the field in the Access design is defined with corresponding DataType
while in the Excel it is not.
This is my function to get the desired worksheet content as DataTable
:
Public Function GetDatatable(sheetName As String, versionFilter As String) As DataTable
Try
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim ds As System.Data.DataSet
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
Dim dbProvider As String = "PROVIDER=Microsoft.ACE.OLEDB.12.0;"
Dim dbSource As String = String.Format("Data Source={0};", Trim(IExcelValue))
Dim dbProperties As String = "Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1;"""
'Set version filter string if needed
If Not versionFilter Is Nothing Then
versionFilter = String.Format(" where numversion = '{0}'", versionFilter)
Else
versionFilter = ""
End If
'Set the connection string
Dim connectionString As String = String.Format("{0}{1}{2}", dbProvider, dbSource, dbProperties)
MyConnection = New System.Data.OleDb.OleDbConnection(connectionString)
MyCommand = New System.Data.OleDb.OleDbDataAdapter(String.Format("select * from [{0}$]{1}", sheetName, versionFilter), MyConnection)
MyCommand.TableMappings.Add("Table", sheetName)
ds = New System.Data.DataSet
MyCommand.Fill(ds)
MyConnection.Close()
GetDatatable = ds.Tables(sheetName)
Catch ex As Exception
MsgBox(ex.ToString)
Return Nothing
End Try
End Function
I know which fields must be Double
, DateTime
or String
and I can loop over those columns and assign the correct DataType
, but that's not elegant.
So, I suppose that the default DataType
of specific field if most of the records are empty in a DataTable
while reading from Excel worksheet is String
type. How could I manage to get the correct DataType
in these cases?
(I don't know if it is important or not, but I'm using Closed XML to write the Excel file)