c# - programacion - no se puede convertir el objeto com del tipo microsoft office interop excel applicationclass
Interoperabilidad de Excel:_Worksheet o Worksheet? (5)
Actualmente estoy escribiendo sobre mecanografía dinámica, y estoy dando un ejemplo de interoperabilidad de Excel. Apenas he hecho una interoperabilidad de Office antes, y se nota. El tutorial de MSDN Office Interop para C # 4 usa la interfaz _Worksheet
, pero también hay una interfaz de Worksheet
. No tengo idea de cuál es la diferencia.
En mi aplicación de demostración absurdamente simple (que se muestra a continuación) o bien funciona bien, pero si las mejores prácticas dictan uno u otro, prefiero usarlo de manera adecuada.
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 profunda inmersión en la interoperabilidad COM o Office, simplemente destacando las nuevas características de C # 4, pero no quiero hacer nada realmente, realmente tonto.
(También puede haber algo realmente tonto en el código anterior, en cuyo caso, hágamelo saber. Usar celdas de inicio / final 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 es probablemente accidental.)
Entonces, ¿debería usar _Worksheet
o Worksheet
, y por qué?
Clases e interfaces para uso interno solamente
Evite utilizar directamente cualquiera de las siguientes clases e interfaces, que se usan internamente y, por lo general, no se usan directamente.
Clase / interfaz: ejemplos
clase classid : ApplicationClass (Word o Excel), WorksheetClass (Excel)
classid Events x _SinkHelper: ApplicationEvents4_SinkHelper (Word), WorkbookEvents_SinkHelper (Excel)
_classid : _Application (Word o Excel), _Worksheet (Excel)
classid Events x: ApplicationEvents4 (Word), AppEvents (Excel)
I classid Events x: IApplicationEvents4 (Word), IAppEvents (Excel)
http://msdn.microsoft.com/en-gb/library/ms247299(office.11).aspx
edit: (re: formateo de esta respuesta) no puede formatear correctamente un guión bajo escapado seguido inmediatamente por un texto en cursiva. Se muestra correctamente en la vista previa pero se rompe cuando se publica
edit2: funciona si haces el guión bajo en cursiva, que es conceptualmente horrible pero se ve igual, supongo
He visto y escrito un poco de C # / código COM Interop 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.
MSDN muestra que la interfaz de 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 de la Worksheet
en todos los casos, ya que no pierde nada y es posible que necesite los eventos que expone.
Si observa el ensamblaje de PIA (Microsoft.Office.Interop.Excel) en Reflector
, la interfaz del Workbook
tiene esta definición ...
public interface Workbook : _Workbook, WorkbookEvents_Event
Workbook
es _Workbook
pero agrega eventos. Lo mismo para Worksheet
de Worksheet
(lo siento, solo me di cuenta de 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 mejor usar Worksheet
, pero esa es la diferencia.
Si recuerdo correctamente, y mi memoria sobre esto es un poco borrosa, ha pasado mucho tiempo desde que saqué el Excel PIA, 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 que se puede crear hay definiciones para tres cosas: la interfaz entrante, la interfaz saliente y el cóctel, que dice "Soy un objeto creíble que implementa esta interfaz entrante y esto interfaz de salida ".
Ahora, cuando la biblioteca de tipos se traduce automáticamente a 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 resumir, usaría Workbook si puede hacerlo de manera conveniente; _Workbook es un poco un detalle de implementación.