次の方法で共有


チュートリアル : 実行時におけるアプリケーション レベルのプロジェクトのワークシートへのコントロールの追加

更新 : 2011 年 4 月

Excel アドインを使用して、任意の開いているワークシートにコントロールを追加できます。 このチュートリアルでは、リボンを使用してユーザーがワークシートに ButtonNamedRange、および ListObject を追加できるようにする方法を説明します。 詳細については、「実行時の Office ドキュメントへのコントロールの追加」を参照してください。

対象: このトピックの情報は、Excel 2007 と Excel 2010 のアプリケーション レベルのプロジェクトに適用されます。詳細については、「Office アプリケーションおよびプロジェクト タイプ別の使用可能な機能」を参照してください。

このチュートリアルでは、次の作業について説明します。

  • ワークシートにコントロールを追加するためのユーザー インターフェイス (UI: User Interface) を提供する。

  • ワークシートにコントロールを追加する。

  • ワークシートからコントロールを削除する。

注意

お使いのマシンで、Visual Studio ユーザー インターフェイスの一部の要素の名前や場所が、次の手順とは異なる場合があります。 これらの要素は、使用している Visual Studio のエディションや独自の設定によって決まります。 詳細については、「Visual Studio の設定」を参照してください。

必須コンポーネント

このチュートリアルを実行するには、次のコンポーネントが必要です。

-

Microsoft Office 開発者ツールを含むエディションの Visual Studio 2010。 詳細については、「[Office ソリューションを開発できるようにコンピューターを構成する](bb398242\(v=vs.100\).md)」を参照してください。
  • Microsoft Office Excel 2007 または Excel 2010

新しい Excel アドイン プロジェクトの作成

まず、Excel のアドイン プロジェクトを作成します。

新しい Excel アドイン プロジェクトを作成するには

  1. Visual Studio で、ExcelDynamicControls という名前の Excel アドイン プロジェクトを作成します。 詳細については、「方法: Visual Studio で Office プロジェクトを作成する」を参照してください。

  2. プロジェクトが .NET Framework 4 を対象としている場合は、Microsoft.Office.Tools.Excel.v4.0.Utilities.dll アセンブリへの参照を追加します。 この参照は、このチュートリアルの後半で Windows フォーム コントロールをワークシートにプログラムで追加するのに必要です。

ワークシートにコントロールを追加するための UI の提供

Excel のリボンにカスタム タブを追加します。 ユーザーはタブにあるチェック ボックスをオンにして、ワークシートにコントロールを追加できます。

ワークシートにコントロールを追加するための UI を提供するには

  1. [プロジェクト] メニューの [新しい項目の追加] をクリックします。

  2. [新しい項目の追加] ダイアログ ボックスで、[リボン (ビジュアル デザイナー)] を選択し、[追加] をクリックします。

    リボン デザイナーで Ribbon1.cs または Ribbon1.vb という名前のファイルが開き、既定のタブとグループが表示されます。

  3. ツールボックス[Office リボン コントロール] タブから、CheckBox コントロールを group1 にドラッグします。

  4. [CheckBox1] をクリックして選択します。

  5. [プロパティ] ウィンドウで、次のプロパティを変更します。

    プロパティ

    名前

    Button

    Label

    Button

  6. group1 に 2 つ目のチェック ボックスを追加し、次のプロパティを変更します。

    プロパティ

    名前

    NamedRange

    Label

    NamedRange

  7. group1 に 3 つ目のチェック ボックスを追加し、次のプロパティを変更します。

    プロパティ

    名前

    ListObject

    Label

    ListObject

ワークシートへのコントロールの追加

マネージ コントロールは、コンテナーとして機能するホスト項目に対してのみ追加できます。 アドイン プロジェクトは任意の開いているブックに対して機能するため、アドインはワークシートをホスト項目に変換するか、または既存のホスト項目を取得してから、コントロールを追加します。 開いているワークシートに基づいた Worksheet ホスト項目を作成するように、各コントロールのクリック イベント ハンドラーにコードを追加します。 次に、ワークシートの現在選択されている位置に ButtonNamedRange、および ListObject を追加します。

