C++ – Excel OpenText method

ccomexcel

I keep getting the ambiguous error code of 0x800A03EC. 

 I've been searching quite a bit to see if I could find a specific reason for the error but unfortunately that code seems to cover a multitude of possible errors. I will copy and paste the code that seems to be giving me problems and hopefully someone will be able to provide me with some feedback on how I might solve the problem. I am using a method called AutoWrap that I came across in this kb21686  article.

I'll add that method here:

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;
}

Everything works fine up until I make this call:

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);

The parameters passed to the function are initialized as:

       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");

If I uncomment the commented out param1 and make a call to Open and pass it that version of param1 everything works wonderfully. Unfortunately when Invoke is called on the OpenText method I get the 0x800A03EC error code. 90% of what I find when searching is performing automation using interop in C# and the other 10% is doing the same thing in VB and while the C# examples are helpful they don't help to explain the parameters being passed when using C++ very well. I feel like it's all a problem with parameters but I'm having difficulty in figuring out exactly what the problem with them is.

Thanks in advance for any help you can offer and pelase let me know if I need to post more code.

Best Answer

From the KB article you linked to:

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

From MSDN, the parameters to OpenText are:

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

So if param1 holds your filename then you are currently trying to pass that as the Local parameter and you aren't passing anything to the Filename parameter which is required