zoukankan      html  css  js  c++  java
  • Excel中Application和ApplicationClass的区别

    Application和ApplicationClass的联系和区别
    Application和ApplicationClass都继承自接口_Application。
    Application为接口。ApplicationClass为类。
    Application和ApplicationClass所拥有的属性、方法基本相同,但是也有一些小的差别。

    比如:ApplicationClass有一个方法:OpenText;而Application却没有这个方法。通过这个方法,可以直接操作Excel去打开用分隔符分割的.txt文件。(注意,是.txt文件而不是.csv文件。)

    namespace Microsoft.Office.Interop.Excel
    {
    [CoClass(typeof(ApplicationClass))]
    [Guid("000208D5-0000-0000-C000-000000000046")]
    public interface Application : _Application, AppEvents_Event
    {
    }
    }
    namespace Microsoft.Office.Interop.Excel
    {
    [ComSourceInterfaces("Microsoft.Office.Interop.Excel.AppEvents")]
    [Guid("00024500-0000-0000-C000-000000000046")]
    [TypeLibType(2)]
    [ClassInterface(0)]
    public class ApplicationClass : _Application, Application, AppEvents_Event
    
    {}
    
    }

    Don't use ApplicationClass (unless you have to)

    http://blogs.msdn.com/b/ptorr/archive/2004/02/05/67872.aspx      

    A comment on Mike Howard's blog exhibits a common problem that I see time and time again: developers are creating instances of Word.ApplicationClass or Excel.ApplicationClass in their projects.

    Even though it's the wrong thing to do, I don't blame them for doing that. I blame IntelliSense.

    First things first: What's the right way to do it? Well, just use Word.Application or Excel.Application (or any other type that follows the same Thinggy / ThinggyClass pattern).

    exhibit  展览品;证据;展示会

    IntelliSense  智能感知

    First things first 先说重要的

    But IntelliSense doesn't show me that as a valid option!

    That's because IntelliSense is not as intelligent as its name might suggest. IntelliSense has a simple rule that says "after the user types the new keyword, show the user a list of new-able things." (Note I may be simplifying things here as I don't work on IntelliSense... but it explains how the system works. Feel free to correct me if you work on that team ;-) ). IntelliSense believes that the only things you can new are concrete, visible classes with one or more visible constructors. And it's almost right.

    intelligent 智能的;聪明的;理解力强的  

    suggest  vt. 提议,建议;启发;使人想起;显示;暗示

    In general, you cannot new an interface because interfaces have no implementation. But the default interfaces on COM CoClasses are a little different;

    the CLR knows something that IntelliSense's parents forgot to teach it.

    Crack open the Excel PIA using ILDASM and have a look at the Application interface. Among the gobbledy-gook, you will see the following:

    gobbledygook  官样文章

    custom instance void [mscorlib]System.Runtime.InteropServices.CoClassAttribute::.ctor(class [mscorlib]System.Type) = ( 01 00 2F 4D 69 63 72 6F 73 6F 66 74 2E 4F 66 66

    69 63 65 2E 49 6E 74 65 72 6F 70 2E 45 78 63 65

    6C 2E 41 70 70 6C 69 63 61 74 69 6F 6E 43 6C 61

    73 73 00 00 ) // ../Microsoft.Office.Interop.Excel.ApplicationClass

     

    This tells the CLR that when someone wants to create an instance of type Application, it should really go ahead and create an instance of ApplicationClass.

    Another tip: In Microsoft Word, you may want to handle the Quit event to do something when the user closes down the application. But the Word.Application interface defines Quit as a method, not an event. What to do?

    Well, you cast it to a Word.ApplicationEvents4_Event (you could find this out by using the Object Browser):

     Word.Application app;

      app = new Word.Application();

      app.Visible = true;

     

      Word.ApplicationEvents4_Event appEvents = app;

      appEvents.Quit += new Word.ApplicationEvents4_QuitEventHandler(QuitHandler);

     

     

    Both of these are due to the way COM works (again I am going to gloss over the details here, so feel free to correct me or point readers to a more accurate, in-depth blog if you have one).

    COM doesn't really have the notion of a 'class' as a first-class (ha ha) object; everything to COM is an interface.

    Now of course in order to get a real live implementation of an interface in your hot little hand, you need to be able to instantiate a concrete implementation of the interface through a function such as CreateObject or CoCreateInstance.

    But these things simply use the ProgID or ClassID to look up the implementation provider in the registry, and from then on you're pretty much dealing with interfaces.

    The COM coclass Application gets turned into the managed class ApplicationClass and a new interface Application is created to represent it and given the custom attribute you see above.

    You should always bind to this interface. I believe this is for versioning reasons, but I can't really remember now (this topic discusses the versioning problem when exposing .NET objects to COM, but we're doing the reverse here).

    The reason you have to have the funky cast to get the Quit event is that COM has no notion of overloads and, indeed, no native notion of events: interfaces can only have methods on them. Instead of having events, a class can expose one or more "source" interfaces which say to clients of the interface "if you implement this interface and then register it with me then I will call the methods on it in an event-like fashion."

    Wherever possible, the CLR will "collapse" the events from the class' source interfaces into the main interface (eg, the Application.WorkbookOpen event in Excel actually comes from the AppEvents_Event interface), but when they have the same name as a method it can't do that so you need to explicitly cast to the original interface.

    Like I said, I missed a lot of detail there (and maybe even told some fibs) so if someone else wants to give a more detailed (and correct!) explanation, please do so.

    But the gist of it all is this: Just as Luke Skywalker puts away the computer targeting system and is told to "use the force" in Star Wars Episode IV, so too should you put away IntelliSense and never use ApplicationClass when programming against Office.

  • 相关阅读:
    Python3 tkinter基础 Radiobutton variable 默认选中的按钮
    oracle函数NVL,NVL2和NULLIF之间的区别和使用
    js如何返回两个数的商的整数和余数部分?
    解决win10打开组策略弹出管理模板对话框问题
    asp.net mvc中动作方法的重定向
    asp.net mvc如何获取url的相关信息
    vs2015如何使用附加进程调试发布在IIS上项目
    未能加载文件或程序集“Oracle.DataAccess”或它的某一个 依赖项。如何解决?
    C#中使用SqlBulkCopy的批量插入和OracleBulkCopy的批量插入
    oracle中计算两个日期的相差天数、月数、年数、小时数、分钟数、秒数等
  • 原文地址:https://www.cnblogs.com/chucklu/p/4046271.html
Copyright © 2011-2022 走看看