随笔:63 文章:1 评论:38 引用:1
博客园 首页 发新随笔
发新文章 联系 订阅订阅管理

2008年12月1日

原文作者:andreww

原文链接: http://blogs.msdn.com/andreww/archive/2008/07/25/creating-a-pivottable-programmatically.aspx

     我接收到一封客户的邮件,问我如何创建Excel数据透视表应用程序.Excel对象模型提供了一系列的对象和方法创建数据透视表(PivotTable).可以通过很多种方法创建数据透视表,在此用一种最简单的方法创建数据透视表从外部数据库读取数据.下面我们就开始我们例子.

     我用的SQL数据库是AdventureWorks,数据库下载地址.在解决方案里,首先创建一个数据连接字符串获取视图vSalesPersonSalesByFiscalYears所有的销售记录.代码如下:

Code

     下一步,在Excel Workbook中,添加一个数据缓存(PivotCathe)到数据缓存集合.并且设置它的连接字符串和SQL Command属性,代码如下:

Code

     下一步,添加一个PivotTable对象到worksheet对象中,PivoTable对象的创建是基于前面创建的PivotCathe对象.代码如下:

Code

     下一步,设置PivotTable显示格式,数据列表的提纲模式替代默认的2*2单元格模式.代码如下:

Code

     下一步,设置"SalesTerritory"字段为页查询字段,"FullName"为行查询字段,代码如下:

Code

     下一步,为2004年的销售数据添加一个标题,代码如下:

Code

      最后,运行一下应用程序,显示结果如下图:

备注:下载数据库跟据你本地的SQL版本下载.安装好数据库后.创建一个Offce Excel文档级项目.把上面的步骤的代码依次拷到Sheet1.cs代码中的Sheet1_Startup方法下.完成后,运行应用程序可以得到上面的运行结果.

posted @ 2008-12-01 15:07 Cameo 阅读(510) | 评论 (0)编辑

2008年10月29日

      CLR是围绕类型工作的.所以在此有必要介绍一下CLR支持的两种类型值类型和引用类型.值类型的基类是System.ValueType,引用类型的基类是System.Object.  Framework 类库提供的类型中,大部份是引用类型.而程序的开发过程中经常用的是值类型.值类型可以提高运用程序的性能.如果一个运用程序都使用引用类型.那么这个运程的性能应该是很糟糕.运用程序执行时,值类型在线程堆栈上分配,而引用类型在托管堆中分配.下面举个例子说明值类型和引用类型在运用程序执行过程中的区别.

Code

     以上是一个比较简单的例子,是关于教师和校长的一个应用程序,教师类型中,有获取教龄,工作内容,查找等操作。运用程序执行时。运用程序的进程首先加载CLR,初始化托管堆(Mangaged Heap)和线程堆栈(Stread Stack). JIT 编译器将应用程序集的中间语言代码(IL)转换成本地的CPU指令(Native code),与此同时,CLR确保应用程序所有类型的程序集都被加载到应用程序域中,接着CLR查找程序集的元数据,提取信息为每个类型分配数据结构。Teacher和President类型是引用类型,数据结构在托管堆(Managed Heap)中分配,如下图:

     

解释一下这两个类型,引用类型的每一个对象在托管堆上分配都有两个额外的对象:类型对象指针(Type object pointer)和同步块索引(Sync block index),这两个成员是CLR用来管理对象。静态字段(Static fields)充许类型内定义的静态数据。虚线下面表示,每个类型对象都包含一张方法表,这张方法表是用来保存每个方法的入口点。如当某个对象调用该对象的某个方法时。就是通过这张方法表来查找对应的方法。从上图可以看出President类型对象方法表只有一个方法。而Teacher类型对象的方法表有三个方法。

     CLR确定Main()方法所需要的Teacher和President类型对象创建和Main()方法被编译成本地的CPU指令后。应用程序的主线程,开始执行main()方法。Main()方法执行时,CLR自动初始化两个本地变量,引用类型初始化为null,值类型初始化为0(分配在线程堆栈上),也就是执行代码的21和22行。如下图

