現在オフラインです。再接続するためにインターネットの接続を待っています

Visual C++ を使用した Office オートメーション

概要
この資料では、Visual C++ で行う Microsoft Office のオートメーションに関する一般的な質問の回答を掲載します。
詳細

この資料の内容

  1. オートメーションについて教えてください。
  2. オートメーションの初心者が学習するための資料の入手先を教えてください。
  3. オートメーションを使用する方法にはどのようなものがありますか。
  4. COM について教えてください。
  5. Office アプリケーションの実行中のインスタンスにアタッチする方法を教えてください。
  6. 省略可能なパラメータの渡し方を教えてください。
  7. Office アプリケーションによって公開されたイベントをキャッチする方法を教えてください。
  8. オートメーション コードの処理速度が遅いのですが、速くする方法はありますか。
  9. -2147352573 や 0x80030002 のような値の大きいエラー値の意味を教えてください。
  10. タイプ ライブラリについて教えてください。
  11. 使用しているオートメーション コードが Microsoft Excel 95 では動作しますが、Microsoft Excel 97 では失敗します。その理由を教えてください。
  12. プログラムを終了しても、自動化しているアプリケーションがメモリから削除されません。その理由を教えてください。
  13. Microsoft Office アプリケーションの操作をオートメーションで実現する方法を教えてください。
  14. 埋め込まれた Microsoft Office アプリケーションを自動化できますか。
  15. Microsoft Office ドキュメントのプロパティにアクセスする方法を教えてください。

