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 _Worksheet
interfaz, pero también hay una Worksheet
interfaz. 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 _Worksheet
o Worksheet
y por qué?
Respuestas:
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.
fuente
Si observa el ensamblado PIA (Microsoft.Office.Interop.Excel) en
Reflector
, laWorkbook
interfaz tiene esta definición ...public interface Workbook : _Workbook, WorkbookEvents_Event
Workbook
es_Workbook
pero agrega eventos. Lo mismo paraWorksheet
(lo siento, acabo de notar que no estabas hablandoWorkbooks
) ...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.fuente
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
fuente
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.
fuente
MSDN muestra que la
Worksheet
interfaz simplemente hereda de las interfaces_Worksheet
yDocEvents_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,Worksheet
no proporciona ningún otro miembro propio. Así que sí, también puede usar laWorksheet
interfaz en todos los casos, ya que no pierde nada con ella y posiblemente necesite los eventos que expone.fuente