【问题标题】:How do you set the value of a cell using Excel Dna?如何使用 Excel Dna 设置单元格的值?
【发布时间】:2013-02-15 13:50:40
【问题描述】:

我的 Excel DNA 插件中有以下代码

在我的 AutoOpen 方法中,我输入了以下代码:

ExcelIntegration.RegisterUnhandledExceptionHandler(ex => ex.ToString());

我的 Excel 工作表调用了以下函数。

[ExcelFunction(Category = "Foo", Description = "Sets value of cell")]
public static Foo(String idx)
{
        Excel.Application app = (Excel.Application)ExcelDnaUtil.Application;
        Excel.Workbook wb = app.Workbooks[1];
        Excel.Worksheet ws = GetSheet("Main");

        // This gives us the row
        Excel.Name idxRange = wb.Names.Item("COL_Main_Index");
        var row = (int)app.WorksheetFunction.Match(idx, idxRange.RefersToRange, 0);

        // Get the Column
        Excel.Name buyOrderRange = wb.Names.Item("COL_Main_BuyOrder");
        var col = (int)buyOrderRange.RefersToRange.Cells.Column;

        // create the range and update it
        Excel.Range r = (Excel.Range)ws.Cells[row, col];
        r.Value ="Foo"; 
}

问题是我实际上无法设置任何单元格值。当我调用该方法时,它会导致最后一行出现错误。

我的错误处理程序给了我以下错误:

{System.Runtime.InteropServices.COMException (0x800A03EC)

我也尝试过像这样设置单元格值:

        r = (Excel.Range)ws.Cells[12, 22];
        const int nCells = 1;
        Object[] args1 = new Object[1];
        args1[0] = nCells;
        r.GetType().InvokeMember("Value2", BindingFlags.SetProperty, null, r, args1);

结果相同。

谁能指出我在这里可能做错了什么?

【问题讨论】:

    标签: c# excel-dna


    【解决方案1】:

    实际上,如果您在异步作业中作为宏执行此操作,则可以在任何单元格中写入。

    简单示例:

    using ExcelDna.Integration;
    using Excel = Microsoft.Office.Interop.Excel;
    
    [ExcelFunction(Category = "Foo", Description = "Sets value of cell")]
    public static Foo(String idx)
    {
        Excel.Application app = (Excel.Application)ExcelDnaUtil.Application;
        Excel.Range range = app.ActiveCell;
    
        object[2,2] dummyData = new object[2, 2] {
            { "foo", "bar" },
            { 2500, 7500 }
        };
    
        var reference = new ExcelReference(
            range.Row, range.Row + 2 - 1, // from-to-Row
            range.Column - 1, range.Column + 2 - 1); // from-to-Column
    
        // Cells are written via this async task
        ExcelAsyncUtil.QueueAsMacro(() => { reference.SetValue(dummyData); });
    
        // Value displayed in the current cell. 
        // It still is a UDF and can be executed multiple times via F2, Return.
        return "=Foo()";
    }
    

    写入单个单元格:

    int row = 5;
    int column = 6;
    var reference = new ExcelReference(row - 1, column - 1);
    
    ExcelAsyncUtil.QueueAsMacro(() => { reference.SetValue("Foobar"); });
    

    // 编辑: 仅供参考,您也可以使用:

    private void WriteArray(object[,] data)
    {
        Excel.Application app = (Excel.Application)ExcelDnaUtil.Application;
        Excel.Worksheet worksheet= (Excel.Worksheet)app.ActiveWorkbook.ActiveSheet;
    
        Excel.Range startCell = app.ActiveCell;
        Excel.Range endCell = (Excel.Range)worksheet.Cells[startCell.Row + data.GetLength(0) - 1, startCell.Column + data.GetLength(1) - 1];
    
        var writeRange = worksheet.Range[startCell, endCell];
        writeRange.Value2 = data;
    }
    

    然后:

    object[,] data = ...;    
    ExcelAsyncUtil.QueueAsMacro(() =>
    {
        WriteArray();
    });
    

    【讨论】:

    • 这适用于第一次通话并中断所有后续通话。
    • 嗯?我们在 Excel 插件 (github.com/PATRONAS/opuxl) 中大量使用这种方法,没有任何问题。在随后的通话中它对您有何影响?
    • 很抱歉给您带来了困惑。我的问题不相关。这最终非常有帮助。 ArrayResizer 很棒,但我实际上并不想要一个数组。只是想写出多个单元格,这完成了工作。
    【解决方案2】:

    Excel 不允许您从用户定义的工作表函数中设置其他工作表单元格。这是为了保留 Excel 用于管理重新计算的依赖关系树。无论您使用的是 VBA、C API 还是 Excel-DNA,这都是正确的。

    最好是添加功能区按钮、上下文菜单或快捷键以通过宏来实现更改。

    有一些丑陋的解决方法,但我不推荐它。

    【讨论】:

    【解决方案3】:

    这是使用 .NET VB 的答案

     Dim row As Integer = 7
            Dim column As Integer = 7
            Dim reference = New ExcelReference(row, column)
    
            ExcelAsyncUtil.QueueAsMacro(Sub()
                                            reference.SetValue("Test")
                                        End Sub)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      • 2021-03-10
      • 2011-08-03
      • 1970-01-01
      相关资源
      最近更新 更多