按标题名称而不是列索引引用VSTO Excel ListObject的列

时间:2011-12-22 13:30:12

标签: excel vsto

实际上,我可以使用以下代码轻松读取VSTO中ListObject的内容。

在这个例子中,我正在阅读给定工作表中的所有产品。使用Excel表格编辑数据,该表格转换为VSTO内的ListObject。我正在使用VS2010和.NET 4.0以及Excel 2010。

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;
}

但有时用户想要添加另一行甚至更改表的列顺序。所以我想知道是否有更好的方法来引用列名而不是列索引。

对此可接受的解决方案是这样的:

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

提前感谢您对此提出的任何建议。

5 个答案:

答案 0 :(得分: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 :(得分:1)

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

假设您的表名为dataTable,其中包含3列(a,b,c)和2列 注意:我正在使用VBA。我认为在使用DataBodyRange时你可以工作。

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

答案 2 :(得分:0)

Sheet1.ListObjects(“dataTable”)。ListColumns [“ColumnName”]。范围[rowOfInterest]?

答案 3 :(得分:0)

由于ListObject不提供该功能,您也可以使用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;
   ...
}

答案 4 :(得分:0)

可以直接按列名访问ListObject列。 @shahkalpesh和@gap很接近,但ListObjects上的索引器成语(VBA,而不是c#)是不匹配的。下面的示例构建一个简单的表,引用第二列的名称,&#34; ColName2&#34;,并修改第二列中的第一个数据单元格;

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;

请注意,您可以使用&#39; DataBodyRange&#39;或者&#39;范围&#39 ;; &#39; DataBodyRange&#39;排除列标题,这通常是合适的。

相关问题