Excel interop: рабочий стол или рабочий лист?

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

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

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 или Office, просто выделив новые возможности С# 4, но я не хочу ничего делать, действительно немой.

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

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

Ответ 1

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

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

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

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

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

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

Ответ 2

Если вы посмотрите на сборку 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, но это различие.

Ответ 3

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

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

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

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

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

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

classid События x: ApplicationEvents4 (Word), AppEvents (Excel)

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

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

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

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

Ответ 4

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

Ответ 5

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