excel中的数据导出到程序里出现的问题,请赐教。
访问shee2页的时候会在 sa = ret; 崩掉。各位帮忙给看看为什么。代码如下: _Application   ExcelApp;     
Workbooks   wbsMybooks;     
_Workbook   wbMyBook;     
Worksheets   wssMySheets;     
_Worksheet   wsMySheet;     
Range   MyRange;  
VARIANT   ret; 
COleVariant VOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
COleSafeArray   sa;  CString strName;
CString strPSW;
int iPort;
DWORD dwIp; VARIANT vMsg;
char cMsg[512];
_bstr_t bMsg;
//创建Excel   2000服务器(启动Excel)     
    
if(!ExcelApp.CreateDispatch("Excel.Application",NULL))     
{     
AfxMessageBox("创建Excel服务失败!");     
exit(1);     
} CString strPath = m_strSelectFile; wbsMybooks = ExcelApp.GetWorkbooks();
wbMyBook = wbsMybooks.Open(strPath,
 VOptional, VOptional, VOptional, VOptional,
 VOptional, VOptional, VOptional, VOptional,
 VOptional, VOptional, VOptional, VOptional,
 VOptional, VOptional);
wssMySheets   =   wbMyBook.GetWorksheets();    int SheetsCount = wssMySheets.GetCount(); for(int k = 1; k <= SheetsCount ; k++)
{
wsMySheet   =   wssMySheets.GetItem(COleVariant((short)k));

MyRange = wsMySheet.GetUsedRange();
ret=MyRange.GetValue(VOptional); 
if(ret.vt   ==   VT_EMPTY) 
//continue;
return;
//Create   the   SAFEARRAY   from   the   VARIANT   ret.  
sa = ret; //当k不等于1的时候这里会崩掉

//Determine   the   array's   dimensions.   
//获得表格总的的行数和列数   
long   lNumRows;      
sa.GetUBound(1,   &lNumRows);     
for(int i = 1; i <= lNumRows; i++)
{          vMsg = MyRange.GetItem(_variant_t((long)i),_variant_t((long)1));
bMsg = (_bstr_t)vMsg;
strcpy(cMsg,bMsg); }
    
}
wbMyBook.Close(COleVariant((short)FALSE),VOptional,VOptional); 
ExcelApp.Quit();

解决方案 »

  1.   

    调试看看ret是什么数据,类型是否正确。
      

  2.   

    sa = ret; //当k不等于1的时候这里会崩掉
    这是一句赋值语句,只有当sa没有初始化才能调用,否则必须现调用Detach函数

    当k==1时,sa是没有初始话的值,因此可以使用上面代码行初始化sa类.
    但是sa以及初始化之后,不就能再这样赋值了.
      

  3.   

    如果你不能保证ret的类型是VT_ARRAY的话,sa = ret; 就会抛出异常。还有一个BUG,就是 ret 应该定义成封装类,比如 COleVariant ret; 而不是 VARIANT ret; 否则很容易发生内存泄露或者接口无法释放。
      

  4.   

    sa = ret; //当k不等于1的时候这里会崩掉
    此时ret.vt 类型为 VT_BSTR正常的时候 ret.vt = 8024 在VT_的枚举中没有这个值。换成  COleSafeArray  sa(ret);
    问题依旧。崩了以后程序会停在这里 : 
    COleSafeArray& COleSafeArray::operator=(const VARIANT& varSrc)
    {
    ASSERT(varSrc.vt & VT_ARRAY);
    AfxCheckError(::VariantCopy(this, (LPVARIANT)&varSrc));
    return *this;
    }
      

  5.   

    这已经非常清楚了。COleSafeArray要求你传递给它的值必须是VT_ARRAY,而你这里ret.vt是VT_BSTR,当然不行了。
    你必须确定你得到的值是VT_ARRAY才能用COleSafeArray去接收,这是非常简单和容易处理的事情。
      

  6.   

    问题已解决,是这样的,如果表仅有一行一列,那么ret=MyRange.GetValue(VOptional); 就会把ret.vt = VT_BSTR .所以就触发断言了ASSERT(varSrc.vt & VT_ARRAY); 
    谢谢大家,我结贴了。