Excel-Interop: _Worksheet oder Arbeitsblatt?

76

Ich schreibe derzeit über dynamisches Tippen und gebe ein Beispiel für Excel Interop. Ich habe bisher kaum ein Office-Interop durchgeführt, und das zeigt es. Das MSDN Office Interop-Lernprogramm für C # 4 verwendet die _WorksheetSchnittstelle, es gibt jedoch auch eine WorksheetSchnittstelle. Ich habe keine Ahnung, was der Unterschied ist.

In meiner absurd einfachen Demo-App (siehe unten) funktioniert beides einwandfrei - aber wenn die beste Vorgehensweise das eine oder andere vorschreibt, 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 zu vermeiden, mich eingehend mit der Interoperabilität von COM oder Office zu befassen, indem ich nur die neuen Funktionen von C # 4 hervorhole - aber ich möchte nichts wirklich, wirklich Dummes tun.

(Der obige Code enthält möglicherweise auch etwas wirklich, wirklich Dummes. In diesem Fall lassen Sie es mich bitte wissen. Die Verwendung separater Start- / Endzellen anstelle von "A1: T1" ist absichtlich - es ist einfacher zu erkennen, dass es sich wirklich um einen Bereich handelt von 20 Zellen. Alles andere ist wahrscheinlich zufällig.)

Also, sollte ich verwenden _Worksheetoder Worksheetund warum?

Jon Skeet
quelle
5
Jon, zusätzlich zu den hervorragenden Antworten, die hier gegeben werden, möchte ich hinzufügen, dass bei der Arbeit mit Excel über die Interop im Allgemeinen der Klassenname verwendet wird, wie er normalerweise in Excel angezeigt wird. Dies bedeutet, dass Sie "Arbeitsblatt" anstelle von "_Worksheet" und "Anwendung" anstelle von "Anwendungsklasse" verwenden. (In einer Diskussion hier wird erläutert, warum Sie die 'ApplicationClass' nicht verwenden sollten: blogs.msdn.com/ptorr/archive/2004/02/05/67872.aspx. ) Wenn Sie mit dem Excel-Objektmodell, das COM ausgesetzt ist, nicht vertraut sind, dann könnte das schwieriger sein, aber ich denke, es sollte die meiste Zeit ziemlich klar sein.
Mike Rosenblum
Glücklicherweise mache ich sehr wenig mit Office - ich versuche wirklich nur, die neuen Funktionen zu zeigen. Vielen Dank für den Link - sehr hilfreich!
Jon Skeet
Es tut mir leid, aber ich muss fragen: Was ist die neue Funktion von C # 4, die Sie hervorheben?
Oskar
In diesem speziellen Fall handelte es sich um eine dynamische Typisierung - die Rückgabetypen verschiedener Methodenaufrufe / -eigenschaften sind effektiv "dynamisch", daher das Fehlen von Casts, die sonst erforderlich wären.
Jon Skeet

Antworten:

77

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

Ein Ereignis ist im Wesentlichen eine Methode, die ein Objekt aufruft, wenn etwas passiert. In .NET sind Ereignisse schlicht und einfach Delegaten. In COM ist es jedoch sehr üblich, eine ganze Reihe von Ereignisrückrufen in Schnittstellen zu organisieren. Sie haben daher 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, von denen Sie erwarten, dass sie andere Personen anrufen, wenn Ereignisse eintreten.

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

Wenn die Typbibliothek nun automatisch in Metadaten übersetzt wird, bleiben diese Beziehungen leider erhalten. Es wäre schöner gewesen, eine handgenerierte PIA zu haben, mit der die Klassen und Schnittstellen mehr den Anforderungen der verwalteten Welt entsprechen, aber leider ist dies nicht geschehen. Daher ist die Office-PIA voll von diesen scheinbar seltsamen Duplikaten, bei denen jedem erstellbaren Objekt zwei Schnittstellen zugeordnet zu sein scheinen, auf denen sich das gleiche Material befindet. Eine der Schnittstellen repräsentiert die Schnittstelle zur Coclass, und eine von ihnen repräsentiert die eingehende Schnittstelle zu dieser Coclass.

