如何使用 MFC 內嵌及自動化 Microsoft Excel 工作表

文章翻譯 文章翻譯
文章編號: 184663 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

結論

本文將告訴您,如何將 Microsoft Excel 工作表內嵌至 SDI MFC 應用程式中的 View 物件。

本文包含內嵌工作表及新增一些文字到儲存格 A1 的逐步指示,以及說明每一個步驟的註解。

雖然本文中的範例程式碼可以直接放入您的應用程式中,不過您要閱讀及了解範例程式碼才能真正獲益 。.

其他相關資訊

Microsoft 僅提供示範性的程式設計範例,不做任何明示或默示的保證。其中包括 (但不限於) 其適售性與適合某特定用途之默示擔保。本文將假設您已相當熟悉示範所使用的程式設計語言,以及用於建立和偵錯程序的工具。Microsoft 技術支援工程師可以協助說明特定程序的功能,但不會修改這些範例以提供附加功能或建構程序來滿足您的特定需求。

如果要建立 MFC 應用程式,請依照下列步驟執行:
  1. 使用 AppWizard 建立名為「Embed_Excel」的新 MFC AppWizard (EXE) 專案。
  2. 選取要建立的應用程式類型為單一文件,並選取要包含的複合文件支援類型為容器。接受其他所有預設設定。

    接著會產生下列類別:

    應用程式:Embed_Excel.h 和 Embed_Excel.cpp 中的 CEmbed_ExcelApp

    框架:MainFrm.h 和 MainFrm.cpp 中的 CMainFrame

    文件:Embed_ExcelDoc.h 和 Embed_ExcelDoc.cpp 中的 CEmbed_ExcelDoc

    檢視:Embed_ExcelView.h 和 Embed_ExcelView.cpp 中的 CEmbed_ExcelView

    容器項目:CntrItem.h 和 CntrItem.cpp 中的 CEmbed_ExcelCntrItem
  3. 按一下 [檢視] 功能表上的 [ClassWizard]。按一下 [自動化] 索引標籤,再按一下 [加入類別],然後選擇 [從型別程式庫 (From a Type Library)]。找出 [Microsoft Excel 型別程式庫 (Microsoft Excel type library)],然後將型別程式庫中的所有類別都加入您的專案。Excel 97 的型別程式庫位於 Excel8.olb 中。Excel 2000 的型別程式庫位於 Excel9.olb 中,而 Excel 2002 和更新版本的型別程式庫則位於 Excel.exe 中。
  4. 將下面這一行加入 CntrItem.h 中:
    LPDISPATCH GetIDispatch();
    					
  5. 然後將 GetIDispatch 方法加入 CntrItem.cpp:
       Sample Code
       -----------
    
    
          /*******************************************************************
          *   This method returns the IDispatch* for the application linked to
          *   this container.
          ********************************************************************/ 
          LPDISPATCH CEmbed_ExcelCntrItem::GetIDispatch()
          {
             //The this and m_lpObject pointers must be valid for this function
             //to work correctly. The m_lpObject is the IUnknown pointer to
             // this object.
             ASSERT_VALID(this);
    
             ASSERT(m_lpObject != NULL);
    
             LPUNKNOWN lpUnk = m_lpObject;
    
             //The embedded application must be running in order for the rest
             //of the function to work.
             Run();
    
             //QI for the IOleLink interface of m_lpObject.
             LPOLELINK lpOleLink = NULL;
             if (m_lpObject->QueryInterface(IID_IOleLink,
                (LPVOID FAR*)&lpOleLink) == NOERROR)
             {
                ASSERT(lpOleLink != NULL);
                lpUnk = NULL;
    
                //Retrieve the IUnknown interface to the linked application.
                if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR)
                {
                   TRACE0("Warning: Link is not connected!\n");
                   lpOleLink->Release();
                   return NULL;
                }
                ASSERT(lpUnk != NULL);
             }
    
             //QI for the IDispatch interface of the linked application.
             LPDISPATCH lpDispatch = NULL;
             if (lpUnk->QueryInterface(IID_IDispatch, (LPVOID FAR*)&lpDispatch)
                !=NOERROR)
             {
                TRACE0("Warning: does not support IDispatch!\n");
                return NULL;
             }
    
             //After assuring ourselves it is valid, return the IDispatch
             //interface to the caller.
             ASSERT(lpDispatch != NULL);
             return lpDispatch;
          }
    					
  6. 將下面這一行加入 Embed_ExcelView.h 中:
          void EmbedAutomateExcel();
    					
  7. 然後將 EmbedAutomateExcel 方法加入 Embed_ExcelView.cpp:
    Sample Code
    -----------
          /********************************************************************
          *   This method encapsulates the process of embedding an Excel
          *   Worksheet in a View object and automating that worksheet to add
          *   some text to cell A1.
          ********************************************************************/ 
          void CEmbed_ExcelView::EmbedAutomateExcel()
          {
             //Change the cursor so the user knows something exciting is going
             //on.
             BeginWaitCursor();
    
             CEmbed_ExcelCntrItem* pItem = NULL;
             TRY
             {
                //Get the document associated with this view, and be sure it's
                //valid.
                CEmbed_ExcelDoc* pDoc = GetDocument();
                ASSERT_VALID(pDoc);
    
                //Create a new item associated with this document, and be sure
                //it's valid.
                pItem = new CEmbed_ExcelCntrItem(pDoc);
                ASSERT_VALID(pItem);
    
                // Get Class ID for Excel sheet.
                // This is used in creation.
                CLSID clsid;
                if(FAILED(::CLSIDFromProgID(L"Excel.sheet",&clsid)))
                   //Any exception will do. We just need to break out of the
                   //TRY statement.
                   AfxThrowMemoryException();
    
                // Create the Excel embedded item.
                if(!pItem->CreateNewItem(clsid))
                   //Any exception will do. We just need to break out of the
                   //TRY statement.
                   AfxThrowMemoryException();
    
                //Make sure the new CContainerItem is valid.
                ASSERT_VALID(pItem);
    
                // Launch the server to edit the item.
                pItem->DoVerb(OLEIVERB_SHOW, this);
    
    
                // As an arbitrary user interface design, this sets the
                // selection to the last item inserted.
                m_pSelection = pItem;   // set selection to last inserted item
                pDoc->UpdateAllViews(NULL);
    
                //Query for the dispatch pointer for the embedded object. In
                //this case, this is the Excel worksheet.
                LPDISPATCH lpDisp;
                lpDisp = pItem->GetIDispatch();
    
                //Add text in cell A1 of the embedded Excel sheet
                _Workbook wb;
                Worksheets wsSet;
                _Worksheet ws;
                Range range;
                _Application app;
    
                //set _Workbook wb to use lpDisp, the IDispatch* of the
                //actual workbook.
                wb.AttachDispatch(lpDisp);
    
    
                //Then get the worksheet's application.
                app = wb.GetApplication();
    
                //Then get the first worksheet in the workbook
                wsSet = wb.GetWorksheets();
                ws = wsSet.GetItem(COleVariant((short)1));
    
                //From there, get a Range object corresponding to cell A1.
                range = ws.GetRange(COleVariant("A1"), COleVariant("A1"));
    
                //Fill A1 with the string "Hello, World!"
                range.SetValue(COleVariant("Hello, World!"));
    
               //NOTE: If you are automating Excel 2002, the Range.SetValue method has an 
               //additional optional parameter specifying the data type.  Because the 
               //parameter is optional, existing code will still work correctly, but new 
               //code should use the new convention.  The call for Excel2002 should look 
               //like the following:
    
               //range.SetValue( C<?xm-insertion_mark_start author="v-thomr" time="20070326T121607-0600"?>O<?xm-insertion_mark_end?><?xm-deletion_mark author="v-thomr" time="20070326T121606-0600" data="o"?>leVariant( (long)DISP_E_PARAMNOTFOUND, VT_ERROR ), 
               //                COleVariant("Hello, World!"));
             }
    
               //Here, we need to do clean up if something went wrong.
               CATCH(CException, e)
               {
                  if (pItem != NULL)
                  {
                     ASSERT_VALID(pItem);
                     pItem->Delete();
    
                  }
                  AfxMessageBox(IDP_FAILED_TO_CREATE);
               }
               END_CATCH
    
               //Set the cursor back to normal so the user knows exciting stuff
               //is no longer happening.
               EndWaitCursor();
            }
    
    					
  8. 將下面這一行加入 Embed_ExcelView.h 中:
          #include "excel8.h"
    						
    注意 如果是將 Excel 2000 自動化,標頭檔為 "excel9.h"。如果是將 Excel 2002 或更新版本的 Excel 自動化,標頭檔則為 "excel.h"。
  9. 查看檢視類別的 OnInsertObject() 方法。值得注意的是,這個方法和我們剛剛撰寫的方法極為相似。事實上,我們所寫的程式碼只是 OnInsertObject() 的特殊情況,它可以讓使用者從可用的 OLE 物件清單中,選取要插入至應用程式的物件。因為我們只想要將 Excel 工作表自動化,所以我們覆寫這個行為。針對我們的應用程式,我們移除 InsertObject() 內部的所有程式碼,並將它取代成對 EmbedAutomateExcel() 的呼叫。
  10. 編譯和執行應用程式。
  11. [編輯] 功能表上,按一下 [插入新物件]
結果:一份 Microsoft Excel 工作表就會內嵌到檢視中。此外,儲存格 A1 會自動填入 "Hello, World!"。

屬性

文章編號: 184663 - 上次校閱: 2007年4月27日 - 版次: 5.0
這篇文章中的資訊適用於:
  • Microsoft Office Excel 2007
  • Microsoft Office Excel 2003
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Visual C++ 6.0 Professional Edition
  • Microsoft Foundation Class Library 4.2
  • Microsoft Office XP Developer Edition
  • Microsoft Office 2000 Developer Edition
關鍵字:?
kbprogramming kbautomation kbhowto kbinterop KB184663
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com