2017-05-04 16 views
2

我遇到以下問題。第一部分代碼通過將所有不同的值拉入列表框供用戶查看。但是,當數據被過濾時,它仍然拉入所有不是我想要的隱藏值。當我試圖只將可見細胞拉入範圍時,它打破了我的範圍轉換爲不同的列表。關於爲什麼打破範圍打破這個任何想法? System.Array myvalues行代碼中斷行「Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:無法將類型'字符串'轉換爲'System.Array'」。對我來說似乎很奇怪。非線性Excel範圍C中的不同列表#

工作代碼:

Range values = sht.Range[cell1, cell2]; 
System.Array myvalues = (System.Array)values.Cells.Value; 
string[] listValues = myvalues.OfType<object>().Select(o => o.ToString()).ToArray(); 
string[] listValues2 = listValues.Distinct().ToArray(); 

斷碼:

Range values = sht.Range[cell1, cell2].SpecialCells(XlCellType.xlCellTypeVisible); 
System.Array myvalues = (System.Array)values.Cells.Value; 
string[] listValues = myvalues.OfType<object>().Select(o => o.ToString()).ToArray(); 
string[] listValues2 = listValues.Distinct().ToArray(); 

編輯:

工作的代碼來處理時,範圍是隱藏的,當它不是:

var extractedFromSheet = new List<object>(); 
      foreach (Range area in values.Areas) 
      { 
       var areaValue = area.Value; 
       if (areaValue is Array) // The area contains multiple cells 
       { 
        var arr = (Array)areaValue; 
        extractedFromSheet.AddRange(arr.OfType<object>().Select(o => o .ToString())); 
       } 
       else // The area contains one cell 
       { 
        extractedFromSheet.Add(areaValue); 
       } 
      } 
      var distinct = extractedFromSheet.Distinct(); 
+0

無法重現錯誤。我所看到的是當範圍的某些部分被過濾器隱藏時,範圍被劃分爲'Areas'。但是這不會導致錯誤,但是'Value'只返回第一個'Area'。 – dee

回答

2

xlCellTypeVisible返回非連續的Range。該範圍有一個.Areas屬性,每個屬性也是一個Range。嘗試迭代values.Areas並從這些範圍中獲取值。

您還需要檢查每個值,因爲它可能是單個值或數組,取決於區域是包含一個單元還是多個單元。這可能是你看到的錯誤。它從一個單元格讀取單個字符串,因此它不返回數組。

這應該這樣做或接近:

var extractedFromSheet = new List<object>(); 
foreach(Range area in values.Areas) 
{ 
    var areaValue = area.Value; 
    if(areaValue is Array) // The area contains multiple cells 
    { 
     extractedFromSheet.AddRange((System.Array)areaValue); 
    } 
    else // The area contains one cell 
    { 
     extractedFromSheet.AddRange(areaValue); 
    } 
} 
var distinct = extractedFromSheet.Distinct(); 

這是一個有點亂了,一個屬性可以返回任何類型的對象或數組。我甚至不記得你必須做的所有事情,以確保引用COM對象得到清理。

https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range.areas.aspx

+0

謝謝,我其實並不知道.Areas屬性。今天會試試這個。 – Clouse24

+1

我也是,我和Excel一起工作了一段時間。這很混亂,因爲它打破/忽略了OOP的所有原則。一個'Range'應該表現得像'Range',其行爲就像'Range'。但是知道你有'Range'並不能告訴你它是如何表現的。 –

+0

所以我不得不將If語句更改爲以下內容以使其適用於所有場景。對於這些對象來說,這是一種很奇怪的方式。 (areaValue是Array)//該區域包含多個單元格 var arr = extractedFromSheet.AddRange(arr.OfType ().Select(o => o .ToString())); } else //該區域包含一個單元格 { extractedFromSheet.Add(areaValue); } – Clouse24