当代码执行到23行时,构建President对象,这时托管堆中,新创建了一个President对象指向President 类型对象( 注意:President对象和President类型对象是不一样的).如下图:

 

如上图新创建的President对象和其它所有的对象一样也包含类型对象指针(Type object pointer)和同步块索引(Sync block index),与类型对象有所不同的是这里包含实例化字段来存储任何基类的实例.当president对象创建时,CLR自动初始化president对象的类型对象指针(Type object pointer)指向对应的President类型对象.同时CLR也初始化了同步块索引(Sync block index).CLR将new操作(实例化President对象)返回的内存地址保存在变量t中(在线程堆栈上).

     当执行24行代码,调用Teacher对象的Lookup静态方法,CLR先在Teacher类型对象的方法表上查找Lookup的方法入口点,接着执行Lookup方法。 假设通过Lookup()查找数据库,得到的结果是Jon是学校的校长(President).因此,间接的Lookup方法在托管堆上创建了一个新的President对象,初始化了Jon,同时将返回的内存地址保存在变量t中。注意:这时的返回的内存地址复盖掉上行代码返回的内存地址。也就是说,变量t不再指向第一个president对象,实际上,也没有其它就量去引用第一个President对象,CLR垃圾回收器会首先释放President对象的内存空间。如下图

 

当执行25行代码,CLR在Teacher类型对象的方法表中查找到GetYearsTeached方法入口并执行。这里要说明一下CLR查找的顺序是从子类到基类,这里是从President类型对象方法表开始查找,没找到,再从基类Teacher类型对象方法表中查找到。假设GetYearsTeached方法返回Jon的教龄是10,并将返回的结果保存在线程堆栈上的变量year中,如下图

 

当执行26代码,调用Teacher对象的虚方法GetProcessReport,CLR查找并检查该方法实现类型,这个例子是President类型对象.即通过President类型对象的方法表查找并执行GetProcessRepor方法.下图标出了这三个方法的本地CPU代码在实现类中位置

注意:如果Teacher对象的Lookup方法查找出来Jon只是一个教师而不是校长,那么,构建的t实例是teacher对象.则执行t.GetProcessReport是调用Teacher对象的GetProcessReport方法.从以上这些图可以看出Teacher和President类型对象都包含类型对象指针,那么他们的类型对象指针会指向哪里?当CLR开始在进程中执行时,立即创建一个特殊的System.Type类型对象.President和Teacher类型对象都是System.Type类型对像的实例.所以President和Teacher类型对象指针指向System.Type 类型对象.另外再说一下System.Type类型对象是它本身的一个实例.所以System.Type类型对象指针指向它本身.如下图:

posted @ 2008-10-29 23:15 Cameo 阅读(1217) | 评论 (5)编辑

2008年10月21日

使用 Visual Studio Tools for Office 可以创建两种类型的解决方案:文档级自定义项和应用程序级外接程序。它们具有以下配置:

  • 文档级自定义项由附加于 Microsoft Office Word 文档或 Microsoft Office Excel 工作簿的托管代码程序集组成。

  • 应用程序级外接程序由作为 Microsoft Office 应用程序中的外接程序运行的托管代码程序集组成。

 使用Visual Studio Tools for Office 开发的应用程序是基于CLR的托管应用程序,而Office 是基于COM 组件的非托管应用程序.所以在此觉得有必要复习一下托管应用程序在CLR中的执行过程.就举一个最简单的例子吧,代码如下:

Code

