Visual C# .NET で Office オートメーション サーバーをバインドする方法

概要

Microsoft Office アプリケーションなどのアプリケーションを自動化する際、Office アプリケーション オブジェクトのプロパティやメソッドの呼び出しを何らかの方法でそれらのオブジェクトに関連付ける必要があります。プロパティやメソッドの呼び出しを、そのプロパティやメソッドが実装されているオブジェクトに関連付ける処理は、一般に "バインディング" と呼ばれています。Visual C# では、"事前バインディング" と "遅延バインディング" という 2 種類のバインディングが利用できます。バインディングの種類の選択により、パフォーマンス、柔軟性、保守性など、プログラムの多くの側面に影響があります。


この資料では、Visual C# のオートメーション クライアントの事前バインディングと遅延バインディングの解説および比較を行い、両方の種類のバインディングを示すコード サンプルを提供します。


事前バインディング

事前バインディングでは、対象の Office アプリケーションについて利用可能な型情報を使用して、必要なメソッドやプロパティに直接バインドします。コンパイラによって型および構文のチェックが実行され、メソッドやプロパティに渡されるパラメータの個数と型、および戻り値の型が適切であることが確認されます。プロパティまたはメソッドの呼び出しを行うのに必要な実行時の処理が少ないため、事前バインディングの方が高速な場合もありますが、遅延バインディングとのパフォーマンスの差は、多くの場合、ごくわずかなものです。


事前バインディングには、バージョンの互換性に関する問題が発生する可能性があるという小さな欠点があります。たとえば、Microsoft Excel 2002 などのオートメーション サーバーに、Excel 2000 では利用できなかった新しいメソッドやプロパティが導入されている場合や、既存のプロパティやメソッドに変更が加えられている場合が例に挙げられます。これらの変更によってオブジェクトのバイナリ レイアウトが変わるため、Excel 2002 の型情報を使用して Excel 2000 を自動化する Visual C# アプリケーションでは、問題が発生する可能性があります。事前バインディングでのこうした問題を回避するため、一般的にオートメーション クライアントの開発およびテストの際には、サポートする Office アプリケーションのバージョンのうち、最も古いバージョンの Office アプリケーションに対応する型情報を使用することを推奨します。


次の手順は、事前バインディングを使用するオートメーション クライアントの作成方法を示したものです。各手順に示されているように、事前バインディングでは、オートメーション クライアントのタイプ ライブラリに対する参照が必要になる点に注意してください。


