close

問題:

OleDB讀取Excel、csv時,某些有資料的欄位卻是空值!?
這是...OleDB的硬傷,先說明一下他的淺規則~


讀取的資料都有行列,每一行的前8格(預設),Excel會解析這8格裡面最多格的型態,並將此行預設為此符合此型態才給讀取,否則為空值。

來看看我們的例子:

 

Input:  

10
11
546
2154489
545
巴拉巴拉巴
454
55

 

Output:

"10"
"11"
"546"
"2154489"
"545"
""
"454"
"55"

 


 

 

解決方法1:
設定系統機碼!
事實上會有這樣的淺規則,就是因為微軟Excel的設定,OleDB是微軟以統一方式來訪問不同儲存格式的應用程式介面,所以OleDB會以Excel的設定來制定這樣的淺規則也是合理的吧。

所以我們只能乖乖的開啟機碼設定來進行修改:
Win xp
開始→搜尋→regedit→HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\3.5\Engines\Excel

Win 7
開始→搜尋→regedit→HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Excel

02    

 

Excel機碼中,ImportMixedTypes的預設值為Text,也就是我們讀取的Excel、csv檔案,若每1行的資料格式不一致,則Jet Engine將其欄位格式自動轉為文字格式。
Excel機碼中,TypeGuessRows 的預設值為8,也就是我們讀取的Excel、csv檔案,若每1行的前8格的資料格式不一致,Jet Engine將會以前8格裡面最多的型態來當作此行的預設型態,若此行某格非此行的預設型態,則讀取時會有null值。

所以,我們將ImportMixedTypes的值仍為Text、TypeGuessRows的值改為0,此時完成收工。
需注意的是將TypeGuessRows的值改為0,這樣一來Jet Engine會將所有資料讀取完再判斷每格欄位的資料型態!也就是說我們讀取的資料量越大,將會影響資料讀取的效能...

最後再提醒一件事,若是此功能需上架(當然會上架啦QQ),代表需修改server上的機碼...所以...上架的話還是放棄吧!以免接下來的開發、維護會哭哭。

 


 


解決方法1.1:
再利用OleDB讀取檔案時,設定檔案路徑設定的地方之中,在Extended Properties=''裡,加入ImportMixedTypes=Text與TypeGuessRows=0,有看過不少人討論這樣做是能解決的,但我沒試出來就是了...

string FileLocation = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\DataExcel.xls;Extended Properties='Excel 8.0;HDR=NO;IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0'";

 


 


解決方法2:
改用 NPOI 來讀取 Excel 吧!如此一來即能一格一格的判斷欄位格式。

使用NPOI.SS.UserModel.ICell.CellType就可以知道是什麼資料型態,接著用對應的資料型態的XXXCellValue屬性去取得資料。

這部分仍須再研究NPOI才是...若都做好要改很麻煩啊。囧rz

 



解決方法3:
設計讀取的excel、csv資料填寫格式,每一行都要填寫相同欄位格式,並且唬弄告知使用者相關的使用規定,開發者設定程式沒按照此設定走而導致讀取時出現null,將出現Error Message,告知使用者需修改相關資料。

騙吃騙吃啦!

 


 

 

結論:

大致上能想的到的解決方法就這幾種,以後有想到會再補上。

有參考到這篇唷!“透過 OleDb 精準讀入 Excel 檔的方法”。

http://blog.miniasp.com/post/2011/04/07/Open-a-ReadOnly-file-will-cause-UnauthorizedAccessException-in-TFS-project.aspx

 

arrow
arrow
    創作者介紹
    創作者 Thisway 的頭像
    Thisway

    Thisway的部落格

    Thisway 發表在 痞客邦 留言(0) 人氣()