2013-02-23 63 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