Search code examples
c#.netexcelexcel-dna

How can I get values of certain cells in background?


I'm trying to create a ExcelReference and then call GetValue(), but this results in a XlCallException (no details provided in the exception).

var val = new ExcelReference(1, 1).GetValue();

What am I doing wrong?


Solution

  • You're probably calling this from inside a UDF. Normal UDFs can't read other parts of the sheet - the idea is that you pass the information you need as a parameter to the function.

    You can mark an Excel-DNA function as a 'Macro-Sheet function', which will allow this to work. (Set IsMacroType=true in the ExcelFunction attribute.) But this had other side-effects on your calculation sequence, for example you might be getting the value from that cell as it was before the calculation started.

    So it's best to stick to Excel's functional style, and pass the extra dependencies into your UDF.


    The other possibility is that you're calling this from a background worker thread. The Excel C API (which you're using through the ExcelReference type) can only be called from the main Excel thread (with some exceptions for thread-safe UDFs). So you need to get your background code to run on the main thread.

    Excel is basically single-threaded, so this is true when using th COM object model too - all calls are marshalled to the main Excel thread by COM before they actually run.

    In an Excel-DNA add-in, you can schedule code to run on the main thread, as a macro, by using the ExcelAsyncUtil.QueueAsMacro(...) helper. The delegate you pass in will run as soon as possible, and can safely make the kind of C API calls you ask about.