概要
この記事では、Visual C++ から Microsoft Office へのオートメーションに関する一般的な質問に回答します。
詳細情報
目次
-
Automation とは
-
Automation を初めて使用する場合、詳細については、どこで適切なリソースを見つけることができますか?
-
Automation を使用する方法はさまざまですか?
-
COM とは
-
操作方法 Office アプリケーションの実行中のインスタンスにアタッチしますか?
-
省略可能なパラメーター操作方法渡しますか?
-
操作方法 Office アプリケーションによって公開されるイベントをキャッチしますか?
-
オートメーション コードが遅すぎます。 どのように私は物事をスピードアップできますか?
-
-2147352573や0x80030002など、これらの巨大なエラー値は何を意味しますか?
-
タイプ ライブラリとは
-
オートメーション コードは Microsoft Excel 95 で動作しましたが、Microsoft Excel 97 では失敗します。 なぜでしょうか?
-
プログラムが完了した後、アプリケーションがメモリに残っているのはなぜですか?
-
Microsoft Office アプリケーション ユーザーとして何をしたいかはわかっていますが、Automation を使用してプログラムでこれを行うにはどうすればよいですか?
-
埋め込み Microsoft Office アプリケーションを自動化できますか?
-
Microsoft Office ドキュメントのドキュメント プロパティにアクセス操作方法
質問と回答
-
Automation
とは Automation (旧称 OLE Automation) は、既存のプログラムの機能を活用し、独自のアプリケーションに組み込むことができるテクノロジです。 たとえば、ユーザーに Microsoft Word を表示せずに、Microsoft Word のスペル チェック機能と文章校正機能をアプリケーションに利用できます。 Microsoft Excel のすべてのグラフ作成、印刷、およびデータ分析ツールを使用することもできます。 このテクノロジを使用すると、開発を大幅に簡素化し、高速化できます。
-
Automation を初めて使用する場合、詳細については、どこで適切なリソースを見つけることができますか? David Kruglinski の "Inside Visual C++" (ISBN:1-57231-565- 2) の第 24 章では、一般的な概要といくつかの優れた例が提供されています。 また、Microsoft サポート技術情報は情報の適切なソースです。
例による学習を希望する場合は、Microsoft サポート技術情報の次の記事を参照してください。
179706 HOWTO MFC を使用して Excel &新しいブックを作成/書式設定する
-
Automation を使用する方法はさまざまですか?
オートメーションには、MFC、#import、C/C++ の 3 つの基本的な方法があります。
-
MFC では、Visual C++ ClassWizard を使用して、Microsoft Office タイプ ライブラリから "ラッパー クラス" を生成します。 これらのクラスと、COleVariant、COleSafeArray、COleException などの他の MFC クラスは、オートメーションのタスクを簡略化します。 通常、この方法は他の方法よりも推奨され、ほとんどの Microsoft サポート技術情報の例では MFC が使用されています。
-
#import、Visual C++ 5.0 で使用できるようになった新しいディレクティブは、指定されたタイプ ライブラリから VC++ の "スマート ポインター" を作成します。 これは非常に強力ですが、Microsoft Office アプリケーションで使用される場合に通常発生する参照カウントの問題のために推奨されないことが多いです。
-
C/C++ オートメーションははるかに困難ですが、MFC のオーバーヘッドや#importの問題を回避するために必要な場合があります。 基本的には、CoCreateInstance() などの API や、IDispatch や IUnknown などの COM インターフェイスを使用します。
COM は C++ クラスを中心に設計されているため、単純な C++ と比較して、C++ からの Automation には若干の違いがあることに注意してください。
-
-
COM
とは オートメーションは、コンポーネント オブジェクト モデル (COM) に基づいています。 COM は、インターフェイスに基づく標準的なソフトウェア アーキテクチャであり、コードを自己完結型オブジェクトに分離するように設計されています。 オブジェクト指向プログラミング (OOP) パラダイムの拡張と考えますが、個別のアプリケーションに適用できます。 各オブジェクトは一連のインターフェイスを公開し、初期化、通知、データ転送などのオブジェクトへのすべての通信は、これらのインターフェイスを介して行われます。
COM は、オペレーティング システムと共にインストールされたダイナミック リンク ライブラリ (DLL) によって提供される一連のサービスでもあります。 自動化では、これらのサービスの多くが使用されます。 1 つの例として、クライアント アプリケーションの呼び出しをサーバー アプリケーションのインターフェイスのメンバー関数にパッケージ化し、それらの呼び出しを引数と共にサーバー アプリケーションに渡す "マーシャリング" サービスがあります。 これにより、サーバーのインターフェイスがクライアントのメモリ空間で公開されているように見えます。これは、クライアントが独自のプロセス空間で実行されている.exeの場合ではありません。 マーシャリングは、サーバーのメソッドから戻り値をプロセスの境界を越えて、クライアントの呼び出しの手に安全に戻ります。 Automation に不可欠な他の多くのサービスは、さまざまな COM ライブラリによって提供されます。 これらの情報のソースには、Kraig Brockschmidt、ISBN 1-55615-843-2、デール・ロジャーソンの「Inside COM」、ISBN 1-57231-349-8、および「Automation Programmer's Reference」ISBN 1-57231-584-9 が含まれます。 -
操作方法 Office アプリケーションの実行中のインスタンスにアタッチしますか?
GetActiveObject() API を使用します。 Automation サーバーは、RegisterActiveObject() API を使用して、ROT (実行中のオブジェクト テーブル) に自身を登録します。 Automation クライアントは、次のようなコードを使用して実行中のインスタンスで取得できます。
// 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 を繰り返すことができますが、別のインスタンスが既に ROT 内にある場合、Office アプリ自体は登録されません。これは、それ自体のモニカーが常に同じであるためです (とにかく区別できませんでした)。 つまり、最初の インスタンス以外のインスタンスにはアタッチできません。 ただし、Office アプリは自分のドキュメントも ROT に登録するため、ROT を反復処理して特定のドキュメントを探し、添付してから Application オブジェクトを取得することで、他のインスタンスに正常にアタッチできます。
PowerPoint は単一インスタンス アプリケーションであるため、これを行う必要はありません。実行できるインスタンスは 1 つだけです。 -
省略可能なパラメーター操作方法渡しますか?
一部のメソッドには、"省略可能" パラメーターがあります。 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 が実際にバックグラウンドで行っていることです。
-
操作方法 Office アプリケーションによって公開されるイベントをキャッチしますか?
基本的には、キャッチするイベント インターフェイス ("シンク") を実装し、アプリケーション ("ソース") とのアドバイザリ接続を設定します。
一般に、アドバイザリ接続を設定するには、サーバーの IConnectionPointContainer を取得し、イベント インターフェイスの IID で FindConnectionPoint() を呼び出します。 これにより、IConnectionPoint インターフェイスが提供され、残っているのは、イベント インターフェイスのインスタンスで Advise() を呼び出す操作です。 これらのイベントが発生すると、サーバーはこのインターフェイスを介してコールバックします。 -
オートメーション コードが遅すぎます。 どのように私は物事をスピードアップできますか?
Automation の速度に関する問題の一般的な原因は、データの繰り返しの読み取りと書き込みです。 これは、Excel Automation クライアントの場合に一般的です。 ただし、ほとんどの人は、このデータは通常、SAFEARRAY を使用して一度にすべてを書き込んだり読み取ったりできることに気付いていません。 詳細と有益な例については、次の Microsoft サポート技術情報の記事を参照してください。179706 HOWTO: MFC を使用して Excel を自動化し、新しいブック
を作成/書式設定する また、クリップボードを使用するとパフォーマンスが向上する場合があることを指摘することが重要です。 たとえば、データをクリップボードにコピーし、オートメーションを使用してサーバーに貼り付けを指示できます。 またはその逆です。クリップボードにコピーするようにサーバーに指示し、アプリケーションに貼り付けます。 -
-2147352573 や 0x80030002 など、これらの巨大なエラー値は何を意味しますか?
これらの値は HRESULT と呼ばれ、winerror.h で定義されています。 最初のビットはエラー結果であるかどうかを表すので、数値は非常に大きくなります。 Visual C++ に付属の ErrLook.Exe ユーティリティを使用して、これらの数値を意味のある説明に変換できます。
プログラムによってエラーの説明を取得する場合は、FormatMessage() API を使用できます。注: Visual C++ 6.0 を使用していて、デバッグ ウォッチ ウィンドウにこの値を含む変数がある場合は、", hr" (引用符なし) を追加して、Visual C++ で翻訳します。
-
タイプ ライブラリ
とは タイプ ライブラリは、C/C++ ヘッダー ファイルに似ています。 これには、サーバーが発行しているインターフェイス、メソッド、およびプロパティが含まれています。 Visual C++ に付属する OLE/COM オブジェクト ビューアー (Oleview.exe) を使用して、タイプ ライブラリを表示できます。 Microsoft Office 95、97、2000 のタイプ ライブラリファイル名の一覧を次に示します
。 Office アプリケーション |タイプ ライブラリ
------------------------+----------------
Word 95 以前の|wb70en32.tlb
Excel 95 以前の|xl5en32.olb
Powerpoint 95 以前の|Powerpoint.tlb
95 以前の|にアクセスするmsaccess.tlb
バインダー 95 |binder.tlb
Schedule+ |sp7en32.olb
プロジェクト |pj4en32.olb
チーム マネージャー |mstmgr1.olb
Word 97 |msword8.olb
Excel 97 |excel8.olb
Powerpoint 97 |msppt8.olb
Access 97 |msacc8.olb
バインダー 97 |msbdr8.olb
グラフ 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
-
オートメーション コードは Excel 95 で動作しましたが、Excel 97 では失敗します。 どうしたんですか。
Excel のオブジェクト モデルは、バージョン 95 から 97 に大幅に変更されました。 Excel 95 では、IDispatch の 1 つの実装ですべてのメソッドとプロパティが実装されました。 これは、多くの場合、オブジェクト X 用のメソッドをオブジェクト Y から呼び出すことができることを意味します。これは適切な設計ではないため、Office 97 では、各オブジェクトに個別の Idispatch 実装があります。 つまり、別のオブジェクト Y からオブジェクト X にメソッドまたはプロパティを要求すると、エラー 0x80020003 -2147352573"メンバーが見つかりません" というエラーが表示されます。 このエラーを回避するには、呼び出し元の基になる IDispatch インターフェイスが意味的に正しいことを確認する必要があります。
-
私が自動化しているアプリケーションは、プログラムが完了した後もメモリにとどまります。 どうしたんですか。
おそらく、これは、取得したインターフェイスをリリースし忘れたため、それを追跡する必要があるためです。 一般的な提案と、検索する内容を次に示します。
-
#importを使用している場合は、関連する参照カウントのバグのいずれかに実行されている可能性が非常に高いです。 多くの場合、バグを回避できますが、通常は他の Automation メソッドのいずれかを使用することをお勧めします。 #importのタイプ ライブラリと使用はかなり複雑であるため、Office アプリケーションではあまり機能しません。 また、このような参照カウントの問題は、#importを使用する場合、インターフェイス レベルの COM 呼び出しの多くがバックグラウンドで行われるため、追跡が困難です。
-
IDispatch * (LPDISPATCH) を返す Open メソッドや New メソッドを呼び出していて、戻り値を無視しているかどうかを確認します。 あなたがしている場合は、この返されたインターフェイスを破棄し、不要になったときにコードを解放するようにコードを変更する必要があります。
-
問題が消えるまでコードのセクションを徐々にコメントアウトしてから、慎重に追加して問題の開始場所を追跡します。
-
ユーザーがアプリケーションに "タッチ" した場合、一部のアプリケーションは引き続き実行されることに注意してください。 自動化中にこれが発生した場合、アプリケーションは後で実行され続ける可能性があります。 Office アプリケーションには、Application オブジェクトに "UserControl" プロパティがあり、この動作を変更するために読み取り/書き込みを行うことができます。
-
また、一部のアプリケーションでは、十分なユーザー インターフェイス "アクション" が発生した場合に実行を続ける場合があります。 アプリケーションを終了する場合は、Application オブジェクトで Quit() メソッドを呼び出します。 Quit が呼び出されると、参照カウントに関係なく、Word はシャットダウンします。 これは COM の動作とは思われません。 ただし、Excel では、それ自体は適切に非表示になりますが、未処理のすべてのインターフェイスがリリースされるまで実行を続けます。 一般に、未処理のすべての参照を解放し、アプリケーションを終了する場合にのみ Quit() を呼び出す必要があります。
-
-
Office アプリケーション ユーザーとして何をしたいかはわかっていますが、Automation を使用してプログラムでこれを行うにはどうすればよいですか?
関心があるのは、使用する必要があるオブジェクト、メソッド、プロパティです。 ユーザーとして実行する操作に基づいて、Word、Excel、Powerpoint のオブジェクト モデルを移動する方法を学習する最善の方法は、マクロ レコーダーを使用することです。 [ツール] メニューから [マクロ]\'[新しいマクロの記録] を選択し、目的のタスクを実行し、[マクロ] \'[記録の停止] を選択するだけです。 記録が完了したら、[ツール] メニューから [マクロ]\[マクロ] を選択し、記録したマクロを選択し、[編集] をクリックします。 これにより、記録したタスクを実行する生成された VBA コードが表示されます。 ほとんどの場合、記録されたマクロは可能な限り最適なコードではありませんが、簡単な例では非常にうまく機能します。 -
埋め込み Office アプリケーションを自動化できますか?
そうですよ。 このトリックは、IDispatch ポインターを取得することです。これは、Visual C++ Technical Note 39 (TN039) で提供されています。
-
Office ドキュメント内のドキュメント プロパティにアクセス操作方法。
ドキュメント プロパティには、Automation を使用するか、IPropertyStorage を介して直接アクセスできます。