Excel的OpenText方法
我不断收到0x800A03EC的模糊错误代码。
我一直在寻找相当多的东西,看看能否find错误的具体原因,但不幸的是,代码似乎涵盖了大量可能的错误。 我将复制并粘贴似乎给我带来问题的代码,希望有人能够就我如何解决问题向我提供一些反馈意见。 我正在使用这个kb21686文章中遇到的称为AutoWrap的方法。
我将在这里添加该方法:
HRESULT AutoWrap(int autoType,VARIANT * pvResult,IDispatch * pDisp,LPOLESTR ptName,int cArgs ...){ //开始variables参数列表... va_list标记; va_start(marker,cArgs); if(!pDisp){ // MessageBox(NULL,“NULL IDispatch传递给AutoWrap()”,“Error”,0x10010); MessageBox(NULL,_T(“IDispatch error”),_ T(“LError”),MB_OK | MB_ICONEXCLAMATION); _exit(0); } //使用的variables... DISPPARAMS dp = {NULL,NULL,0,0}; DISPID dispidNamed = DISPID_PROPERTYPUT; DISPID dispid; HRESULT hr; char buf [200]; char szName [200]; //转换为ANSI WideCharToMultiByte(CP_ACP,0,ptName,-1,szName,256,NULL,NULL); //获取名称传递的DISPID ... hr = pDisp-> GetIDsOfNames(IID_NULL,&ptName,1,LOCALE_USER_DEFAULT,&dispID); if(FAILED(hr)){ sprintf_s(buf,“IDispatch :: GetIDsOfNames(\”%s \“)失败w / err 0x%08lx”,szName,hr); MessageBox(NULL,CString(buf),_T(“AutoWrap()”),MB_OK | MB_ICONEXCLAMATION); _exit(0); 返回hr; } //为参数分配内存... VARIANT * pArgs = new VARIANT [cArgs + 1]; //提取参数... for(int i = 0; i <cArgs; i ++){ pArgs [i] = va_arg(marker,VARIANT); } //build立DISPPARAMS dp.cArgs = cArgs; dp.rgvarg = pArgs; //处理财产投入的特殊情况! if(autoType&DISPATCH_PROPERTYPUT){ dp.cNamedArgs = 1; dp.rgdispidNamedArgs =&dispidNamed; } //拨打电话! hr = pDisp-> Invoke(dispID,IID_NULL,LOCALE_SYSTEM_DEFAULT,autoType,&dp,pvResult,NULL,NULL); if(FAILED(hr)){ sprintf_s(buf,“IDispatch :: Invoke(\”%s \“=%08lx)失败w / err 0x%08lx”,szName,dispID,hr); MessageBox(NULL,CString(buf),_T(“AutoWrap()”),MB_OK | MB_ICONEXCLAMATION); _exit(0); 返回hr; } //结束variables参数部分... va_end用来(标记); 删除[] pArgs; 返回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错误代码。 search时发现的90%是使用C#中的interop来执行自动化,而另外10%是在VB中做同样的事情,虽然C#示例很有帮助,但它们无法解释使用C ++时传递的参数。 我觉得这是一个参数问题,但我很难弄清楚他们的问题到底是什么。
预先感谢您可以提供的任何帮助和pelase让我知道如果我需要发布更多的代码。
从您链接到的KB文章:
一个警告是,如果你传递多个参数,他们需要以相反的顺序传递。
从MSDN ,到OpenText
的参数是:
expression.OpenText(Filename, Origin, StartRow, DataType, TextQualifier, ConsecutiveDelimiter, Tab, Semicolon, Comma, Space, Other, OtherChar, FieldInfo, TextVisualLayout, DecimalSeparator, ThousandsSeparator, TrailingMinusNumbers, Local)
所以,如果param1
保存你的文件名,那么你当前正在尝试将它作为Local
parameter passing,而不是传递任何东西给需要的Filename
参数
即使这个问题是很久以前,我想回答。 我一整天都在努力挣扎,但最终还是完成了。
代码0x800a03ec是含糊不清的,它本质上意味着,(没有罪恶的意思!),你愚蠢! 你做了一件相当愚蠢的事情,试着自己找出来。 接近于旧的“语法错误”,没有进一步的解释。
所以,对于代码0x800a03ec没有单一的含义,并且使用谷歌search,你可以看到它发生在范围内使用基于零的地址,以及许多其他情况。
在这种情况下,必须将parameter passing给DISPATCH_METHOD调用IN REVERSE 。 显然,用单个参数不会导致麻烦,并且许多调度调用可以用单个参数来完成。
所以,当我想打开一个只有文件名的工作簿时,一切正常。
AutoWrap(DISPATCH_METHOD, &Result, pExcelWorkbooks, "Open", 1, fn);
但是,例如下面的代码不起作用:
_variant_t fn("MyExcelBook.xlsx"), updatelinks(0), readonly(true); VARIANT Result; hr = Autowrap(DISPATCH_METHOD, &Result, pExcelWorkbooks, "Open", 3, fn, updatelinks, readonly);
它产生0x800a03ec并不会加载工作簿。
若要修改而不重写所有的调用,AutoWrap函数应该扩展如下:
// 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); }
(只显示相关部分,请参阅前面的文章中的整个方法)。
所以现在我调用C ++版本的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); }
正如你所看到的,你不必填写你不会使用的尾部选项,就像在VB代码和C#中一样。
快乐的编码,1月
PS,我看到相反的东西之前指出(见上文)..我无法弄清楚,直到现在我看到它…