下图为执行的流程图

     简单说说执行过程,VS.NET IDE 调用CSC.exe编译器生成EXE程序集.以32位操作系统为例.当执行EXE程序集时,首行创建一个32位的进程,这个进程中的主线程会去调用MSCorEE.dll组件来初始化CLR,MSCorEE.dll位于C:\WINDOWS\system32目录下,用来判断一台机器是否安装.NET Framework.初如化的CLR会去加载EXE程序集,并从函数入口点Main()开始执行程序,CLR为Main方法中调用的Console类型分配一个单独的内部结构,并为每个该类型的每个方法付上地址,以便该方法调用的时候使用,当首次调用WriteLine()方法时,会去调用JIT编译器,JIT编译器从元数据中查找WriteLine方法,把它编译成本地的CPU代码.并修改存储在Console类型中WriteLine的指针,这样子第二次开始调用WriteLine方法可直接执行本地的CPU代码.另外对元数据有点补充,元数据有二张表,一张是类型表,如用来核对编译时的参数类型.另一个是成员表.说明该托管模块有哪些成员.托管应用程序的执行过程就介绍到这边,下面介绍一下Office应用程序的执行过程.

     VSTO创建的两种解决方案,不管是文档级自定义项,还是应用程序级外接程序,部署后都是由office文档和程序集(dll文件)两个部份组成.当打开具体托管代码office文档时,VSTO加载程序将启动VSTO 运行库(Runtime),创建应用程序域并将该应用程序域的策略设置为不信任“我的电脑”区域.接着VSTO 运行库初始化公共语言运行库(CLR)到应用程序域中.被初始化的CLR加载与文档对应的托管程序集.托管程序通过主互操作程序集PIA(适配器)来捕获文档中发生的事件.接下去具体谈谈Office文档调用程序集的过程.

     1.文档级自定义项的体系结构

     1).2007 Microsoft Office system 的自定义项体系结构

 

  

    不管是文档级自定义项,还是应用程序级外接程序,都存在着指针,用来保存关链的托管程序集的地址.在Office2007文档提供了_AssemblyLocation 属性,用来存储部署清单.当用户打开属于 2007 Microsoft Office 自定义项的文档时,应用程序从 _AssemblyLocation读取部署清单.接着从部署清单中读取应用程序清单.来查找最新的文档级自定义项程序集.自定项程序集过主互操作程序集PIA与Office COM组件进行通信.

 

      2).Microsoft Office 2003 的自定义项体系结构

 

 

     在Office2003文档级自义定项中,不同的是用运行时存储控件来保存应用程序清单.当用户打开属于 2003 Microsoft Office 自定义项的文档时,应用程序从运行时存储控件中读取应用程序清单.应用程序清单加载可选的部署清单来查找最新的文档级自义定项程序集.自定项程序集过主互操作程序集PIA与Office COM组件进行通信.

     在此有必要说说VSTO Runtime 3.0和VSTO Runtime 2.0加载组件是不同的.在VSTO Runtime 3.0,应用程序首先加载VSTOEE.dll组件,接着加载VSTOLoader.dll组件来初始化公共语言运行库.而在VSTO Runtime 2.0只提供AddinLoader.dll来初始化公共语言运行库.

 

     2.应用程序级外接程序的体系结构

     1).2007 Microsoft Office system 的外接程序体系结构

 

 

     与文档级自定义项程序相比,应用程序外接程序是通过注册来发现应用程序的.当用户打开属于 2007 Microsoft Office 应用程序外接程序文档时.应用程序读取注册表项,接着读取部署清单.从部署清单中读取应用程序清单来查找最新的外接程序程序集.外接程序程序集通过主互操作程序集(PIA)与Office COM组件通信.

     2).Microsoft Office 2003 的外接程序体系结构

 

 

     与Microsoft Office 2007 的外接程序相比.加载外接程序程序集的过程基本上是一样的.有一点不同的是应用程序清单加载可选择的部署清单来查找最新的外接程序程序集,外接程序程序集通过主互操作程序集(PIA)与Office COM组件通信.

posted @ 2008-10-21 18:12 Cameo 阅读(2043) | 评论 (7)编辑

2008年10月7日

 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5
 6namespace TypeCast
 7{
 8    internal class Employee
 9    
10    
11    }

12    internal class Manager : Employee
13    
14    
15    }

