问题描述
对于标量(即非数组式)可选参数,我将使用以下模式:
For scalar (i.e. non array-like) optional arguments, I would use this pattern :
[<ExcelFunction(Category= "Test", Description= "Test optional arguments.")>]
let test_test1 ([<ExcelArgument(Description= "Optional. This is a double. Default is 42.0.")>] arg1 : obj) : double =
match arg1 with
| :? ExcelMissing -> 42.0 // the argument was missing
| :? double as d -> d // the argument was a double
| _ -> -1.0 // otherwise
我不确定这段代码在Excel-Dna/F#中是否是惯用的",但似乎是可行的".
I am not sure if this code is "idiomatic" within Excel-Dna / F# but it seems to "work".
但是,我不确定如何继续执行类似数组的可选参数.例如:
However I am not sure how to proceed for optional array-like arguments. Eg :
[<ExcelFunction(Category= "Test", Description= "Test optional arguments.")>]
let test_test2 ([<ExcelArgument(Description= "Optional. This is a double. Default is [42, 42].")>] arg1 : obj[]) : double[] =
match arg1.[0] with
| :? ExcelMissing -> [42.0; 42.0] |> List.toArray // the argument was missing OR it was an empty array
| :? double as d -> arg1 |> castToDouble // the argument was an array and its first argument was a double
| _ -> Array.empty // otherwise
以上似乎适用于大多数情况,但不允许正确处理边缘情况:例如,如果arg1是一个空数组. (castToDouble
是自定义的obj[] -> double[]
转换函数)
The above seems to work for most cases but does not allow to handle the edge-cases properly : eg if arg1 is an empty array. (castToDouble
being a custom obj[] -> double[]
conversion function)
在F#/Excel-Dna中处理可选双精度数组的正确/惯用方式是什么,然后如何重写test_test2?
What would be the right / idiomatic way to handle optional double arrays in F# / Excel-Dna and how could I then rewrite test_test2?
===========编辑===
=========== EDIT ===
按照Govert的建议,我尝试了以下方法:
Following Govert's advice, I tried the following :
[<ExcelFunction(Category= "Test", Description= "Test optional arguments.")>]
let test_test3 ([<ExcelArgument(Description= "Optional. This is a double. Default is [42, 42].")>] arg1 : obj) : double[] =
match arg1 with
| :? (double[]) as ds -> [1.0; 2.0] |> List.toArray // the argument was a array of double elements
| :? ExcelMissing -> [42.0; 42.0] |> List.toArray // the argument was missing OR it was an empty array
| _ -> Array.empty // otherwise
...但是不幸的是,当我传递一个双精度数组(或其他形式)时,得到了#NUM!
输出.只有当我什么都不做时,我才能正确获得[42.0,42.0]数组.
... but unfortunately I get a #NUM!
output when I pass an array of doubles (or of anything else). It's only when I pass nothing that I correctly get the [42.0, 42.0] array.
推荐答案
这涵盖了所有可能性:
[<ExcelFunction("describes the input argument")>]
let describe(arg1 : obj) : string =
match arg1 with
| :? double as d -> sprintf "Double: %f" d
| :? string as s -> "String: " + s
| :? bool as b -> sprintf "Boolean: %b" b
| :? ExcelError as err -> sprintf "ExcelError: %A" err
| :? (obj[,]) as arr -> sprintf "Array[%i, %i]" (Array2D.length1 arr) (Array2D.length2 arr)
| :? ExcelEmpty -> "<<Empty>>"
| :? ExcelMissing -> "<<Missing>>"
| _ -> "!? Unheard of ?!"
这篇关于ExcelDna F#和可选参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!