The Excel C API (XlCall.Excel(...)) can be safely be called in these contexts:
* Inside your AutoOpen handler.
* Inside an Excel-DNA UDF function.
* Inside an Excel-DNA macro.
* Inside you IExcelAddIn AutoOpen and AutoClose implementations.
Places where you can't use the C API:
* Ribbon callback methods.
* Excel COM object model event handlers.
* Any thread that is not the main Excel thread or a calculation thread when Excel is doing multithreaded calculation (for functions marked as thread-safe - only limited calls allowed by Excel in this context).
* The main thread when Excel didn't initiate the call, e.g. a timer or Windows form handler, even if it is running on the main thread.
From any context or thread you can schedule code to run in a macro context where the C API is supported, by calling ExcelAsyncUtil.QueueAsMacro(...).This will schedule the code to run as a macro, as soon as Excel is ready (calculations are complete, user
not editing a formula etc.)
Similarly, there are some restrictions on when the COM object model is safe to use from your add-in (if you get the root COM object with a call to ExcelDnaUtil.Application). You should only use the COM object model when running on the main thread, never
for cross-thread calls. The COM object model is safe to call in these contexts:
* Ribbon callback methods.
* Macro context (e.g. public void methods marked with [ExcelCommand]).
* COM object event handlers.
It's not clear whether the COM object model is safe to use in a UDF context when called from a formula in a calculation. Microsoft says this is not supported, but some calls to the object model seem to work fine in this context.
------------
In general Excel does not allow you to make changes to the sheet from a function. So if you tried to call ExcelReference.SetValue(..) inside a function, that would always fail. Excel has some other restrictions on what C API calls can be made inside a
function. Some C API features are only available in functions that are marked as IsMacroType=true, like the xlfGetXXX information functions.
------------
I don't know much about calls to xlUDF and VBA. You can keep the following in mind:
* There are separate xlUDF and xlcRun C API calls. I'm not sure exactly how they differ, but I guess xlUDF only works with VBA functions, not Subs.
* You can also initiate a VBA procedure with the COM object model call Application.Run(...).
* I'm confused about how the names work when calling VBA macros - sometimes you need the sheet or workbook name, other times not. Sometime you need brackets or single quotes, other times not. It's very confusing.
* Remember that there might be a difference between the Active sheet (which is the sheet that the user has focus on) and the Current sheet (which is the sheet where a calculation is called from). This might make a difference with what your VBA calls see.
------------
If you really want to have a user-defined function to have side-effects like writing stuff to the sheet (something I think is dangerous and should never be done) then the way to do it is to schedule a macro (with ExcelAsyncUtil.QueueAsMacro) from inside
your function which will then run and apply the sheet changes after the calculation is complete.
-Govert