Cómo: Tener acceso a objetos de interoperabilidad de Office mediante las características de Visual C# 2010 (Guía de programación de C#)

Visual C# 2010 presenta nuevas características que simplifican el acceso a objetos de la API de Office. Las nuevas características incluyen argumentos con nombre y opcionales, un nuevo tipo denominado dynamic y la capacidad de pasar argumentos a parámetros de referencia en los métodos COM como si fueran parámetros de valor.

En este tema utilizará las nuevas características para escribir código que crea y muestra una hoja de cálculo de Microsoft Office Excel. A continuación, escribirá código para agregar un documento de Office Word que contiene un icono que se vincula a la hoja de cálculo de Excel.

Para completar este tutorial, debe tener Microsoft Office Excel 2007 y Microsoft Office Word 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 crear una aplicación de consola

  1. Inicie Visual Studio.

  2. En el menú Archivo, elija Nuevo y haga clic en Proyecto. Aparecerá el cuadro de diálogo Nuevo proyecto.

  3. En el recuadro Plantillas instaladas, expanda Visual C# y, a continuación, haga clic en Windows.

  4. Examine la parte superior del cuadro de diálogo Nuevo proyecto a fin de asegurarse de que .NET Framework 4 está seleccionado como versión de .NET Framework de destino.

  5. En el panel Plantillas, haga clic en Aplicación de consola.

  6. Escriba un nombre para el proyecto en el campo Nombre.

  7. Haga clic en Aceptar.

    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 página .NET, seleccione Microsoft.Office.Interop.Word en la lista Nombre de componente y, a continuación, mantenga presionada la tecla CTRL y seleccione Microsoft.Office.Interop.Excel.

  3. Haga clic en Aceptar.

Para agregar las directivas using necesarias

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

  2. Agregue las siguientes directivas using al principio del archivo de código.

    using Excel = Microsoft.Office.Interop.Excel;
    using Word = Microsoft.Office.Interop.Word;
    

Para crear una lista de cuentas bancarias

  1. Pegue la siguiente definición de clase en Program.cs, bajo la clase Program.

    public class Account
    {
        public int ID { get; set; }
        public double Balance { get; set; }
    }
    
  2. Agregue el siguiente código al método Main para crear una lista bankAccounts que contiene dos cuentas.

    // Create a list of accounts.
    var bankAccounts = new List<Account> {
        new Account { 
                      ID = 345678,
                      Balance = 541.27
                    },
        new Account {
                      ID = 1230221,
                      Balance = -127.44
                    }
    };
    

Para declarar un método que exporta información de cuentas a Excel

  1. Agregue el siguiente método a la clase Program para configurar una hoja de cálculo de Excel.

    El método Add tiene un parámetro opcional para especificar una plantilla determinada. 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 siguiente código, 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).

    static void DisplayInExcel(IEnumerable<Account> accounts)
    {
        var excelApp = new Excel.Application();
        // Make the object visible.
        excelApp.Visible = true;
    
        // Create a new, empty workbook and add it to the collection returned 
        // by property Workbooks. The new workbook becomes the active workbook.
        // Add has an optional parameter for specifying a praticular template. 
        // Because no argument is sent in this example, Add creates a new workbook. 
        excelApp.Workbooks.Add();
    
        // This example uses a single workSheet. The explicit type casting is
        // removed in a later procedure.
        Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet;
    }
    
  2. Agregue el siguiente código al final de DisplayInExcel. El código inserta valores en las dos primeras columnas de la primera fila de la hoja de cálculo.

    // Establish column headings in cells A1 and B1.
    workSheet.Cells[1, "A"] = "ID Number";
    workSheet.Cells[1, "B"] = "Current Balance";
    
  3. Agregue el siguiente código al final de DisplayInExcel. El bucle foreach coloca la información de la lista de cuentas en las dos primeras columnas de filas sucesivas de la hoja de cálculo.

    
    var row = 1;
    foreach (var acct in accounts)
    {
        row++;
        workSheet.Cells[row, "A"] = acct.ID;
        workSheet.Cells[row, "B"] = acct.Balance;
    }
    
  4. Agregue el siguiente código al final de DisplayInExcel para ajustar el ancho de las columnas al contenido.

    workSheet.Columns[1].AutoFit();
    workSheet.Columns[2].AutoFit();
    

    Las versiones anteriores de C# requieren una conversión explícita para estas operaciones, porque ExcelApp.Columns[1] devuelve Object y AutoFit es un método Range de Excel. En las siguientes líneas se muestra la conversión.

    ((Excel.Range)workSheet.Columns[1]).AutoFit();
    ((Excel.Range)workSheet.Columns[2]).AutoFit();
    

    Visual C# 2010 convierte automáticamente el Object devuelto en dynamic si se hace referencia al ensamblado por la opción de compilador /link; o, lo que es lo mismo, si la propiedad de Excel Embed Interop Types está establecida en True. True es el valor predeterminado de esta propiedad.

