有谁用过MFC Typelib在MFC中加入Exel的处理。问题:
用CApplication打开.xls文件时,只能通过
CApplication::FindFile()
用对话框打开,能不能有方法通过编程方式打开呢?HRESULT hr = OleInitialize(NULL); // {00024500-0000-0000-C000-000000000046}coclass CApplication
CLSID clsid = {0x00024500, 0x0000, 0x0000, 
{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
};    IDispatch *pIDispatch = NULL;
::CoCreateInstance(clsid,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IDispatch,
(void **)&pIDispatch
); CApplication app(pIDispatch);用app怎样和文件F:\a.xls关联起来呢?
我只能用app.FindFile(),然后,弹出一个讨厌的对话框,才能选中这个文件,有什么方法用编程的方式在程序中直接加入打开a.xls的代码,而不要弹出这个对话框呢?谢谢!

解决方案 »

  1.   

    毫无保留的奉献一下我的代码:
    对于office的编程,你可以参考msdn的如下内容:
    MSDN (October 2001)文章:
    Q184663 HOWTO: Embed and Automate a Microsoft Excel worksheet with MFC 
    Q179706 HOWTO: Use MFC to Automate Excel & Create/Format a New Workbook 
    Q186120 HOWTO: Use MFC to Automate Excel and Fill a Range with an Array 
    Q186427 HOWTO: Catch Microsoft Excel 97 Application Events Using VC++ 下面开始处理从Excel文件中抽取内容以及其它信息:
    void CEmbed_ExcelView::OnOleReadcontents() 
    {
    // OLE Variant for Optional.
    COleVariant VOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

    _Application objApp;
    _Workbook objBook;
    Workbooks objBooks;
    Worksheets objSheets;
    _Worksheet objSheet;
    Range objRange;
    VARIANT ret;

    // 下面生成Excel实例并打开一个存在的工作簿:
    objApp.CreateDispatch("Excel.Application");
    objBooks = objApp.GetWorkbooks();
    objBook = objBooks.Open("c:\\SOLVSAMP.XLS",
    VOptional, VOptional, VOptional, VOptional,
    VOptional, VOptional, VOptional, VOptional,
    VOptional, VOptional, VOptional, VOptional);
    objSheets = objBook.GetWorksheets();
    int SheetsCount=objSheets.GetCount();//这里获得了sheet的数目

    FILE *fp; //创建一个txt文件用来存放从Excel文件中抽取的文本内容
    fp=fopen("c:\\SOLVSAMP.txt","wt"); //将文件打开 for(int sheet=1;sheet<=SheetsCount;sheet++){//注意:从1开始。
    objSheet = objSheets.GetItem(COleVariant((short)sheet));//获得指定的工作表

    ※1 CString SheetName = objSheet . GetName();//获得当前工作表名称
    fprintf(fp,"工作表%d:%s\n",sheet,SheetName); //将这个名称输出
      objRange = objSheet.GetUsedRange();//这里获得所有的已用的Cells(单元格)
    ※2  //objRange = objSheet.GetRange(COleVariant("A1"), COleVariant("D20"));
    ret = objRange.GetValue();
    if(ret.vt == VT_EMPTY) continue; //碰到空的工作表就返回
    COleSafeArray sa(ret);
    //判断数组的维数
    long lNumRows;
    long lNumCols;
    sa.GetUBound(1, &lNumRows);
    sa.GetUBound(2, &lNumCols);
    //输出中的SAFEARRAY元素
    long index[2];
    VARIANT val;
    int r, c;
    for(r=1;r<=lNumRows;r++)
    {
    CString contents;
    bool bEmpty=true;
    for(c=1;c<=lNumCols;c++)
    {
    index[0]=r;
    index[1]=c;
    sa.GetElement(index, &val);
    switch(val.vt)
    {
    case VT_BOOL: //如果单元格中的值为布尔值
    {
    bool flag=val.boolVal;
    if(flag==true) contents+="TRUE"; //输出的内容进行转换
    else contents+="FALSE";
    bEmpty=false;
    break;
    }
    case VT_R8:  //如果单元格中的值为数字
    {//这里将整数从实数中分离出来,防止整数后面有一串‘0’。
    float value=val.dblVal;
    char buffer[20];
    sprintf(buffer,"%f",value);
    CString tmp=buffer;
    int dot=tmp.Find('.');
    CString Left=tmp.Left(dot);
    tmp=tmp.Mid(dot+1);
    if(tmp=="000000") contents+=Left;
    else contents+=buffer;
    bEmpty=false;
    contents+="    ";//tab,用于格式控制
    break;
    }
    case VT_BSTR://文字
    {
    contents+=(CString)val.bstrVal;
    //if(1==c) Ar=contents.GetLength();
    contents+="    ";//tab
    bEmpty=false;
    break;
    }
    case VT_EMPTY:
    break;
    }//end of case Empty
    }//end of switch
    }//end of col
    if(fp){
    if(  !contents.IsEmpty()  )   //内容不为空,就输出
    {
    fprintf(fp,"%s",contents);
    fprintf(fp,"\n");
    }
    }
    }//end of rows
    fprintf(fp,"\n");
    }//end of deal with different sheet.
    if(fp) fclose(fp);  //关闭打开的文件
    objBook.Close(COleVariant((short)FALSE), VOptional, VOptional);
    objApp.Quit();    
    }
      

  2.   

    大家都向 liuxianzhi(碧渊)兄学习!!