如何在 F# 中编写一个可以从 Excel 调用的函数,它将一个范围作为输入并将一个数组输出到 ssheet 中?
How do I write a function in F# that can be called from Excel and which will take a range as input and output an array into the ssheet?
我知道如何在 C# 中执行此操作,并且我可以使用 Excel DNA 创建加载项。我无法弄清楚启用函数 f 的 F# 语法,为了简单起见,它执行类似于 f(x)= 维数 [2,2] 的二维数组,其中包含 x 的所有 4 个值。因此,我将从 excel 中调用 f,从单元格中获取输入,它会 return 2x2 数组。 (我将在这里做更复杂的事情——但如果我能理解那个简单的案例,我会没事的)。非常感谢帮助!
我创建 F# 函数的尝试如下所示:
let array2D : int [,] = Array2D.zeroCreate 20 20
let g x = array2D
我遇到的问题是,它没有在 xla 名称下的 excel 下拉列表中显示为函数。
工作 C# 示例:
public static double[,] arraytoexcel(int N)
{
double[,] RetArray = new double[N, N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
RetArray[i, j] = N;
}
}
return RetArray;
}
你可能想要这样的东西:
let calculateCellContents size x y = float (y * size + x) // Whatever math you need
let mkArray size = Array2D.init size size (calculateCellContents size)
请注意 calculateCellContents
returns 一个 float(C# double
的 F# 名称),而不是 int。您的 C# 示例具有返回 double
值数组的函数,如果 XLA 正在寻找具有该签名的函数(返回浮点数数组),那么这可能是它未显示的一个可能原因。
现在,如果这不能解决 "this doesn't appear as a function in the excel dropdown" 问题,我想到了另外两种可能性。首先,如果您应该为 Excel 下拉菜单设置函数属性以便能够找到它,则语法为 [<AttributeName>]
。例如:
let calculateCellContents size x y = float (y * size + x) // Whatever math you need
[<ExcelFunction(Description="Make a simple array")>]
let mkArray size = Array2D.init size size (calculateCellContents size)
其次,可能是您必须更改函数的类型。 F# 函数的类型为 FSharpFunc
,XLA 完全有可能寻找 Func
而不是 FSharpFunc
。您可以通过从 F# 函数创建一个新的 System.Func
对象来在它们之间进行转换:
let calculateCellContents size x y = float (y * size + x) // Whatever math you need
let mkArray size = Array2D.init size size (calculateCellContents size)
let mkArrayVisibleFromExcel = new System.Func<int,float>(mkArray)
或者可能:
[<ExcelFunction(Description="Make a simple array")>]
let mkArrayVisibleFromExcel = new System.Func<int,float>(mkArray)
如果这不起作用,请尝试将 mkArray
更改为采用 float
参数,并相应地更改对 Array2D.init
的调用:
let calculateCellContents sizeF x y = float y * sizeF + float x // Whatever math you need
let mkArray (sizeF:float) =
Array2D.init (int sizeF) (int sizeF) (calculateCellContents sizeF)
[<ExcelFunction(Description="Make a simple array")>]
let mkArrayVisibleFromExcel = new System.Func<float,float>(mkArray)
如果其中 none 可以使您的函数在 Excel 的 XLA 下拉列表中可见,那我就没主意了。
我知道如何在 C# 中执行此操作,并且我可以使用 Excel DNA 创建加载项。我无法弄清楚启用函数 f 的 F# 语法,为了简单起见,它执行类似于 f(x)= 维数 [2,2] 的二维数组,其中包含 x 的所有 4 个值。因此,我将从 excel 中调用 f,从单元格中获取输入,它会 return 2x2 数组。 (我将在这里做更复杂的事情——但如果我能理解那个简单的案例,我会没事的)。非常感谢帮助!
我创建 F# 函数的尝试如下所示:
let array2D : int [,] = Array2D.zeroCreate 20 20
let g x = array2D
我遇到的问题是,它没有在 xla 名称下的 excel 下拉列表中显示为函数。
工作 C# 示例:
public static double[,] arraytoexcel(int N)
{
double[,] RetArray = new double[N, N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
RetArray[i, j] = N;
}
}
return RetArray;
}
你可能想要这样的东西:
let calculateCellContents size x y = float (y * size + x) // Whatever math you need
let mkArray size = Array2D.init size size (calculateCellContents size)
请注意 calculateCellContents
returns 一个 float(C# double
的 F# 名称),而不是 int。您的 C# 示例具有返回 double
值数组的函数,如果 XLA 正在寻找具有该签名的函数(返回浮点数数组),那么这可能是它未显示的一个可能原因。
现在,如果这不能解决 "this doesn't appear as a function in the excel dropdown" 问题,我想到了另外两种可能性。首先,如果您应该为 Excel 下拉菜单设置函数属性以便能够找到它,则语法为 [<AttributeName>]
。例如:
let calculateCellContents size x y = float (y * size + x) // Whatever math you need
[<ExcelFunction(Description="Make a simple array")>]
let mkArray size = Array2D.init size size (calculateCellContents size)
其次,可能是您必须更改函数的类型。 F# 函数的类型为 FSharpFunc
,XLA 完全有可能寻找 Func
而不是 FSharpFunc
。您可以通过从 F# 函数创建一个新的 System.Func
对象来在它们之间进行转换:
let calculateCellContents size x y = float (y * size + x) // Whatever math you need
let mkArray size = Array2D.init size size (calculateCellContents size)
let mkArrayVisibleFromExcel = new System.Func<int,float>(mkArray)
或者可能:
[<ExcelFunction(Description="Make a simple array")>]
let mkArrayVisibleFromExcel = new System.Func<int,float>(mkArray)
如果这不起作用,请尝试将 mkArray
更改为采用 float
参数,并相应地更改对 Array2D.init
的调用:
let calculateCellContents sizeF x y = float y * sizeF + float x // Whatever math you need
let mkArray (sizeF:float) =
Array2D.init (int sizeF) (int sizeF) (calculateCellContents sizeF)
[<ExcelFunction(Description="Make a simple array")>]
let mkArrayVisibleFromExcel = new System.Func<float,float>(mkArray)
如果其中 none 可以使您的函数在 Excel 的 XLA 下拉列表中可见,那我就没主意了。