Para ejecutar el proyecto

  1. Agregue la siguiente línea al final de Main.

    // Display the list in an Excel spreadsheet.
    DisplayInExcel(bankAccounts);
    
  2. Presione CTRL+F5.

    Aparece una hoja de cálculo de Excel que contiene los datos de las dos cuentas.

Para agregar un documento de Word

  1. Para mostrar maneras adicionales en las que Visual C# 2010 mejora la programación de Office, el siguiente código abre una aplicación de Word y crea un icono que establece un vínculo con la hoja de cálculo de Excel.

    Pegue el método CreateIconInWordDoc, que aparece más adelante en este paso, en la clase Program. CreateIconInWordDoc utiliza argumentos con nombre y opcionales para reducir la complejidad de las llamadas a los métodos Add y PasteSpecial. Estas llamadas incorporan otras dos nuevas características de Visual C# 2010 que simplifican las llamadas a los métodos COM que tienen parámetros de referencia. En primer lugar, puede enviar argumentos a los parámetros de referencia como si fueran parámetros de valor. Es decir, puede enviar valores directamente, sin crear una variable para cada parámetro de referencia. El compilador genera variables temporales en las que contener los valores de argumento y las descarta cuando se regresa de la llamada. En segundo lugar, se puede omitir la palabra clave ref en la lista de argumentos.

    El método Add tiene cuatro parámetros de referencia, todos ellos opcionales. En Visual C# 2010, puede omitir los argumentos para cualquiera o todos los parámetros si desea utilizar sus valores predeterminados. En Visual C# 2008 y las versiones anteriores, se tiene que proporcionar un argumento para cada parámetro y el argumento debe ser una variable, porque los parámetros son de referencia.

    El método PasteSpecial inserta el contenido del Portapapeles. El método tiene siete parámetros de referencia, todos ellos opcionales. El siguiente código especifica los argumentos para dos de ellos: Link, a fin de crear un vínculo con el origen del contenido del Portapapeles; y DisplayAsIcon, para mostrar el vínculo como un icono. En Visual C# 2010, puede utilizar argumentos con nombre para esos dos y omitir los demás. Aunque se trata de parámetros de referencia, no hay que utilizar la palabra clave ref ni que crear variables para enviarlas como argumentos. Puede enviar los valores directamente. En Visual C# 2008 y las versiones anteriores, se debe enviar un argumento de variable para cada parámetro de referencia.

    static void CreateIconInWordDoc()
    {
        var wordApp = new Word.Application();
        wordApp.Visible = true;
    
        // The Add method has four reference parameters, all of which are 
        // optional. Visual C# 2010 allows you to omit arguments for them if
        // the default values are what you want.
        wordApp.Documents.Add();
    
        // PasteSpecial has seven reference parameters, all of which are 
        // optional. This example uses named arguments to specify values 
        // for two of the parameters. Although these are reference 
        // parameters, you do not need to use the ref keyword, or to create 
        // variables to send in as arguments. You can send the values directly.
        wordApp.Selection.PasteSpecial( Link: true, DisplayAsIcon: true);
    }
    

    En Visual C# 2008 o versiones anteriores del lenguaje, se necesita el siguiente código, que es más complejo.

    static void CreateIconInWordDoc2008()
    {
        var wordApp = new Word.Application();
        wordApp.Visible = true;
    
        // The Add method has four parameters, all of which are optional. 
        // In Visual C# 2008 and earlier versions, an argument has to be sent 
        // for every parameter. Because the parameters are reference  
        // parameters of type object, you have to create an object variable
        // for the arguments that represents 'no value'. 
    
        object useDefaultValue = Type.Missing;
    
        wordApp.Documents.Add(ref useDefaultValue, ref useDefaultValue,
            ref useDefaultValue, ref useDefaultValue);
    
        // PasteSpecial has seven reference parameters, all of which are
        // optional. In this example, only two of the parameters require
        // specified values, but in Visual C# 2008 an argument must be sent
        // for each parameter. Because the parameters are reference parameters,
        // you have to contruct variables for the arguments.
        object link = true;
        object displayAsIcon = true;
    
        wordApp.Selection.PasteSpecial( ref useDefaultValue,
                                        ref link,
                                        ref useDefaultValue,
                                        ref displayAsIcon,
                                        ref useDefaultValue,
                                        ref useDefaultValue,
                                        ref useDefaultValue);
    }
    
  2. Agregue la siguiente instrucción al final de Main.

    // Create a Word document that contains an icon that links to
    // the spreadsheet.
    CreateIconInWordDoc();
    
  3. Agregue la siguiente instrucción al final de DisplayInExcel. El método Copy agrega la hoja de cálculo al Portapapeles.

    // Put the spreadsheet contents on the clipboard. The Copy method has one
    // optional parameter for specifying a destination. Because no argument  
    // is sent, the destination is the Clipboard.
    workSheet.Range["A1:B3"].Copy();
    
  4. Presione CTRL+F5.

    Aparece un documento de Word que contiene un icono. Haga doble clic en el icono para traer la hoja de cálculo al primer plano.

