2009-06-26 8 views
64

В настоящее время я пишу о динамической типизации, и я приведу пример взаимодействия Excel. Раньше я почти ничего не делал в офисе, и это видно. MSDN Office Interop tutorial для C# 4 использует интерфейс _Worksheet, но есть также интерфейс Worksheet. Я понятия не имею, в чем разница.Excel interop: рабочий стол или рабочий лист?

В моем абсурдно простом демонстрационном приложении (показано ниже) работает нормально - но если лучшая практика диктует то или иное, я бы предпочел использовать его надлежащим образом.

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

Я пытаюсь не делать полное глубокое погружение в COM или офис взаимодействие, просто выделяя новые возможности C# 4 - но я не хочу, чтобы сделать что-нибудь на самом деле, действительно немое.

(Возможно, в приведенном выше коде может быть что-то действительно, действительно глупое, и в этом случае, пожалуйста, дайте мне знать. Использование отдельных стартовых/конечных ячеек вместо «A1: T1» является преднамеренным - легче видеть, что это действительно диапазон из 20 ячеек. Все остальное, вероятно, случайное.)

Итак, следует ли использовать _Worksheet или Worksheet и почему?

+5

Джон, в дополнение к отличным ответам уделяется здесь, Я бы добавил, что, вообще говоря, при работе с Excel через interop, используйте имя класса, как обычно появляется в Excel. Это означает использование «Worksheet» вместо «_Worksheet» и использование «Application» вместо «ApplicationClass». (Здесь обсуждается, почему нельзя использовать «ApplicationClass»: http://blogs.msdn.com/ptorr/archive/2004/02/05/67872.aspx.) Если вы не знакомы с объектной моделью Excel как подвергается воздействию COM, тогда это может быть сложнее, но я думаю, что это должно быть довольно ясно большую часть времени. –

+0

К счастью, я делаю * очень мало с Office - на самом деле просто пытается показать новые функции. Большое спасибо за ссылку, хотя - очень полезно! –

+0

Прошу прощения, но мне нужно спросить - Какая новая особенность C# 4, которую вы выделяете? – Oskar

ответ

72

Если я правильно помню - и моя память на этом немного нечеткая, прошло много времени с тех пор, как я разделил Excel PIA - это так.

Событие по существу является методом, который объект вызывает, когда что-то происходит. В .NET события - это делегаты, простые и простые. Но в COM очень часто организовывается целая куча обратных вызовов событий в интерфейсы. Таким образом, у вас есть два интерфейса для данного объекта - «входящий» интерфейс, методы, которые вы ожидаете от других людей, и «исходящий» интерфейс - методы, которые вы ожидаете вызвать у других людей, когда происходят события.

В неуправляемых метаданных - библиотеке типов - для создаваемого объекта существуют определения для трех вещей: входящий интерфейс, исходящий интерфейс и класс, в котором говорится: «Я являюсь творческим объектом, который реализует это входящий интерфейс и этот исходящий интерфейс ».

Теперь, когда библиотека типов автоматически преобразуется в метаданные, эти отношения, к сожалению, сохраняются. Было бы лучше иметь ручную PIA, которая сделала классы и интерфейсы более похожими на то, что мы ожидали бы в управляемом мире, но, к сожалению, этого не произошло. Поэтому Office PIA полна этих, казалось бы, странных дубликатов, где каждый создаваемый объект, похоже, имеет два интерфейса, связанных с ним, с тем же материалом на них. Один из интерфейсов представляет собой интерфейс к классу, и один из них представляет собой входящий интерфейс для этого класса.

Интерфейс _Workbook - это входящий интерфейс на языке книги. Интерфейс рабочей книги - это интерфейс, который представляет собой сам класс, и поэтому наследуется от _Workbook.

Короче говоря, я бы использовал Рабочую книгу, если вы можете сделать это удобно; _Workbook - это немного детализация реализации.

+0

Это рабочий лист/_Раздел, о котором мы говорим здесь. вы делали то же неверное истолкование, что и JP, но, как он указывает, ситуация в основном эквивалентна. ;) – Noldorin

7

Я видел и написал довольно много кода C#/Excel COM Interop за последние несколько лет, и я видел Рабочий лист, используемый практически в каждом случае. Я никогда не видел ничего определенного от Microsoft по этому вопросу.

+0

Спасибо. Из интереса вы не отставали от улучшений в C# 4? Они звучат так, как будто они будут иметь большое значение с точки зрения взаимодействия с Office, но без опыта я действительно просто догадываюсь (иначе блефование, когда дело доходит до написания книги ...) –

+0

Динамические/COM-улучшения Interop выглядите полезными, когда вам нужно использовать COM, но я уверен, что не буду использовать динамическую функцию намного больше. То, что я действительно с нетерпением жду, есть в C# 4/.NET 4 - это кодовые контракты и параллельная библиотека задач. –

6

MSDN показывает, что интерфейс Worksheet просто наследует интерфейсы _Worksheet и DocEvents_Event. Казалось бы, что один просто предоставляет события, которые объект рабочего листа может повысить в дополнение ко всему остальному. Насколько я вижу, Worksheet не предоставляет никаких других своих собственных. Так что да, вы могли бы просто пойти с использованием интерфейса Worksheet во всех случаях, так как вы ничего не теряете от него и потенциально могут нуждаться в событиях, которые он предоставляет.

+4

Jon Skeet * вопрос * вопрос ?? Мне пришлось принять эту редкую оппортунизм, чтобы ответить! :) – Noldorin

+0

(Кроме того, я мог бы просто выбрать Рабочий лист, потому что это подчеркивание выглядит ужасно уродливо там ... Но серьезно, кажется, нет причин не делать этого.) – Noldorin

24

Если посмотреть на сборку PIA (Microsoft.Office.Interop.Excel) в Reflector, интерфейс Workbook имеет это определение ...

public interface Workbook : _Workbook, WorkbookEvents_Event 

Workbook является _Workbook, но добавляет события. То же самое для Worksheet (извините, только заметил, что вы не говорили о 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; 
} 

Я бы сказал, что лучше всего использовать Worksheet, но разница ,

8

Классы и интерфейсы для внутреннего использования Только

Избегайте непосредственно с помощью любого из следующих классов и интерфейсов, , которые используются внутри и являются обычно не используются непосредственно.

Класс/Интерфейс: Примеры

Classid Класс: ApplicationClass (Word или Excel), WorksheetClass (Excel)

Classid События х _SinkHelper: ApplicationEvents4_SinkHelper (Word), WorkbookEvents_SinkHelper (Excel)

_classid: _Application (Word или Excel), _Worksheet (Excel)

ClassID События х: ApplicationEvents4 (Word), AppEvents (Excel)

I Classid События x: IApplicationEvents4 (Word), IAppEvents (Excel)

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

редактировать: (Re: форматирование этого ответа) не может правильно форматировать сбежавший подчеркивание сразу за наклонным текстом.Показывает правильно в режиме предварительного просмотра, но сломан, когда писал

edit2: работает, если вы сделаете сам подчеркивание курсивом, который концептуально ужасно, но выглядит так же, я полагаю,

Смежные вопросы