3

C# を使用して Excel スプレッドシートからデータを取得しようとしています。スプレッドシートのデータには、次の特徴があります。

  • 列名が割り当てられていません

  • 行はさまざまな列の長さを持つことができます

  • 一部の行はメタデータであり、これらの行は次の行の列の内容にラベルを付けます

したがって、作成する必要があるオブジェクトの名前は常に最初の列にあり、そのパラメーターは次の列に含まれています。上の行からパラメーター名を取得することが重要です。例:

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

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

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

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

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

残念ながら、データは異種であり、どの行が「一緒に属する」かを判断する唯一の方法は、行の最初の列が空であるかどうかを確認することです。そうである場合は、その行のすべてのデータを読み取り、上の行を確認して、適用されるパラメーター名を確認します。最初は、簡単なアプローチは単純にループすることだと思いました

1) すべてのシートを含むデータセット、
2) データテーブル (シート)、
3) 行。

しかし、ネストされたループと if ステートメントを使用してこのデータを抽出しようとすると、恐ろしい、判読不能で柔軟性のないコードになることがわかりました。LINQ でこれを行う方法はありますか? この記事を見て、データ間の空の行をフィルタリングすることから始めましたが、実際にはどこにも行きませんでした。誰かがいくつかのコードスニペットで正しい方向に私を向けることができますか?

前もって感謝します !ヒロ

4

1 に答える 1

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);
    }
}
于 2013-02-23T16:40:53.230 に答える