Interoperabilidad de Excel: _Worksheet u Worksheet?

76

Actualmente estoy escribiendo sobre escritura dinámica y estoy dando un ejemplo de interoperabilidad de Excel. Casi no he hecho ninguna interoperabilidad de Office antes, y se nota. El tutorial de MSDN Office Interop para C # 4 usa la _Worksheetinterfaz, pero también hay una Worksheetinterfaz. No tengo idea de cuál es la diferencia.

En mi aplicación de demostración absurdamente simple (que se muestra a continuación), cualquiera de las dos funciona bien, pero si las mejores prácticas dictan una u otra, prefiero usarla de manera apropiada.

using System;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;

class DynamicExcel
{
    static void Main()
    {
        var app = new Excel.Application { Visible = true };
        app.Workbooks.Add();

        // Can use Excel._Worksheet instead here. Which is better?
        Excel.Worksheet workSheet = app.ActiveSheet;

        Excel.Range start = workSheet.Cells[1, 1];
        Excel.Range end = workSheet.Cells[1, 20];
        workSheet.get_Range(start, end).Value2 = Enumerable.Range(1, 20)
                                                           .ToArray();
    }
}

Estoy tratando de evitar hacer una inmersión profunda en la interoperabilidad de COM u Office, solo destacando las nuevas características de C # 4, pero no quiero hacer nada realmente tonto.

(También puede haber algo realmente tonto en el código anterior, en cuyo caso, hágamelo saber. Usar celdas de inicio / finalización separadas en lugar de solo "A1: T1" es deliberado; es más fácil ver que es realmente un rango de 20 celdas. Cualquier otra cosa probablemente sea accidental).

Entonces, ¿debería usar _Worksheeto Worksheety por qué?

Jon Skeet
fuente
5
Jon, además de las excelentes respuestas que se dan aquí, agregaría que, en general, cuando trabaje con Excel a través de la interoperabilidad, use el nombre de la clase como aparece normalmente en Excel. Esto significa que use 'Hoja de trabajo' en lugar de '_Hoja de trabajo' y use 'Aplicación' en lugar de 'Clase de aplicación'. (Una discusión aquí explica por qué no usar 'ApplicationClass': blogs.msdn.com/ptorr/archive/2004/02/05/67872.aspx. ) Si no está familiarizado con el modelo de objetos de Excel expuesto a COM, entonces esto podría ser más complicado, pero creo que debería ser bastante claro la mayor parte del tiempo.
Mike Rosenblum
Afortunadamente, estoy haciendo muy poco con Office, en realidad solo intento mostrar las nuevas funciones. Muchas gracias por el enlace, ¡muy útil!
Jon Skeet
Lo siento, pero tengo que preguntar: ¿Cuál es la nueva característica de C # 4 que está destacando?
Oskar
Para este caso particular, fue la tipificación dinámica: los tipos de retorno de varias llamadas / propiedades de métodos son efectivamente "dinámicos", de ahí la falta de conversiones que de otra manera serían necesarias.
Jon Skeet

Respuestas:

77

Si recuerdo correctamente, y mi memoria sobre esto es un poco confusa, ha pasado mucho tiempo desde que desmonté el PIA de Excel, es así.

Un evento es esencialmente un método al que un objeto llama cuando sucede algo. En .NET, los eventos son delegados, simple y llanamente. Pero en COM, es muy común organizar un montón de devoluciones de llamada de eventos en interfaces. Por lo tanto, tiene dos interfaces en un objeto determinado: la interfaz "entrante", los métodos que espera que otras personas le llamen y la interfaz "saliente", los métodos que espera llamar a otras personas cuando suceden eventos.

En los metadatos no administrados, la biblioteca de tipos, para un objeto creable hay definiciones para tres cosas: la interfaz entrante, la interfaz saliente y la coclase, que dice "Soy un objeto creable que implementa esta interfaz entrante y esta interfaz de salida ".

Ahora, cuando la biblioteca de tipos se traduce automáticamente en metadatos, esas relaciones, lamentablemente, se conservan. Hubiera sido mejor tener un PIA generado a mano que hiciera que las clases y las interfaces se ajustaran más a lo que esperaríamos en el mundo administrado, pero lamentablemente, eso no sucedió. Por lo tanto, Office PIA está lleno de estas duplicaciones aparentemente extrañas, donde cada objeto creable parece tener dos interfaces asociadas, con las mismas cosas en ellas. Una de las interfaces representa la interfaz de la coclase y una de ellas representa la interfaz entrante de esa coclase.

La interfaz _Workbook es la interfaz entrante en la coclase del libro de trabajo. La interfaz del Libro de trabajo es la interfaz que representa la coclase en sí y, por lo tanto, hereda de _Workbook.

