我正在使用F#和Excel Interop将数据输出到Excel电子表格。我的第一个方法是单独设置每个单元格:
worksheet.Range(range1).Value2 <- "=sum(a1:a10)"
worksheet.Range(range2).Value2 <- "=min(a1:a10)"
worksheet.Range(range3).Value2 <- "=max(a1:a10)"
(* etc *)
但是,当有大量公式时,这太慢了,所以我切换到了一个数组:
worksheet.Range(range).Value2 <- [| "=sum(a1:a10)"
"=min(a1:a10)"
"=max(a1:a10)" |]
或
worksheet.Range(range).Formula <- [| "=sum(a1:a10)"
"=min(a1:a10)"
"=max(a1:a10)" |]
但是,现在Excel只在单元格中显示这些字符串,而不是计算公式的值。我也尝试过:
worksheet.Range(range).FormulaArray <- [| "=sum(a1:a10)"
"=min(a1:a10)"
"=max(a1:a10)" |]
但这与每个公式的目标范围相混淆。我不确定那里发生了什么。 (Excel不会将其保留为"a1:a10"
,而是根据公式的位置转换目标范围。)
有更好的方法吗?
更新:我也尝试使用“= MIN($ G $ 2:$ G $ 5)”,但这产生了相同的效果,其中Excel只显示字符串而不评估公式。
对于它的价值,如果我进入单元格,擦除然后重新添加公式中的任何字符,当我点击“输入”时,Excel将对其进行评估。
更新2 :我还尝试了以下内容:
worksheet.Range(range).FormulaR1C1 <- [| "=sum(R2C[0]:R4C[0])"
"=average(R2C[0]:R4C[0])"
"=min(R2C[0]:R4C[0])"
"=max(R2C[0]:R4C[0])" |]
但是我遇到了同样的问题:Excel将它们渲染为字符串而不是评估公式。
答案 0 :(得分:7)
Daniel的答案应该有效,但我发现使用R1C1格式的公式更容易。您的代码应如下所示:
ws.Range(range).FormulaR1C1 <- [| "=sum(R1C1:R10C1)";
"=min(R1C1:R10C1)";
"=max(R1C1:R10C1)" |]
这将生成具有绝对地址的公式。您可以使用R [vertical_offset] C [horizontal_offset]构建相对地址。选择整行或列也很容易:R1是整行第一行,C4是整个“D”列。
使用纯F#中的String.Format或sprintf轻松构建R1C1地址。
编辑:我快速检查了一下vba,它无法正常工作。 Excel将第一个数组元素放在范围内的每个单元格中。无论如何,R1C1寻址点仍然有效。它就像标题公式的魅力(即ws.Range(headerRange).FormulaR1C1&lt; - “= sum(R2C [0]:R10C [0]”),所以我会保留答案。
EDIT2:我认为ArrayFormula适用于array formulas,所以它也无效。
EDIT3:我做了一些研究,找到了一些我认为不可能的答案:)。
首先,将这些字符串作为公式,将它们转换为对象:
let formulas : obj[] = [| "=sum(R1C1:R10C1)";
"=min(R1C1:R10C1)";
"=max(R1C1:R10C1)" |]
然后将其放入FormulaR1C1:
ws.Range(range).FormulaR1C1 <- formulas
第二,重要部分:上面的例子假设范围是三个细胞的水平范围(即F3:H3)。如果你试图把它放在垂直范围内(即F3:F5),你会注意到,这个和公式在范围内的每个单元格中重复。我敢打赌,在这种情况下,公式应该是二维对象数组,第一行外部数组是公式数组,但我在尝试将其放入range.FormulaR1C1时得到SafeArrayTypeObjectExtension。看看this msdn docs:
如果范围是一维或二维范围,则可以将公式设置为具有相同尺寸的Visual Basic数组。同样,您可以将公式放入Visual Basic数组中。
稍后我会再看一下这个例外。
答案 1 :(得分:1)
假设您的第一种方法有效且慢意味着类型(而不是执行)太慢,它可能更快/更容易像这样更新一堆单元格
[
range1, "=sum(a1:a10)"
range2, "=min(a1:a10)"
range3, "=max(a1:a10)"
...
]
|> List.iter (fun (range, value) -> worksheet.Range(range).Value2 <- value)
答案 2 :(得分:1)
或者你可以从fsnip.net http://fssnip.net/aV上的这个片段中获得一些想法,它实现了Excel的一些高阶函数。 (与使用电子表格设备相比,这是一个更长的镜头性能,因为该片段并不是真正的性能。)