16    class Program
17    {
18        static void Main(string[] args)
19        {
20            Manager m = new Manager();
21            Employee e = m as Employee;
22            if (e != null)
23            {
24                Console.WriteLine(e.GetType().ToString());
25            }

26
27            PromoteEmployee(m);
28            //the cast above no fails:Cause Manager is derived from Employee
29
30
31            Object o = new object();
32            Employee e1 = o as Employee;
33            if (e1 != null)
34            {
35                Console.WriteLine(e.GetType().ToString());
36            }

37            //the cast above fails:no exception is thrown,but e1 is set to null
38
39            PromoteEmployee(o);
40            //the cast above fails: exception is thrown
41        }

42
43        public static void PromoteEmployee(Object o)
44        {
45            Employee e = (Employee)o;
46            Console.WriteLine(e.GetType().ToString());
47        }

48    }

49

注意:用As 类型转换操作不会抛出异常.

posted @ 2008-10-07 10:38 Cameo 阅读(44) | 评论 (0)编辑

2008年9月12日

     Visual Studio Tools for Office,简称VSTO ,是开发基于Office解决方案的一组工具.通过将 Microsoft Office 2003 或 2007 Microsoft Office system 用作解决方案的前端,您可以利用熟悉的 Microsoft Office 用户界面和内置工具,例如拼写检查、修订和电子邮件支持。Microsoft Office 解决方案的另一个好处是脱机使用解决方案的客户端部分,与使用基于 Web 的体系结构相比,这样更有可能实现复杂的解决方案。

     Visual Studio Tools for Office 包含用于文档级自定义项和应用程序级外接程序的项目模板。要决定最适合您的解决方案的项目类型,请考虑您希望代码是仅当特定文档打开时运行,还是只要 Microsoft Office 应用程序运行就可用。

     文档级自定义项包括一个程序集,该程序集与 Microsoft Office Word 2003 或 Microsoft Office Excel 2003 中的一个文档、工作簿或模板关联。该程序集在关联的文档打开时加载。您创建的自定义项中的功能仅在关联的文档打开时可用。自定义项不能进行应用程序范围的更改,例如当任何文档打开时都显示一个新菜单项。

     应用程序级外接程序包含一个与某个 Microsoft Office 应用程序关联的程序集。通常,该外接程序在关联的应用程序启动时运行,当然,用户也可以在关联应用程序已在运行时加载外接程序。您创建的外接程序中的功能可用于应用程序本身,而与所打开的文档无关。

       请有兴趣的朋友在这里留下您的帐号,我们一起来学习和研究VSTO

posted @ 2008-09-12 13:49 Cameo 阅读(287) | 评论 (12)编辑

2008年8月1日

     摘要: 耦合与变化耦合是软件不能抵御变化灾难的根本性原因。不仅实体对象与实体对象之间存在耦合关系,实体对象与行为操作之间也存在耦合关系。 动机(Motivation)在软件构建过程中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合——比如需要对行为进行“记录、撤销/重做(undo/redo)、事务... 阅读全文
posted @ 2008-08-01 19:35 Cameo 阅读(76) | 评论 (0)编辑

2008年7月28日

无处不在的Template Method
     如果你只想掌握一种设计模式,那么它就是Template Method!

     变化——是软件设计的永恒主题,如何管理变化带来的复杂性?设计模式的艺术性和复杂度就在于如何分析,并发现系统中的变化点和稳定点,并使用特定的设计方法来应对这种变化。

动机(Motivation)
     在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
     如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?

意图(Intent)
     定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
                                                                                                                                                      ——《设计模式》GoF

结构(Structure)

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Template_method
{
    
//框架开发者-先开发

    
public abstract class Vehical //表示汽车
    {
        
protected abstract void startup();//业界的共识 虚方法前加protected
        protected abstract void run();
        
protected abstract void turn(int degree);
        
protected abstract void stop();
        
public void Test()  //非虚方法前加public
        {
            
// 测试数据记录
            startup();//晚绑定-留给应用程序开发人员;扩展点

            
// 测试数据记录
            run();//晚绑定-留给应用程序开发人员;扩展点

            
// 测试数据记录
            turn(40);//晚绑定-留给应用程序开发人员;扩展点

            
// 测试数据记录
            stop();//晚绑定-留给应用程序开发人员;扩展点

            
//生成测试报表
        }

    
    }



    
//应用程序开发-晚开发

    
public class HongqiCar : Vehical
    
{
        
protected override void startup()
        
{
            Console.WriteLine(
"startup");
        }


        
protected override void run()
        
{
            Console.WriteLine(
"run");
        }

        
protected override void turn(int degree)
        
{
            Console.WriteLine(
"degree");
        }

        
protected override void stop()
        
{
            Console.WriteLine(
"stop");
        }


    }


    
class VehicalTestFramework
    
{
        
public static void DoTest(Vehical vehical)
        
{
            vehical.Test();
        }

    }

    
class Program
    
{
        
static void Main(string[] args)
        
{
            VehicalTestFramework.DoTest(
new HongqiCar());
            Console.ReadLine();
        }

    }

}

 