Die _Workbook-Schnittstelle ist die eingehende Schnittstelle in der Arbeitsmappen-Coclass. Die Workbook-Schnittstelle ist die Schnittstelle, die die Coclass selbst darstellt und daher von _Workbook erbt.

Kurz gesagt, ich würde Workbook verwenden, wenn Sie dies bequem tun können. _Workbook ist ein kleines Implementierungsdetail.

Eric Lippert
quelle
Es ist Arbeitsblatt / _Worksheet, über das wir hier sprechen ... Sie haben die gleiche Fehlinterpretation wie JP gemacht, aber wie er betont, ist die Situation im Grunde gleichwertig. ;)
Noldorin
25

Wenn Sie sich die PIA-Assembly (Microsoft.Office.Interop.Excel) in ansehen Reflector, hat die WorkbookSchnittstelle diese Definition ...

public interface Workbook : _Workbook, WorkbookEvents_Event

Workbookist _Workbookaber fügt Ereignisse hinzu. Gleiches gilt für Worksheet(Entschuldigung, ich habe gerade bemerkt, dass Sie nicht darüber gesprochen haben 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 am besten zu verwenden Worksheet, aber das ist der Unterschied.

JP Alioto
quelle
8

Klassen und Schnittstellen nur für den internen Gebrauch

Vermeiden Sie die direkte Verwendung einer der folgenden Klassen und Schnittstellen, die intern verwendet werden und normalerweise nicht direkt verwendet werden.

Klasse / Schnittstelle: Beispiele

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

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

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

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

Ich klassifiziere Ereignisse x: IApplicationEvents4 (Word), IAppEvents (Excel)

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

edit: (erneutes Formatieren dieser Antwort) kann einen maskierten Unterstrich gefolgt von kursivem Text nicht korrekt formatieren. Wird in der Vorschau korrekt angezeigt, ist jedoch beim Posten fehlerhaft

edit2: funktioniert, wenn Sie den Unterstrich selbst kursiv machen, was konzeptionell schrecklich ist, aber vermutlich gleich aussieht

barrowc
quelle
7

Ich habe in den letzten Jahren ziemlich viel C # / Excel COM Interop-Code gesehen und geschrieben, und ich habe gesehen, dass Arbeitsblätter in fast allen Fällen verwendet wurden. Ich habe noch nie etwas Bestimmtes von Microsoft zu diesem Thema gesehen.

Joe Erickson
quelle
Vielen Dank. Haben Sie 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 vermute (auch bekannt als Bluffen, wenn es darum geht, das Buch zu schreiben ...)
Jon Skeet
Die Verbesserungen von Dynamic / COM Interop sehen nützlich aus, wenn Sie COM verwenden müssen, aber ich bin mir ziemlich sicher, dass ich die dynamische Funktion für viel mehr nicht verwenden werde. Die Dinge, auf die ich mich in C # 4 / .NET 4 wirklich freue, sind Codeverträge und Task Parallel Library.
Joe Erickson
6

MSDN zeigt, dass die WorksheetSchnittstelle einfach von den _Worksheetund DocEvents_EventSchnittstellen erbt . Es scheint, dass man einfach die Ereignisse bereitstellt, die ein Arbeitsblattobjekt zusätzlich zu allem anderen auslösen könnte. Soweit ich sehen kann, Worksheetgibt es keine anderen eigenen Mitglieder. Also ja, Sie Worksheetkönnen in jedem Fall genauso gut die Benutzeroberfläche verwenden, da Sie dadurch nichts verlieren und möglicherweise die Ereignisse benötigen, die sie offenlegt.

Noldorin
quelle
4
Jon Skeet fragt eine Frage ?? Ich musste diese seltene Gelegenheit nutzen, um zu antworten! :)
Noldorin
(Außerdem könnte ich mich einfach für die Verwendung von Arbeitsblatt entscheiden, da dieser Unterstrich dort schrecklich hässlich aussieht ... Aber im Ernst, es scheint keinen Grund zu geben, dies nicht zu tun.)
Noldorin