c++ - Excel OpenText 方法

标签 c++ excel com

我不断收到 0x800A03EC 的模糊错误代码。

我进行了大量搜索,想看看是否能找到错误的具体原因,但不幸的是,该代码似乎涵盖了多种可能的错误。我将复制并粘贴似乎给我带来问题的代码,希望有人能够就我如何解决问题向我提供一些反馈。我正在使用我在此 kb21686 中遇到的一种称为 AutoWrap 的方法文章。

我将在此处添加该方法:

HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) {
    // Begin variable-argument list...
    va_list marker;
    va_start(marker, cArgs);

    if(!pDisp) {
        //MessageBox(NULL, "NULL IDispatch passed to AutoWrap()", "Error", 0x10010);
        MessageBox(NULL,_T("IDispatch error"),_T("LError"),MB_OK | MB_ICONEXCLAMATION);
        _exit(0);
    }

    // Variables used...
    DISPPARAMS dp = { NULL, NULL, 0, 0 };
    DISPID dispidNamed = DISPID_PROPERTYPUT;
    DISPID dispID;
    HRESULT hr;
    char buf[200];
    char szName[200];


    // Convert down to ANSI
    WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);

    // Get DISPID for name passed...
    hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
    if(FAILED(hr)) {
        sprintf_s(buf, "IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx", szName, hr);
        MessageBox(NULL, CString(buf), _T("AutoWrap()"), MB_OK | MB_ICONEXCLAMATION);
        _exit(0);
        return hr;
    }

    // Allocate memory for arguments...
    VARIANT *pArgs = new VARIANT[cArgs+1];
    // Extract arguments...
    for(int i=0; i<cArgs; i++) {
        pArgs[i] = va_arg(marker, VARIANT);
    }

    // Build DISPPARAMS
    dp.cArgs = cArgs;
    dp.rgvarg = pArgs;

    // Handle special-case for property-puts!
    if(autoType & DISPATCH_PROPERTYPUT) {
        dp.cNamedArgs = 1;
        dp.rgdispidNamedArgs = &dispidNamed;
    }

    // Make the call!
    hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);
    if(FAILED(hr)) {
        sprintf_s(buf, "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr);
        MessageBox(NULL, CString(buf), _T("AutoWrap()"), MB_OK | MB_ICONEXCLAMATION);
        _exit(0);
        return hr;
    }
    // End variable-argument section...
    va_end(marker);

    delete [] pArgs;

    return hr;
}

在我发出这个调用之前一切正常:

AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBooks, L"OpenText",18,param1,vtMissing,vtMissing,paramOpt,paramOpt,
                vtMissing,vtMissing,vtMissing,paramTrue,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing
                ,vtMissing,vtMissing);

传递给函数的参数初始化为:

       VARIANT param1,paramOpt,paramFalse,paramTrue;
        param1.vt = VT_BSTR;
        paramOpt.vt = VT_I2;
        paramOpt.iVal = 1;
        paramFalse.vt = VT_BOOL;
        paramFalse.boolVal = 0;
        paramTrue.vt = VT_BOOL;
        paramTrue.boolVal = 1;
        //param1.bstrVal = ::SysAllocString(L"C:\\Documents and Settings\\donaldc\\My Documents\\DepositSlip.xls");
        param1.bstrVal = ::SysAllocString(L"C:\\logs\\TestOut.txt");

如果我取消对已注释掉的 param1 的注释并调用 Open 并将该版本的 param1 传递给它,一切都会正常运行。不幸的是,当在 OpenText 方法上调用 Invoke 时,我得到了 0x800A03EC 错误代码。我在搜索时发现的 90% 是在 C# 中使用互操作执行自动化,另外 10% 是在 VB 中做同样的事情,虽然 C# 示例很有帮助,但它们无助于很好地解释使用 C++ 时传递的参数.我觉得这都是参数的问题,但我很难弄清楚它们到底是什么问题。

在此先感谢您提供的任何帮助,如果我需要发布更多代码,请告诉我。

最佳答案

来自您链接到的知识库文章:

One caveat is that if you pass multiple parameters, they need to be passed in reverse-order.

来自 MSDNOpenText 的参数是:

expression.OpenText(Filename, Origin, StartRow, DataType, 
TextQualifier, ConsecutiveDelimiter, Tab, Semicolon, Comma, 
Space, Other, OtherChar, FieldInfo, TextVisualLayout, DecimalSeparator, 
ThousandsSeparator, TrailingMinusNumbers, Local)

因此,如果 param1 包含您的文件名,那么您目前正在尝试将其作为 Local 参数传递,而您没有将任何内容传递给 Filename 需要的参数

关于c++ - Excel OpenText 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1492513/

相关文章:

c++ - C++ Azure 移动库中的更新功能损坏

vba - 如何阻止ActiveX对象在office中自动改变大小?

python - 将Excel公式转换为python

windows - 无法使用Windows Media编码器设置默认音频设备

c++ - 进程外 COM 服务器 - 每个调用进程一个服务器进程?

c++ - 如何为模板化 operator() 编写最好的 is_callable 特性

c++ - 所有进程退出的广播消息(MPI)

给定名称的目录的 C++ 路径

performance - Excel vba Application.screenupdating 与 Application.visible

c# - 使用 GC.AddMemoryPressure 触发更频繁的运行时可调用包装器 (RCW) 终结是否合适?