Reputation: 2503
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.
Upvotes: 0
Views: 2304
Reputation: 457
Even though this question was put ages ago, I want to answer it. I struggled much through the day with this, but got it done eventually.
Code 0x800a03ec is ambiguous, it means essentially, (NO OFFENSE MEANT!), you dumbhead! you did something pretty stupid, try finding it out for yourself. Close to the old "syntax error" without further elucidation.
So, there is no single meaning for code 0x800a03ec and, googling around, you can see it occurs when using zero based addressing in ranges, and many other gotcha situations.
The gotcha in this case is that you have to pass the parameters to a DISPATCH_METHOD call IN REVERSE. Obviously, with a single parameter this will not lead to trouble, and many dispatch calls can do with a single parameter.
So, when I want to open a workbook with just the filename, everything is OK.
AutoWrap(DISPATCH_METHOD, &Result, pExcelWorkbooks, "Open", 1, fn);
But e.g. the following code does not work:
_variant_t fn("MyExcelBook.xlsx"), updatelinks(0), readonly(true);
VARIANT Result;
hr = Autowrap(DISPATCH_METHOD, &Result, pExcelWorkbooks, "Open", 3, fn, updatelinks, readonly);
It produces 0x800a03ec and won't load the workbook.
To amend this without rewriting all your calls, the AutoWrap function should be extended as follows:
// Allocate memory for arguments..
VARIANT * pArgs = new VARIANT[cArgs + 1];
// Extract arguments..
if (autoType & DISPATCH_METHOD)
{ // reverse (variable) DISPATCH parameters after cArgs
for (int i = 1; i <= cArgs; i++)
pArgs[cArgs-i] = va_arg(marker, VARIANT);
}
else
{
for (int i = 0; i < cArgs; i++)
pArgs[i] = va_arg(marker, VARIANT);
}
(only relevant part shown, see earlier post for the whole method).
So now I call the C++ version of workbooks.open()
_variant_t fn("MyExcelBook.xlsx"), updatelinks(0), readonly(true), optional(DISP_E_PARAMNOTFOUND, VT_ERROR);
VARIANT Result; readonly,
hr = Autowrap(DISPATCH_METHOD, &Result, pExcelWorkbooks, "Open", 7, fn, updatelinks,
optional, optional, optional, readonly);
// copy the dispatch pointer to the workbook pointer
if (Result.vt == VT_DISPATCH)
{
pExcelWorkbook = Result.pdispVal;
// save the workbook pointer to close it later if needed
if (pExcelWorkbook)
IDworkBooks.push_back(pExcelWorkbook);
}
As you can see, you do not have to fill in the tail options you are not going to use anyway, as in some VB code and C#.
Happy coding, Jan
PS, I see the reverse thing was noted before (see above).. I couldn't figure out where I had seen it until now...
Upvotes: 0
Reputation: 10679
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
Upvotes: 2