2009-06-26 18 views
64

Actualmente estoy escribiendo sobre tipado dinámico, y estoy dando un ejemplo de interoperabilidad de Excel. Apenas he hecho una interoperabilidad de Office antes, y se nota. El MSDN Office Interop tutorial para C# 4 usa la interfaz _Worksheet, pero también hay una interfaz Worksheet. No tengo idea de cuál es la diferencia.Interoperabilidad de Excel: _Worksheet o Worksheet?

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

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(); 
    } 
} 

que estoy tratando de evitar hacer una profunda inmersión completa en COM o la interoperabilidad de Office, basta con resaltar las nuevas características de C# 4 - pero no quiere hacer nada muy, muy tonto.

(Puede que también haya algo realmente estúpido en el código anterior, en cuyo caso comuníquemelo. Utilizar celdas de inicio/final separadas en lugar de solo "A1: T1" es deliberado, es más fácil ver que es genuinamente un rango de 20 celdas. Cualquier otra cosa es probablemente accidental.)

Entonces, ¿debo usar _Worksheet o Worksheet, y por qué?

+5

Jon, además de las excelentes respuestas que se da aquí, Yo agregaría que, en general, cuando se trabaja con Excel a través de la interoperabilidad, use el nombre de la clase como aparece normalmente en Excel. Esto significa usar 'Hoja de cálculo' en lugar de '_ Hoja de trabajo', y usar 'Aplicación' en lugar de 'Clase de aplicación'. (Una explicación aquí explica por qué no se debe usar 'ApplicationClass': http://blogs.msdn.com/ptorr/archive/2004/02/05/67872.aspx). Si no está familiarizado con el modelo de objetos de Excel como expuesto a COM, entonces esto podría ser más complicado, pero creo que debería quedar bastante claro la mayor parte del tiempo. –

+0

Afortunadamente estoy haciendo * muy * poco con Office, realmente solo estoy tratando de mostrar las nuevas funciones. Muchas gracias por el enlace, ¡muy útil! –

+0

Lo siento pero tengo que preguntar: ¿Cuál es la nueva característica de C# 4 que está resaltando? – Oskar

Respuesta

72

Si recuerdo correctamente - y mi memoria sobre esto es un poco borrosa, ha sido un largo tiempo desde que tomé el Excel PIA aparte - es así.

Un evento es esencialmente un método que un objeto llama cuando sucede algo. En .NET, los eventos son delegados, simple y llanamente. Pero en COM, es muy común organizar una gran cantidad de devoluciones de llamadas de eventos en las 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 los eventos.

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

Ahora, cuando la biblioteca de tipos se traduce automáticamente en metadatos, esas relaciones, lamentablemente, se conservan. Hubiera sido más agradable 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, la PIA de Office está llena de estas duplicaciones aparentemente extrañas, donde cada objeto creable parece tener dos interfaces asociadas con las mismas cosas. Una de las interfaces representa la interfaz para el coclass y una de ellas representa la interfaz entrante para ese coclass.

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

Para abreviar, utilizaría Workbook si puede hacerlo cómodamente; _Workbook es un poco un detalle de implementación.

+0

Es la hoja de trabajo/_Worksheet de la que estamos hablando aquí .. Hiciste la misma mala interpretación que JP, pero como él señala, la situación es básicamente equivalente. ;) – Noldorin

7

He visto y escrito un poco de C#/código de Interoperabilidad COM de 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.

+0

Gracias. Por interés, ¿ha estado al día con las mejoras en C# 4? * Suenan * como si marcaran una gran diferencia en términos de interoperabilidad de Office, pero sin la experiencia que realmente estoy adivinando (alias farolear, cuando se trata de escribir el libro ...) –

+0

Las mejoras dinámicas/COM Interop parece útil cuando tiene que usar COM, pero estoy bastante seguro de que no usaré la función dinámica por mucho más que eso. Las cosas que realmente estoy esperando encontrar en C# 4/.NET 4 son contratos de código y Task Parallel Library. –

6

MSDN muestra que la interfaz Worksheet simplemente hereda de las interfaces _Worksheet y DocEvents_Event. Parecería que uno simplemente proporciona los eventos que un objeto de la hoja de trabajo puede generar de forma adicional a todo lo demás. Por lo que puedo ver, Worksheet no proporciona ningún otro miembro propio. Así que, sí, también puede utilizar la interfaz Worksheet en todos los casos, ya que no pierde nada y es posible que necesite los eventos que expone.

+4

Jon Skeet * pregunta * una pregunta ?? ¡Tenía que aprovechar esta rara oportunidad para responder! :) – Noldorin

+0

(Además, podría elegir usar la Hoja de trabajo porque ese guión bajo se ve horriblemente feo ... Pero, en serio, parece que no hay razón para no hacerlo). – Noldorin

24

Si nos fijamos en el conjunto del PIA (Microsoft.Office.Interop.Excel) en Reflector, la interfaz Workbook tiene esta definición ...

public interface Workbook : _Workbook, WorkbookEvents_Event 

Workbook es _Workbook pero añade eventos. Lo mismo para Worksheet (lo siento, acabo de notar que no estaba hablando de 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 .

8

clases e interfaces para uso interno Sólo

Evitar directamente a través de cualquiera de los siguientes clases e interfaces, que se utilizan internamente y están normalmente no se utiliza 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)

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

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

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

edición: (re: El formato de esta respuesta) no puede formatear correctamente un guión escapado seguido inmediatamente por el texto en cursiva.Muestra correctamente en vista previa, pero roto cuando se publiquen

Edit2: funciona si se hace el guión en sí cursiva, que es conceptualmente horrible, pero se ve igual que supongo

Cuestiones relacionadas