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保存你的文件名,那么你当前正在尝试将它作为Localparameter 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,我看到相反的东西之前指出(见上文)..我无法弄清楚,直到现在我看到它…