ワークシートにコントロールを追加するには

  1. リボン デザイナーで [Button] をダブルクリックします。

    [Button] チェック ボックスの Click イベント ハンドラーがコード エディターで開きます。

  2. Button_Click イベント ハンドラーを次のコードで置き換えます。

    このコードでは、GetVstoObject メソッドを使用してブックの最初のワークシートを表すホスト項目を取得し、現在選択されているセルに Button コントロールを追加します。

    Private Sub Button_Click(ByVal sender As System.Object, _
        ByVal e As Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) _
            Handles Button.Click
    
        Dim NativeWorksheet As Microsoft.Office.Interop.Excel.Worksheet =
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1)
    
        ' Use the following line of code in projects that target the .NET Framework 4.
        Dim worksheet As Microsoft.Office.Tools.Excel.Worksheet =
            Globals.Factory.GetVstoObject(NativeWorksheet)
    
        ' In projects that target the .NET Framework 3.5, use the following line of code.
        ' Dim worksheet = CType(Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1),  _
        '    Excel.Worksheet).GetVstoObject()
    
        Dim buttonName As String = "MyButton"
    
        If CType(sender, RibbonCheckBox).Checked Then
            Dim selection As Excel.Range = Globals.ThisAddIn.Application.Selection
            If Not (selection Is Nothing) Then
                Dim button As New Microsoft.Office.Tools.Excel.Controls.Button()
                worksheet.Controls.AddControl(button, selection, buttonName)
            End If
        Else
            worksheet.Controls.Remove(buttonName)
        End If
    End Sub
    
    private void Button_Click(object sender, RibbonControlEventArgs e)
    {
        // Use the following line of code in projects that target the .NET Framework 4.
        Worksheet worksheet = Globals.Factory.GetVstoObject(
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]);
    
        // In projects that target the .NET Framework 3.5, use the following line of code.
        // Worksheet worksheet = 
        //     ((Excel.Worksheet)Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]).GetVstoObject();
    
        string buttonName = "MyButton";
    
        if (((RibbonCheckBox)sender).Checked)
        {
            Excel.Range selection = Globals.ThisAddIn.Application.Selection as Excel.Range;
            if (selection != null)
            {
                Microsoft.Office.Tools.Excel.Controls.Button button =
                    new Microsoft.Office.Tools.Excel.Controls.Button();
                worksheet.Controls.AddControl(button, selection, buttonName);
            }
        }
        else
        {
            worksheet.Controls.Remove(buttonName);
        }
    }
    
  3. ソリューション エクスプローラーで、Ribbon1.cs または Ribbon1.vb を選択します。

  4. [表示] メニューの [デザイナー] をクリックします。

  5. リボン デザイナーで [NamedRange] をダブルクリックします。

  6. NamedRange_Click イベント ハンドラーを次のコードで置き換えます。

    このコードでは、GetVstoObject メソッドを使用してブックの最初のワークシートを表すホスト項目を取得し、現在選択されている 1 つまたは複数のセルに NamedRange コントロールを定義します。

    Private Sub NamedRange_Click(ByVal sender As System.Object, _
        ByVal e As Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) _
            Handles NamedRange.Click
    
        Dim NativeWorksheet As Microsoft.Office.Interop.Excel.Worksheet =
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1)
    
        ' Use the following line of code in projects that target the .NET Framework 4.
        Dim worksheet As Microsoft.Office.Tools.Excel.Worksheet =
            Globals.Factory.GetVstoObject(NativeWorksheet)
    
        ' In projects that target the .NET Framework 3.5, use the following line of code.
        ' Dim worksheet = CType(Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1),  _
        '    Excel.Worksheet).GetVstoObject()
    
        Dim rangeName As String = "MyNamedRange"
    
        If CType(sender, RibbonCheckBox).Checked Then
            Dim selection As Excel.Range = Globals.ThisAddIn.Application.Selection
            If Not (selection Is Nothing) Then
                Dim namedRange As NamedRange = _
                    worksheet.Controls.AddNamedRange(selection, rangeName)
            End If
        Else
            worksheet.Controls.Remove(rangeName)
        End If
    End Sub
    
    private void NamedRange_Click(object sender, RibbonControlEventArgs e)
    {
        // Use the following line of code in projects that target the .NET Framework 4.
        Worksheet worksheet = Globals.Factory.GetVstoObject(
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]);
    
        // In projects that target the .NET Framework 3.5, use the following line of code.
        // Worksheet worksheet = 
        //     ((Excel.Worksheet)Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]).GetVstoObject();
    
        string Name = "MyNamedRange";
    
        if (((RibbonCheckBox)sender).Checked)
        {
            Excel.Range selection = Globals.ThisAddIn.Application.Selection as Excel.Range;
            if (selection != null)
            {
                worksheet.Controls.AddNamedRange(selection, Name);
            }
        }
        else
        {
            worksheet.Controls.Remove(Name);
        }
    }
    
  7. リボン デザイナーで [ListObject] をダブルクリックします。

  8. ListObject_Click イベント ハンドラーを次のコードで置き換えます。

    このコードでは、GetVstoObject メソッドを使用してブックの最初のワークシートを表すホスト項目を取得し、現在選択されている 1 つまたは複数のセルに ListObject を定義します。

    Private Sub ListObject_Click(ByVal sender As System.Object, _
        ByVal e As Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) _
            Handles ListObject.Click
    
        Dim NativeWorksheet As Microsoft.Office.Interop.Excel.Worksheet =
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1)
    
        ' Use the following line of code in projects that target the .NET Framework 4.
        Dim worksheet As Microsoft.Office.Tools.Excel.Worksheet =
            Globals.Factory.GetVstoObject(NativeWorksheet)
    
        ' In projects that target the .NET Framework 3.5, use the following line of code.
        ' Dim worksheet = CType(Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1),  _
        '    Excel.Worksheet).GetVstoObject()
    
        Dim listObjectName As String = "MyListObject"
    
        If CType(sender, RibbonCheckBox).Checked Then
            Dim selection As Excel.Range = _
                Globals.ThisAddIn.Application.Selection
            If Not (selection Is Nothing) Then
                worksheet.Controls.AddListObject(selection, listObjectName)
            End If
        Else
            worksheet.Controls.Remove(listObjectName)
        End If
    End Sub
    
    private void ListObject_Click(object sender, RibbonControlEventArgs e)
    {
        // Use the following line of code in projects that target the .NET Framework 4.
        Worksheet worksheet = Globals.Factory.GetVstoObject(
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]);
    
        // In projects that target the .NET Framework 3.5, use the following line of code.
        // Worksheet worksheet = 
        //     ((Excel.Worksheet)Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]).GetVstoObject();
    
        string listObjectName = "MyListObject";
    
        if (((RibbonCheckBox)sender).Checked)
        {
            Excel.Range selection = Globals.ThisAddIn.Application.Selection as Excel.Range;
            if (selection != null)
            {
                worksheet.Controls.AddListObject(selection, listObjectName);
            }
        }
        else
        {
            worksheet.Controls.Remove(listObjectName);
        }
    }
    
  9. リボン コード ファイルの先頭に次のステートメントを追加します。

    Imports Excel = Microsoft.Office.Interop.Excel
    Imports Microsoft.Office.Tools.Excel
    Imports Microsoft.Office.Tools.Excel.Extensions
    
    using Excel = Microsoft.Office.Interop.Excel;
    using Microsoft.Office.Tools.Excel;
    using Microsoft.Office.Tools.Excel.Extensions;
    

