2009-06-26 6 views
64

Attualmente sto scrivendo sulla tipizzazione dinamica e sto dando un esempio di interoperabilità con Excel. Non ho quasi mai fatto l'interoperabilità con Office prima, e mostra. Il MSDN Office Interop tutorial per C# 4 utilizza l'interfaccia _Worksheet, ma è presente anche un'interfaccia Worksheet. Non ho idea di quale sia la differenza.Interop di Excel: _Worksheet o foglio di lavoro?

Nella mia app demo assurdamente semplice (mostrata sotto) funziona bene, ma se le migliori pratiche dettano l'una o l'altra, preferisco usarlo in modo appropriato.

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

sto cercando di evitare di fare una full profonda immersione in COM o l'interoperabilità di Office, solo mettendo in evidenza le nuove caratteristiche di C# 4 - ma io non voglio fare qualcosa di veramente, veramente stupido.

(Potrebbe esserci qualcosa di veramente stupido nel codice sopra, in tal caso per favore fatemelo sapere.Utilizzare celle di avvio/fine separate invece di "A1: T1" è intenzionale - è più facile vederlo è veramente una gamma di 20 celle. Tutto il resto è probabilmente casuale.)

Quindi, dovrei usare _Worksheet o Worksheet e perché?

+5

Jon, oltre alle risposte eccellenti in fase di data qui, Vorrei aggiungere che, in generale, quando si lavora con Excel tramite l'interoperabilità, utilizzare il nome della classe così come normalmente appare in Excel. Ciò significa utilizzare "foglio di lavoro" anziché "_Worksheet" e utilizzare "Applicazione" anziché "ApplicationClass". (Una discussione qui spiega perché non usare la 'ApplicationClass': http://blogs.msdn.com/ptorr/archive/2004/02/05/67872.aspx.) Se non si ha familiarità con il modello di oggetti Excel come esposto a COM, questo potrebbe essere più complicato, ma penso che dovrebbe essere abbastanza chiaro la maggior parte del tempo. –

+0

Fortunatamente sto facendo * molto * poco con Office - in realtà sto solo cercando di mostrare le nuove funzionalità. Grazie mille per il collegamento - molto utile! –

+0

Mi dispiace ma devo chiederti: qual è la nuova funzionalità di C# 4 che stai evidenziando? – Oskar

risposta

72

Se ricordo correttamente - e la mia memoria su questo è un po 'confusa, è passato molto tempo da quando ho smontato Excel PIA - è così.

Un evento è essenzialmente un metodo che un oggetto chiama quando succede qualcosa. In .NET, gli eventi sono delegati, semplici e semplici. Ma in COM, è molto comune organizzare un intero gruppo di callback di eventi in interfacce. Hai quindi due interfacce su un dato oggetto: l'interfaccia "in entrata", i metodi che ti aspetti che altre persone ti chiamino e l'interfaccia "in uscita", i metodi che prevedi di chiamare su altre persone quando si verificano eventi.

Nei metadati non gestiti - la libreria dei tipi - per un oggetto creabile esistono definizioni per tre elementi: l'interfaccia in entrata, l'interfaccia in uscita e la coclasse, che dice "Sono un oggetto creabile che implementa questo interfaccia in entrata e questa interfaccia in uscita ".

Ora, quando la libreria dei tipi viene automaticamente tradotta in metadati, tali relazioni sono, purtroppo, conservate. Sarebbe stato più bello avere un PIA generato a mano che rendesse le classi e le interfacce più conformi a ciò che ci aspetteremmo nel mondo gestito, ma purtroppo ciò non è accaduto. Quindi l'Office PIA è pieno di queste duplicazioni apparentemente strane, in cui ogni oggetto creabile sembra avere due interfacce ad esso associate, con le stesse cose su di esse. Una delle interfacce rappresenta l'interfaccia della coclasse e una di esse rappresenta l'interfaccia in entrata per quella coclea.

L'interfaccia _Workbook è l'interfaccia in entrata sulla coclasse della cartella di lavoro. L'interfaccia della cartella di lavoro è l'interfaccia che rappresenta la coclasse stessa e pertanto eredita da _Workbook.

Per farla breve, userei la cartella di lavoro se lo si può fare comodamente; _Workbook è un piccolo dettaglio di implementazione.

+0

È il foglio di lavoro/_Worksheet di cui stiamo parlando qui .. Hai fatto lo stesso errore di lettura di JP, ma come sottolinea, la situazione è sostanzialmente equivalente. ;) – Noldorin

7

Ho visto e scritto un bel po 'di codice di interoperabilità COM C#/Excel negli ultimi anni e ho visto il foglio di lavoro utilizzato in quasi tutti i casi. Non ho mai visto nulla di definitivo da Microsoft sull'argomento.

+0

Grazie. Interessato, hai tenuto il passo con i miglioramenti in C# 4? Loro * suonano * come se facessero una grande differenza in termini di interoperabilità di Office, ma senza l'esperienza sto solo indovinando (alias bluffando, quando si tratta di scrivere il libro ...) –

+0

I miglioramenti dinamici/COM Interop sembra utile quando devi usare COM, ma sono abbastanza sicuro che non userò la funzione dinamica per molto più di quello. Le cose che non vedo l'ora di vedere in C# 4/.NET 4 sono i contratti in codice e la libreria parallela Task. –

6

MSDN mostra che l'interfaccia Worksheet eredita semplicemente dalle interfacce _Worksheet e DocEvents_Event. Sembrerebbe che si forniscono semplicemente gli eventi che un oggetto del foglio di lavoro potrebbe generare in aggiunta a tutto il resto. Per quanto posso vedere, Worksheet non fornisce alcun altro membro. Quindi sì, si potrebbe anche usare l'interfaccia Worksheet in tutti i casi, dal momento che non si perde nulla e potenzialmente potrebbero essere necessari gli eventi che espone.

+4

Jon Skeet * chiede * una domanda ?? Ho dovuto prendere questa rara opportunità di rispondere! :) – Noldorin

+0

(Inoltre, potrei semplicemente scegliere di usare il foglio di lavoro perché quel segno di sottolineatura sembra terribilmente brutto lì ... Ma seriamente, non sembra esserci alcuna ragione per non farlo.) – Noldorin

24

Se si guarda l'assemblea PIA (Microsoft.Office.Interop.Excel) nel Reflector, l'interfaccia Workbook ha questa definizione ...

public interface Workbook : _Workbook, WorkbookEvents_Event 

Workbook è _Workbook ma aggiunge eventi. Lo stesso vale per Worksheet (mi dispiace, appena notato che non parlavi 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; 
} 

io direi che è soluzione migliore per utilizzare Worksheet, ma questa è la differenza .

8

Classi e Interfacce interno Uso

Evitare direttamente utilizzando uno dei seguenti classi e interfacce, che vengono utilizzati internamente e sono genere non utilizzati direttamente.

classe/interfaccia: Esempi

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

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

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

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

ho classid Eventi x: IApplicationEvents4 (Word), IAppEvents (Excel)

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

edit: (re: la formattazione di questa risposta) non può formattare correttamente un carattere di sottolineatura sfuggito seguito immediatamente da un testo in corsivo.Spettacoli correttamente in anteprima, ma rotto una volta inviati

EDIT2: funziona se si fa il segno di sottolineatura in sé italico che è concettualmente orribile, ma sembra lo stesso suppongo