我的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);
结果相同。
任何人都可以指出我在这里做错了吗?
答案 0 :(得分:5)
Excel不允许您在用户定义的工作表函数中设置其他工作表单元格。这是为了保留Excel用于管理重新计算的依赖关系树。无论您使用的是VBA,C API还是Excel-DNA,都是如此。
最好是添加功能区按钮,上下文菜单或快捷键以通过宏实现更改。
有一些丑陋的解决方法,但我不推荐它。
答案 1 :(得分:5)
实际上,如果您在作为宏的异步作业中执行此操作,则可以在任何单元格中写入。
简单示例:
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;
}
//编辑: 只是fyi,你也可以使用:
object[,] data = ...;
ExcelAsyncUtil.QueueAsMacro(() =>
{
WriteArray();
});
然后:
{{1}}
答案 2 :(得分:0)
以下是使用.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)