使用Excel Interop的公式

Nic*_*ner 6 .net f# excel-interop

我正在使用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 *)
Run Code Online (Sandbox Code Playgroud)

但是,当有大量公式时,这太慢了,所以我切换到了一个数组:

worksheet.Range(range).Value2 <- [| "=sum(a1:a10)"
                                    "=min(a1:a10)"
                                    "=max(a1:a10)" |]
Run Code Online (Sandbox Code Playgroud)

要么

worksheet.Range(range).Formula <- [| "=sum(a1:a10)"
                                     "=min(a1:a10)"
                                     "=max(a1:a10)" |]
Run Code Online (Sandbox Code Playgroud)

但是,现在Excel只在单元格中显示这些字符串,而不是计算公式的值.我也尝试过:

worksheet.Range(range).FormulaArray <- [| "=sum(a1:a10)"
                                          "=min(a1:a10)"
                                          "=max(a1:a10)" |]
Run Code Online (Sandbox Code Playgroud)

但这与每个公式的目标范围相混淆.我不确定那里发生了什么.(而不是将其保留为"a1:a10",Excel根据公式的位置转换目标范围.)

有一个更好的方法吗?

更新:我也尝试使用"= 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])" |]
Run Code Online (Sandbox Code Playgroud)

但我遇到了同样的问题:Excel将它们呈现为字符串而不是评估公式.

rkr*_*ahl 7

Daniel的答案应该有效,但我发现使用R1C1格式的公式更容易.您的代码应该像这样使用它:

ws.Range(range).FormulaR1C1 <- [| "=sum(R1C1:R10C1)";
                                  "=min(R1C1:R10C1)"; 
                                  "=max(R1C1:R10C1)" |]
Run Code Online (Sandbox Code Playgroud)

这将生成具有绝对地址的公式.您可以使用R [vertical_offset] C [horizo​​ntal_offset]构建相对地址.选择整行或列也很容易:R1是整行的第一行,C4是整个"D"列.

使用纯F#中的String.Format或sprintf可以轻松构建R1C1地址.

编辑:我快速检查了vba,它将无法正常工作.Excel将第一个数组元素放在范围内的每个单元格中.无论如何,R1C1寻址点仍然有效.它就像标题公式的魅力(即ws.Range(headerRange).FormulaR1C1 < - "= sum(R2C [0]:R10C [0]"),所以我将保持答案完整.

EDIT2:我认为ArrayFormula用于数组公式,所以它也不起作用.

编辑3:我做了一些研究,找到了一些我认为不可能的答案:).

首先,将这些字符串作为公式,将它们转换为对象:

let formulas : obj[] = [| "=sum(R1C1:R10C1)";
                          "=min(R1C1:R10C1)"; 
                          "=max(R1C1:R10C1)" |]
Run Code Online (Sandbox Code Playgroud)

然后把它放在FormulaR1C1中:

ws.Range(range).FormulaR1C1 <- formulas
Run Code Online (Sandbox Code Playgroud)

第二,重要部分:上面的例子假设范围是三个细胞的水平范围(即F3:H3).如果你试图把它放在垂直范围内(即F3:F5),你会注意到,这个和公式在范围内的每个单元格中重复.我敢打赌,在这种情况下,公式应该是二维对象数组,第一行外部数组是公式数组,但我在尝试将其放入range.FormulaR1C1时得到SafeArrayTypeObjectExtension.看看这个msdn文档:

如果范围是一维或二维范围,则可以将公式设置为具有相同尺寸的Visual Basic数组.同样,您可以将公式放入Visual Basic数组中.

我稍后再看一下这个例外.

  • 重要的一步是向上转换到`obj`。一旦你这样做了,你甚至可以将公式放入 `Value2` 中,它工作正常。 (2认同)