Tutorial: Agregar controles a una hoja de cálculo en tiempo de ejecución en un proyecto en el nivel de la aplicación

Puede agregar controles a una hoja de cálculo abierta mediante un complemento de Excel. En este tutorial se muestra cómo utilizar la cinta de opciones para permitir que los usuarios agreguen un Button, un NamedRange y un ListObject a una hoja de cálculo. Para obtener más información, vea Agregar controles a documentos de Office en tiempo de ejecución.

Se aplica a: la información de este tema se aplica a los proyectos de nivel de aplicación para Excel 2007 y Excel 2010. Para obtener más información, vea Características disponibles por aplicación y tipo de proyecto de Office.

En este tutorial se muestran las tareas siguientes:

  • Proporcionar una interfaz de usuario para agregar controles a la hoja de cálculo.

  • Agregar controles a la hoja de cálculo.

  • Quitar controles de la hoja de cálculo.

Nota

Es posible que su equipo muestre nombres o ubicaciones diferentes para algunos de los elementos de la interfaz de usuario de Visual Studio incluidos en las instrucciones siguientes. La edición de Visual Studio que se tenga y la configuración que se utilice determinan estos elementos. Para obtener más información, vea Valores de configuración de Visual Studio.

Requisitos previos

Necesita los componentes siguientes para completar este tutorial:

-

Una edición de Visual Studio 2010 que incluye las herramientas para desarrolladores de Microsoft Office. Para obtener más información, vea [Configurar un equipo para desarrollar soluciones de Office](bb398242\(v=vs.100\).md).
  • Microsoft Office Excel 2007 o Excel 2010.

Crear un nuevo proyecto de complemento de Excel

Comience por crear un proyecto de complemento de Excel.

Para crear un nuevo proyecto de complemento de Excel

  1. En Visual Studio, cree un proyecto de complemento de Excel con el nombre ExcelDynamicControls. Para obtener más información, vea Cómo: Crear proyectos de Office en Visual Studio.

  2. Si su proyecto está destinado a .NET Framework 4, agregue una referencia al ensamblado Microsoft.Office.Tools.Excel.v4.0.Utilities.dll. Esta referencia es obligatoria para agregar mediante programación un control Windows Forms a una hoja de cálculo posteriormente en este tutorial.

Proporcionar una interfaz de usuario para agregar controles a una hoja de cálculo

Agregue una pestaña personalizada a la cinta de opciones de Excel. Los usuarios pueden activar las casillas de la ficha para agregar controles a una hoja de cálculo.

Para proporcionar una interfaz de usuario para agregar controles a una hoja de cálculo

  1. En el menú Proyecto, haga clic en Agregar nuevo elemento.

  2. En el cuadro de diálogo Agregar nuevo elemento, seleccione Cinta (diseñador visual) y haga clic en Agregar.

    Un archivo denominado CustomerRibbon.cs o CustomerRibbon.vb se abre en el Diseñador de la cinta de opciones y muestra una ficha y un grupo predeterminados.

  3. Desde la ficha Controles de la cinta de opciones de Office del Cuadro de herramientas, arrastre un control CheckBox a group1.

  4. Haga clic en CheckBox1 para seleccionarlo.

  5. En la ventana Propiedades, cambie las siguientes propiedades.

    Propiedad

    Valor

    Name

    Button

    Label

    Button

  6. Agregue una segunda casilla a group1 y, a continuación, cambie las propiedades siguientes.

    Propiedad

    Valor

    Name

    NamedRange

    Label

    NamedRange

  7. Agregue una tercera casilla a group1 y, a continuación, cambie las propiedades siguientes.

    Propiedad

    Valor

    Name

    ListObject

    Label

    ListObject

Agregar controles a la hoja de cálculo

Los controles administrados únicamente se pueden agregar a los elementos host que actúan como contenedores. Dado que los proyectos de complemento funcionan con cualquier libro abierto, el complemento convierte la hoja de cálculo en un elemento host, u obtiene un elemento host existente, antes de agregar el control. Agregue código a los controladores de eventos "click" de cada control para generar un elemento host Worksheet basado en la hoja de cálculo abierta. A continuación, agregue un Button, un NamedRangey un ListObject a la selección actual de la hoja de cálculo.

