Excel挂起…另一个评估树的bug?

Excel 2003,Windows XP SP3:

我们有一些Excel用户,他们使用非常大的复杂的Excel工作簿。 一个典型的工作簿可能有60多个工作表,并且大小可以超过70MB。 我们制作了一个.xll插件,并在整个这些电子表格中使用。 我们的插件具有丰富的debugging和日志function。 我们一直在生产插件的版本,并使用它们将近10年。 我们的Excel界面的基础设施因此被certificate是坚实的和稳定的。

有些情况下,Excel挂在一段特定的代码中; 也就是说,它挂在Excel本身的代码中,并挂在一个特定的代码段。 在这种情况下,有一个密码循环(可​​能是20个机器指令,没有“调用”),它会无休止地执行。 该代码似乎是行走一个循环链表,通常只有less数节点,例如只有四个节点。 我看起来像是在走一个与评估树(某些部分)相对应的链表 – 我根本不确定。

我已经能够用一个令人难以置信的简单插件(3个返回固定数据的注册函数)和一个令人难以置信的简单电子表格(5个单元格,3个使用3个插件函数的公式)来performance行为。 只有在完成对工作表中的所有单元格的评估以及用结果更新屏幕之后,Excel才会挂起。 无论使用哪种Excel SDK版本(v5.0,v12.0和v14.0都经过testing),它都会挂起。

以下是示例代码的链接: Sample .xls工作簿和相应的.xll插件和插件的源代码

插件的来源是微不足道的:

#include <windows.h> #if SDK_VER == 5 #include "xlcall_v5_0.h" #elif SDK_VER == 12 #include "xlcall_v12_0.h" #elif SDK_VER == 14 #include "xlcall_v14_0.h" #endif extern "C" __declspec(dllexport) int xlAutoOpen(void) { #define N_FUNCTIONS 3 #define N_FUNCTION_REGISTRATION_PARAMETERS 3 char* rgFuncs[N_FUNCTIONS][N_FUNCTION_REGISTRATION_PARAMETERS] = { {"\013FunctionOne", "\002RP", "\013FunctionOne"}, {"\013FunctionTwo", "\002RP", "\013FunctionTwo"}, {"\014FunctionFour", "\003RBP", "\014FunctionFour"} }; XLOPER xlFuncParams[N_FUNCTION_REGISTRATION_PARAMETERS+1]; LPXLOPER ppxlFuncParams[N_FUNCTION_REGISTRATION_PARAMETERS+1]; Excel4(xlGetName, (ppxlFuncParams[0] = &xlFuncParams[0]), 0); for(int i = 0; i < N_FUNCTIONS; i++) { for (int j = 1; j <= N_FUNCTION_REGISTRATION_PARAMETERS; j++) { xlFuncParams[j].xltype = xltypeStr; xlFuncParams[j].val.str = rgFuncs[i][j-1]; ppxlFuncParams[j] = &xlFuncParams[j]; } Excel4v(xlfRegister, 0, N_FUNCTION_REGISTRATION_PARAMETERS+1, ppxlFuncParams); } Excel4(xlFree, 0, 1, (LPXLOPER)&xlFuncParams[0]); return 1; } extern "C" __declspec(dllexport) LPXLOPER xlAddInManagerInfo(LPXLOPER xAction) { static XLOPER xInfo; XLOPER xloCoerceType, xIntAction; xloCoerceType.xltype = xltypeInt; xloCoerceType.val.w = xltypeInt; Excel4(xlCoerce, &xIntAction, 2, xAction, (LPXLOPER)&xloCoerceType); if( xIntAction.xltype == xltypeInt && xIntAction.val.w == 1) { xInfo.xltype = xltypeStr; xInfo.val.str = "\010ExcelBug"; } else { xInfo.xltype = xltypeErr; xInfo.val.err = xlerrValue; } return (LPXLOPER)&xInfo; } LPXLOPER XLReturn(const double* pdData, const int nData, bool bRow=false) { static XLOPER xlDLLResult; static int nAllocated = 0; if( nAllocated==0 ) { xlDLLResult.xltype = xltypeMulti; nAllocated=max(nData,2); xlDLLResult.val.array.lparray = new XLOPER[nAllocated]; } else if( nAllocated < nData ) { delete [] xlDLLResult.val.array.lparray; nAllocated = nData; xlDLLResult.val.array.lparray = new XLOPER[nAllocated]; } for(int i = 0; i < nData; ++i) { xlDLLResult.val.array.lparray[i].xltype = xltypeNum; xlDLLResult.val.array.lparray[i].val.num = pdData[i]; } xlDLLResult.val.array.rows = (WORD)(bRow? 1 : nData ); xlDLLResult.val.array.columns = (WORD)(bRow? nData : 1 ); return (LPXLOPER) &xlDLLResult; } extern "C" __declspec(dllexport) LPXLOPER FunctionOne( LPXLOPER ) { double dData = 41144.; return XLReturn(&dData, 1); } extern "C" __declspec(dllexport) LPXLOPER FunctionTwo( LPXLOPER ) { const double pdData[2] = {41145., 41176.}; return XLReturn(pdData, 2); } extern "C" __declspec(dllexport) LPXLOPER FunctionFour( double, LPXLOPER ) { const double pdData[2] = {41145., -0.01345212}; return XLReturn(pdData, 2, true); } 

演示问题的电子表格位于上面链接指向的包中。

有没有人看过类似的行为(是的,描述非常模糊,所以我意识到它很难说…)?

这已被Microsoft确认为Excel 2003中的一个错误。它在更多的情况下出现在我的简单示例中。 我的简单例子需要卸载和重新加载插件,但我有错误发生的情况下,我只是在做范围calcs。 它总是似乎发生在一个范围计算后,试图表计算(shift-F9)。 他们不愿意修复它。 我很惊讶,我没有看到任何其他抱怨这个错误。