MFC操作EXCEL向单元格写入数据崩溃

ljwxy900 2014-03-13 12:06:58

InitExcelApp();
OpenExcelApp();
NewExcelBook();
CheckType();

m_ExlRge = m_ExlSheet.get_Range(COleVariant(_T("A1")), COleVariant(_T("A1")));
m_ExlRge.put_Value2(COleVariant(_T("图片名称")));

调试时调用get_Range处崩溃,具体在下面这句
SCODE sc = m_lpDispatch->Invoke(dwDispID, IID_NULL, 0, wFlags,
&dispparams, pvarResult, &excepInfo, &nArgErr);
完整代码见下方:
void COleDispatchDriver::InvokeHelperV(DISPID dwDispID, WORD wFlags,
VARTYPE vtRet, void* pvRet, const BYTE* pbParamInfo, va_list argList)
{
if (m_lpDispatch == NULL)
{
TRACE(traceOle, 0, "Warning: attempt to call Invoke with NULL m_lpDispatch!\n");
return;
}

COleDispParams dispparams;
memset(&dispparams, 0, sizeof dispparams);

// determine number of arguments
if (pbParamInfo != NULL)
dispparams.cArgs = lstrlenA((LPCSTR)pbParamInfo);

DISPID dispidNamed = DISPID_PROPERTYPUT;
if (wFlags & (DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF))
{
ASSERT(dispparams.cArgs > 0);
dispparams.cNamedArgs = 1;
dispparams.rgdispidNamedArgs = &dispidNamed;
}
CVariantBoolConverter tempArgs; //Used to convert VARIANT_BOOL | VT_BYREF --> BOOL*.
if (dispparams.cArgs != 0)
{
// allocate memory for all VARIANT parameters
VARIANT* pArg = new VARIANT[dispparams.cArgs];
ASSERT(pArg != NULL); // should have thrown exception
dispparams.rgvarg = pArg;
memset(pArg, 0, sizeof(VARIANT) * dispparams.cArgs);

// get ready to walk vararg list
const BYTE* pb = pbParamInfo;
pArg += dispparams.cArgs - 1; // params go in opposite order

while (*pb != 0)
{
ASSERT(pArg >= dispparams.rgvarg);

pArg->vt = *pb; // set the variant type
if (pArg->vt & VT_MFCBYREF)
{
pArg->vt &= ~VT_MFCBYREF;
pArg->vt |= VT_BYREF;
}
switch (pArg->vt)
{
case VT_UI1:
pArg->bVal = va_arg(argList, BYTE);
break;
case VT_UI2:
pArg->uiVal = va_arg(argList, USHORT);
break;
case VT_UI4:
pArg->ulVal = va_arg(argList, ULONG);
break;
case VT_UI8:
pArg->ullVal = va_arg(argList, ULONGLONG);
break;
case VT_I1:
pArg->cVal = va_arg(argList, char);
break;
case VT_I2:
pArg->iVal = va_arg(argList, short);
break;
case VT_I4:
pArg->lVal = va_arg(argList, long);
break;
case VT_I8:
pArg->llVal = va_arg(argList, LONGLONG);
break;
case VT_R4:
pArg->fltVal = (float)va_arg(argList, double);
break;
case VT_R8:
pArg->dblVal = va_arg(argList, double);
break;
case VT_DATE:
pArg->date = va_arg(argList, DATE);
break;
case VT_CY:
//CY is always passed by ref
pArg->cyVal = *va_arg(argList, CY*);
break;
case VT_BSTR:
{
LPCOLESTR lpsz = va_arg(argList, LPOLESTR);
pArg->bstrVal = ::SysAllocString(lpsz);
if (lpsz != NULL && pArg->bstrVal == NULL)
{
AfxThrowMemoryException();
}
}
break;
#if !defined(_UNICODE)
case VT_BSTRA:
{
LPCSTR lpsz = va_arg(argList, LPSTR);
CStringW strMBToUnicode(lpsz);
pArg->bstrVal = ::SysAllocString(static_cast<LPCWSTR>(strMBToUnicode));
if (lpsz != NULL && pArg->bstrVal == NULL)
AfxThrowMemoryException();
pArg->vt = VT_BSTR;
}
break;
#endif
case VT_DISPATCH:
pArg->pdispVal = va_arg(argList, LPDISPATCH);
break;
case VT_ERROR:
pArg->scode = va_arg(argList, SCODE);
break;
case VT_BOOL:
V_BOOL(pArg) = (VARIANT_BOOL)(va_arg(argList, BOOL) ? -1 : 0);
break;
case VT_VARIANT:
//VARIANT is always passed by ref
*pArg = *va_arg(argList, VARIANT*);
break;
case VT_UNKNOWN:
pArg->punkVal = va_arg(argList, LPUNKNOWN);
break;

case VT_UI1|VT_BYREF:
pArg->pbVal = va_arg(argList, BYTE*);
break;
case VT_UI2|VT_BYREF:
pArg->puiVal = va_arg(argList, USHORT*);
break;
case VT_UI4|VT_BYREF:
pArg->pulVal = va_arg(argList, ULONG*);
break;
case VT_UI8|VT_BYREF:
pArg->pullVal = va_arg(argList, ULONGLONG*);
break;
case VT_I1|VT_BYREF:
pArg->pcVal = va_arg(argList, char*);
break;
case VT_I2|VT_BYREF:
pArg->piVal = va_arg(argList, short*);
break;
case VT_I4|VT_BYREF:
pArg->plVal = va_arg(argList, long*);
break;
case VT_I8|VT_BYREF:
pArg->pllVal = va_arg(argList, LONGLONG*);
break;
case VT_R4|VT_BYREF:
pArg->pfltVal = va_arg(argList, float*);
break;
case VT_R8|VT_BYREF:
pArg->pdblVal = va_arg(argList, double*);
break;
case VT_DATE|VT_BYREF:
pArg->pdate = va_arg(argList, DATE*);
break;
case VT_CY|VT_BYREF:
pArg->pcyVal = va_arg(argList, CY*);
break;
case VT_BSTR|VT_BYREF:
pArg->pbstrVal = va_arg(argList, BSTR*);
break;
case VT_DISPATCH|VT_BYREF:
pArg->ppdispVal = va_arg(argList, LPDISPATCH*);
break;
case VT_ERROR|VT_BYREF:
pArg->pscode = va_arg(argList, SCODE*);
break;
case VT_BOOL|VT_BYREF:
{
// coerce BOOL into VARIANT_BOOL
BOOL* pboolVal = va_arg(argList, BOOL*);
*pboolVal = *pboolVal ? MAKELONG(0xffff, 0) : 0;
pArg->pboolVal = (VARIANT_BOOL*)pboolVal;
tempArgs.AddPair( CVariantBoolPair(pboolVal,pArg->pboolVal,FALSE) );
}
break;
case VT_VARIANT|VT_BYREF:
pArg->pvarVal = va_arg(argList, VARIANT*);
break;
case VT_UNKNOWN|VT_BYREF:
pArg->ppunkVal = va_arg(argList, LPUNKNOWN*);
break;

default:
ASSERT(FALSE); // unknown type!
break;
}

--pArg; // get ready to fill next argument
++pb;
}
}

// initialize return value
VARIANT* pvarResult = NULL;
VARIANT vaResult;
AfxVariantInit(&vaResult);
if (vtRet != VT_EMPTY)
pvarResult = &vaResult;

// initialize EXCEPINFO struct
EXCEPINFO excepInfo;
memset(&excepInfo, 0, sizeof excepInfo);

UINT nArgErr = (UINT)-1; // initialize to invalid arg

// make the call
SCODE sc = m_lpDispatch->Invoke(dwDispID, IID_NULL, 0, wFlags,
&dispparams, pvarResult, &excepInfo, &nArgErr);

//When VT_BOOL | VT_BYREF is passed to com server, after Invoke returns -
//Convert VARIANT_TRUE[FALSE] --> BOOL TRUE[FALSE].
tempArgs.CopyVarBoolsIntoBOOLs();
// cleanup any arguments that need cleanup
if (dispparams.cArgs != 0)
{
VARIANT* pArg = dispparams.rgvarg + dispparams.cArgs - 1;
const BYTE* pb = pbParamInfo;
while (*pb != 0)
{
switch ((VARTYPE)*pb)
{
#if !defined(_UNICODE)
case VT_BSTRA:
#endif
case VT_BSTR:
VariantClear(pArg);
break;
}
--pArg;
++pb;
}
}
delete[] dispparams.rgvarg;
dispparams.rgvarg = NULL;

// throw exception on failure
if (FAILED(sc))
{
VariantClear(&vaResult);
if (sc != DISP_E_EXCEPTION)
{
// non-exception error code
AfxThrowOleException(sc);
}

// make sure excepInfo is filled in
if (excepInfo.pfnDeferredFillIn != NULL)
excepInfo.pfnDeferredFillIn(&excepInfo);

// allocate new exception, and fill it
COleDispatchException* pException =
new COleDispatchException(NULL, 0, excepInfo.wCode);
ASSERT(pException->m_wCode == excepInfo.wCode);
if (::SysStringLen(excepInfo.bstrSource))
{
pException->m_strSource = excepInfo.bstrSource;
}
::SysFreeString(excepInfo.bstrSource);
if (::SysStringLen(excepInfo.bstrDescription))
{
pException->m_strDescription = excepInfo.bstrDescription;
}
::SysFreeString(excepInfo.bstrDescription);
if (::SysStringLen(excepInfo.bstrHelpFile))
{
pException->m_strHelpFile = excepInfo.bstrHelpFile;
}
::SysFreeString(excepInfo.bstrHelpFile);
pException->m_dwHelpContext = excepInfo.dwHelpContext;
pException->m_scError = excepInfo.scode;

// then throw the exception
THROW(pException);
}

if (vtRet != VT_EMPTY)
{
// convert return value
if (vtRet != VT_VARIANT)
{
SCODE scChangeType = VariantChangeType(&vaResult, &vaResult, 0, vtRet);
if (FAILED(scChangeType))
{
TRACE(traceOle, 0, "Warning: automation return value coercion failed.\n");
VariantClear(&vaResult);
AfxThrowOleException(scChangeType);
}
ASSERT(vtRet == vaResult.vt);
}

// copy return value into return spot!
switch (vtRet)
{
case VT_UI1:
*(BYTE*)pvRet = vaResult.bVal;
break;
case VT_UI2:
*(USHORT*)pvRet = vaResult.uiVal;
break;
case VT_UI4:
*(ULONG*)pvRet = vaResult.ulVal;
break;
case VT_UI8:
*(ULONGLONG*)pvRet = vaResult.ullVal;
break;
case VT_I1:
*(char*)pvRet = vaResult.cVal;
break;
case VT_I2:
*(short*)pvRet = vaResult.iVal;
break;
case VT_I4:
*(long*)pvRet = vaResult.lVal;
break;
case VT_I8:
*(LONGLONG*)pvRet = vaResult.llVal;
break;
case VT_R4:
*(float*)pvRet = vaResult.fltVal;
break;
case VT_R8:
*(double*)pvRet = vaResult.dblVal;
break;
case VT_DATE:
*(double*)pvRet = *(double*)&vaResult.date;
break;
case VT_CY:
*(CY*)pvRet = vaResult.cyVal;
break;
case VT_BSTR:
AfxBSTR2CString((CString*)pvRet, vaResult.bstrVal);
SysFreeString(vaResult.bstrVal);
break;
case VT_DISPATCH:
*(LPDISPATCH*)pvRet = vaResult.pdispVal;
break;
case VT_ERROR:
*(SCODE*)pvRet = vaResult.scode;
break;
case VT_BOOL:
*(BOOL*)pvRet = (V_BOOL(&vaResult) != 0);
break;
case VT_VARIANT:
*(VARIANT*)pvRet = vaResult;
break;
case VT_UNKNOWN:
*(LPUNKNOWN*)pvRet = vaResult.punkVal;
break;

default:
ASSERT(FALSE); // invalid return type specified
}
}
}

