錯誤重現:
-----------------------------------------------------------------------
在導入Excel讀取數據時,其中的一個字段保存的值有如下格式:"2011072014","20110Aad10","25124Adfa","例子asdfadf" 這樣的 混合了 "字母/數字/中文"數據, 在Excel表格中的前 8條 或 前 8+ 條數據中的 這個列中的數據都是 由純數字組成的,如"2011072012","2011072013","2011072014",到了大於8行的時候的該列的數據組成變成了 數字+中文 + 字母的組合,這樣就會出現取不到該列值的問題
錯誤原因:
-----------------------------------------------------------------------
Excel讀取數據列的格式 是按照每一列前8個數據的類型來判斷讀寫時的類型的。比如前8個數據有3個是字幕,5個是數字,那么這一整列都是以數字型來讀的,類型最多的那么不管第8條之后是什么類型,都當作這個類型來讀取,那些字母都讀不了。
使用Microsoft.Jet.OLEDB.4.0讀取數據會出現當某一字段內分別含有文本和數字的混合數據時,某一類型的數據會產生丟失。
產生這種問題的根源與Excel ISAM[3](Indexed Sequential Access Method,即索引順序存取方法)驅動 程序的限制有關,Excel ISAM 驅動程序通過檢查前幾行中實際值確定一個 Excel 列的類型,然后選擇能夠代表其樣本中大部分值的數據類型 [4]。也即Excel ISAM查找某列前幾行(默認情況下是8行),把占多的類型作為其處理類型。例如如果數字占多,那么其它含有字母等文本的數據項 就會置空;相反如果文本居多,純數字的數據項就會被置空。
現具體分析在第1節程序代碼Extended Properties項中的HDR 和IMEX所代表的含義。HDR用來設置是否將Excel表中第一行作為字段名,“YES”代表是,“NO”代表不是即也為數據內容;IMEX是用來告訴 驅動程序使用Excel文件的模式,其值有0、1、2三種,分別代表導出、導入、混合模式。
當我們設置IMEX=1時將強制混合數據轉換 為文本,但僅僅這種設置並不可靠,IMEX=1只確保在某列前8行數據至少有一個是文本項的時候才起作用,它只是把查找前8行數據中數據類型占優選擇的行 為作了略微的改變。例如某列前8行數據全為純數字,那么它仍然以數字類型作為該列的數據類型,隨后行里的含有文本的數據仍然變空。
另一個改進的措施是IMEX=1與注冊表 值TypeGuessRows配合使用,TypeGuessRows 值決定了ISAM 驅動程序從前幾條數據采樣確定數據類型,默認為“8”。可以通過 修改“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel”下的該注冊表值來更 改采樣行數。但是這種改進還是沒有根本上解決問題,即使我們把IMEX設為“1”, TypeGuessRows設得再大,例如1000,假設數據表有 1001行,某列前1000行全為純數字,該列的第1001行又是一個文本,ISAM驅動的這種機制還是讓這列的數據變成空。
在sql server用法
SELECT *
FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0',
'Data Source="E:\數據.xls";
User ID=Admin;Password=;Extended properties=''Excel 8.0;HDR=YES;IMEX=1''')
-----------------------------------------------------------------------
在項目中加入如下代碼,自動修改注冊表!
RegistryKey reg_TypeGuessRows = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Jet\4.0\Engines\Excel"); reg_TypeGuessRows.SetValue("TypeGuessRows", 5000);