2011-12-22 3 views
2

実際には、次のコードを使用してVSTOのListObjectの内容を簡単に読み取ることができます。参照VSTO Excel ListObjectの列を列のインデックスではなくヘッダー名

この例では、特定のシートからすべての製品を読み込んでいます。データは、VSTO内のListObjectに変換されるExcelテーブルを使用して編集されます。私は

private IEnumerable<Produto> ReadFromWorksheet() 
{ 
    var produtosLidos = new List<Produto>(); 


    try 
    { 
     foreach (Excel.ListRow row in Globals.Sheet1.tblProdutos.ListRows) 
     { 

      var id = RangeUtils.ToInt(row.Range[1, 1]) ?? -1; 
      var codigo = RangeUtils.ToString(row.Range[1, 2]); 
      var nome = RangeUtils.ToString(row.Range[1, 3]); 
      var qtdDisp = RangeUtils.ToDecimal(row.Range[1, 4]); 
      var unidMed = RangeUtils.ToString(row.Range[1, 5]); 
      var valor = RangeUtils.ToDecimal(row.Range[1, 6]); 


      if (string.IsNullOrEmpty(codigo) ||nome == null || qtdDisp == null || unidMed == null || valor == null) 
       throw new ApplicationException("Os campos Nome, Qtd. Disponível, Unid. de Medida e Valor são obrigatórios."); 


      var p = new Produto(); 
      p.Id = id; 
      p.CodigoProduto = codigo; 
      p.Nome = nome; 
      p.QtdDisponivel = qtdDisp; 
      p.UnidadeMedida = unidMed; 
      p.Valor = valor; 
      p.DataUltimaAlteracao = DateTime.Now; 
      p.Acao = RangeUtils.ToString(row.Range[1, 8]); 
      p.Ativo = true; 

      produtosLidos.Add(p); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
     return null; 
    } 
    return produtosLidos; 
} 

エクセル2010、また、.NET 4.0としてVS2010を使用しています。しかし、時にはユーザーが別の行を追加したり、テーブルの列の順序を変更できます望んでいます。ですから、列インデックスの代わりに列名で各行を参照する方が良いかどうかを知りたいと思います。この上の任意のアドバイスを事前に

var myValue = row.Range[1, "My Value"]; 

ありがとう:このため

受け入れ可能な解決策は、このようなものになるだろう。

答えて

1
Sheet1.ListObjects("dataTable").DataBodyRange(2, "b").Value 

テーブルが3列(a、b、c)と2行のdataTableという名前であると仮定します。
注:私はVBAを使用しています。私はDataBodyRangeを使用するときにあなたのことがうまくいくと思っています。

var myValue = Sheet1.ListObjects("dataTable").DataBodyRange[1, "myColumnHeader"]; 
+0

こんにちは@shahkalpesh、私はこの技術を試して、それは動作しませんでした。 VSTOはこのような列へのアクセス方法を受け入れていないようです。例外は次のとおりです。型の不一致。 (HRESULTからの例外:0x80020005(DISP_E_TYPEMISMATCH))。私は次のコードで試しました:for(int i = 1; i <= Globals.Sheet1.tblProdutos.ListRows.Count; i ++) { var value = _tbl.DataBodyRange [1、 "Valor Previsto"]; Debug.WriteLine(value); } –

+0

@MárioMeyrelles:テーブル名、シート名、列名を設定ごとに変更して、上記のVBAコードがあなたのケースで機能するかどうか試してみることはできますか? – shahkalpesh

+0

こんにちは@shahkalpesh、私はVBAの内部でこのアプローチを試して、それは動作しませんでした。 Sub Button1_Click() 'うまく動作します。 Debug.Print Sheet6.ListObjects( "tblSaidas")。DataBodyRange(1、1)。値 が列である ' ます。Debug.Print Sheet6.ListObjects( "tblSaidas")。DataBodyRange(1、 "武勇Previstoを")は動作しません。値 End Subの –

2

私はちょうど同様の問題に遭遇しました。ここでヘッダー名に行ったのは、

private void listSPRData_BeforeDoubleClick(Range Target, ref bool Cancel) 
{ 
    foreach (Range c in Target.ListObject.HeaderRowRange.Cells) 
    { 
     // Do something... 
     // "c.Value" contains the name of your header. 
     // When you find your column, you can break to avoid unnecessary looping. 
    } 
} 

希望です。

+1

このような状況を克服するカスタムソリューションを開発しなければなりませんでした。基本的には、VSTOの読み込みでは、すべての列とそのインデックスを辞書にマップし、このマッピングをクラスフィールドに格納することです。 public void ReadColumnPositions() { cols =新しい辞書(); オブジェクト[、] columnData = _tbl.HeaderRowRange.Value; (int i = 1; i <= columnData.GetLength(1); i ++) cols.Add(columnData [1、i] .ToString()、i); } } –

0

Sheet1.ListObjects( "dataTable")。ListColumns ["ColumnName"]。範囲[rowOfInterest]? ListObjectは、その機能を提供していませんので

+0

コンパイラエラー:「呼び出し不可能なメンバ 'sheet1.ListObjects」をメソッドのように使用することはできません。 –

0

、代わりにあなたがRange.Findを使用することができます。..

Range cellFind = Sheet1.Cells.Find(What: "Column your looking for", After: Type.Missing, LookIn: Excel.XlFindLookIn.xlValues, LookAt: Excel.XlLookAt.xlWhole, SearchOrder: Excel.XlSearchOrder.xlByColumns, SearchDirection: Excel.XlSearchDirection.xlNext, MatchCase: false, SearchFormat: false); 

if (cellFind != null) 
{ 
    int columnIndex = cellFind.Column; 
    ... 
} 
0

あなたことができ、列名によって直接アクセスListObject列。 @shahkalpeshと@gapは近いですが、ListObjectsのインデクサイディオム(VBA、c#ではなく)はミスマッチです。以下の例は、単純なテーブルを作成し、2番目の列をその名前 "ColName2"で参照し、2番目の列の最初のデータセルを変更します。

object[,] Data = new object[,] {{ "ColName1", "ColName2"}, { 11, 12 }, {21, 22 }}; 
Excel.Range tblRange = Globals.SParameters.Range["B20:C22"]; 
tblRange.Value = Data; 

Globals.SParameters.Controls.AddListObject(tblRange, "tblProdutos"); 
Globals.SParameters.ListObjects["tblProdutos"].ListColumns["ColName2"].DataBodyRange[1] = 55; 

「DataBodyRange」または「Range」を使用できます。 'DataBodyRange'は、通常適切な列ヘッダーを除外します。

関連する問題