C#Excel VSTO无法将字符串转换为String.Array

问题描述 投票:1回答:2

我是VSTO C#excel加载项的新手。我期待在一个范围内找到非空/空行的总数。我的代码查看范围“A4:E4”并计算总行数。

这是代码:

private void button1_Click(object sender, RibbonControlEventArgs e)
        {
            Workbook workbook =  Globals.ThisAddIn.GetWorkBook("c:\\temp\\testfile.xlsx");
            Worksheet mergeSheet = workbook.Worksheets["Data"];
            Excel.Range mergeCells = mergeSheet.Range["A4:E4"];
            var colValues = (System.Array)mergeCells.Columns[1].Cells.Value;
            var strArray = colValues.OfType<object>().Select(o => o.ToString()).ToArray();
            var rowCount = strArray.Length;
        }

 [public Excel.Workbook GetWorkBook(string pathName)
        {
            return (Excel.Workbook)Application.Workbooks.Open(pathName);
        }][1]

我得到错误var colValues = (System.Array)mergeCells.Columns[1].Cells.Value;on行:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'Cannot convert type 'string' to 'System.Array''

它在我的范围内有两行时有效。我有硬编码范围A4:E4产生错误。我的excel表(testfile.xlsx)如下所示:

enter image description here

任何想法如何解决这个问题?

当我有两行时,相同的代码行有效。例如,以下行更新

Excel.Range mergeCells = mergeSheet.Range["A4:E5"];

enter image description here

c# vsto excel-addins
2个回答
1
投票

问题是Range.Value可以返回不同类型的对象。其中,它可以回归

  • String类型的单个值,如果范围包含单个单元格包含字符串或
  • 一个值数组,如果范围包含多个单元格。

最简单的解决方案是计算单元格数并在数组中“包装”特殊的“单值”情况:

var range = mergeCells.Columns[1].Cells;
var values = (range.Count == 1)
    ? new object[] { range.Value })
    : ((Sytem.Array)range.Value).Cast<object>();

1
投票

这条线给我带来了麻烦,var colValues = (System.Array)mergeCells.Columns[1].Cells.Value

该行只有一个值。请注意,当mergeCells范围有两行时,相同的行有效。

Why it does not work for single cell range:

单个单元格的Value不是数组(它是Long,String,DateTime等),并且不会以这种方式转换为数组。您可以通过以下测试看到:

var myArray = (System.Array)"hello"

这会给其他类型带来同样的失败:

enter image description here

Why it works for multi-cell range:

多单元格范围的Value将返回单个单元格值的变体数组,这些数组要么是,要么可以转换为System.Array

可能有更好的分辨率,但至少你应该能够做到:

var colValues;
if (mergeCells.Columns[1].Cells.Count > 1)
{
    colValues = (System.Array)mergeCells.Columns[1].Cells.Value;
}
else
{
    // NB: you may need to cast other data types to string
    //     or you could use .Cells[0].Text.Split()
    colValues = (System.Array)mergeCells.Columns[1].Cells[0].Value.Split();
}
© www.soinside.com 2019 - 2024. All rights reserved.