在 vsto 工作簿应用程序中按名称获取工作表
getting worksheet by name in vsto workbook application
此代码通过功能区在 VSTO excel 工作簿应用程序中将工作表添加到我的工作簿:
Globals.ThisWorkbook.Worksheets.Add();
Excel.Window window = e.Control.Context;
Excel.Worksheet activeWorksheet =((Excel.Worksheet)window.Application.ActiveSheet);
添加的工作表也是活动的(很明显)。如何在工作簿应用程序中获取现有工作表 - 最好是按名称?
这给了我(在我添加上面的工作表之前)2 正确,因为有 2 个工作表:
var nows = Globals.ThisWorkbook.Worksheets.Count;
有人会认为我至少可以像这样通过索引访问工作表:
var ws = Globals.ThisWorkbook.Worksheets[0];
但这会抛出这个异常:
$exception {"Invalid index. (Exception from HRESULT: 0x8002000B (DISP_E_BADINDEX))"} System.Runtime.InteropServices.COMException
有什么想法吗?理想情况下,我想通过 name 访问工作表。谢谢!
更新: 对不起,我错过了你说的最后一行:
Ideally, I would like to access the worksheets via name. Thanks!
实际上 Excel Ole Automation 允许您通过 相同 索引器按名称访问工作表:
而不是:
var ws = Globals.ThisWorkbook.Worksheets[1];
...只需使用:
var ws = Globals.ThisWorkbook.Worksheets["Foo"];
在这种情况下,看起来像 C# 的索引器实际上是简写的:
var ws = Globals.ThisWorkbook.Worksheets.Item("Foo");
...其中传入 Item()
的参数是一个对象(就 COM 而言,Variant
)。 COM 集合的约定是公开一个带参数的项目 属性(是的,您没有看错),但是 VB 和 .NET 简化了它。
原答案:
Excel 通过 .NET 的互操作是通过 Ole Automation 实现的,这在历史上可以追溯到通过 Visual Basic(不是 VB.NET)应用程序访问大多数内容的时代,这些应用程序使用 1-based arrarys and not 0
.
访问第一个元素的正确语法是:
var ws = Globals.ThisWorkbook.Worksheets[1];
您可以使用 LINQ 在集合中查询您感兴趣的 Worksheet
的名称。
以下returns单匹配Worksheet
或null
.
var worksheet =
Globals.ThisWorkbook.Worksheets.Cast<Worksheet>()
.SingleOrDefault(w => w.Name == "worksheet_name");
如果可能有多个同名,请使用 Where()
和 ToList()
。
var worksheet =
Globals.ThisWorkbook.Worksheets.Cast<Worksheet>()
.Where(w => w.Name == "worksheet_name")
.ToList();
此代码通过功能区在 VSTO excel 工作簿应用程序中将工作表添加到我的工作簿:
Globals.ThisWorkbook.Worksheets.Add();
Excel.Window window = e.Control.Context;
Excel.Worksheet activeWorksheet =((Excel.Worksheet)window.Application.ActiveSheet);
添加的工作表也是活动的(很明显)。如何在工作簿应用程序中获取现有工作表 - 最好是按名称?
这给了我(在我添加上面的工作表之前)2 正确,因为有 2 个工作表:
var nows = Globals.ThisWorkbook.Worksheets.Count;
有人会认为我至少可以像这样通过索引访问工作表:
var ws = Globals.ThisWorkbook.Worksheets[0];
但这会抛出这个异常:
$exception {"Invalid index. (Exception from HRESULT: 0x8002000B (DISP_E_BADINDEX))"} System.Runtime.InteropServices.COMException
有什么想法吗?理想情况下,我想通过 name 访问工作表。谢谢!
更新: 对不起,我错过了你说的最后一行:
Ideally, I would like to access the worksheets via name. Thanks!
实际上 Excel Ole Automation 允许您通过 相同 索引器按名称访问工作表:
而不是:
var ws = Globals.ThisWorkbook.Worksheets[1];
...只需使用:
var ws = Globals.ThisWorkbook.Worksheets["Foo"];
在这种情况下,看起来像 C# 的索引器实际上是简写的:
var ws = Globals.ThisWorkbook.Worksheets.Item("Foo");
...其中传入 Item()
的参数是一个对象(就 COM 而言,Variant
)。 COM 集合的约定是公开一个带参数的项目 属性(是的,您没有看错),但是 VB 和 .NET 简化了它。
原答案:
Excel 通过 .NET 的互操作是通过 Ole Automation 实现的,这在历史上可以追溯到通过 Visual Basic(不是 VB.NET)应用程序访问大多数内容的时代,这些应用程序使用 1-based arrarys and not 0
.
访问第一个元素的正确语法是:
var ws = Globals.ThisWorkbook.Worksheets[1];
您可以使用 LINQ 在集合中查询您感兴趣的 Worksheet
的名称。
以下returns单匹配Worksheet
或null
.
var worksheet =
Globals.ThisWorkbook.Worksheets.Cast<Worksheet>()
.SingleOrDefault(w => w.Name == "worksheet_name");
如果可能有多个同名,请使用 Where()
和 ToList()
。
var worksheet =
Globals.ThisWorkbook.Worksheets.Cast<Worksheet>()
.Where(w => w.Name == "worksheet_name")
.ToList();