0

我正在尝试使用 Excel 互操作从电子表格中检索单元格值,但我正在使用的以下代码生成编译器错误:

找不到编译动态表达式所需的一种或多种类型。您是否缺少参考?

Range currentFind = sheet.Cells.Find("some string", Type.Missing,
                    XlFindLookIn.xlValues, XlLookAt.xlPart, 
                    XlSearchOrder.xlByRows, XlSearchDirection.xlNext,
                    false, Type.Missing, Type.Missing);

if (currentFind[1,1].Value != null)
{
    string CellValue = currentFind[1,1].Value.ToString();
}

知道这里发生了什么吗?我猜可能需要投射一些东西,但我不确定是什么。我试过 cast currentFind[1,1].Value,但这似乎不起作用。

编辑:

我找到了一种解决方法,设置Embed Interop TypesFalse参考,但我仍然想知道这里发生了什么以及如何处理这种情况。

4

2 回答 2

4

您是否添加了对Microsoft.CSharp以及的引用Microsoft.Office.Interop.Excel?这在过去为我解决了这个问题 - 例外情况是缺少解析属性dynamic类型所需的类型信息。Value异常通常也会尝试建议缺少的引用。

嵌入互操作类型发生了什么?

.NET (C#) 4.0 引入dynamic了将COM 主机返回对象值视为dynamic类型的能力。这应该让我们在编写代码时更轻松,因为我们不必在编写代码时将返回对象显式转换为我们想要的类型。如果true在您的程序集上设置了“嵌入互操作类型”,则会发生这种情况;这也是您在 VS 中添加的引用的默认值。

本质上,VS 是在编译时为您在程序集中使用的类型嵌入 PIA 的子集(请参阅“.net4 的新无 pia 功能 [部署 PIA] 的优势是什么”的答案,了解为什么这样做很好) . 但是,它需要访问参考树中的所有 PIA 才能执行此操作。

dynamic允许后期绑定。所以我猜你的情况Value已经成为一种动态类型,将在运行时解决,这是错误的,因为它无法获得正确的程序集和 PIA 参考。如果您将“嵌入互操作类型”设置为falsethenValue将成为一种object类型,这可以防止出现问题(但您现在需要在某个时候强制转换为正确的类型)。

为什么要嵌入 PIA 信息?

它可以使部署和支持多个版本的 Office 变得更加容易(只要您不使用比您测试的更早/更高版本中不受支持的功能)。不过,这并不容易;很多都可能出错。

MSDN - 演练:Office 编程(C# 和 Visual Basic)提到了这一点,但除了说它是一件好事之外,并没有把它当作什么大事。

例如:如果我在 VS2010 中启动一个项目并引用位于

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Visual Studio Tools for Office\PIA\Office12\Microsoft.Office.Interop.Excel.dll

然后我没有遇到这个问题,将嵌入互操作类型设置true为它会自动添加

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\Microsoft.CSharp.dll

也可以作为参考。如果我然后删除Microsoft.CSharp引用,我会收到编译器错误,但它会指出以下错误,这就是我最初找到解决方案的方式:

找不到编译动态表达式所需的一种或多种类型。您是否缺少对 Microsoft.CSharp.dll 和 System.Core.dll 的引用?

于 2013-05-23T18:13:26.727 回答
0

您似乎需要为您的项目添加一些参考。不确定您还有哪些其他代码,但如果是这样,您需要将互操作程序集添加到您的项目中。检查您的编辑器是否将任何行标记为错误,并检查您在该行中使用的对象的类型。

在旁注中,我看到以下行存在潜在问题:

if (currentFind[1,1].Value != null)

如果未找到该值,则 currentFind 为 null 并且您正尝试像访问数组一样访问 null。尝试检查 currentFind 是否不为空:

if (currentFind != null)
于 2013-05-14T10:02:58.013 回答