2013-02-15 47 views
4

我有下面的代碼在我的Excel插件DNA如何使用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"; 
} 

問題是我實際上無法設置任何單元格值。當我調用該方法時,會在最後一行中導致錯誤。

我的錯誤處理程序給我的followign錯誤:

{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); 

具有相同的結果。

任何人都可以指出我可能在這裏做錯了嗎?

回答

5

Excel不允許您在用戶定義的工作表函數中設置其他工作表單元格。這是爲了保留Excel用來管理重新計算的依賴關係樹。無論您是使用VBA,C API還是Excel-DNA,情況都是如此。

最好是添加一個功能區按鈕,上下文菜單或快捷鍵,以通過宏實現更改。

有一些醜陋的解決方法,但我不會推薦它。

+0

和往常一樣Govert,你是對的。感謝您的確認。 – chollida 2013-02-19 15:41:17

+0

其中一個解決方法可以在這裏找到: http://excel-dna.net/2011/01/30/resizing-excel-udf-result-arrays/ – Kukks 2013-07-09 08:17:48

3

實際上,如果您在異步作業中以宏爲單位執行此操作,則可以在任何單元格中編寫代碼。

簡單的例子:

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(); 
}); 
+0

這適用於第一次通話,並休息所有後續調用。 – neonScarecrow 2017-01-25 22:56:03

+0

嗯?我們在Excel Addin(https://github.com/PATRONAS/opuxl)中大量使用這種方法,沒有任何問題。 在隨後的通話中,它如何突破? – ASN 2017-01-27 08:09:59

+0

對不起,我感到困惑。我的問題是無關的。這最終是非常有幫助的。 ArrayResizer非常棒,但我實際上並不需要數組。只是想寫出來給多個單元格,而這個工作就完成了。 – neonScarecrow 2017-01-30 22:44:13

相關問題