Template Method模式的几个要点
     • Template Method模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构
     • 除了可以灵活应对子步骤的变化外,“不要调用我,让我来调用你”的反向控制结构是Template Method的典型应用。
     • 在具体实现方面,被Template Method调用的虚方法可以具有实现,也可以没有任何实现(抽象方法、纯虚方法),但一般推荐将它们设置为protected方法。

     模版方法模式实际上是所有模式中最为常见的几个模式之一,而且很多人可能使用过模版方法模式而没有意识到自己已经使用了这个模式。模版方法模式是基于继承的代码复用的基本技术,模版方法模式的结构和用法也是面向对象设计的核心

 

posted @ 2008-07-28 19:17 Cameo 阅读(62) | 评论 (0)编辑

2008年7月25日

直接与间接

     人们对于复杂的软件系统常常有一种处理手法,即增加一层间接层,从而对系统获得一种更为灵活、满足特定需求的解决方案

     

动机(Motivation)
     在面向对象系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问会给使用者、或者系统结构带来很多麻烦。
     如何在不失去透明操作对象的同时来管理/控制这些对象特有的复杂性?增加一层间接层是软件开发中常见的解决方式

意图(Intent)
     为其他对象提供一种代理以控制对这个对象的访问
                                                                 ——《设计模式》GoF
 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Proxy
{

    
Subject

    
RealSubject

    
Proxy

    
Client
}

Proxy模式的几个要点
     • “增加一层间接层”是软件系统中对许多复杂问题的一种常见解决方法。在面向对象系统中,直接使用某些对象会带来很多问题,作为间接层的proxy对象便是解决这一问题的常用手段。
     • 具体proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象做细粒度的控制,如copy-on-write技术,有些可能对组件模块提供抽象代理层,在架构层次对对象做proxy。
     • Proxy并不一定要求保持接口的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的。
posted @ 2008-07-25 11:29 Cameo 阅读(40) | 评论 (0)编辑

2008年7月20日

     摘要: 面向对象的代价面向对象很好地解决了系统抽象性的问题,同时在大多数情况下,也不会损及系统的性能。但是,在某些特殊的应用中下,由于对象的数量太大,采用面向对象会给系统带来难以承受的内存开销(拆箱操作)。比如图形应用中的图元等对象、字处理应用中的字符对象等。 动机(Motivation)采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行时代价——主要指内存需求方面的代价(空... 阅读全文
posted @ 2008-07-20 10:43 Cameo 阅读(35) | 评论 (0)编辑

2008年7月16日

     摘要: 意图(Intent)为子系统中的一组接口提供一个一致的界面,Façade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。——《设计模式》GoF 下列的图形只是我自己对软件产品的了解Facade模式的两层含义:1.简单  2.解藕 [代码]结构(Structure)Facade模式的几个要点• 从客户程序的角度来看, Facade模式不仅简化了整个组件系统的接口,同... 阅读全文
posted @ 2008-07-16 11:08 Cameo 阅读(326) | 评论 (0)编辑
CALENDER
<2009年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

公告

网名:Cameo Chen
位置:中国 上海
MSN:xinxiu_chen@hotmail.com

与我联系

搜索

 

常用链接

留言簿

我管理的小组

我参加的小组

我参与的团队

随笔分类

随笔档案

常用链接

最新评论

阅读排行榜

评论排行榜


Powered By: 博客园
模板提供沪江博客