在 F# 中写入 Excel

问题描述 投票:0回答:2

有人有使用 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
f# excel-dna microsoft.office.interop.excel
2个回答
1
投票

我使用 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"

0
投票

我在这里找到了问题的答案

我的错误是尝试从已通过加载项导出到 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;
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.