2009-06-26 3 views
64

Ich schreibe gerade über dynamische Typisierung, und ich gebe ein Beispiel für Excel-Interop. Ich habe vorher noch keine Office-Interop gemacht, und es zeigt sich. Die MSDN Office Interop tutorial für C# 4 verwendet die _Worksheet Schnittstelle, aber es gibt auch eine Worksheet Schnittstelle. Ich habe keine Ahnung, was der Unterschied ist.Excel-Interop: _Worksheet oder Arbeitsblatt?

In meiner absurd einfachen Demo-App (siehe unten) funktioniert beides gut - aber wenn Best Practice das eine oder andere diktiert, würde ich es lieber angemessen verwenden.

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

Ich versuche dabei eine vollständige Tieftauch in COM oder Office Interoperabilität zu vermeiden, Hervorhebung nur die neuen Features von C# 4 - aber ich will nichts wirklich tun, wirklich dumm.

(Es kann auch etwas wirklich, wirklich dumm in dem Code oben sein, in diesem Fall lass es mich wissen. Verwenden separate Start/Ende-Zellen statt nur "A1: T1" ist absichtlich - es ist einfacher zu sehen, dass es ist wirklich eine Reihe von 20 Zellen.Anderes ist wahrscheinlich zufällig.)

Also, sollte ich _Worksheet oder Worksheet verwenden, und warum?

+5

Jon, zusätzlich zu den hervorragenden Antworten hier gegeben wird, Ich würde hinzufügen, dass im Allgemeinen, wenn Sie mit Excel über das Interop arbeiten, verwenden Sie den Klassennamen, wie es normalerweise in Excel erscheint. Dies bedeutet, dass Sie 'Arbeitsblatt' statt '_Worksheet' verwenden und 'Anwendung' anstelle von 'ApplicationClass' verwenden. (Eine Diskussion hier erklärt, warum Sie die 'ApplicationClass' nicht verwenden sollten: http://blogs.msdn.com/pyrtor/archive/2004/02/05/67872.aspx.) Wenn Sie mit dem Excel-Objektmodell nicht vertraut sind ausgesetzt COM, dann könnte dies schwieriger sein, aber ich denke, es sollte die meiste Zeit ziemlich klar sein. –

+0

Glücklicherweise mache ich * sehr * wenig mit Office - versuche wirklich nur die neuen Funktionen zu zeigen. Vielen Dank für den Link - sehr hilfreich! –

+0

Es tut mir leid, aber ich muss fragen - Was ist die neue Funktion von C# 4, die Sie hervorheben? – Oskar

Antwort

72

Wenn ich mich richtig erinnere - und meine Erinnerung daran ist ein bisschen verschwommen, es ist lange her, dass ich den Excel PIA auseinander genommen habe - so ist es.

Ein Ereignis ist im Wesentlichen eine Methode, die ein Objekt aufruft, wenn etwas passiert. In .NET sind Ereignisse Delegierte, schlicht und einfach. In COM ist es jedoch üblich, eine ganze Reihe von Ereignisrückrufen in Schnittstellen zu organisieren. Sie haben also zwei Schnittstellen für ein bestimmtes Objekt - die "eingehende" Schnittstelle, die Methoden, von denen Sie erwarten, dass andere Personen Sie anrufen, und die "ausgehende" Schnittstelle, die Methoden, die Sie erwarten, wenn Ereignisse passieren.

In den nicht verwalteten Metadaten - der Typbibliothek - für ein erstellbares Objekt gibt es Definitionen für drei Dinge: die Eingangsschnittstelle, die Ausgangsschnittstelle und die Co-Klasse, die besagt "Ich bin ein erstellbares Objekt, das dies implementiert eingehende Schnittstelle und diese ausgehende Schnittstelle ".

Jetzt, wenn die Typbibliothek automatisch in Metadaten übersetzt wird, werden diese Beziehungen leider beibehalten. Es wäre netter gewesen, einen handgenerierten PIA zu haben, der die Klassen und Interfaces besser an das anpassen würde, was wir in der verwalteten Welt erwarten würden, aber das ist leider nicht passiert. Daher ist das Office PIA voll von diesen scheinbar seltsamen Duplikationen, bei denen jedem erstellbaren Objekt zwei Interfaces zugeordnet sind, mit demselben Material. Eine der Schnittstellen stellt die Schnittstelle zur Co-Klasse dar, und eine davon stellt die eingehende Schnittstelle zu dieser Co-Klasse dar.

Die _Workbook-Schnittstelle ist die eingehende Schnittstelle in der Arbeitsmappen-Co-Klasse. Die Arbeitsmappenschnittstelle ist die Schnittstelle, die die Co-Klasse selbst darstellt und daher von _Workbook erbt.

Lange Rede kurzer Sinn, ich würde Workbook verwenden, wenn Sie dies bequem tun können; _Workbook ist ein bisschen ein Implementierungsdetail.

+0

Es ist Worksheet/_Worksheet wir reden hier über .. Sie haben das gleiche falsch verstanden wie JP, aber wie er betont, ist die Situation im Grunde äquivalent. ;) – Noldorin