En pocas palabras, usaría Workbook si puede hacerlo convenientemente; _Workbook es un pequeño detalle de implementación.

Eric Lippert
fuente
Es Hoja de trabajo / _ Hoja de trabajo de la que estamos hablando aquí ... hiciste la misma lectura errónea que JP, pero como él señala, la situación es básicamente equivalente. ;)
Noldorin
25

Si observa el ensamblado PIA (Microsoft.Office.Interop.Excel) en Reflector, la Workbookinterfaz tiene esta definición ...

public interface Workbook : _Workbook, WorkbookEvents_Event

Workbookes _Workbookpero agrega eventos. Lo mismo para Worksheet(lo siento, acabo de notar que no estabas hablando Workbooks) ...

public interface Worksheet : _Worksheet, DocEvents_Event

DocEvents_Event ...

[ComVisible(false), TypeLibType((short) 0x10), ComEventInterface(typeof(DocEvents),
                     typeof(DocEvents_EventProvider))]
public interface DocEvents_Event
{
    // Events
    event DocEvents_ActivateEventHandler Activate;
    event DocEvents_BeforeDoubleClickEventHandler BeforeDoubleClick;
    event DocEvents_BeforeRightClickEventHandler BeforeRightClick;
    event DocEvents_CalculateEventHandler Calculate;
    event DocEvents_ChangeEventHandler Change;
    event DocEvents_DeactivateEventHandler Deactivate;
    event DocEvents_FollowHyperlinkEventHandler FollowHyperlink;
    event DocEvents_PivotTableUpdateEventHandler PivotTableUpdate;
    event DocEvents_SelectionChangeEventHandler SelectionChange;
}

Yo diría que es la mejor opción para usar Worksheet, pero esa es la diferencia.

JP Alioto
fuente
8

Clases e interfaces para uso interno únicamente

Evite el uso directo de cualquiera de las siguientes clases e interfaces, que se utilizan internamente y normalmente no se utilizan directamente.

Clase / interfaz: ejemplos

classid Clase: ApplicationClass (Word o Excel), WorksheetClass (Excel)

classid Eventos x _SinkHelper: ApplicationEvents4_SinkHelper (Word), WorkbookEvents_SinkHelper (Excel)

_classid : _Application (Word o Excel), _Worksheet (Excel)

Eventos classid x: ApplicationEvents4 (Word), AppEvents (Excel)

I classid Eventos x: IApplicationEvents4 (Word), IAppEvents (Excel)

http://msdn.microsoft.com/en-gb/library/ms247299(office.11).aspx

editar: (re: formateo de esta respuesta) no se puede formatear correctamente un guión bajo de escape seguido inmediatamente por texto en cursiva. Se muestra correctamente en la vista previa pero se rompe cuando se publica

edit2: funciona si pones el guión bajo en cursiva, lo cual es conceptualmente horrible pero se ve igual, supongo

carretilla
fuente
7

He visto y escrito bastante código de interoperabilidad COM de C # / Excel en los últimos años y he visto la hoja de trabajo utilizada en casi todos los casos. Nunca he visto nada definitivo de Microsoft sobre el tema.

Joe Erickson
fuente
Gracias. Por interés, ¿se ha mantenido al día con las mejoras en C # 4? Ellos suenan como si hubieran hacen una gran diferencia en cuanto a la Oficina de interoperabilidad, pero sin la experiencia que estoy realmente sólo una suposición (también conocido como un farol, cuando se trata de escribir el libro ...)
Jon Skeet
Las mejoras de interoperabilidad dinámica / COM parecen útiles cuando tienes que usar COM, pero estoy bastante seguro de que no usaré la función dinámica para mucho más que eso. Las cosas que realmente estoy esperando están en C # 4 / .NET 4 son contratos de código y Task Parallel Library.
Joe Erickson
6

MSDN muestra que la Worksheetinterfaz simplemente hereda de las interfaces _Worksheety DocEvents_Event. Parecería que uno simplemente proporciona los eventos que un objeto de hoja de trabajo podría generar además de todo lo demás. Por lo que puedo ver, Worksheetno proporciona ningún otro miembro propio. Así que sí, también puede usar la Worksheetinterfaz en todos los casos, ya que no pierde nada con ella y posiblemente necesite los eventos que expone.

Noldorin
fuente
4
Jon Skeet haciendo una pregunta ?? ¡Tuve que aprovechar esta rara oportunidad para responder! :)
Noldorin
(Además, podría elegir usar Hoja de trabajo porque ese guión bajo se ve terriblemente feo allí ... Pero en serio, parece que no hay razón para no hacerlo).
Noldorin