ワークシートからのコントロールの削除

ワークシートが保存されて閉じられるとき、コントロールは保持されません。 ワークシートを保存する前に、生成されたすべての Windows フォーム コントロールをプログラムによって削除する必要があります。そうしないと、ワークシートを再び開いたときに、コントロールのアウトラインが表示されることになります。 生成されたホスト項目のコントロール コレクションから Windows フォーム コントロールを削除するコードを、WorkbookBeforeSave イベントに追加します。 詳細については、「Office ドキュメントでのダイナミック コントロールの永続化」を参照してください。

ワークシートからコントロールを削除するには

  1. ソリューション エクスプローラーで、ThisAddIn.cs または ThisAddIn.vb を選択します。

  2. [表示] メニューの [コード] をクリックします。

  3. ThisAddIn クラスに次のメソッドを追加します。 このコードはブックの最初のワークシートを取得し、HasVstoObject メソッドを使用して、ワークシートにワークシート オブジェクトが生成されているかどうかを確認します。 生成されたワークシート オブジェクトにコントロールがある場合は、コードはそのワークシート オブジェクトを取得し、コントロール コレクションを反復処理してコントロールを削除します。

    Sub Application_WorkbookBeforeSave _
        (ByVal workbook As Microsoft.Office.Interop.Excel.Workbook, _
         ByVal SaveAsUI As Boolean, ByRef Cancel As Boolean) _
         Handles Application.WorkbookBeforeSave
    
        Dim worksheet As Excel.Worksheet = workbook.Worksheets(1)
    
        ' Use the following code in projects that target the .NET Framework 4.
        If Globals.Factory.HasVstoObject(worksheet) And
            Globals.Factory.GetVstoObject(worksheet).Controls.Count > 0 Then
            Dim vstoWorksheet As Worksheet = Globals.Factory.GetVstoObject(worksheet)
    
            ' In projects that target the .NET Framework 3.5, use the following code.
            ' If worksheet.HasVstoObject() And worksheet.GetVstoObject().Controls.Count > 0 Then
            ' Dim vstoWorksheet As Worksheet = worksheet.GetVstoObject()
    
            While vstoWorksheet.Controls.Count > 0
                Dim vstoControl As Object = vstoWorksheet.Controls(0)
                vstoWorksheet.Controls.Remove(vstoControl)
            End While
        End If
    End Sub
    
    void Application_WorkbookBeforeSave(Microsoft.Office.Interop.Excel.Workbook workbook, 
        bool SaveAsUI, ref bool Cancel)
    {
        Excel.Worksheet worksheet =
            workbook.Worksheets[1] as Excel.Worksheet;
    
        // Use the following lines of code in projects that target the .NET Framework 4.
        if (Globals.Factory.HasVstoObject(worksheet) && 
            Globals.Factory.GetVstoObject(worksheet).Controls.Count > 0)
        {
            Worksheet vstoWorksheet = Globals.Factory.GetVstoObject(worksheet);
    
        // In projects that target the .NET Framework 3.5, use the following line of code.
        // if (worksheet.HasVstoObject() && worksheet.GetVstoObject().Controls.Count > 0)
        // {
        //     Worksheet vstoWorksheet = worksheet.GetVstoObject();               
    
            while (vstoWorksheet.Controls.Count > 0)
            {
                object vstoControl = vstoWorksheet.Controls[0];
                vstoWorksheet.Controls.Remove(vstoControl);
            }
    
        }
    }
    
  4. C# では、WorkbookBeforeSave イベントのイベント ハンドラーを作成する必要があります。 このコードを ThisAddIn_Startup メソッドに追加できます。 イベンド ハンドラーの作成方法の詳細については、「方法: Office プロジェクトでイベント ハンドラーを作成する」を参照してください。 ThisAddIn_Startup メソッドを次のコードに置き換えます。

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        this.Application.WorkbookBeforeSave += 
            new Microsoft.Office.Interop.Excel.AppEvents_WorkbookBeforeSaveEventHandler
                (Application_WorkbookBeforeSave);
    }
    

