1

Excel 2003、Windows XP SP3:

非常に大規模で複雑なExcelブックを操作するExcelユーザーが多数います。一般的なワークブックには60以上のワークシートがあり、サイズは70MB以上です。作成した.xllアドインがあり、これらのスプレッドシート全体で使用されています。アドインには、広範なデバッグ機能とログ機能があります。アドインのバージョンを作成し、ほぼ10年間使用しています。したがって、Excelインターフェイスのインフラストラクチャは、堅牢で安定していることが証明されています。

Excelが特定のコードでハングする特定の状況があります。つまり、Excel自体のコード内にハングし、特定の1つのコードにハングします。この場合、コードのタイトなループ(おそらく、「呼び出し」のない20のマシン命令)があり、それが際限なく実行されます。コードは循環するリンクリストを歩いているように見えます。多くの場合、ノードは少なく、たとえば4つのノードしかありません。評価ツリー(の一部)に対応するリンクリストを歩いているように見えますが、まったくわかりません。

信じられないほど単純なアドイン(固定データを返す3つの登録済み関数)と信じられないほど単純なスプレッドシート(​​5つのセル、3つのアドイン関数を使用する3つの数式)で動作を明示することができました。ワークシートのすべてのセルの評価が完了し、結果で画面を更新した後にのみ、Excelがハングします。使用されているExcelSDKのバージョンに関係なくハングします(v5.0、v12.0、およびv14.0はすべてテスト済み)。

サンプルコードへのリンクは次のとおりです。サンプルの.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);
}

問題を示すスプレッドシートは、上記のリンクで示されているパッケージに含まれています。

誰かが同様の振る舞いを見たことがありますか(はい、説明は非常に曖昧なので、言うのは難しいと思います...)?

4

1 に答える 1

0

これは Microsoft によって Excel 2003 のバグとして確認されています。この単純な例よりも多くの状況で発生します。私の単純な例では、アドインのアンロードと再ロードが必要でしたが、単純に範囲計算を行っている状況でエラーが発生しました。範囲計算の後にシート計算 (shift-F9) を試みると、常に発生するようです。彼らはそれを修正する気はありません。このバグについて他に苦情が寄せられていないことに驚いています。

于 2012-09-15T02:12:39.810 に答える