2010-03-11 28 views
21

在Excel公式公式中的錯誤,您可以使用=ISERR(A1)=ISERROR(A1)如何知道,如果一個細胞在C#

在VBA宏,您可以使用IsError(sheet.Cells(1, 1))

但使用VSTO Excel加載項項目我沒有在Microsoft.Office.Interop.Excel API下找到類似的功能。我只想知道單元格中是否有錯誤,我對錯誤類型並不感興趣。

我目前的解決方法是爲所有現有的錯誤信息做到這一點:

if (((Range)sheet.Cells[1, 1]).Text == "#N/A" || ...) 

有沒有更好的方式來做到這一點。在API中有一個簡單的函數嗎?

+0

'(sheet.Cells [1,1] as Range).Text'看起來更好。 – 2010-03-11 12:24:35

+0

它看起來更好,但如果由於某些原因Cells [1,1]不是Range類型,那麼我們將有一個NullReferenceException而不是InvalidCastException。我更喜歡獲取更精確的Exception類型,而不是提高可讀性。 – Pascal 2010-03-15 11:53:31

回答

12

可以使用WorksheetFunction方法:

Globals.ThisAddIn.Application.WorksheetFunction.IsErr(...) 

[Your Excel Object].WorksheetFunction.IsErr(...) 

IsErr在語義上等同於Excel工作表的功能,只代替的小區基準通行中的實際值 - AFAIK 。

+2

快速注意:'WorksheetFunction.IsErr'將在設計中爲#N/A值返回false。因此,要使用這種方法,應該使用'WorksheetFunction.IsError'。如果你需要選擇*特定的* CVErr值,那麼你可以使用'WorksheetFunction.IsNA'來獲取#N/A值,但對於任何其他特定的CVErr類型,你必須使用我已經概述的方法下面。 – 2010-03-29 14:43:44

+0

感謝您的澄清,邁克! – code4life 2010-03-30 15:25:18

+0

出於某種原因,WorksheetFunction.IsError()不適用於我,但另一種解決方案(測試'是Int32')確實有效。 – earcam 2012-03-09 16:29:33

58

在.NET中處理CVErr值是一個非常棘手的問題。問題在於.NET(正確)將CVErr視爲錯誤處理的過時。但是,CVErr值仍然在Excel單元格中使用,所以這是Excel自動化的一個相當大的省略。

幸運的是,有一種解決方法。檢查CVErr值的方法是檢查單元格保存的數據類型。如果所保存的值被輸入爲Integer(Int32),則所保存的值爲CVErr。 (請注意,單元格中保存的數值通常被輸入爲Double,只有CVerr值可以作爲整數。)

也就是說,在最簡單的級別上,要測試CVErr值,您只需要做的就是使用下面的函數:

bool IsXLCVErr(object obj) 
{ 
    return obj is Int32; 
} 

如果需要檢查特定CVErr值(例如,#N/A),那麼你會先檢查,以確保數據類型是一個整數(Int32)已與然後根據下表檢查單元所具有的特定值:

  • -2146826281 =#DIV/0!
  • -2146826246 =#N/A
  • -2146826245 = #GETTING_DATA
  • -2146826259 =#NAME?
  • -2146826288 = #NULL!
  • -2146826252 = #NUM!
  • -2146826265 = #REF!
  • -2146826273 = #VALUE!

例如,你的代碼看起來是這樣的:

enum CVErrEnum : Int32 
{ 
    ErrDiv0 = -2146826281, 
    ErrGettingData = -2146826245, 
    ErrNA = -2146826246, 
    ErrName = -2146826259, 
    ErrNull = -2146826288, 
    ErrNum = -2146826252, 
    ErrRef = -2146826265, 
    ErrValue = -2146826273 
} 

bool IsXLCVErr(object obj) 
{ 
    return (obj) is Int32; 
} 

bool IsXLCVErr(object obj, CVErrEnum whichError) 
{ 
    return (obj is Int32) && ((Int32)obj == (Int32)whichError); 
} 

我對這個幾年前寫了一個詳細的兩篇文章:

這些文章是爲VB.NET編寫的,但其原理與C#完全相同。你應該沒有翻譯的麻煩,但如果你有任何問題,那麼請問。 (有一天我希望有時間爲C#更新這篇文章,如果發生這種情況,我會編輯帖子以包含鏈接。)

希望這有助於!

+10

這種類型的答案讓人們希望SO具有「每日超級提示」功能 – AakashM 2010-03-11 16:08:14

+0

感謝邁克這是我一直在尋找的信息。得到了奇怪的返回行數,並沒有意識到VBA將CVErr中的單元格與.net(將它們視爲Int值)的處理方式不同。 – 2010-03-12 05:04:40

+0

很高興這有所幫助!幾年前,當我第一次遇到這個問題時,真的讓我暈了一個循環,這是一個看似不可能解決的問題,所以一旦我找到了解決辦法,我只需要把它寫出來就可以了 – 2010-03-13 23:51:01