I've implemented Excel functions that should return values depending on the workbook in which they are evaluating.
That, however, turned out to be quite problematic to get right, as ExcelDna gives us only the application, not the calling worksheet.
There is one worksheet that is special (I believe it's the one that has user focus), which we can get with:
(ExcelDnaUtil.Application as Microsoft.Office.Interop.Excel.Application).ActiveWorkbook
But that is not always the one that the respective function is evaluating in.
To see that, try this function:
[ExcelFunction(IsVolatile = true)]
public static string TestDna(string name)
{
var excel = ExcelDnaUtil.Application as Microsoft.Office.Interop.Excel.Application;
return excel.ActiveWorkbook.GetHashCode().ToString();
}
Open up Excel, get a second Excel workbook and put the two windows side by side. Evaluate the formula in each.
You will see that each time the formula is evaluated in one workbook, the value of the other changes as well - to the wrong value.
If one defines the function as non-volatile the situation seems better, but then I have a different problem: I do need to refresh the cells when underlying data sources change, and I can only change all workbooks at once, with a call to Application.CalculateFullRebuild. Doing that will again have some workbooks have the wrong value for ActiveWorkbook.
So what to do?
I think ideally, ExcelDna should tell what context a function is evaluated in, if that is possible.