7

Ich habe in den letzten Jahren ziemlich viel C#/Excel COM Interop Code gesehen und geschrieben und ich habe in fast jedem Fall Arbeitsblätter gesehen. Ich habe noch nie etwas Definitives von Microsoft zu diesem Thema gesehen.

+0

Danke. Hast du aus Interesse mit den Verbesserungen in C# 4 Schritt gehalten? Sie * klingen *, als würden sie einen großen Unterschied in Bezug auf Office Interop machen, aber ohne die Erfahrung, die ich wirklich nur rate (aka bluffen, wenn es darum geht, das Buch zu schreiben ...) –

+0

Die dynamischen/COM Interop Verbesserungen sehen nützlich aus, wenn Sie COM verwenden müssen, aber ich bin ziemlich sicher, dass ich die dynamische Funktion für viel mehr als das nicht verwenden werde. Die Dinge, auf die ich mich sehr freue, sind C# 4/.NET 4, Code Contracts und Task Parallel Library. –

6

MSDN zeigt, dass die Schnittstelle Worksheet einfach von den Schnittstellen _Worksheet und DocEvents_Event erbt. Es scheint, dass man einfach die Ereignisse angibt, die ein Arbeitsblatt-Objekt zusätzlich zu allem anderen auslösen könnte. Soweit ich sehen kann, stellt Worksheet keine eigenen Mitglieder zur Verfügung. Also, ja, Sie könnten genauso gut mit der Worksheet Schnittstelle in allen Fällen gehen, da Sie nichts damit verlieren, und möglicherweise die Ereignisse benötigen, die es enthüllt.

+4

Jon Skeet * fragt * eine Frage ?? Ich musste diese seltene Gelegenheit ergreifen, um zu antworten! :) – Noldorin

+0

(Außerdem könnte ich einfach wählen, um Worksheet zu verwenden, weil der Unterstrich dort schrecklich hässlich aussieht ... Aber im Ernst, es scheint keinen Grund, dies nicht zu tun.) – Noldorin

24

Wenn Sie an der PIA Montage aussehen (Microsoft.Office.Interop.Excel) in Reflector, die Workbook Schnittstelle diese Definition hat ...

public interface Workbook : _Workbook, WorkbookEvents_Event 

Workbook ist _Workbook sondern fügt Ereignisse. Das Gleiche gilt für Worksheet (sorry, nur bemerkt, dass Sie sprechen nicht über 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; 
} 

Ich würde sagen, es ist die beste Wahl ist Worksheet zu verwenden, aber das ist der Unterschied .

8

Klassen und Interfaces für Interne Verwendung Nur

Vermeiden Sie direkt eine der folgenden Klassen und Schnittstellen, , die intern verwendet werden und sind typischerweise nicht direkt verwendet.

Klasse/Schnittstelle: Beispiele

classid Klasse: ApplicationClass (Word oder Excel), WorksheetClass (Excel)

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

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

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

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

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

bearbeiten: (Re: Formatierung dieser Antwort) kann nicht richtig ein entflohener Strich formatiert werden, unmittelbar gefolgt von kursiven Text.Zeige richtig in der Vorschau aber gebrochen, als geschrieben

edit2: funktioniert, wenn Sie das Unterstreichungs selbst kursiv machen, die vom Konzept her ist schrecklich, aber gleich aussieht Ich nehme