2012-07-24 60 views
0

嗨我不斷從下面的代碼中獲取此錯誤,想知道是否有人可以幫助。空引用Excel文檔C#

error processing excel file: cannot perform runtime binding on a null reference 

代碼:

private void Import_Click(object sender, RoutedEventArgs e) 
    { 
     Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); 

     // Show open file dialog box 
     Nullable<bool> result = dlg.ShowDialog(); 

     // Process open file dialog box results 
     if (result == true) 
     { 
      // Open document 
      string filename = dlg.FileName; 

      Microsoft.Office.Interop.Excel.Application vExcelObj = new Microsoft.Office.Interop.Excel.Application(); 
      try 
      { 
       Microsoft.Office.Interop.Excel.Workbook theWorkbook = vExcelObj.Workbooks.Open(filename, Type.Missing, true); 

       Microsoft.Office.Interop.Excel.Worksheet sheet = theWorkbook.Worksheets[1]; 

       string vFirstName = "temp"; 
       string vLastName = "temp"; 
       int vIndex = 1; 

       while (vFirstName != "") 
       { 
        // Change the letters of the appropriate columns here! 
        // In my example, 'A' is first name, 'B' last name 
        vFirstName = sheet.get_Range("A" + vIndex.ToString()).Value.ToString(); // if i take out the exception handling the error is on this line 
        vLastName = sheet.get_Range("B" + vIndex.ToString()).Value.ToString(); 


        this.SaveNewCustomer(vFirstName, vLastName); 

        vIndex++; 

       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show("Error processing excel file : " + ex.Message); 
      } 
      finally 
      { 
       vExcelObj.Quit(); 
      } 
     } 
    } 

    private void SaveNewCustomer(string firstName, string lastName) 
    { 
     string uri = "http://localhost:8002/Service/Customer"; 
     StringBuilder sb = new StringBuilder(); 
     sb.Append("<Customers>"); 
     sb.AppendLine("<FirstName>" + firstName + "</FirstName>"); 
     sb.AppendLine("<LastName>" + lastName + "</LastName>"); 
     sb.AppendLine("</Customers>"); 
     string NewStudent = sb.ToString(); 
     byte[] arr = Encoding.UTF8.GetBytes(NewStudent); 
     HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri); 
     req.Method = "POST"; 
     req.ContentType = "application/xml"; 
     req.ContentLength = arr.Length; 
     Stream reqStrm = req.GetRequestStream(); 
     reqStrm.Write(arr, 0, arr.Length); 
     reqStrm.Close(); 
     HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); 
     reqStrm.Close(); 
     resp.Close(); 
    } 

} 

的代碼只是需要一個excel文件,並改掉將數據發送到我的web服務。

所以我嘗試使用下面的方法,但它凍結了應用程序:S沒有錯誤只是掛起。 編輯嘗試:

   while (vFirstName != "") 
       { 
         var columnACell = sheet.get_Range("A" + vIndex.ToString()); 
         var columnBCell = sheet.get_Range("B" + vIndex.ToString()); 
         var columnACellValue = columnACell.Value; 
         var columnBCellValue = columnBCell.Value; 


        if (columnACellValue != null && columnBCellValue != null) 
        { 
         vFirstName = columnACellValue.ToString(); 
         vLastName = columnBCellValue.ToString(); 

         this.SaveNewStaff(vFirstName, vLastName); //, vPassword 

         vIndex++; 
        } 
       } 
      } 

enter image description here

+0

哪一行引發異常? – Steve 2012-07-24 20:12:29

+0

'vFirstName = sheet.get_Range(「A」+ vIndex.ToString())。Value.ToString();' – 2012-07-24 20:15:38

+0

我想這個值返回null,然後調用ToString()失敗。檢查在對象var中獲取Value並測試它是否爲null。 – Steve 2012-07-24 20:18:23

回答

3

EDIT 2

剛接手的代碼,並通過它加強。發現問題。我想我誤解了最初發生的事情。

發生什麼事是循環while (vFirstName != "")將繼續前進,直到vFirstName是一個空字符串。但這絕不會發生!這裏的原因:

  • 一切都會好起來,只要列A和B將具有值。代碼將按預期行事。
  • 當代碼到達一個沒有值的Excel行時,它會打到一個空單元格,它將.Value設置爲null。這導致異常。

因此,真正的解決方案是讓循環繼續進行,直到它碰到具有null值的單元格,然後退出。有點像這樣:

while (true) { 
    // Split the satements 
    var columnACell = sheet.get_Range("A" + vIndex.ToString()); 
    var columnBCell = sheet.get_Range("B" + vIndex.ToString()); 
    var columnACellValue = columnACell.Value; 
    var columnBCellValue = columnBCell.Value; 

    if (columnACellValue != null && columnBCellValue != null) { 
     vFirstName = columnACellValue.ToString(); 
     vLastName = columnBCellValue.ToString(); 

    } else { 
     break; 
    } 

    this.SaveNewCustomer(vFirstName, vLastName); 

    vIndex++; 

}; 

剛剛測試這對我的結束,似乎工作。

在另外一個筆記上,請確保您完全退出Excel,因爲調用Excel.Quit()通常是不夠的。打開任務管理器,並檢查是否有額外的EXCEL.exe實例浮動。爲了防止那些我在完成它之後通常會殺死Excel(比正確釋放Excel的COM對象更容易),如this post中所述。


原帖

聽起來好像這裏有幾個選項:

  • 細胞是空的,這意味着它的.Valuenull
  • sheetnull
  • get_Range()返回null - 這聽起來不太可能。

將行拆分爲單獨的語句並查看其中哪一個引發錯誤。這會告訴你在哪裏看得更遠。

通過你正在做的事情來判斷 - 搜索列直到你找到名字 - 這聽起來像是你正在碰到單元格內的空值'Value s。爲了解決這個問題,我通常添加一個快速的if語句來測試Valuenull

編輯

下面是一個例子(可能無法編譯),希望能修復細胞內null價值,並幫助查明其他null - 相關問題。像這樣的東西更換有問題的線路:

var columnACell = sheet.get_Range("A" + vIndex.ToString()); 
var columnBCell = sheet.get_Range("B" + vIndex.ToString()) 
var columnACellValue = columnACell.Value; 
var columnBCellValue = columnBCell.Value; 

if (columnACellValue != null && columnBCellValue != null) { 
    vFirstName = columnACellValue.ToString(); 
    vLastName = columnBCellValue.ToString(); 
} 

注意,我假定你的C#編譯器通過var支持隱式靜態類型。

+0

你能否提供一個例子,與C的即時垃圾不得不得到的幫助,試圖創造這一點。這是原來的[問題](http://stackoverflow.com/questions/11270839/excel-doc-contents-to-webservice)? – 2012-07-24 20:24:28

+1

這指甲。 +1。我唯一需要添加/更改的是,雖然將行分成幾個語句將有助於縮小範圍(不管是否應該這樣做),但使用調試器並檢查輸入和輸出會使其成爲可靠的事情。 – Beska 2012-07-24 20:24:38

+0

嘿我試過你的方法,但它凍結了應用程序?我把我的問題編輯不知道如果我做正確 – 2012-07-24 20:35:24

0

表爲空。也許只有1個工作表?您正在使用工作表[1]返回第二個,當然.. :)

+0

你確定嗎?所有的Excel文檔都有3張作爲標準,並且在我的視圖中有3張工作表,我必須參考第一張工作表? – 2012-07-24 20:19:16

+2

我認爲Worksheets []是基於一個(從一個而不是零開始),所以Worksheets [1]將成爲這種情況下的第一個工作表。 – 2012-07-24 20:20:39

+0

那麼,是不是也可能是get_Range調用返回null,然後在試圖獲取Value時拋出? – Beska 2012-07-24 20:21:21

0

嘗試拆分讀取值的代碼並測試它是否爲null。

object oName = sheet.get_Range("A" + vIndex.ToString()).Value; 
vFirstName = (oName == null ? string.Empty : oName.ToString(); 
object oLast = sheet.get_Range("B" + vIndex.ToString()).Value; 
vLastName = (oLast == null ? string.Empty : oLast.ToString()); 
if(vFirstName.Length > 0 && vLastName.Length > 0) 
    this.SaveNewCustomer(vFirstName, vLastName); 

並注意到在您的SaveNewStaff/Customer(....)中關閉了RequestStream兩次。 也許第二次關閉凍結你的代碼。

reqStrm.Close(); 
    HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); 
    reqStrm.Close(); // <= Already closed before? 
+0

嗨tryed同樣的問題應用程序仍然凍結。這很奇怪,因爲它們仍然添加到服務中,只是不明白爲什麼我打開並導入Excel文檔後程序凍結。 – 2012-07-24 21:07:05

+0

如果你在while指令上設置了一個斷點,然後按下了F11的代碼,那麼代碼會在哪一行凍結? – Steve 2012-07-24 21:10:54