2011-04-21 113 views
4

我有一個Excel 2007工作簿,其中包含我正在使用ADO.NET導入到DataTable對象中的數據表。有沒有更好的方式在Excel中表示「空」值?

通過一些實驗,我設法找到了兩種不同的方法來指示電池,應該以「空」的ADO.NET來處理:

  1. 細胞是完全空白。
  2. 該單元包含#N/A

不幸的是,這兩個是有問題的:

  1. 我的大部分在Excel中的數據列是通過公式生成的,但它不可能在Excel中生成一個公式,結果在一個完全空白細胞。只有一個完全空白的單元格纔會被認爲是空的(一個空字符串將不起作用)。

  2. 計算結果爲#N/A(由於實際的查找錯誤,或者因爲使用了NA()功能)被認爲無效的任何結構式。這似乎是理想的解決方案,直到我發現Excel工作簿必須打開才能正常工作。只要關閉工作簿,OLEDB就會突然開始將所有這些#N/A視爲字符串。這填寫DataTable時會導致類似下面的異常:

    輸入字符串格式不正確。無法在Value列中存儲<#N/A>。預期的類型是Int32。

問:我怎麼能指示,而不必有打開工作簿時,我填的是DataTable通過Excel公式一個空值?或者可以做些什麼來使#N/A的值即使在工作簿關閉時也被視爲空值?

在情況下,它是很重要的,我的連接字符串使用以下方法建立:

var builder = new OleDbConnectionStringBuilder 
{ 
    Provider = "Microsoft.ACE.OLEDB.12.0", 
    DataSource = _workbookPath 
}; 
builder.Add("Extended Properties", "Excel 12.0 Xml;HDR=Yes;IMEX=0"); 
return builder.ConnectionString; 

_workbookPath是完整路徑到工作簿)。

我試過IMEX=0IMEX=1但它沒有區別。

+0

I不能真正看到這個問題嗎?你有可能修改公式嗎? – Cilvic 2011-04-21 20:09:39

+0

@Cilvic,對不起,你是對的。我會添加一個。 – devuxer 2011-04-21 20:21:04

+0

@Cilvic,是的,我完全可以編輯公式。我需要知道的是公式結果將在null中。一旦我知道了,我可以編輯公式以在我需要任何時候生成該值。 – devuxer 2011-04-21 20:31:27

回答

6

您正在碰到許多非常令人沮喪的Excel用戶正在經歷的磚牆。不幸的是,Excel作爲一個公司工具非常普遍,而且看起來相當健壯,不幸的是,因爲每個單元格/列/行都有一個變體數據類型,所以它使用其他工具(如MySQL,SQL Server,R,RapidMiner,SPSS和名單繼續。看起來,Excel 2007/2010並沒有得到很好的支持,在考慮32/64位版本時更是如此,這在當今時代是很醜陋的。

主要問題是,當ACE/Jet訪問Excel中的每個字段時,他們使用註冊表設置'TypeGuessRows'來確定要使用多少行來評估數據類型。 「行掃描」的默認值是8行。註冊表設置'TypeGuessRows'可以從一(1)到十六(16)行指定一個整數值,或者您可以指定零(0)來掃描所有現有行。如果您無法更改註冊表設置(例如在90%的辦公環境中),則會使生活困難,因爲猜測的行數限制爲前8位。

例如,沒有註冊表更改 如果第一個#N/A的出現在前8行內,則IMEX = 1將以字符串「#N/A」的形式返回錯誤。如果IMEX = 0,則#N/A將返回'Null'。

如果#N/A的第一次出現超出前8行,則兩個IMEX = 0 & IMEX = 1都返回'Null'(假定所需的數據類型爲數字)。

隨着註冊表更改(TypeGuessRows = 0),那麼一切都應該沒問題。

或許有4個選項:

  1. 更改註冊表設置TypeGuessRows = 0

  2. 列表中的前8行作爲 '虛擬數據'(例如備忘錄場/ NCHAR所有可能類型的變化(最大值)/錯誤#N/A等)

  3. 改正所有數據類型在Excel

    異常
  4. 不要使用Excel - 認真值得考慮!

編輯: 只需要把引導的:)另外兩件事情真的激怒了我的;如果工作表上的第一個字段在前8行中空白,並且您無法編輯註冊表設置,則整個工作表會返回爲空白(許多有趣的對話告訴管理員他們是合併單元格的傻瓜!)。此外,如果在Excel 2007/2010中,如果您需要非連續導入(例如,列1中的關鍵字和列255+以上的數據),那麼您有一個部門返回具有> 255列/字段的工作表,那麼您將遇到大問題。

+0

+1,謝謝。我想我已經能夠通過在填充Excel數據之前將數據庫的模式導入到「DataTable」中來避免整個「使用前8行問題猜測數據類型」。不過,這並不能解決null問題。我想出了一個使用com interop的解決方案,它似乎爲我提供了所需的速度和靈活性。到目前爲止,它實際上比我的OLEDB解決方案更快。最後,我現在堅持使用Excel,因爲它非常適合我所做的工作(以及所有同事使用它),但確實有改進的餘地。 – devuxer 2011-04-23 01:57:53

+0

要小心..使用模式是好的,正確的做法,但從ACE/Jet返回的數據/記錄集不一定匹配您定義的模式。 – osknows 2011-04-23 02:16:32

+0

真的......我想我在想的是通過使用模式,至少會拋出一個異常來表明Excel確定的數據類型不正確。這就是說,使用interop而不是OLEDB可以完全避免這個問題。 – devuxer 2011-04-23 06:54:56

相關問題