1

我是用 C# 编写加载项的新手(对于 C# 也是如此)。我已经看到 ExcelDNA 非常适合简单的函数,但我被一个简单的任务困住了:操纵范围(特别是通过它们的名字来解决)。您会看到我尝试将 Interop 用于此任务,这对我来说看起来很简单。在这段非常简单的代码中我做错了什么?我已经去了 ExcelDNA 谷歌小组,但我只发现了非常尴尬的答案

首先十分感谢

使用 ExcelDna.Integration;

namespace MyAddIn
{
    public class MyClass    {
        [ExcelFunction(Category = "MyFunctions", IsMacroType = true)]
        public static string MyMacro(int a, int b)
        {
            var app = (Microsoft.Office.Interop.Excel.Application) ExcelDnaUtil.Application;
            var range = app.get_Range("MyTag"); // this line does not fail, but I don't know if it
                                                // selects the right range -- although MyTag exists
            range.set_Value("hello") // it fails here            
            return (string) range.Value2; // or it would fail here as well
        }
    }
}

它抛出这个错误

mscorlib.dll 中出现“System.Reflection.TargetInvocationException”类型的第一次机会异常 mscorlib.dll 中出现“System.Runtime.InteropServices.COMException”类型的第一次机会异常

4

1 回答 1

2

如果您注释掉 set_range 行,并确保 MyTag 单元格中有一个字符串,您的函数就可以正常工作。

主要问题在于 set_Range 尝试。Excel 不允许您从工作表函数设置工作表的其他部分。您需要将其更改为由菜单或功能区按钮触发的宏(返回“void”)。(设置 IsMacroType=true 不会将您的函数变成宏,它只是将您的函数注册为特殊类型。)

你可以试试:

[ExcelCommand(MenuName="My Macros", MenuText="Set MyTag value")]
public static void MySetterMacro()
{
    var app = (Microsoft.Office.Interop.Excel.Application) ExcelDnaUtil.Application;
    var range = app.Range["MyTag"];
    range.Value = "Hello there!";
}                

我假设您使用的是 C# 4,所以我们不需要 get_Value、set_Value 的东西。如果您使用的是 C# 3.5,我认为您需要说

range.set_Value(Type.Missing, "Old-Style Hello");

因为 Value 是一个参数化的属性,而 C# 4 之前的 C#/COM 互操作被延迟了。

于 2011-08-19T06:14:52.833 回答