2009-06-26 22 views
64

Obecnie piszę o dynamicznym pisaniu i podaję przykład interop Excel. Zwykle nie robiłem żadnego interopingu w Office i to pokazuje. Interfejs MSDN Office Interop tutorial dla C# 4 wykorzystuje interfejs _Worksheet, ale istnieje również interfejs Worksheet. Nie mam pojęcia, jaka jest różnica.Excel interop: _Worksheet lub Worksheet?

W mojej absurdalnie prostej aplikacji demonstracyjnej (pokazanej poniżej) albo działa dobrze - ale jeśli najlepsza praktyka dyktuje jedno lub drugie, wolałbym użyć tego odpowiednio.

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

staram się unikać robienia pełną głębokiego nurkowania w COM lub Office interoperacyjności, tylko podkreślając nowe funkcje C# 4 - ale nie chcę nic robić naprawdę głupie.

(W powyższym kodzie może być coś naprawdę, naprawdę głupiego, w takim przypadku proszę dać mi znać. Używanie oddzielnych komórek początkowych/końcowych zamiast tylko "A1: T1" jest celowe - łatwiej to zauważyć to naprawdę zakres 20 komórek. Cokolwiek innego jest prawdopodobnie przypadkowe.)

Więc, czy powinienem użyć _Worksheet lub Worksheet i dlaczego?

+5

Jon, oprócz doskonałych odpowiedzi podane są tutaj, Dodałbym, że generalnie, podczas pracy z Excelem poprzez interop, użyj nazwy klasy tak, jak zwykle pojawia się w Excelu. Oznacza to użycie "Arkusza roboczego" zamiast "_Worksheet" i użycie "Aplikacja" zamiast "ApplicationClass". (Omówiona tutaj dyskusja wyjaśnia, dlaczego nie należy używać "ApplicationClass": http://blogs.msdn.com/ptorr/archive/2004/02/05/67872.aspx.) Jeśli nie znasz modelu obiektów programu Excel jako narażone na COM, to może być trudniejsze, ale myślę, że powinno to być dość jasne przez większość czasu. –

+0

Na szczęście robię * bardzo * mało z Office - naprawdę tylko próbuję pokazać nowe funkcje. Bardzo dziękuję za link - bardzo pomocny! –

+0

Przykro mi, ale muszę zapytać - Jaka jest nowa funkcja C# 4, którą podkreślasz? – Oskar

Odpowiedz

72

Jeśli dobrze pamiętam - a moje wspomnienia na ten temat są nieco niewyraźne, minęło dużo czasu, odkąd wybrałem Excel PIA - tak to wygląda.

Zdarzenie jest zasadniczo metodą wywoływaną przez obiekt, gdy coś się dzieje. W .NET zdarzenia są delegatami, proste i proste. Jednak w COM bardzo często organizuje się cały szereg wywołań zdarzeń w interfejsy. Masz zatem dwa interfejsy na danym obiekcie - interfejs "przychodzący", metody, których oczekują od Ciebie inne osoby, oraz interfejs "wychodzący", metody, które możesz wywoływać u innych osób, gdy zdarzają się zdarzenia.

W niezarządzanych metadanych - w bibliotece typów - dla obiektu, który można utworzyć, znajdują się definicje trzech rzeczy: interfejsu przychodzącego, interfejsu wychodzącego i kokosowego, który mówi: "Jestem obiektem do tworzenia, który implementuje to interfejs przychodzący i ten interfejs wychodzący ".

Teraz, gdy biblioteka typów jest automatycznie tłumaczona na metadane, te relacje są, niestety, zachowywane. Byłoby fajniej mieć ręcznie generowane PIA, które sprawiło, że klasy i interfejsy byłyby bardziej zgodne z oczekiwaniami w zarządzanym świecie, ale niestety tak się nie stało. Dlatego Office PIA jest pełen tych pozornie dziwnych duplikacji, gdzie każdy możliwy do utworzenia obiekt wydaje się mieć dwa interfejsy z nim powiązane, z tymi samymi elementami na nich. Jeden z interfejsów reprezentuje interfejs do coclass, a jeden z nich reprezentuje interfejs przychodzący do tej coclass.

Interfejs _Workbook jest interfejsem przychodzącym w skoroszycie skoroszytu. Interfejs skoroszytu jest interfejsem reprezentującym samą coclass i dlatego dziedziczy z _Workbook.

Krótko mówiąc, używałbym Skoroszytu, jeśli możesz to zrobić wygodnie; _Workbook to trochę szczegółów implementacji.

+0

To arkusz roboczy/_Worksheet, o którym tutaj mowa .. Zrobiłeś to samo błędne odczytanie co JP, ale jak sam podkreśla, sytuacja jest w zasadzie równoważna. ;) – Noldorin

