C# Excel VSTO 无法将字符串转换为 String.Array
C# Excel VSTO can not convert string to String.Array
我是 VSTO C# excel 加载项的新手。我正在寻找一个范围内的非 null/empty 行的总数。我的代码查看范围 "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;
:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'Cannot convert type 'string' to 'System.Array''
当我的范围内有两行时它会起作用。我对范围 A4:E4 进行了硬编码以产生错误。我的 excel sheet (testfile.xlsx) 如下所示:
有什么办法可以解决这个问题吗?
当我有两行时,同一行代码有效。例如,以下行已更新
Excel.Range mergeCells = mergeSheet.Range["A4:E5"];
This line is causing me trouble, var colValues = (System.Array)mergeCells.Columns[1].Cells.Value
This row has only one value. Note that same line works when mergeCells
range has two rows.
为什么它不适用于单个单元格范围:
单个单元格的 Value
不是数组(它是 Long、String、DateTime 等),不会以这种方式转换为数组。您可以通过如下测试看到这一点:
var myArray = (System.Array)"hello"
这将给其他类型带来同样的失败:
为什么它适用于多单元格范围:
多单元格区域的 Value
将 return 单个单元格值的变体数组,它可以是或可以转换为 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();
}
问题是 Range.Value
可以 return 不同类型的对象。其中,它可以return
- 类型为
String
的单个值,如果范围包含单个包含字符串的单元格或
- 一组值,如果范围包含多个单元格。
最简单的解决方案是计算单元格的数量和 "wrap" 数组中的特殊 "single value" 情况:
var range = mergeCells.Columns[1].Cells;
var values = (range.Count == 1)
? new object[] { range.Value })
: ((Sytem.Array)range.Value).Cast<object>();
我是 VSTO C# excel 加载项的新手。我正在寻找一个范围内的非 null/empty 行的总数。我的代码查看范围 "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;
:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'Cannot convert type 'string' to 'System.Array''
当我的范围内有两行时它会起作用。我对范围 A4:E4 进行了硬编码以产生错误。我的 excel sheet (testfile.xlsx) 如下所示:
有什么办法可以解决这个问题吗?
当我有两行时,同一行代码有效。例如,以下行已更新
Excel.Range mergeCells = mergeSheet.Range["A4:E5"];
This line is causing me trouble,
var colValues = (System.Array)mergeCells.Columns[1].Cells.Value
This row has only one value. Note that same line works when
mergeCells
range has two rows.
为什么它不适用于单个单元格范围:
单个单元格的 Value
不是数组(它是 Long、String、DateTime 等),不会以这种方式转换为数组。您可以通过如下测试看到这一点:
var myArray = (System.Array)"hello"
这将给其他类型带来同样的失败:
为什么它适用于多单元格范围:
多单元格区域的 Value
将 return 单个单元格值的变体数组,它可以是或可以转换为 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();
}
问题是 Range.Value
可以 return 不同类型的对象。其中,它可以return
- 类型为
String
的单个值,如果范围包含单个包含字符串的单元格或 - 一组值,如果范围包含多个单元格。
最简单的解决方案是计算单元格的数量和 "wrap" 数组中的特殊 "single value" 情况:
var range = mergeCells.Columns[1].Cells;
var values = (range.Count == 1)
? new object[] { range.Value })
: ((Sytem.Array)range.Value).Cast<object>();