Para establecer la propiedad Embed Interop Types

  1. Es posible realizar más mejoras al llamar a un tipo COM que no requiere un ensamblado de interoperabilidad primario (PIA) en tiempo de ejecución. Quitar la dependencia de los PIA da lugar a independencia de la versión y facilita la implementación. Para obtener más información sobre las ventajas de la programación sin PIA, vea Tutorial: Incrustar los tipos de los ensamblados administrados (C# y Visual Basic).

    Además, programar resulta más fácil porque los tipos que se requieren y devuelven por los métodos COM se pueden representar utilizando el tipo dynamic en lugar de Object. Las variables que tienen el tipo dynamic no se evalúan hasta el tiempo de ejecución, lo que elimina la necesidad de la conversión explícita. Para obtener más información, vea Uso de tipo dinámico (Guía de programación de C#).

    En Visual C# 2010, el comportamiento predeterminado consiste en incrustar información de tipos en lugar de utilizar PIA. Debido a ese valor predeterminado, algunos de los ejemplos anteriores se simplifican, porque no se requiere la conversión explícita. Por ejemplo, la declaración de worksheet en DisplayInExcel se escribe así: Excel._Worksheet workSheet = excelApp.ActiveSheet; y no así: Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet. Las llamadas a AutoFit en el mismo método también requerirían una conversión explícita sin ningún valor predeterminado, porque ExcelApp.Columns[1] devuelve Object y AutoFit es un método de Excel. En el ejemplo de código siguiente se muestra la conversión.

    ((Excel.Range)workSheet.Columns[1]).AutoFit();
    ((Excel.Range)workSheet.Columns[2]).AutoFit();
    
  2. Para cambiar el valor predeterminado y utilizar PIA en lugar de incrustar información de tipos, expanda el nodo Referencias del Explorador de soluciones y, a continuación, seleccione Microsoft.Office.Interop.Excel o Microsoft.Office.Interop.Word.

  3. Si no puede ver la ventana Propiedades, presione F4.

  4. Busque Embed Interop Types en la lista de propiedades y cambie su valor por False. De igual forma, puede compilar mediante la opción del compilador /reference en lugar de /link en un símbolo del sistema.

Para agregar formato adicional a la tabla

  1. Reemplace las dos llamadas a AutoFit en DisplayInExcel por la siguiente instrucción.

    // Call to AutoFormat in Visual C# 2010.
    workSheet.Range["A1", "B3"].AutoFormat(
        Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);
    

    El método AutoFormat tiene siete parámetros de valor, todos ellos opcionales. Los argumentos con nombre y opcionales permiten proporcionar argumentos para ninguno, algunos o todos ellos. En la instrucción anterior, se proporciona un argumento para uno solo de los parámetros, Format. Dado que Format es el primer parámetro de la lista de parámetros, no es necesario proporcionar el nombre de parámetro. Sin embargo, puede que la instrucción resulte más fácil de entender si se incluye el nombre del parámetro, como se muestra en el siguiente código.

    // Call to AutoFormat in Visual C# 2010.
    workSheet.Range["A1", "B3"].AutoFormat(Format:
        Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);
    
  2. Presione CTRL+F5 para ver el resultado. Hay otros formatos en la enumeración XlRangeAutoFormat.

  3. Compare la instrucción del paso 1 con el siguiente código, que muestra los argumentos que obligatorios en Visual C# 2008 y en las versiones anteriores.

    // The AutoFormat method has seven optional value parameters. The
    // following call specifies a value for the first parameter, and uses 
    // the default values for the other six. 
    
    // Call to AutoFormat in Visual C# 2008. This code is not part of the
    // current solution.
    excelApp.get_Range("A1", "B4").AutoFormat(Excel.XlRangeAutoFormat.xlRangeAutoFormatTable3, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing);
    

Ejemplo

En el código siguiente se muestra el ejemplo completo.

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


namespace OfficeProgramminWalkthruComplete
{
    class Walkthrough
    {
        static void Main(string[] args)
        {
            // Create a list of accounts.
            var bankAccounts = new List<Account> 
            {
                new Account { 
                              ID = 345678,
                              Balance = 541.27
                            },
                new Account {
                              ID = 1230221,
                              Balance = -127.44
                            }
            };

            // Display the list in an Excel spreadsheet.
            DisplayInExcel(bankAccounts);

            // Create a Word document that contains an icon that links to
            // the spreadsheet.
            CreateIconInWordDoc();
        }

        static void DisplayInExcel(IEnumerable<Account> accounts)
        {
            var excelApp = new Excel.Application();
            // Make the object visible.
            excelApp.Visible = true;

            // Create a new, empty workbook and add it to the collection returned 
            // by property Workbooks. The new workbook becomes the active workbook.
            // Add has an optional parameter for specifying a praticular template. 
            // Because no argument is sent in this example, Add creates a new workbook. 
            excelApp.Workbooks.Add();

            // This example uses a single workSheet. 
            Excel._Worksheet workSheet = excelApp.ActiveSheet;

            // Earlier versions of C# require explicit casting.
            //Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet;

            // Establish column headings in cells A1 and B1.
            workSheet.Cells[1, "A"] = "ID Number";
            workSheet.Cells[1, "B"] = "Current Balance";

            var row = 1;
            foreach (var acct in accounts)
            {
                row++;
                workSheet.Cells[row, "A"] = acct.ID;
                workSheet.Cells[row, "B"] = acct.Balance;
            }

            workSheet.Columns[1].AutoFit();
            workSheet.Columns[2].AutoFit();

            // Call to AutoFormat in Visual C# 2010. This statement replaces the 
            // two calls to AutoFit.
            workSheet.Range["A1", "B3"].AutoFormat(
                Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);

            // Put the spreadsheet contents on the clipboard. The Copy method has one
            // optional parameter for specifying a destination. Because no argument  
            // is sent, the destination is the Clipboard.
            workSheet.Range["A1:B3"].Copy();
        }

        static void CreateIconInWordDoc()
        {
            var wordApp = new Word.Application();
            wordApp.Visible = true;

            // The Add method has four reference parameters, all of which are 
            // optional. Visual C# 2010 allows you to omit arguments for them if
            // the default values are what you want.
            wordApp.Documents.Add();

            // PasteSpecial has seven reference parameters, all of which are 
            // optional. This example uses named arguments to specify values 
            // for two of the parameters. Although these are reference 
            // parameters, you do not need to use the ref keyword, or to create 
            // variables to send in as arguments. You can send the values directly.
            wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true);
        }
    }

    public class Account
    {
        public int ID { get; set; }
        public double Balance { get; set; }
    }
}

Vea también

Tareas

Cómo: Usar argumentos opcionales y con nombre en la programación de Office (Guía de programación de C#)

Referencia

dynamic (Referencia de C#)

Type.Missing

Conceptos

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

Otros recursos

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