我正在使用Excel-DNA在Excel中开发一些UDF。从Excel传递到我的UDF的参数之一是范围。当使用特定范围(例如“ A1:C50”)时,UDF可以正常工作。以下是我的函数定义的示例:

[ExcelCommand()]
public static object CalcSMA(object[,] range, int num_points) {
    ...
}


但是,当传递整个列范围(例如“ A:C”)时,出现“内存不足”错误。我可以通过设置参数属性AllowReference = true并将参数类型更改为object来避免错误,如下例所示:

[ExcelCommand()]
public static object CalcSMA([ExcelArgument("Range", AllowReference=true)]object range, int num_points) {
    ExcelReference xref = (ExcelReference)range;
    ...
}


但是现在,我一直想知道UDF实际上需要多少行。我可以尝试迭代工作表中的所有行,但这效率很低。有没有一种方法可以将ExcelReference(xref)裁剪到使用的范围?我想避免使函数易失(IsMacroType = true),但是如果需要的话,会这样做。

最佳答案

在VBA(或COM)中,可以将Range参数与Range参数的父级的UsedRange相交。但是在XLL中,获取使用范围并不简单,因为XLL接口没有为工作表提供UsedRange方法。因此,您必须使用COM接口(从XLL UDF内部出现问题)。我构建了一个例程,该例程使用AfterCalculate事件来缓存每个工作表的已用范围。

这里有一些讨论方法
https://fastexcel.wordpress.com/2014/09/26/getting-used-range-in-an-xll-udf-multi-threading-and-com/

请注意,如果您愿意将UDF设为单线程宏类型UDF,则可以使用GETDOCUMENT(10)XLL api。但是痛苦可能不值得。

09-07 21:32
查看更多