请帮忙查一下,这个问题困扰我两天了。
...全文
610 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
手上调试的问题解决了。。。 虽然有点莫名其妙,但是还是摸出了点门路,勉强解决了这个问题吧。。。。 lz的代码没有看,我这举个例子吧。。。c++ class X { public : A geta() const { return a; } private: A a; }; class A { public: B getInstanceOfb() const { return b;} private: B b; }; class B { public : int B_f1(..) }; 在这个程序里面,想要访问类X里面的成员调用的方法 B_f1, 偷懒了就写成: int result = X.geta().getInstanceOfb.B_b(..); 写的时候不觉得什么,但是。。。。结果就没那么happy了。。。 别偷懒。。。 A a = X.geta(); B b = a.getInstanceOfb(); int result = b.B_f(..); 我这里解决问题的思路是这样。。。。不喜可自喷,不鸟不谢,
  • 打赏
  • 举报
回复
。。。这个问题还是没有解决。。。程序崩了。。尼玛。。
yyy940702 2014-10-12
  • 打赏
  • 举报
回复
再顶一下。。。同样问题。。。
dufangyu1990 2014-06-27
  • 打赏
  • 举报
回复
请问楼主解决了吗,我现在也是这个问题
向立天 2014-04-15
  • 打赏
  • 举报
回复
您好 我是本版版主 此帖已多日无人关注 请您及时结帖 如您认为问题没有解决可按无满意结帖处理 另外本版设置了疑难问题汇总帖 并已在版面置顶 相关规定其帖子中有说明 您可以根据规定提交您帖子的链接 如您目前不想结帖只需回帖说明 我们会删除此结帖通知 见此回复三日内无回应 我们将强制结帖 相关规定详见界面界面版关于版主结帖工作的具体办法
yeah2000 2014-03-15
  • 打赏
  • 举报
回复
参考这个 http://download.csdn.net/detail/yeah2000/2411878
许文君 2014-03-14
  • 打赏
  • 举报
回复
先要获得他已使用的行列数,然后再逐行取
ljwxy900 2014-03-14
  • 打赏
  • 举报
回复
还是崩溃,你是说excel的接口有问题?
ganmaojiushijiu 2014-03-14
  • 打赏
  • 举报
回复
我用vsto(C#)这样访问的时候也会奔溃
allenhiman 2014-03-13
  • 打赏
  • 举报
回复
去掉这两句就不崩溃了吗? 如果还崩代表你的接口对象有问题

15,978

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