我有一个使用Excel-DNA创建的Excel Addin,并且有一个UDF作为Excel加载项的一部分。假设该函数在单元格A10中,我将删除列Z.我发现此操作会导致函数再次执行。
有没有办法防止这种行为发生?这与计算模型或波动率有关吗?
编辑1
我正在使用以下代码来实现类似Bloomberg BDH功能的行为 - 即该函数是在第一个单元格中编写的,而其余的数组是通过线程编写的。
我有两个问题:
我已经看到了第1项和第1项的实施。以上2项运作良好,但无法确定如何做到这一点。有没有人有任何想法
public class ArrayWriter
{
#region Methods
#region WriteArray
[ExcelFunction(IsHidden=true)]
public object WriteArray(object[,] arrayToWrite)
{
object caller = null;
object formula = null;
AddInFacade facade;
// if not in a function
if (!ExcelDnaUtil.IsInFunctionWizard())
{
facade = new AddInFacade();
if (arrayToWrite != null)
{
// if writing more than one cell, use threads
if (arrayToWrite.GetLength(0) > 1 || arrayToWrite.GetLength(1) > 1)
{
var xlApp = ExcelDnaUtil.Application as Application;
Type xlAppType = xlApp.GetType();
caller = xlApp.Caller;
//caller = xlAppType.InvokeMember("ActiveCell", BindingFlags.GetProperty, null, xlApp, null);
formula = xlAppType.InvokeMember("FormulaR1C1Local", BindingFlags.GetProperty, null, caller, null);
// create instance of ObjectForThread and set all properties of the class
ObjectForThread threadObject = new ObjectForThread()
{
xlRef = caller,
value = arrayToWrite,
};
// create a new thread calling the method WriteFromThread and start the thread
Thread threadWriter = new Thread(() => WriteFromThread(threadObject));
threadWriter.Start();
}
else
{
facade.SetMouseCursor(XlMousePointer.xlDefault);
}
}
else
{
arrayToWrite = new object[1, 1];
arrayToWrite[0, 0] = "No data was returned.";
facade.SetMouseCursor(XlMousePointer.xlDefault);
}
}
return arrayToWrite[0,0];
}
#endregion
#region WriteFromThread
private void WriteFromThread(Object boxedThreadObject)
{
AddInFacade facade = new AddInFacade();
ObjectForThread unboxedThreadObject = (ObjectForThread)boxedThreadObject;
Object cellBelow;
Type typeCellReference = unboxedThreadObject.xlRef.GetType();
try
{
for (int i = 0; i < unboxedThreadObject.value.GetLength(0); i++)
{
for (int j = 0; j < unboxedThreadObject.value.GetLength(1); j++)
{
// do not write the first cell as this is what is returned by the function
if (i > 0 || j > 0)
{
cellBelow = typeCellReference.InvokeMember("Offset", BindingFlags.GetProperty, null, unboxedThreadObject.xlRef, new object[] { i, j });
typeCellReference.InvokeMember("Value", BindingFlags.SetProperty, null, cellBelow, new[] { Type.Missing, unboxedThreadObject.value[i, j] });
}
}
}
}
catch(Exception ex)
{
string szError = ex.Message;
}
finally
{
// attempt to kill all COM references
unboxedThreadObject.xlRef = null;
unboxedThreadObject.value = null;
//Set the mouse cursor to the default cursor since the entire array has now been written
facade.SetMouseCursor(XlMousePointer.xlDefault);
unboxedThreadObject = null;
cellBelow = null;
facade = null;
}
}
#endregion
#endregion
#region ObjectForThread Class
public class ObjectForThread
{
public object xlRef { get; set; }
public object[,] value { get; set; }
}
#endregion
}
答案 0 :(得分:1)
更改此行为的唯一方法是更改Application.Calculation属性。但你不想这样做。此属性应该只是暂时更改,然后应该重置为以前的值。否则,您正在编写一个在共享沙箱中无法正常播放的插件。