質問と答え

  1. オートメーションについて教えてください。

    オートメーション (以前の OLE オートメーション) は、既存のプログラムの機能を利用して、その機能を独自のアプリケーションに組み込むことができるようにするテクノロジです。たとえば、Microsoft Word を表示せずに、Microsoft Word のスペル チェックと文章校正の機能をアプリケーションで使用できます。さらに、Microsoft Excel のグラフ、印刷、およびデータ分析ツールもすべて使用できます。このテクノロジによって開発がきわめて簡略化され、開発期間も短縮できます。
  2. オートメーションの初心者が学習するための資料の入手先を教えてください。

    『Inside Visual C++ Version 5』 (David Kruglinski 著、ISBN:4-7561-2174-8) の第 24 章に、一般的な概要といくつかの役立つサンプルが記載されています。また、「サポート技術情報」 (Microsoft Knowledge Base) も有益な情報源です。この資料自体が初心者に適しています。より具体的な資料については、「サポート技術情報」 (Microsoft Knowledge Base) の次の資料を参照してください。
    152023 OLE オートメーションについて学ぶための資料の場所について
    サンプルを利用して学習するには、「サポート技術情報」 (Microsoft Knowledge Base) の次の資料を参照してください。
    179706 [HOWTO] MFC による Excel のオートメーションで新しいブックの作成や書式設定を行う方法
  3. オートメーションを使用する方法にはどのようなものがありますか。

    オートメーションを使用するには、3 つの基本的な方法 (MFC、#import、および C/C++) があります。

    • MFC では、Visual C++ のクラス ウィザードを使用して、Microsoft Office タイプ ライブラリから "ラッパー クラス" を生成します。これらのクラス、および、COleVariant、COleSafeArray、COleException などの他の MFC クラスにより、オートメーションのタスクが簡単になります。通常は、他の方法よりもこの方法を使用することを推奨します。「サポート技術情報」 (Microsoft Knowledge Base) の例でも、多くの場合 MFC を使用しています。
    • #import は、Visual C++ 5.0 で使用可能になった新しいディレクティブです。これは、指定したタイプ ライブラリから VC++ の "スマート ポインタ" を作成します。#import は高機能ですが、あまりお勧めしません。一般的に、このディレクティブを Microsoft Office アプリケーションで使用すると、参照カウントの問題が発生します。
    • C/C++ オートメーションはこれらよりはるかに習得が困難ですが、MFC でのオーバーヘッドや、#import の問題を回避するために必要な場合があります。基本的には、CoCreateInstance() などの API、および IDispatch や IUnknown などの COM インターフェイスを使用して作業します。
    COM は C++ クラスに沿って設計されているため、C++ のオートメーションは、標準 C のオートメーションと比較すると若干違いがあります。詳細については、「サポート技術情報」 (Microsoft Knowledge Base) の次の資料で C の例を参照してください。
    181473 [HOWTO] C++ アプリケーションではなく C アプリケーションからの OLE オートメーションの使用方法
  4. COM について教えてください。

    オートメーションは、コンポーネント オブジェクト モデル (COM) に基づいています。COM は、インターフェイスに基づいた標準のソフトウェア アーキテクチャで、コードが独立したオブジェクトに分割されるように設計されています。これは、オブジェクト指向プログラミング (OOP) パラダイムの拡張と考えることができますが、個別のアプリケーションに適用されます。各オブジェクトは、一連のインターフェイスを公開し、初期化、通知、データの転送などのオブジェクトへのすべての通信をそれらのインターフェイスで行います。

    また、COM は、オペレーティング システムと一緒にインストールされたダイナミック リンク ライブラリ (DLL) で提供される一連のサービスでもあります。オートメーションは、これらのサービスを多数使用します。たとえば、"マーシャリング" サービスは、クライアント アプリケーションにおけるサーバー アプリケーションのインターフェイスのメンバ関数の呼び出しをパッケージ化し、引数を含めてこれらの関数呼び出しをサーバー アプリケーションに渡します。これにより、サーバーのインターフェイスがクライアントのメモリ空間で公開されているように見えます。これは、クライアントが独自のプロセス空間で実行される .exe (実行ファイル) の場合とは異なります。また、マーシャリングは、プロセスの境界を越えてサーバーのメソッドから戻り値を取得し、クライアントの呼び出しに戻り値を安全に返します。この他にも、オートメーションに不可欠なサービスがさまざまな COM ライブラリによって多数提供されています。COM に関する情報源として、『Inside Ole 改訂新版』 (Kraig Brockschmidt 著、ISBN 4-7561-1618-3)、『Inside COM』 (Dale Rogerson 著、4-7561-2176-4)、および『オートメーション プログラマーズ リファレンス』 (ISBN 4-7561-2179-9) があります。
  5. Office アプリケーションの実行中のインスタンスにアタッチする方法を教えてください。

    GetActiveObject() API を使用します。オートメーション サーバーは、RegisterActiveObject() API を使用して実行中オブジェクト テーブル (ROT) にサーバー自身を登録します。オートメーション クライアントでは、次のようなコードを使用して、実行中のインスタンスを取得できます。
          // Translate server ProgID into a CLSID. ClsidFromProgID      // gets this information from the registry.      CLSID clsid;      CLSIDFromProgID(L"Excel.Application", &clsid);        // Get an interface to the running instance, if any..      IUnknown *pUnk;      HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);      ASSERT(!FAILED(hr));      // Get IDispatch interface for Automation...      IDispatch *pDisp;      hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pDisp);      ASSERT(!FAILED(hr));      // Release the no-longer-needed IUnknown...      pUnk->Release();						
    : アタッチする Office アプリケーションのインスタンスが複数実行されている場合、GetActiveObject() API を使用してアタッチできるのは、最初に起動されたインスタンスのみです。

    理論上は、インスタンスごとに ROT の処理を繰り返して実行することができますが、Office アプリケーションでは、別のインスタンスが既に ROT に存在する場合、アプリケーションの登録を行いません。これは、インスタンスのモニカがすべて同じである (区別する方法がない) ためです。つまり、最初のインスタンス以外、どのインスタンスにもアタッチできません。ただし、Office アプリケーションではドキュメントも ROT に登録するため、次の方法で他のインスタンスにアタッチすることができます。ROT の検索処理を繰り返して特定のドキュメントを見つけ、そのドキュメントにアタッチして、そこから Application オブジェクトを取得します。「サポート技術情報」 (Microsoft Knowledge Base) の次の資料には、ROT 内をループして、ドキュメント名を検索するコードが掲載されています。
    190985 [HOWTO] Excel ファイルまたは Word 文書の IDispatch を OCX から取得する方法
    PowerPoint は、シングル インスタンス アプリケーションであるため、この操作を実行する必要はありません。PowerPoint では、インスタンスは 1 つしか実行されません。
  6. 省略可能なパラメータの渡し方を教えてください。

    一部のメソッドには "省略可能な" パラメータが含まれています。Visual Basic では、メソッドの呼び出し時に、このようなパラメータを省略できます。ただし、Visual C++ での呼び出し時には、.vt フィールドが VT_ERROR、.scode フィールドが DISP_E_PARAMNOTFOUND である特別な VARIANT を渡す必要があります。コードの例を以下に示します。
          // VARIANT used in place of optional-parameters.      VARIANT varOpt;      varOpt.vt = VT_ERROR;      varOpt.scode = DISP_E_PARAMNOTFOUND;						
    これは、実際に、Visual Basic の内部で実行されているコードです。
  7. Office アプリケーションによって公開されたイベントをキャッチする方法を教えてください。

    基本的には、キャッチするイベント インターフェイス ("シンク") を実装し、アプリケーション ("ソース") とのアドバイザリ コネクションをセットアップします。以下の資料では、Microsoft Word の例を手順を追って説明しています。
    183599 Visual C++ を使用して Word アプリケーションのイベントをキャッチする方法
    一般的に、アドバイザリ コネクションをセットアップするには、サーバーの IConnectionPointContainer を取得し、イベント インターフェイスの IID を使用して FindConnectionPoint() を呼び出します。これにより、IConnectionPoint インターフェイスが提供されるので、以後はイベント インターフェイスのインスタンスを使用して Advise() を呼び出すだけです。その後サーバーは、イベントが発生したときに、このインターフェイスを使用してコールバックします。
  8. オートメーション コードの処理速度が遅いのですが、速くする方法はありますか。

    オートメーションの速度に関する問題は、多くの場合、データの読み取りおよび書き込みが繰り返し実行されることが原因です。これは Excel オートメーション クライアントでよく発生します。あまり知られていませんが、通常 SAFEARRAY を使用することによって、このデータの書き込みと読み取りを一度に実行できます。詳細および参考例については、「サポート技術情報」 (Microsoft Knowledge Base) の以下の資料を参照してください。
    186120 MFC を使用して Excel を自動化し、配列のデータをセル範囲に入力する方法
    186122 MFC を使用して Excel 2000 または Excel 2002 を自動化し、セル範囲のデータを配列に取得する方法
    179706 [HOWTO] MFC による Excel のオートメーションで新しいブックの作成や書式設定を行う方法
    また、クリップボードを使用すると、パフォーマンスが向上する可能性があります。たとえば、データをクリップボードにコピーし、オートメーションを使用してサーバーで貼り付けを実行することができます。反対に、サーバーでクリップボードへのコピーを実行し、アプリケーションに貼り付けることもできます。
  9. -2147352573 や 0x80030002 のような値の大きいエラー値の意味を教えてください。

    これらの値は、HRESULT と呼ばれ、winerror.h で定義されています。数字が非常に大きいのは、最上位のビットが、エラー結果であるかどうかを表すためです。Visual C++ に付属の ErrLook.Exe ユーティリティを使用すると、これらの数字をわかりやすい説明に変換できます。

    プログラムを使用してエラーの説明を取得するには、FormatMessage() API を使用します。FormatMessage() の使用に関する詳細および例を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
    186063 [INFO] VB または VBA のオートメーション エラー (Long 型) の取得方法
    122957 [SAMPLE] OLE エラー コードのデコード ツール Decode32 および Decode 16
    : Visual C++ 6.0 を使用していて、この値を含む変数がデバッグ ウォッチ ウィンドウに存在する場合、その変数に ", hr" (二重引用符は含みません) を追加すると、Visual C++ でその値がわかりやすい説明に変換されます。
  10. タイプ ライブラリについて教えてください。

    タイプ ライブラリは、C/C++ ヘッダー ファイルに似ています。タイプ ライブラリには、サーバーが公開しているインターフェイス、メソッド、およびプロパティが含まれています。Visual C++ に付属の OLE/COM Object Viewer (Oleview.exe) を使用してタイプ ライブラリを参照できます。以下に、Microsoft Office 95、97、および 2000 のタイプ ライブラリ ファイル名の一覧を示します。
           Office アプリケーション     | タイプ ライブラリ       ------------------------+----------------       Word 95 以前              | wb70en32.tlb       Excel 95 以前             | xl5en32.olb       Powerpoint 95 以前       | Powerpoint.tlb       Access 95 以前            | msaccess.tlb       Binder 95               | binder.tlb       Schedule+               | sp7en32.olb       Project                 | pj4en32.olb       Team Manager            | mstmgr1.olb       Word 97                 | msword8.olb       Excel 97                | excel8.olb       Powerpoint 97           | msppt8.olb       Access 97               | msacc8.olb       Binder 97               | msbdr8.olb       Graph 97                | graph8.olb       Outlook 97              | msoutl8.olb       Outlook 98              | msoutl85.olb       Word 2000               | msword9.olb       Excel 2000              | excel9.olb       Powerpoint 2000         | msppt9.olb       Access 2000             | msacc9.olb       Outlook 2000            | msoutl9.olb       Word 2002               | msword.olb       Excel 2002              | excel.exe       Powerpoint 2002         | msppt.olb       Access 2002             | msacc.olb       Outlook 2002            | msoutl.olb 						
  11. 使用しているオートメーション コードが Excel 95 では動作しますが、Excel 97 では失敗します。その理由を教えてください。

    Excel のオブジェクト モデルは、Excel 95 から Excel 97 にかけて大幅に変更されています。Excel 95 では、単一の IDispatch の実装内にすべてのメソッドおよびプロパティを実装していました。つまり、ほとんどの場合、オブジェクト X 用のメソッドをオブジェクト Y から呼び出すことができましたが、これはあまり優れた設計ではありません。そのため、Office 97 では、オブジェクトごとに、個別の IDispatch を実装します。つまり、あるオブジェクト X のメソッドまたはプロパティを別のオブジェクト Y から要求すると、エラー 0x80020003、-2147352573 "メンバが見つかりません" が表示されます。このエラーを回避するには、呼び出し元の IDispatch インターフェイスが適切なインターフェイスであることを確認する必要があります。詳細については、「サポート技術情報」 (Microsoft Knowledge Base) の次の資料を参照してください。
    172108 [OLE] エラー 2147352573 のトラブルシューティング
  12. プログラムを終了しても、自動化しているアプリケーションがメモリから削除されません。

    おそらく、取得したインターフェイスを解放しなかったのが原因です。このインターフェイスを追跡して見つけ出す必要があります。以下に、一般的な考え方と検索する対象について説明します。

    • #import を使用している場合、このディレクティブに関連する参照カウントの不具合のいずれかが発生している可能性があります。ほとんどの場合この不具合は回避できますが、通常、他のオートメーション メソッドのいずれかを使用することをお勧めします。#import は、タイプ ライブラリと使用方法が複雑であるため、Office アプリケーションにおいてはあまり適していません。また、#import を使用した場合、インターフェイス レベルの COM 呼び出しが多数内部で実行されるため、このような参照カウントの問題の追跡は困難です。
    • Open や New など、IDispatch * (LPDISPATCH) を返す任意のメソッドを呼び出すときに、戻り値を処理していないかどうかを確認します。これに該当する場合は、この返されたインターフェイスが放置されているため、必要がなくなったときにインターフェイスを解放するようにコードを変更する必要があります。
    • 問題が発生しなくなるまでコードのセクションを順にコメントにします。その後、注意深くそのコードのコメントを外し、問題が発生している最初の部分を発見します。
    • 一部のアプリケーションでは、ユーザーがそのアプリケーションに "タッチする" と実行中の状態のままになることがあるため、注意が必要です。自動化している間にこの状態が発生すると、その後もアプリケーションは実行中のままになります。Office アプリケーションの Application オブジェクトに "UserControl" プロパティがあります。このプロパティの読み取りおよび書き込みを行うことによってこの動作を変更できます。
    • また、一部のアプリケーションでは、ユーザー インターフェイスで多数の "操作" を行うと、実行中の状態のままになります。アプリケーションを終了させる場合、Application オブジェクトで Quit() メソッドを呼び出します。Word は、Quit を呼び出すと、参照カウントに関係なくシャットダウンされます。これは COM で想定されている動作ではありません。これに対して Excel で Quit を呼び出した場合は、画面には表示されなくなりますが、未完了のインターフェイスがすべて解放されるまで実行中の状態のままです。通常は、未完了の参照をすべて解放する必要があります。アプリケーションを終了する場合にのみ、Quit() を呼び出します。
  13. Office アプリケーションの操作をオートメーションで実現する方法を教えてください。

    使用する必要があるオブジェクト、メソッドおよびプロパティに注目します。Word、Excel、および PowerPoint のオブジェクト モデルを操作する方法を、ユーザーの操作に基づいて理解するには、マクロの記録機能を使用する方法が最適です。[ツール] メニューの [マクロ] をポイントし、[新しいマクロの記録] をクリックします。関心のあるタスクを実行して、[マクロ] をポイントし、[記録終了] をクリックします。記録が完了したら、[ツール] メニューの [マクロ] をポイントし、[マクロ] をクリックします。記録したマクロをクリックし、[編集] をクリックします。この操作により、記録した作業を実行するように生成された VBA コードが表示されます。記録されたマクロのコードは最適化されていないことがほとんどですが、参照用の簡単なサンプルとして役立ちます。
  14. 埋め込まれた Office アプリケーションを自動化できますか。

    もちろん可能です。IDispatch ポインタを取得することが秘訣です。このポインタについては、Visual C++ のテクニカル ノート 39 (TN039) に記載されています。手順を追って説明しているサンプルについては、「サポート技術情報」 (Microsoft Knowledge Base) の次の資料を参照してください。
    184663 MFC を使用して Microsoft Excel ワークシートの埋め込みとオートメーションを行う方法
  15. Office ドキュメントのプロパティにアクセスする方法を教えてください。

    ドキュメント プロパティにアクセスするには、オートメーションを使用するか、直接 IPropertyStorage を使用します。各メソッドの実際の動作については、「サポート技術情報」 (Microsoft Knowledge Base) の次の資料を参照してください。
    179494 オートメーションを使用して組み込みのドキュメント プロパティを取得する方法
    186898 [HOWTO] VC++ を使用して複合ドキュメントのプロパティを直接読み取る方法
関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 196776 (最終更新日 2005-03-21) を基に作成したものです。

この資料に含まれているサンプル コード/プログラムは英語版を前提に書かれたものをありのままに記述しており、日本語環境での動作は確認されておりません。
coledispatchdriver colesafearray colevariant _com_ptr_t _com_variant_t IPropertySetStorage
プロパティ

文書番号:196776 - 最終更新日: 06/10/2005 08:22:00 - リビジョン: 6.1

Microsoft Project 2000 Standard Edition, Microsoft Excel 2000 Standard Edition, Microsoft Visual C++ 4.0 Standard Edition, Microsoft Visual C++ 5.0 Enterprise Edition, Microsoft Visual C++ 6.0 Enterprise Edition, Microsoft Visual C++ 5.0 Professional Edition, Microsoft Visual C++ 6.0 Professional Edition, Microsoft Visual C++, 32-bit Learning Edition 6.0, Microsoft Access 97 Standard Edition, Microsoft Excel 97 Standard Edition, Microsoft PowerPoint 97 Standard Edition, Microsoft Outlook 97 Standard Edition, Microsoft Word 97 Standard Edition, Microsoft Access 2000 Standard Edition, Microsoft PowerPoint 2000 Standard Edition, Microsoft Outlook 2000 Standard Edition, Microsoft Word 2000, Microsoft Access 2002 Standard Edition, Microsoft Excel 2002 Standard Edition, Microsoft PowerPoint 2002 Standard Edition, Microsoft Word 2002, Microsoft Outlook 2002 Standard Edition

  • kbautomation kbfaq KB196776
フィードバック