事前バインディングを使用するオートメーション クライアントの作成

  1. Microsoft Visual Studio .NET を起動します。[ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。[プロジェクトの種類] ボックスの一覧の [Visual C# プロジェクト] をクリックし、[テンプレート] ボックスの一覧の [Windows アプリケーション] をクリックし、[OK] をクリックします。デフォルトで Form1 が作成されます。
  2. Microsoft Excel Object Library への参照を追加します。この操作を行うには、以下の手順を実行します。
    1. [プロジェクト] メニューの [参照の追加] をクリックします。
    2. [COM] タブをクリックして [Microsoft Excel version_number Object Library] をクリックし、[選択] をクリックします。


      : Office 2003 には、プライマリ相互運用機能アセンブリ (PIA) が含まれています。Office XP には PIA は含まれていませんが、ダウンロードできます。
      Office XP 用の PIA の関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
      328912 Microsoft Office XP 用の PIA (Primary Interop Assemblies) のダウンロード
    3. [参照の追加] ダイアログ ボックスで [OK] をクリックして、選択を確定します。選択したライブラリのラッパーを生成するかどうかを確認するメッセージが表示されたら、[はい] をクリックします。
  3. [表示] メニューの [ツールボックス] をクリックしてツールボックスを表示し、Form1 にボタンを 1 つ追加します。
  4. [Button1] をダブルクリックします。フォームのコード ウィンドウが表示されます。
  5. コード ウィンドウには、次のコードが表示されます。
    private void button1_Click(object sender, System.EventArgs e)
    {
    }
    これを次のコードで置き換えます。
    private void button1_Click(object sender, System.EventArgs e)
    {
    Excel.Application objApp;
    Excel._Workbook objBook;
    Excel.Workbooks objBooks;
    Excel.Sheets objSheets;
    Excel._Worksheet objSheet;
    Excel.Range range;

    try
    {
    // Instantiate Excel and start a new workbook.
    objApp = new Excel.Application();
    objBooks = objApp.Workbooks;
    objBook = objBooks.Add( Missing.Value );
    objSheets = objBook.Worksheets;
    objSheet = (Excel._Worksheet)objSheets.get_Item(1);

    range = objSheet.get_Range("A1", Missing.Value);

    range.set_Value(Missing.Value, "Hello, World!" );

    //Return control of Excel to the user.
    objApp.Visible = true;
    objApp.UserControl = true;
    }
    catch( Exception theException )
    {
    String errorMessage;
    errorMessage = "Error: ";
    errorMessage = String.Concat( errorMessage, theException.Message );
    errorMessage = String.Concat( errorMessage, " Line: " );
    errorMessage = String.Concat( errorMessage, theException.Source );

    MessageBox.Show( errorMessage, "Error" );
    }
    }
  6. コード ウィンドウの先頭までスクロールします。using ディレクティブの一覧の末尾に次の行を追加します。
    using System.Reflection;
    using Excel = Microsoft.Office.Interop.Excel;

遅延バインディング

事前バインディングとは対照的に、遅延バインディングでは、プロパティやメソッドの呼び出しをそのオブジェクトにバインドする処理が実行時まで延期されます。遅延バインディングを行うには、対象となるオブジェクトで特別な COM インターフェイス IDispatch が実装されている必要があります。Visual C# では、IDispatch::GetIDsOfNames メソッドを使用して、そのオブジェクトでサポートされているメソッドおよびプロパティを確認し、IDispatch::Invoke メソッドを使用して、それらのメソッドやプロパティを呼び出すことができます。このような遅延バインディングには、事前バインディングでは避けられないバージョン依存関係を部分的に回避できるという利点があります。ただし、オートメーション コードの完全性をコンパイル時にチェックできなくなり、メソッドやプロパティの適切な呼び出しを支援する Intellisense 機能が提供されないという欠点もあります。


Visual C# で遅延バインディングを使用するには、System.Type.InvokeMember メソッドを使用します。このメソッドにより、IDispatch::GetIDsOfNames および IDispatch::Invoke が呼び出され、オートメーション サーバーのメソッドとプロパティがバインドされます。


遅延バインディングを使用するオートメーション クライアントの作成

  1. Microsoft Visual Studio .NET を起動します。[ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。[プロジェクトの種類] ボックスの一覧の [Visual C# プロジェクト] をクリックし、[テンプレート] ボックスの一覧の [Windows アプリケーション] をクリックし、[OK] をクリックします。デフォルトで Form1 が作成されます。
  2. [表示] メニューの [ツールボックス] をクリックしてツールボックスを表示し、Form1 にボタンを 1 つ追加します。
  3. [Button1] をダブルクリックします。フォームのコード ウィンドウが表示されます。
  4. コード ウィンドウには、次のコードが表示されます。
    private void button1_Click(object sender, System.EventArgs e)
    {
    }
    これを次のコードで置き換えます。
    private void button1_Click(object sender, System.EventArgs e)
    {
    object objApp_Late;
    object objBook_Late;
    object objBooks_Late;
    object objSheets_Late;
    object objSheet_Late;
    object objRange_Late;
    object[] Parameters;

    try
    {
    // Get the class type and instantiate Excel.
    Type objClassType;
    objClassType = Type.GetTypeFromProgID("Excel.Application");
    objApp_Late = Activator.CreateInstance(objClassType);

    //Get the workbooks collection.
    objBooks_Late = objApp_Late.GetType().InvokeMember( "Workbooks",
    BindingFlags.GetProperty, null, objApp_Late, null );

    //Add a new workbook.
    objBook_Late = objBooks_Late.GetType().InvokeMember( "Add",
    BindingFlags.InvokeMethod, null, objBooks_Late, null );

    //Get the worksheets collection.
    objSheets_Late = objBook_Late.GetType().InvokeMember( "Worksheets",
    BindingFlags.GetProperty, null, objBook_Late, null );

    //Get the first worksheet.
    Parameters = new Object[1];
    Parameters[0] = 1;
    objSheet_Late = objSheets_Late.GetType().InvokeMember( "Item",
    BindingFlags.GetProperty, null, objSheets_Late, Parameters );

    //Get a range object that contains cell A1.
    Parameters = new Object[2];
    Parameters[0] = "A1";
    Parameters[1] = Missing.Value;
    objRange_Late = objSheet_Late.GetType().InvokeMember( "Range",
    BindingFlags.GetProperty, null, objSheet_Late, Parameters );

    //Write "Hello, World!" in cell A1.
    Parameters = new Object[1];
    Parameters[0] = "Hello, World!";
    objRange_Late.GetType().InvokeMember( "Value", BindingFlags.SetProperty,
    null, objRange_Late, Parameters );

    //Return control of Excel to the user.
    Parameters = new Object[1];
    Parameters[0] = true;
    objApp_Late.GetType().InvokeMember( "Visible", BindingFlags.SetProperty,
    null, objApp_Late, Parameters );
    objApp_Late.GetType().InvokeMember( "UserControl", BindingFlags.SetProperty,
    null, objApp_Late, Parameters );
    }
    catch( Exception theException )
    {
    String errorMessage;
    errorMessage = "Error: ";
    errorMessage = String.Concat( errorMessage, theException.Message );
    errorMessage = String.Concat( errorMessage, " Line: " );
    errorMessage = String.Concat( errorMessage, theException.Source );

    MessageBox.Show( errorMessage, "Error" );
    }
    }
  5. コード ウィンドウの先頭までスクロールします。using ディレクティブの一覧の末尾に次の行を追加します。
    using System.Reflection; 

関連情報

詳細については、次の MSDN (Microsoft Developer Network) Web サイトを参照してください。
Microsoft Office Development with Visual Studio

http://msdn2.microsoft.com/en-us/library/aa188489(office.10).aspx
バインディングの関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
245115 [INFO] オートメーションにおける事前バインディングおよび実行時バインディングの使用
244167 [INFO] 複数のバージョンの Office に対応するオートメーション クライアントの作成
247579 [INFO] Office アプリケーションの自動化には可能な限り DISPID バインドを使用する
プロパティ

文書番号:302902 - 最終更新日: 2008/11/11 - リビジョン: 1

フィードバック