共用方式為


逐步解說:在應用程式層級專案的執行階段中將控制項加入至工作表

更新:2011 年 4 月

您可以使用 Excel 增益集,將控制項加入至任何開啟的工作表。 本逐步解說將示範如何使用功能區,讓使用者將 ButtonNamedRangeListObject 加入至工作表。 如需詳細資訊,請參閱在執行階段將控制項加入至 Office 文件

**適用於:**本主題中的資訊適用於 Excel 2007 和 Excel 2010 的應用程式層級專案。如需詳細資訊,請參閱依 Office 應用程式和專案類型提供的功能

這個逐步解說將說明下列工作:

  • 提供可將控制項加入至工作表的使用者介面 (UI)。

  • 將控制項加入至工作表。

  • 從工作表移除控制項。

注意事項注意事項

您的電腦可能會在下列說明中,以不同名稱或位置顯示某些 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 增益集專案。 如需詳細資訊,請參閱 HOW TO:在 Visual Studio 中建立 Office 專案

  2. 如果專案的目標為 .NET Framework 4,則加入 Microsoft.Office.Tools.Excel.v4.0.Utilities.dll 組件的參考。 本逐步解說稍後會需要用到此參考,以便使用程式設計的方式將 Windows Form 控制項加入至工作表。

提供可將控制項加入至工作表的 UI

將自訂索引標籤加入至 Excel 功能區。 使用者可以選取索引標籤上的核取方塊,將控制項加入至工作表。

若要提供可將控制項加入至工作表的 UI

  1. 按一下 [專案] 功能表上的 [加入新項目]。

  2. 在 [加入新項目] 對話方塊中,選取 [功能區 (視覺化設計工具)],然後按一下 [加入]。

    名為 Ribbon1.cs 或 Ribbon1.vb 的檔案會在功能區設計工具中開啟,並顯示預設索引標籤和群組。

  3. 從 [工具箱] 的 [Office 功能區控制項] 索引標籤,將 CheckBox 控制項拖曳至 [group1]。

  4. 按一下 [CheckBox1] 予以選取。

  5. 在 [屬性] 視窗中變更下列屬性。

    屬性

    Name

    Button

    Label

    Button

  6. 將第二個核取方塊加入至 [group1],然後變更下列屬性。

    屬性

    Name

    NamedRange

    Label

    NamedRange

  7. 將第三個核取方塊加入至 [group1],然後變更下列屬性。

    屬性

    Name

    ListObject

    Label

    ListObject

將控制項加入至工作表

Managed 控制項只能加入至當做容器 (Container) 的主項目。 因為增益集專案會使用任何開啟的活頁簿,所以增益集會將工作表轉換為主項目,或取得現有主項目,再加入控制項。 請將程式碼加入至每個控制項的 Click 事件處理常式,以產生基於開啟之工作表的 Worksheet 主項目。 然後,在工作表的目前選取範圍中加入 ButtonNamedRangeListObject

若要將控制項加入至工作表

  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 方法取得代表活頁簿中第一個工作表的主項目,然後為目前選取的儲存格定義 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 方法取得代表活頁簿中第一個工作表的主項目,然後為目前選取的儲存格定義 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 Form 控制項,否則該活頁簿下次開啟時,只會顯示控制項的外框。 請將程式碼加入至 WorkbookBeforeSave 事件,以便從產生之主項目的控制項集合移除 Windows Form 控制項。 如需詳細資訊,請參閱在 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 方法中。 如需建立事件處理常式的詳細資訊,請參閱 HOW TO:在 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 工作表中使用 Windows Form 控制項

NamedRange 控制項

ListObject 控制項

其他資源

Excel 方案

Office 文件上的控制項

變更記錄

日期

記錄

原因

2011 年 4 月

新增文字來描述當專案以 .NET Framework 4.0 為目標時必須加入的組件參考。

內容 Bug 修正。