MFC を使用して Microsoft Excel ワークシートの埋め込みとオートメーションを行う方法

概要

この資料では、SDI の MFC アプリケーションで Microsoft Excel ワークシートを View オブジェクトに埋め込む方法について説明します。



この資料では、ワークシートを埋め込み、セル A1 にテキストを追加する方法を手順を追って説明し、各手順についても説明しています。



この資料のサンプル コードをコピーして任意のアプリケーションに貼り付けることができますが、サンプル コードを読んで理解すると、実際の場面で役立てることができます。

詳細

マイクロソフトは、この情報をプログラミング言語の使用方法の一例として提供するだけであり、市場性および特定目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。この資料は、例示されているプログラミング言語やプロシージャの作成およびデバッグに使用するツールについて理解されているユーザーを対象としています。Microsoft Support 担当者は、特定のプロシージャの機能についての問い合わせにはお答えできますが、ユーザー固有の目的に合わせた機能の追加、プロシージャの作成などの内容変更は行っておりません。



MFC アプリケーションを作成するには、以下の手順を実行します。

  1. AppWizard を使用して、"Embed_Excel" という名前の新しい MFC AppWizard (exe) プロジェクトを作成します。

  2. 作成するアプリケーションの種類として単一文書インターフェイス (SDI) を選択します。また、サポートする複合ドキュメントの種類としてコンテナを選択します。その他のデフォルトの設定はそのまま使用します。



    以下のクラスが生成されます。

    アプリケーション : CEmbed_ExcelApp (Embed_Excel.h および Embed_Excel.cpp)


    フレーム : CMainFrame (MainFrm.h および MainFrm.cpp)


    ドキュメント : CEmbed_ExcelDoc (Embed_ExcelDoc.h および Embed_ExcelDoc.cpp)


    ビュー : CEmbed_ExcelView (Embed_ExcelView.h および Embed_ExcelView.cpp)


    コンテナ アイテム : CEmbed_ExcelCntrItem (CntrItem.h および CntrItem.cpp)
  3. [表示] メニューの [ClassWizard] をクリックし、[オートメーション] タブをクリックします。次に、[クラスの追加] をクリックし、[タイプ ライブラリから] をクリックします。Microsoft Excel のタイプ ライブラリを見つけ、このタイプ ライブラリのすべてのクラスをプロジェクトに追加します。Excel 97 の場合、タイプ ライブラリは Excel8.olb にあります。Excel 2000 の場合、タイプ ライブラリは Excel9.olb にあります。Excel 2002 以降の場合、タイプ ライブラリは Excel.exe にあります。
  4. CntrItem.h に以下の行を追加します。

    LPDISPATCH GetIDispatch();
  5. 次に、CntrItem.cpp に GetIDispatch メソッドを追加します。

       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. 次に、Embed_ExcelView.cpp に EmbedAutomateExcel メソッドを追加します。

    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. View クラスの OnInsertObject() メソッドを確認します。注目すべき点は、このメソッドと記述したメソッドが非常に似ていることです。実際、記述したコードは OnInsertObject() の特殊なケースにすぎません。OnInsertObject を使用すると、ユーザーは使用可能な OLE オブジェクトの一覧から選択してアプリケーションに挿入できます。Excel ワークシートを自動化するだけなので、この動作はオーバーライドします。作成するアプリケーションでは、InsertObject() の内部にあるすべてのコードを削除し、EmbedAutomateExcel() の呼び出しに置き換えます。

  10. アプリケーションをコンパイルし、実行します。

  11. [編集] メニューの [オブジェクトの作成と貼り付け] をクリックします。

結果 : Microsoft Excel ワークシートがビューに埋め込まれます。また、オートメーションによりセル A1 に "Hello, World!" と入力されます。

プロパティ

文書番号:184663 - 最終更新日: 2007/05/29 - リビジョン: 1

フィードバック