ソリューションのテスト

リボンのカスタム タブからコントロールを選択し、ワークシートに追加します。 ワークシートを保存すると、これらのコントロールは削除されます。

ソリューションをテストするには

  1. F5 キーを押してプロジェクトを実行します。

  2. Sheet1 で任意のセルを選択します。

  3. [アドイン] タブをクリックします。

  4. [group1] グループで、[Button] をクリックします。

    選択したセルにボタンが表示されます。

  5. Sheet1 で別のセルを選択します。

  6. [group1] グループで、[NamedRange] をクリックします。

    選択したセルに、名前付き範囲が定義されます。

  7. Sheet1 で一連のセルを選択します。

  8. [group1] グループで、[ListObject] をクリックします。

    選択したセルにリスト オブジェクトが追加されます。

  9. ワークシートを保存します。

    Sheet1 に追加したコントロールは表示されなくなります。

次の手順

Excel アドイン プロジェクトのコントロールの詳細については、以下のトピックを参照してください。

参照

概念

Excel ソリューション

Excel ワークシート上での Windows フォーム コントロールの使用

NamedRange コントロール

ListObject コントロール

その他の技術情報

Office ドキュメントのコントロール

履歴の変更

日付

履歴

理由

2011 年 4 月

プロジェクトが .NET Framework 4 を対象とする場合に追加する必要があるアセンブリ参照の説明テキストを追加しました。

コンテンツ バグ修正