Para agregar controles a una hoja de cálculo

  1. En el Diseñador de la cinta de opciones, haga doble clic en Button.

    El controlador de eventos Click de la casilla Button se abre en el Editor de código.

  2. Reemplace el controlador de evento Button_Click con el código siguiente.

    Este código utiliza el método GetVstoObject para obtener un elemento host que representa la primera hoja de cálculo del libro y, a continuación, agrega un control Button a la celda que está seleccionada.

    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. En el Explorador de soluciones, seleccione Ribbon1.cs o Ribbon1.vb.

  4. En el menú Ver, haga clic en Diseñador.

  5. En el Diseñador de la cinta de opciones, haga doble clic en NamedRange.

  6. Reemplace el controlador de evento NamedRange_Click con el código siguiente.

    Este código utiliza el método GetVstoObject para obtener un elemento host que representa la primera hoja de cálculo del libro y, a continuación, define un control NamedRange para la celda o celdas que están seleccionadas.

    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. En el Diseñador de la cinta de opciones, haga doble clic en ListObject.

  8. Reemplace el controlador de evento ListObject_Click con el código siguiente.

    Este código utiliza el método GetVstoObject para obtener un elemento host que representa la primera hoja de cálculo del libro y, a continuación, define un control ListObject para la celda o celdas que están seleccionadas.

    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. Agregue las siguientes instrucciones a la parte superior del archivo de código de la cinta de opciones.

    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;
    

Quitar controles de la hoja de cálculo

No se conservan los controles cuando se guarda y se cierra la hoja de cálculo. Debería quitar mediante programación todos los controles generados de formularios Windows Forms antes de guardar la hoja de cálculo, o solamente aparecerá un contorno del control cuando se vuelva a abrir el libro. Agregue código al evento WorkbookBeforeSave que quita los controles de formularios Windows Forms de la colección de controles del elemento host generado. Para obtener más información, vea Guardar controles dinámicos en documentos de Office.

Para quitar controles de la hoja de cálculo

  1. En el Explorador de soluciones, seleccione ThisAddIn.cs o ThisAddIn.vb.

  2. En el menú Ver, haga clic en Código.

  3. Agregue el método siguiente a la clase ThisAddIn. Este código obtiene la primera hoja de cálculo del libro y, a continuación, utiliza el método HasVstoObject para comprobar si la hoja tiene un objeto de hoja de cálculo generado. Si el objeto de hoja de cálculo generado tiene controles, el código obtiene ese objeto de hoja de cálculo, recorre en iteración la colección del control y quita los controles.

    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. En C#, debe crear un controlador de eventos para el evento WorkbookBeforeSave. Puede colocar este código en el método ThisAddIn_Startup. Para obtener información sobre cómo crear controladores de eventos, vea Cómo: Crear controladores de eventos en proyectos de Office. Reemplace el método ThisAddIn_Startup por el código siguiente.

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

Comprobar la solución

Agregue controles a una hoja de cálculo seleccionándolos en una ficha personalizada de la cinta de opciones. Al guardar la hoja de cálculo, se quitan estos controles.

Para probar la solución.

  1. Presione F5 para ejecutar el proyecto.

  2. Seleccione cualquier celda de Sheet1.

  3. Haga clic en la ficha Complementos.

  4. En el grupo group1, haga clic en Button.

    Aparecerá un botón en la celda seleccionada.

  5. Seleccione una celda diferente en Sheet1.

  6. En el grupo group1, haga clic en NamedRange.

    Se definirá un rango con nombre para la celda seleccionada.

  7. Seleccione una serie de celdas en Sheet1.

  8. En el grupo group1, haga clic en ListObject.

    Se agregará un objeto de lista a las celdas seleccionadas.

  9. Guarde la hoja de cálculo.

    Los controles que agregó a Sheet1 ya no aparecen.

Pasos siguientes

Para obtener más información sobre controles en los proyectos de complemento de Excel, vea este tema:

Vea también

Conceptos

Usar controles de formularios Windows Forms en hojas de cálculo de Excel

NamedRange (Control)

ListObject (Control)

Otros recursos

Soluciones de Excel

Controles en documentos de Office

Historial de cambios

Fecha

Historial

Motivo

1 de abril de 2011

Se ha agregado texto que describe una referencia de ensamblado que se debe agregar si el proyecto está destinado a .NET Framework 4.

Corrección de errores de contenido.