简体   繁体   English

Excel互操作:_Worksheet还是Worksheet?

[英]Excel interop: _Worksheet or Worksheet?

I'm currently writing about dynamic typing, and I'm giving an example of Excel interop. 我目前正在写有关动态类型的文章,并以Excel互操作为例。 I've hardly done any Office interop before, and it shows. 我以前几乎没有做过Office互操作,它显示了。 The MSDN Office Interop tutorial for C# 4 uses the _Worksheet interface, but there's also a Worksheet interface. C#4的MSDN Office Interop教程使用_Worksheet接口,但也有一个Worksheet接口。 I've no idea what the difference is. 我不知道有什么区别。

In my absurdly simple demo app (shown below) either works fine - but if best practice dictates one or the other, I'd rather use it appropriately. 在我荒唐的简单演示应用程序(如下所示)中,任何一个都可以正常工作-但如果最佳实践决定了一个或另一个,我宁愿适当地使用它。

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

I'm trying to avoid doing a full deep-dive into COM or Office interoperability, just highlighting the new features of C# 4 - but I don't want to do anything really, really dumb. 我试图避免深入探讨COM或Office的互操作性,只是强调C#4的新功能-但我不想做任何真正非常愚蠢的事情。

(There may be something really, really dumb in the code above as well, in which case please let me know. Using separate start/end cells instead of just "A1:T1" is deliberate - it's easier to see that it's genuinely a range of 20 cells. Anything else is probably accidental.) (上面的代码中可能还会有一些非常愚蠢的东西,在这种情况下,请告诉我。故意使用单独的开始/结束单元格而不是仅使用“ A1:T1”-更容易看出它确实是一个范围20个单元格。其他任何事情都可能是偶然的。)

So, should I use _Worksheet or Worksheet , and why? 因此,我应该使用_Worksheet还是Worksheet ,为什么?

If I recall correctly -- and my memory on this is a bit fuzzy, it has been a long time since I took the Excel PIA apart -- it's like this. 如果我没记错-我对此的记忆有点模糊,那么自从我将Excel PIA分开以来已经很长时间了-就是这样。

An event is essentially a method that an object calls when something happens. 事件本质上是某种事件发生时对象调用的方法。 In .NET, events are delegates, plain and simple. 在.NET中,事件是简单且简单的委托。 But in COM, it is very common to organize a whole bunch of event callbacks into interfaces. 但是在COM中,将大量事件回调组织到接口中是很常见的。 You therefore have two interfaces on a given object -- the "incoming" interface, the methods you expect other people to call on you, and the "outgoing" interface, the methods you expect to call on other people when events happen. 因此,您在给定对象上有两个接口-“传入”接口(您希望其他人调用的方法)和“传出”接口(您希望在事件发生时调用其他人的方法)。

In the unmanaged metadata -- the type library -- for a creatable object there are definitions for three things: the incoming interface, the outgoing interface, and the coclass, which says "I'm a creatable object that implements this incoming interface and this outgoing interface". 在非托管元数据(类型库)中,对于可创建对象,有以下三项定义:传入接口,传出接口和coclass,它表示“我是实现此传入接口和该对象的可创建对象。传出接口”。

Now when the type library is automatically translated into metadata, those relationships are, sadly, preserved. 现在,当类型库自动转换为元数据时,很遗憾地保留了这些关系。 It would have been nicer to have a hand-generated PIA that made the classes and interfaces conform more to what we'd expect in the managed world, but sadly, that didn't happen. 拥有一个手工生成的PIA来使类和接口更符合我们在托管环境中的期望会更好,但是遗憾的是那没有发生。 Therefore the Office PIA is full of these seemingly odd duplications, where every creatable object seems to have two interfaces associated with it, with the same stuff on them. 因此,Office PIA充满了这些看似奇怪的重复项,其中每个可创建对象似乎都具有与其关联的两个接口,并且它们上具有相同的内容。 One of the interfaces represents the interface to the coclass, and one of them represents the incoming interface to that coclass. 其中一个接口表示该类的接口,而其中一个表示该类的传入接口。

