2009-06-26 113 views
64

我目前正在写关于动态类型的,我给出了一个Excel互操作的例子。我之前几乎没有做任何Office互操作,并且它显示。 C#4的MSDN Office Interop tutorial接口使用_Worksheet接口,但也有一个接口Worksheet。我不知道有什么区别。Excel互操作:_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

乔恩,除了优秀的答案在这里被赋予,我会补充一点,一般来说,通过interop使用Excel时,请使用类名,因为它通常出现在Excel中。这意味着使用'Worksheet'而不是'_Worksheet',并使用'Application'而不是'ApplicationClass'。 (此处的讨论解释了为什么不使用'ApplicationClass':http://blogs.msdn.com/ptorr/archive/2004/02/05/67872.aspx。)如果您不熟悉Excel对象模型为暴露给COM,那么这可能会更棘手,但我认为大部分时间应该是非常清楚的。 – 2009-06-27 01:00:28

+0

幸运的是,我在Office上做的*很少,实际上只是试图展示这些新功能。非常感谢链接 - 非常有帮助! – 2009-06-27 05:47:10

+0

对不起,但不得不提问 - 您强调的是C#4的新功能是什么? – Oskar 2009-07-09 15:40:49

回答

72

如果我记得正确 - 我对此的记忆有点模糊,自从我将Excel PIA分开以来已经很长时间了 - 就像这样。

事件本质上是一个对象在发生事件时调用的方法。在.NET中,事件是委托,简单明了。但在COM中,将大量事件回调组织到接口中是非常常见的。因此,您在给定对象上有两个接口 - “传入”接口,您希望其他人呼叫您的方法以及“传出”接口,您希望在事件发生时调用其他人的方法。

在非托管元数据 - 类型库中 - 对于可创建对象,有三件事情的定义:传入接口,传出接口和coclass,它说“我是一个可实现此功能的可创建对象传入接口和此传出接口“。

现在,当类型库自动转换为元数据时,可悲的是,这些关系被保留下来。有一个手工生成的PIA会更好,这使得类和接口更符合我们在管理世界中的预期,但可悲的是,这并没有发生。因此Office PIA充满了这些看似奇怪的重复,每个可创建的对象似乎都有两个与之关联的接口,并且上面有相同的东西。其中一个接口表示coclass的接口,其中一个接口表示该coclass的传入接口。

_Workbook接口是工作簿共同体上的传入接口。 Workbook接口是表示coclass本身的接口,因此继承自_Workbook。长话短说,如果您可以方便地使用Workbook,我会使用Workbook; _Workbook是一个实现细节。

7

在过去的几年中,我已经看到和写了相当多的C#/ Excel COM Interop代码,并且我几乎在每种情况下都看到了Worksheet。我从来没有见过微软在这个问题上有任何确定性。

6

MSDN显示Worksheet接口简单地继承了_WorksheetDocEvents_Event接口。似乎只是简单地提供了工作表对象可能引发的其他事件。据我所知,Worksheet不提供任何其他自己的成员。所以是的,你不妨在所有情况下使用接口,因为你不会失去任何东西,并且可能需要它暴露的事件。

24

如果你看一下在Reflector的PIA组件(的Microsoft.Office.Interop.Excel),该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活动X _SinkHelper: ApplicationEvents4_SinkHelper( Word),WorkbookEvents_SinkHelper(Excel)

_classid_Application(Word或Excel),_Worksheet(EXCEL)

的classid活动X:ApplicationEvents4 (字),AppEvents(EXCEL)

的classid事件x: IApplicationEvents4(Word),IAppEvents(Excel)

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

编辑:(RE:这个答案的格式),不能正确格式化转义下划线紧接着斜体文字。在预览显示正确,但贴

EDIT2时折断工作,如果你让下划线本身斜体在概念上是可怕的,但看起来是一样的,我想