Tutorial: Programación de Office (C# y Visual Basic)

Visual Studio 2010 incluye nuevas características de C# y Visual Basic que mejoran la programación de Microsoft Office. Cada lenguaje ha agregado características que ya existen en el otro lenguaje.

Entre las nuevas características de C# se encuentran los argumentos opcionales y con nombre, los valores devueltos que tienen el tipo dynamic, y, en la programación COM, la capacidad para omitir la palabra clave ref y obtener acceso a las propiedades indizadas. Entre las nuevas características de Visual Basic se encuentran las propiedades implementadas automáticamente, las instrucciones en expresiones lambda y los inicializadores de colección.

Ambos lenguajes habilitan la incrustación de la información de tipos, lo que permite la implementación de ensamblados que interactúan con componentes COM sin tener que implementar los ensamblados de interoperabilidad primarios (PIA) en el equipo del usuario. Para obtener más información, vea Tutorial: Incrustar los tipos de los ensamblados administrados (C# y Visual Basic).

En este tutorial, se muestran las nuevas características en el contexto de la programación de Office, si bien un gran número de ellas también resultan útiles en la programación en general. En el tutorial, usará primero un complemento de Excel para crear un libro de Excel. A continuación, creará un documento de Word con un vínculo al libro. Por último, verá cómo se puede activar y desactivar la dependencia de un PIA.

Requisitos previos

Para completar este tutorial debe tener Microsoft Office Excel 2010 o 2007 y Microsoft Office Word 2010 o 2007 instalados en el equipo.

Si utiliza un sistema operativo anterior a Windows Vista, asegúrese de que .NET Framework 2.0 esté instalado.

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.

Para instalar una aplicación complementaria de Excel

  1. Inicie Visual Studio.

  2. En el menú Archivo, elija Nuevo y haga clic en Proyecto.

  3. En el recuadro Plantillas instaladas, expanda Visual Basic o Visual C#, expanda Office y, a continuación, haga clic en 2010 (o 2007 si usa Office 2007).

  4. En el recuadro Plantillas, haga clic en Complemento de Excel 2010 (o Complemento de Excel 2007).

  5. Compruebe la parte superior del recuadro Plantillas para asegurarse de que .NET Framework 4 aparece en el cuadro Versión de .NET Framework de destino.

  6. En el cuadro Nombre, escriba un nombre para el proyecto si desea asignarle uno.

  7. Haga clic en Aceptar.

  8. El nuevo proyecto aparecerá en el Explorador de soluciones.

Para agregar referencias

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el nombre del proyecto y, a continuación, haga clic en Agregar referencia. Aparecerá el cuadro de diálogo Agregar referencia.

  2. En la pestaña .NET, seleccione Microsoft.Office.Interop.Excel, versión 14.0.0.0 (o versión 12.0.0.0 para Excel 2007), en la lista Nombre de componente y, a continuación, mantenga presionada la tecla CTRL y seleccione Microsoft.Office.Interop.Word, versión 14.0.0.0 (o versión 12.0.0.0 para Word 2007).

  3. Haga clic en Aceptar.

Para agregar las instrucciones Imports o las directivas using necesarias

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el archivo ThisAddIn.vb o ThisAddIn.cs y, a continuación, haga clic en Ver código.

  2. Agregue las siguientes instrucciones Imports (Visual Basic) o directivas using (C#) al principio del archivo de código si aún no figuran en dicho archivo.

    Imports Microsoft.Office.Interop
    
    using System.Collections.Generic;
    using Excel = Microsoft.Office.Interop.Excel;
    using Word = Microsoft.Office.Interop.Word;
    

Para crear una lista de cuentas bancarias

  1. En el Explorador de soluciones, haga clic con el botón secundario en el nombre del proyecto, haga clic en Agregar y, a continuación, haga clic en Clase. Asigne a la clase el nombre Account.vb si usa Visual Basic o Account.cs si usa C#. Haga clic en Agregar.

  2. Reemplace la definición de la clase Account con el código siguiente. Las definiciones de clase utilizan propiedades implementadas automáticamente, una nueva característica de Visual Basic en Visual Studio 2010. Para obtener más información, vea Propiedades implementadas automáticamente (Visual Basic).

    Public Class Account
        Property ID As Integer = -1
        Property Balance As Double
    End Class
    
    class Account
    {
        public int ID { get; set; }
        public double Balance { get; set; }
    }
    
  3. Para crear una lista de bankAccounts que contiene dos cuentas, agregue el siguiente código al método ThisAddIn_Startup en ThisAddIn.vb o ThisAddIn.cs. Las declaraciones de las listas utilizan inicializadores de colección, una característica nueva de Visual Basic en Visual Studio 2010. Para obtener más información, vea Información general de los inicializadores de colección (Visual Basic).

    Dim bankAccounts As New List(Of Account) From {
        New Account With {
                              .ID = 345,
                              .Balance = 541.27
                         },
        New Account With {
                              .ID = 123,
                              .Balance = -127.44
                         }
        }
    
    var bankAccounts = new List<Account> {
        new Account {
            ID = 345,
            Balance = 541.27
        },
        new Account {
            ID = 123,
            Balance = -127.44
        }
    };
    

Para exportar datos a Excel

  1. En el mismo archivo, agregue el siguiente método a la clase ThisAddIn. El método configura un libro de Excel y exporta los datos a dicho libro.

    Sub DisplayInExcel(ByVal accounts As IEnumerable(Of Account),
                   ByVal DisplayAction As Action(Of Account, Excel.Range))
    
        With Me.Application
            ' Add a new Excel workbook.
            .Workbooks.Add()
            .Visible = True
            .Range("A1").Value = "ID"
            .Range("B1").Value = "Balance"
            .Range("A2").Select()
    
            For Each ac In accounts
                DisplayAction(ac, .ActiveCell)
                .ActiveCell.Offset(1, 0).Select()
            Next
    
            ' Copy the results to the Clipboard.
            .Range("A1:B3").Copy()
        End With
    End Sub
    
    void DisplayInExcel(IEnumerable<Account> accounts,
               Action<Account, Excel.Range> DisplayFunc)
    {
        var excelApp = this.Application;
        // Add a new Excel workbook.
        excelApp.Workbooks.Add();
        excelApp.Visible = true;
        excelApp.Range["A1"].Value = "ID";
        excelApp.Range["B1"].Value = "Balance";
        excelApp.Range["A2"].Select();
    
        foreach (var ac in accounts)
        {
            DisplayFunc(ac, excelApp.ActiveCell);
            excelApp.ActiveCell.Offset[1, 0].Select();
        }
        // Copy the results to the Clipboard.
        excelApp.Range["A1:B3"].Copy();
    }
    

    En este método, se usan dos características nuevas de C#. Ambas características ya existen en Visual Basic.

    • El método Add tiene un parámetro opcional para especificar una plantilla concreta. Los parámetros opcionales, nuevos en Visual C# 2010, permiten omitir el argumento del parámetro si se desea utilizar su valor predeterminado. Dado que no se envía ningún argumento en el ejemplo anterior, Add utiliza la plantilla predeterminada y crea un nuevo libro. La instrucción equivalente en versiones anteriores de C# requiere un argumento de marcador de posición: excelApp.Workbooks.Add(Type.Missing).

      Para obtener más información, vea Argumentos opcionales y con nombre (Guía de programación de C#).

    • Las propiedades Range y Offset del objeto Range usan la característica de propiedades indizadas. Esta característica permite utilizar estas propiedades de los tipos COM con la siguiente sintaxis típica de C#. Las propiedades indizadas también permiten utilizar la propiedad Value del objeto Range, por lo que no es necesario usar la propiedad Value2. La propiedad Value está indizada, pero el índice es opcional. En el siguiente ejemplo, los argumentos opcionales y las propiedades indizadas funcionan conjuntamente.

      // Visual C# 2010 provides indexed properties for COM programming.
      excelApp.Range["A1"].Value = "ID";
      excelApp.ActiveCell.Offset[1, 0].Select();
      

      En las versiones anteriores del lenguaje, se requiere la siguiente sintaxis especial.

      // In Visual C# 2008, you cannot access the Range, Offset, and Value
      // properties directly.
      excelApp.get_Range("A1").Value2 = "ID";
      excelApp.ActiveCell.get_Offset(1, 0).Select();
      

      El usuario no puede crear propiedades indizadas. La característica solo admite el uso de propiedades indizadas existentes.

      Para obtener más información, vea Cómo: Utilizar propiedades indizadas en la programación de interoperabilidad COM (Guía de programación de C#).

  2. Agregue el siguiente código al final de DisplayInExcel para ajustar el ancho de las columnas al contenido.

    ' Add the following two lines at the end of the With statement.
    .Columns(1).AutoFit()
    .Columns(2).AutoFit()
    
    excelApp.Columns[1].AutoFit();
    excelApp.Columns[2].AutoFit();
    

    Estas adiciones muestran otra característica nueva de C# 2010: los valores de Object devueltos por los hosts COM, como Office, se tratan como si tuvieran el tipo dynamic. Esto sucede automáticamente cuando la opción Incrustar tipos de interoperabilidad está establecida en su valor predeterminado (True) o, lo que es lo mismo, cuando se hace referencia al ensamblado mediante la opción del compilador /link. El tipo dynamic permite el enlace en tiempo de ejecución, que ya está disponible en Visual Basic, y evita la conversión explícita que se requiere en Visual C# 2008 y las versiones anteriores del lenguaje.

    Por ejemplo, excelApp.Columns[1] devuelve un Object y AutoFit es un método de la interfaz Range de Excel. Sin dynamic, es preciso convertir el objeto devuelto por excelApp.Columns[1] en una instancia de Range antes de llamar al método AutoFit.

    // Casting is required in Visual C# 2008.
    ((Excel.Range)excelApp.Columns[1]).AutoFit();
    
    // Casting is not required in Visual C# 2010.
    excelApp.Columns[1].AutoFit();
    

    Para obtener más información sobre cómo incrustar los tipos de interoperabilidad, vea los procedimientos "Para buscar la referencia a un PIA" y "Restaurar la dependencia de un PIA" más adelante en este tema. Para obtener más información sobre dynamic, vea dynamic (Referencia de C#) o Uso de tipo dinámico (Guía de programación de C#).

Para invocar DisplayInExcel

  1. Agregue el siguiente código al final del método ThisAddIn_StartUp. La llamada a DisplayInExcel contiene dos argumentos. El primer argumento es el nombre de la lista de cuentas que se va a procesar. El segundo argumento es una expresión lambda de varias líneas que define cómo se van a procesar los datos. Los valores de balance e ID de cada cuenta se muestran en celdas adyacentes y la fila aparece en color rojo si el saldo es menor que cero. Las expresiones lambda de varias líneas son una característica nueva de Visual Basic 2010. Para obtener más información, vea Lambda (expresiones) (Visual Basic).

    DisplayInExcel(bankAccounts,
           Sub(account, cell)
               ' This multiline lambda expression sets custom
               ' processing rules for the bankAccounts.
               cell.Value = account.ID
               cell.Offset(0, 1).Value = account.Balance
    
               If account.Balance < 0 Then
                   cell.Interior.Color = RGB(255, 0, 0)
                   cell.Offset(0, 1).Interior.Color = RGB(255, 0, 0)
               End If
           End Sub)
    
    DisplayInExcel(bankAccounts, (account, cell) =>
    // This multiline lambda expression sets custom processing rules  
    // for the bankAccounts.
    {
        cell.Value = account.ID;
        cell.Offset[0, 1].Value = account.Balance;
        if (account.Balance < 0)
        {
            cell.Interior.Color = 255;
            cell.Offset[0, 1].Interior.Color = 255;
        }
    });
    
  2. Para ejecutar el programa, presione F5. Aparece una hoja de cálculo de Excel que contiene los datos de las cuentas.

Para agregar un documento de Word

  • Agregue el siguiente código al final del método ThisAddIn_StartUp para crear un documento de Word que contiene un vínculo al libro de Excel.

    Dim wordApp As New Word.Application
    wordApp.Visible = True
    wordApp.Documents.Add()
    wordApp.Selection.PasteSpecial(Link:=True, DisplayAsIcon:=True)
    
    var wordApp = new Word.Application();
    wordApp.Visible = true;
    wordApp.Documents.Add();
    wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true);
    

    En este código, se muestran algunas de las nuevas características de C#: la capacidad para omitir la palabra clave ref en la programación COM, los argumentos con nombre y los argumentos opcionales. Estas características ya existen en Visual Basic. El método PasteSpecial tiene siete parámetros, cada uno de los cuales se define como un parámetro de referencia opcional. Antes de Visual C# 2010, había que definir variables de objeto para utilizarlas como argumentos de los siete parámetros, incluso cuando no se tenía ningún valor significativo para enviar. Los parámetros opcionales y con nombre permiten designar por su nombre los parámetros a los que se desea obtener acceso y enviar argumentos únicamente a esos parámetros. En este ejemplo, se envían argumentos para indicar que debe crearse un vínculo al libro en el Portapapeles (parámetro Link) y que dicho vínculo debe mostrarse como un icono en el documento de Word (parámetro DisplayAsIcon). Visual C# 2010 también permite omitir la palabra clave ref para estos argumentos. Compare el siguiente segmento de código de Visual C# 2008 con la única línea que se requiere en Visual C# 2010:

    // Call to PasteSpecial in Visual C# 2008.
    object iconIndex = Type.Missing;
    object link = true;
    object placement = Type.Missing;
    object displayAsIcon = true;
    object dataType = Type.Missing;
    object iconFileName = Type.Missing;
    object iconLabel = Type.Missing;
    wordApp.Selection.PasteSpecial(ref iconIndex,
                                   ref link,
                                   ref placement,
                                   ref displayAsIcon,
                                   ref dataType,
                                   ref iconFileName,
                                   ref iconLabel);
    
    // Call to PasteSpecial in Visual C# 2010.
    wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true);
    

Para ejecutar la aplicación

  • Presione F5 para ejecutar la aplicación. Se abre Excel y se muestra una tabla que contiene la información de las dos cuentas de bankAccounts. A continuación, aparece un documento de Word que contiene un vínculo a la tabla de Excel.

Para limpiar el proyecto completado

  • En Visual Studio, en el menú Generar, haga clic en Limpiar solución. De lo contrario, el complemento se ejecutará cada vez que abra Excel en el equipo.

Para buscar la referencia a un PIA

  1. Ejecute la aplicación de nuevo, pero no haga clic en Limpiar solución.

  2. En el menú Inicio, haga clic en Todos los programas. A continuación, haga clic en Microsoft Visual Studio 2010, en Visual Studio Tools y, después, en Símbolo del sistema de Visual Studio (2010).

  3. Escriba ildasm en la ventana Símbolo del sistema de Visual Studio (2010) y, a continuación, presione ENTRAR. Aparecerá la ventana IL DASM.

  4. En el menú Archivo de la ventana IL DASM, haga clic en Abrir. Haga doble clic en Visual Studio 2010 y, a continuación, haga doble clic en Proyectos. Abra la carpeta del proyecto y busque nombre del proyecto.dll en la carpeta bin/Debug. Haga doble clic en nombre del proyecto.dll. Aparecerá una nueva ventana con los atributos del proyecto, además de referencias a otros módulos y ensamblados. Observe que los espacios de nombres Microsoft.Office.Interop.Excel y Microsoft.Office.Interop.Word están incluidos en el ensamblado. De forma predeterminada, en Visual Studio 2010, el compilador importa en el ensamblado los tipos requeridos de un PIA al que se hace referencia.

    Para obtener más información, vea Cómo: Ver el contenido de un ensamblado.

  5. Haga doble clic en el icono MANIFIESTO. Aparecerá una ventana con una lista de los ensamblados que contienen los elementos a los que hace referencia el proyecto. La lista no incluye Microsoft.Office.Interop.Excel ni Microsoft.Office.Interop.Word. Dado que los tipos requeridos por el proyecto se han importado en el ensamblado, no se necesita ninguna referencia a un PIA. Esto facilita la implementación. Los PIA no tienen que estar presentes en el equipo del usuario y, dado que las aplicaciones no requieren la implementación de una versión concreta de un PIA, se pueden diseñar de modo que funcionen con varias versiones de Office, siempre y cuando existan las API necesarias en todas las versiones.

    Dado que ya no es necesaria la implementación de los PIA, se puede crear una aplicación en escenarios avanzados que funcione con varias versiones de Office, incluidas versiones anteriores. No obstante, esto funciona únicamente si el código no utiliza ninguna API que no esté disponible en la versión de Office que se está usando. No siempre queda claro si una API concreta está disponible en una versión anterior, por lo que no se recomienda usar versiones anteriores de Office.

    Nota

    Office no publicaba ensamblados PIA antes de Office 2003. Por consiguiente, la única manera de generar un ensamblado de interoperabilidad para Office 2002 o versiones anteriores consiste en importar la referencia COM.

  6. Cierre la ventana del manifiesto y la ventana de ensamblados.

Para restaurar la dependencia de un PIA

  1. En el Explorador de soluciones, haga clic en el botón Mostrar todos los archivos. Expanda la carpeta Referencias y seleccione Microsoft.Office.Interop.Excel. Presione F4 para que se muestre la ventana Propiedades.

  2. En la ventana Propiedades, cambie el valor de Incrustar tipos de interoperabilidad de True a False.

  3. Repita los pasos 1 y 2 de este procedimiento para Microsoft.Office.Interop.Word.

  4. En C#, convierta en comentario las dos llamadas a Autofit al final del método DisplayInExcel.

  5. Presione F5 para comprobar que el proyecto sigue ejecutándose correctamente.

  6. Repita los pasos del 1 al 3 del procedimiento anterior para abrir la ventana de ensamblados. Observe que Microsoft.Office.Interop.Word y Microsoft.Office.Interop.Excel ya no figuran en la lista de ensamblados incrustados.

  7. Haga doble clic en el icono MANIFIESTO y desplácese por la lista de ensamblados a los que se hace referencia. La lista incluye Microsoft.Office.Interop.Word y Microsoft.Office.Interop.Excel. Dado que la aplicación hace referencia a los PIA Excel y Word y dado que el valor de la propiedad Incrustar tipos de operabilidad es False, es preciso que ambos ensamblados existan en el equipo del usuario final.

  8. En Visual Studio, haga clic en Limpiar solución en el menú Compilación para limpiar el proyecto completado.

Vea también

Tareas

Tutorial: Incrustar los tipos de los ensamblados administrados (C# y Visual Basic)

Tutorial: Crear el primer complemento en el nivel de la aplicación para Excel

Referencia

Propiedades autoimplementadas (Guía de programación de C#)

Inicializadores de objeto y de colección (Guía de programación de C#)

dynamic (Referencia de C#)

Expresiones lambda (Guía de programación de C#)

Interoperabilidad (Guía de programación de C#)

Conceptos

Propiedades implementadas automáticamente (Visual Basic)

Información general de los inicializadores de colección (Visual Basic)

Parámetros opcionales (Visual Basic)

Pasar argumentos por posición o por nombre (Visual Basic)

Argumentos opcionales y con nombre (Guía de programación de C#)

Enlace en tiempo de compilación y en tiempo de ejecución (Visual Basic)

Lambda (expresiones) (Visual Basic)

Otros recursos

Uso de tipo dinámico (Guía de programación de C#)

Cómo: Utilizar propiedades indizadas en la programación de interoperabilidad COM (Guía de programación de C#)

Tutorial: Incrustar información de tipos de los ensamblados de Microsoft Office (C# y Visual Basic)

Interoperabilidad COM (Visual Basic)