2013-02-23 66 views
3

我想從使用C#的Excel電子表格檢索數據。在電子表格中的數據有如下特點:從Excel中檢索「行對」

  • 沒有列名稱分配

  • 行可具有不同的柱長度

  • 一些行是元數據,並且這些行標記內容下一行

因此在列的,我需要構造對象總是有他們的名字第第一列,其參數包含在下一列中。從上面的行中檢索參數名稱很重要。舉個例子:

row1|---------|FirstName|Surname| 

row2|---Person|Bob------|Bloggs-| 

row3|---------|---------|-------| 

row4|---------|Make-----|Model--| 

row5|------Car|Toyota---|Prius--| 

因此,不幸中的數據是異構的,並且只有這樣才能確定是什麼行「屬於彼此」是檢查該行的第一列是否爲空。如果是,則讀取該行中的所有數據,並通過檢查上面的行來檢查哪些參數名稱適用。 起初我認爲直接的方法是簡單地通過循環

1)含有的所有片材的數據集,然後
2)的數據表(即片材),並
3)的行。

但是,我發現試圖使用嵌套循環提取此數據,並且如果語句導致可怕的,不可讀和不靈活的代碼。 有沒有辦法在LINQ中做到這一點?我看了一下this article,從數據之間的空行過濾開始,但沒有真正得到任何地方。請問有人可以用一些代碼片段指向正確的方向嗎?

在此先感謝! hiro

+0

我很確定,LINQ不是那種問題的好選擇。即使你使用LINQ完成它,它也將是不可讀和不靈活的,這是因爲你正在嘗試閱讀的數據,而不是因爲選擇這樣做的方法。 – MarcinJuraszek 2013-02-23 14:33:01

回答

3

我看到你已經接受了答案,但我認爲更通用的解決方案是可能的 - 使用反射。

假設您的數據爲List<string[]>,其中列表中的每個元素都是包含相應行中所有單元格的字符串數組。

List<string[]> data; 
data = LoadData(); 

var results = new List<object>(); 
string[] headerRow; 

var en = data.GetEnumerator(); 
while(en.MoveNext()) 
{ 
    var row = en.Current; 
    if(string.IsNullOrEmpty(row[0])) 
    { 
     headerRow = row.Skip(1).ToArray(); 
    } 
    else 
    { 
     Type objType = Type.GetType(row[0]); 
     object newItem = Activator.CreateInstance(objType); 

     for(int i = 0; i < headerRow.Length; i++) 
     { 
      objType.GetProperty(headerRow[i]).SetValue(newItem, row[i+1]); 
     } 
     results.Add(newItem); 
    } 
} 
+0

輝煌!這與我所期望的解決方案非常接近。威廉希望它是好的,如果將此標記爲解決方案,但您的輸入同樣讚賞當然=) – 2013-02-23 17:10:03

+1

好!我喜歡反思...... +1 – Willem 2013-02-23 17:15:11

+0

@MarcinJuraszek我對C#並不熟悉,但這個想法很優雅。 VBA是否可行 - 您能否提供鏈接或樣本?當然這是一個公平的upvote。 – 2013-02-23 18:57:39