如何将不连续的单元格范围从 Excel 传递到 ExcelDNA 函数

How to pass discontinuous range of cells from Excel to ExcelDNA function

考虑这样的 ExcelDNA 函数定义:

[ExcelFunction(Name = "Fnc1", Description = "Fnc1")]
public static object Fnc1(
    [ExcelArgument(Name = "Arg1", Description = "Arg1", AllowReference = true)]
    object rng)
{
    // ...
}

Is there a way how to call ExcelDNA function with discontinuous range of unknown amount of cells?

我试过像这样声明参数params object[] rng,但也不走运。

为了拥有一个 Excel-DNA 函数,允许在 运行 时传入 未知 个参数,您需要使用params object[] 在你的函数参数中。

public static class MyFunctions
{
    [ExcelFunction]
    public static object Hello(params object[] values)
    {
        return "Hello " + DateTime.Now;
    }
}

那么使用硬编码值调用它并不重要,例如=Hello(10, 20) 或者如果您使用单元格引用,例如=Hello(A1,A5,A10).

但是,Excel-DNA 不支持开箱即用的可变参数数量,因此您必须使用 ExcelDna.Registration 帮助程序库才能注册您的函数。

安装 ExcelDna.Registration NuGet package,然后在 .dna 文件中,标记要使用 ExplicitRegistration 的加载项程序集引用,例如:

<?xml version="1.0" encoding="utf-8"?>
<DnaLibrary Name="My Add-In" (...)>
  <ExternalLibrary Path="MyAddIn.dll" ExplicitRegistration="true" (...) />
</DnaLibrary>

然后,在您的 AutoOpen 中,您使用 ProcessParamsRegistrations 调用注册函数...例如

public class AddIn : IExcelAddIn
{
    public void AutoOpen()
    {
        ExcelRegistration
            .GetExcelFunctions()
            .ProcessParamsRegistrations()
            .RegisterFunctions();

        // ...
    }

    public void AutoClose()
    {
        // ...
    }
}

Implicit vs Explicit Registration of functions

默认情况下,Excel-DNA 会搜索程序集中的每个 public static 方法,并将它们注册为 Excel 的函数。这就是隐式注册过程。

ExplicitRegistration="true" 关闭 关闭 隐式注册,因此不会自动注册任何内容 - 你必须自己做 - 这就是我在 AutoOpen 上面的 ... RegisterFunctions() 调用。 如果您不关闭 隐式 注册,那么函数最终会被注册两次(一次通过隐式过程,然后通过您的代码)你会收到错误消息

如果您想允许多个参数,其他答案很有用,并且可能最容易让最终用户使用。但是您也可以通过在公式中添加括号将不连续的范围直接传递到您开始的单个 AllowReference=true 参数中:

=Fnc1((A1,A5,A10:A12))

您得到的单个 ExcelReference 将有多个 InnerReferences 用于不相交的部分。

括号消除了将逗号用作范围联合运算符和函数调用中的参数分隔符之间的歧义。