Взаимодействие с Excel: _Worksheet или Worksheet?
В настоящее время я пишу о динамической типизации, и я привожу пример взаимодействия Excel. Я почти не делал взаимодействия с Office раньше, и это видно. В учебнике MSDN Office Interop для C# 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, просто выделяя новые функции C# 4 - но я не хочу делать что-то действительно, очень глупое.
(В приведенном выше коде также может быть что-то очень, очень глупое, в этом случае, пожалуйста, дайте мне знать. Использование отдельных начальных / конечных ячеек вместо просто "A1:T1" является преднамеренным - легче увидеть, что это действительно диапазон из 20 ячеек. Все остальное, вероятно, случайно.)
Итак, я должен использовать _Worksheet
или же Worksheet
, и почему?
5 ответов
Если я правильно помню - и моя память об этом немного размыта, прошло много времени с тех пор, как я разбирал Excel PIA - это так.
Событие - это, по сути, метод, который объект вызывает, когда что-то происходит. В.NET события являются делегатами, простыми и понятными. Но в COM очень часто можно организовать целую кучу обратных вызовов событий в интерфейсах. Таким образом, у вас есть два интерфейса для данного объекта - "входящий" интерфейс, методы, которые вы ожидаете, что другие люди будут вызывать вас, и "исходящий" интерфейс, методы, которые вы ожидаете вызвать у других людей, когда происходят события.
В неуправляемых метаданных - библиотеке типов - для создаваемого объекта есть определения для трех вещей: входящий интерфейс, исходящий интерфейс и кокласс, который говорит: "Я - создаваемый объект, который реализует этот входящий интерфейс и это исходящий интерфейс ".
Теперь, когда библиотека типов автоматически переводится в метаданные, эти отношения, к сожалению, сохраняются. Было бы лучше иметь созданную вручную PIA, которая бы соответствовала классам и интерфейсам в большей степени, чем мы ожидали в управляемом мире, но, к сожалению, этого не произошло. Поэтому Office PIA полон этих, казалось бы, странных дубликатов, где каждый создаваемый объект, кажется, имеет два интерфейса, связанных с ним, с одинаковыми элементами на них. Один из интерфейсов представляет интерфейс к коклассу, а один из них представляет входящий интерфейс к этому коклассу.
Интерфейс _Workbook является входящим интерфейсом в коклассе книги. Интерфейс Workbook - это интерфейс, который представляет сам Coclass и, следовательно, наследуется от _Workbook.
Короче говоря, я бы использовал Workbook, если вы можете сделать это удобно; _Workbook - это немного детали реализации.
Если вы посмотрите на сборку 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
, но это разница.
Классы и интерфейсы только для внутреннего использования
Избегайте прямого использования любого из следующих классов и интерфейсов, которые используются внутри и обычно не используются напрямую.
Класс / Интерфейс: Примеры
classid Class: 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: работает, если вы сделаете подчеркивание курсивом, который концептуально ужасен, но выглядит так же, я полагаю
За последние несколько лет я видел и написал довольно много кода C# / Excel COM Interop, и я видел, что Worksheet используется почти во всех случаях. Я никогда не видел ничего определенного от Microsoft по этому вопросу.
MSDN показывает, что Worksheet
интерфейс просто наследуется от _Worksheet
а также DocEvents_Event
интерфейсы. Казалось бы, можно просто предоставить события, которые объект рабочего листа может вызвать в дополнение ко всему остальному. Насколько я вижу, Worksheet
не предоставляет других своих членов. Так что да, вы могли бы просто пойти с использованием Worksheet
интерфейс во всех случаях, так как вы ничего от него не потеряете, и, возможно, могут потребоваться события, которые он выставляет.