The _Workbook interface is the incoming interface on the workbook coclass. _Workbook接口是工作簿coclass上的传入接口。 The Workbook interface is the interface which represents the coclass itself, and therefore inherits from _Workbook. Workbook接口是代表coclass本身的接口,因此是从_Workbook继承的。

Long story short, I would use Workbook if you can do so conveniently; 长话短说,如果可以方便的话,我会使用Workbook。 _Workbook is a bit of an implementation detail. _Workbook有点实现细节。

If you look at the PIA assembly (Microsoft.Office.Interop.Excel) in Reflector , the Workbook interface has this definition ... 如果您在Reflector查看PIA程序集(Microsoft.Office.Interop.Excel),则Workbook界面具有此定义...

public interface Workbook : _Workbook, WorkbookEvents_Event

Workbook is _Workbook but adds events. Workbook_Workbook但添加了事件。 Same for Worksheet (sorry, just noticed you were not talking about Workbooks ) ... 同样适用于Worksheet (对不起,只是注意到您没有在谈论Workbooks )...

public interface Worksheet : _Worksheet, DocEvents_Event

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

I would say it's best bet to use Worksheet , but that's the difference. 我会说最好使用Worksheet ,但这就是区别。

Classes and Interfaces for Internal Use Only 仅供内部使用的类和接口

Avoid directly using any of the following classes and interfaces, which are used internally and are typically not used directly. 避免直接使用以下任何类和接口,这些类和接口在内部使用,通常不直接使用。

Class/Interface : Examples 类/接口: 示例

classid Class : ApplicationClass (Word or Excel), WorksheetClass (Excel) classid类别: ApplicationClass(Word或Excel),WorksheetClass(Excel)

classid Events x _SinkHelper : ApplicationEvents4_SinkHelper (Word), WorkbookEvents_SinkHelper (Excel) classid事件x _SinkHelper: ApplicationEvents4_SinkHelper(Word),WorkbookEvents_SinkHelper(Excel)

_classid : _Application (Word or Excel), _Worksheet (Excel) _classid_Application(Word或Excel),_ Worksheet(Excel)

classid Events x : ApplicationEvents4 (Word), AppEvents (Excel) classid事件x: ApplicationEvents4(Word),AppEvents(Excel)

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

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

edit: (re: formatting of this answer) cannot correctly format an escaped underscore followed immediately by italic text. 编辑:(re:此答案的格式)无法正确设置转义的下划线,然后立即加上斜体文本。 Shows correctly in preview but broken when posted 在预览中正确显示,但在发布时损坏

edit2: works if you make the underscore itself italic which is conceptually horrible but looks the same I suppose edit2:如果您将下划线本身设置为斜体,则该方法在概念上是可怕的,但我认为应该与之相同

I have seen and written quite a bit of C# / Excel COM Interop code over the last few years and I've seen Worksheet used in almost every case. 在过去的几年中,我已经看到并编写了很多C#/ Excel COM Interop代码,而且我已经看到了几乎在每种情况下都使用了工作表。 I have never seen anything definitive from Microsoft on the subject. 我从未见过Microsoft对此主题做出任何明确的决定。

MSDN shows that the Worksheet interface simply inherits from the _Worksheet and DocEvents_Event interfaces. MSDN显示, Worksheet接口仅继承自_WorksheetDocEvents_Event接口。 It would seem that one simply provides the events that a worksheet object might raise in additional to everything else. 似乎只是提供了工作表对象可能会引发的其他事件。 As far as I can see, Worksheet doesn't provide any other members of its own. 据我所知, Worksheet未提供其自身的任何其他成员。 So yeah, you might as well just go with using the Worksheet interface in all cases, since you don't lose anything by it, and potentially might need the events it exposes. 是的,您最好还是在所有情况下都使用Worksheet界面,因为它不会丢失任何东西,并且可能需要它公开的事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM