有人有使用 Microsoft.Office.Interop 从 F# 向 Excel 电子表格写入值的经验吗?我可以很好地读取值,但是当我尝试更改单元格的值时,我总是会出错。我看到有此错误的帖子,其中列或行为 0,但在我的情况下,这些值始终为正。我正在从 excel-dna 获取我的 Excel 应用程序对象。
let getCell (sheet: Excel.Worksheet) (row: int, col:int) =
let rng = sheet.Cells.Item(row, col) :?> Excel.Range
match isNull rng with
| true ->
None
| false ->
match isNull rng.Value2 with
| true -> None
| false ->
let s = "Hello"
let o = s :> obj // passing in unboxed string does not help
rng.Value2 <- o // this line throws an error Exception from HRESULT: 0x800A03EC Error
Some rng.Value2
我使用 NetOffice(https://netoffice.io/ - 小心获取正确的 Nuget 包)。
例如,在打开一个新的空白工作簿后从功能区处理程序调用此代码时有效:
open NetOffice.ExcelApi
...
use app = new Application (null, ExcelDnaUtil.Application)
let wb = app.ActiveWorkbook
let sheet = wb.Sheets.["Sheet1"] :?> Worksheet
let range = sheet.Cells.[1, 1]
range.Value2 <- "Hello"
我的错误是尝试从已通过加载项导出到 Excel 的函数内部更新单元格。 UDF 不允许有副作用。解决方案是在当前函数完成后将 lambda 添加到要完成的队列中(ExcelAsyncUtil.QueueAsMacro)。
这里的代码是 C#,因为我想看看 F# 是否是问题所在,但事实并非如此——尽管我还没有尝试从 F# 传递 lambda 函数
using ExcelDna.Integration;
using Microsoft.Office.Interop.Excel;
using System;
public static class MyFunctions
{
[ExcelFunction(Description = "My first .NET function")]
public static string HelloDna(string name)
{
name = "Hello " + name + ". No error occured";
Application xlApp = (Application) ExcelDnaUtil.Application;
Worksheet ws = (Worksheet) xlApp.ActiveSheet;
Range r = (Range) ws.Cells[3, 3];
try
{
r.Value2 = "Hello"; //throws error because I am updating a cell in code that is calculating a value
}
catch (Exception e) {
name = e.Message;
}
return name;
}
[ExcelFunction(Description = "My second .NET function")]
public static string HelloDna2(string name)
{
ExcelAsyncUtil.QueueAsMacro(() =>
{
var refB1 = new ExcelReference(0, 0, 1, 1, "Sheet1");
refB1.SetValue("Done!");
});
return "Hello " + name;
}
}