7

W ciągu ostatnich kilku lat widziałem i napisałem całkiem sporo kodu C#/Excel COM Interop i widziałem, że arkusz roboczy był używany niemal w każdym przypadku. Nigdy nie widziałem niczego ostatecznego od Microsoft na ten temat.

+0

Dzięki. Ciekawe, czy nadążasz za poprawkami w C# 4? Brzmią tak, jakby miały duże znaczenie dla interopcji Office, ale bez doświadczenia po prostu zgaduję (aka blefowanie, jeśli chodzi o pisanie książki ...) –

+0

Ulepszenia dynamiki/COM Interop wyglądają na przydatne, gdy trzeba korzystać z COM, ale jestem prawie pewien, że nie użyję funkcji dynamicznej w dużo większym stopniu. Rzeczy, których naprawdę nie mogę się doczekać, to C# 4/.NET 4: kontrakty kodowe i biblioteka zadań. –

6

MSDN pokazuje, że interfejs Worksheet po prostu dziedziczy po interfejsach _Worksheet i DocEvents_Event. Wydaje się, że po prostu dostarcza się zdarzeń, które obiekt arkusza może podnieść w dodatku do wszystkiego innego. O ile widzę, Worksheet nie dostarcza żadnych innych członków. Więc tak, równie dobrze możesz korzystać z interfejsu Worksheet we wszystkich przypadkach, ponieważ nic nie tracisz i potencjalnie może potrzebować ujawnionych zdarzeń.

+4

Jon Skeet * zadając * pytanie? Musiałem skorzystać z tej rzadkiej okazji, aby odpowiedzieć! :) – Noldorin

+0

(Poza tym, mógłbym po prostu użyć arkusza roboczego, ponieważ podkreślenie wygląda okropnie brzydko ... Ale poważnie, wydaje się, że nie ma powodu, aby tego nie robić). – Noldorin

24

Jeśli spojrzeć na zespole PIA (Microsoft.Office.Interop.Excel) w Reflector interfejs Workbook ma tę definicję ...

public interface Workbook : _Workbook, WorkbookEvents_Event 

Workbook jest _Workbook ale dodaje wydarzenia. Sama dla Worksheet (przepraszam, po prostu zauważyłem, że nie rozmawiali o 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; 
} 

Powiedziałbym, że to najlepiej użyć Worksheet, ale to jest różnica .

8

Klasy i interfejsy do użytku wewnętrznego Tylko

Unikać bezpośrednio przy użyciu jednej z następujących klas i interfejsów, które są używane wewnętrznie i są zazwyczaj nie stosuje się bezpośrednio.

Klasa/Interfejs: Przykłady

CLASSID Klasa: ApplicationClass (Word lub Excel), WorksheetClass (Excel)

CLASSID Imprezy x _SinkHelper: ApplicationEvents4_SinkHelper (Word), WorkbookEvents_SinkHelper (Excel)

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

classid wydarzenia X: ApplicationEvents4 (Word), AppEvents (Excel)

I CLASSID Zdarzenia x: IApplicationEvents4 (Word), IAppEvents (Excel)

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

edit: (re: formatowanie tej odpowiedzi) nie może prawidłowo sformatować zbiegłym podkreślenia następuje natychmiast przez kursywy.Pokazuje poprawnie w podglądzie ale złamane kiedy pisał

Edit2: Prace jeśli zrobisz sama podkreślenia kursywą który jest koncepcyjnie straszne, ale wygląda tak samo jak przypuszczam

Powiązane problemy