ExcelServices--开发一个能够应用在Office2007客户端使用的自定义函数

笔者在上一篇介绍了如何开发一个用户自定义函数,由于部署在服务器端。。。在实际需求,通过这种方式使用,有时给我们的工作带来极大不便。用户体验也不是很好。所以我们也可以把自定义的函数所在的类定义为一个COM组件,然后在Excel2007中注册就可以使用了。具体的操作继续拿上篇(Excelservice--用户自定义函数中的DEMO进行改造下就可实现,主要是添加了两个函数,用来注册组件)
项目代码:
  1using System;
  2using System.Collections.Generic;
  3using System.Text;
  4using Microsoft.Office.Excel.Server.Udf;
  5using System.Data;
  6using System.Data.SqlClient;
  7using System.Runtime.InteropServices;
  8using Microsoft.Win32;
  9namespace Getproductsalespercentudf
 10{
 11
 12
 13    [Guid(GetValue.ClsId)]//创建一个GUID
 14    [ProgId(GetValue.ProgId)]//指定该项目的ID
 15    [ClassInterface(ClassInterfaceType.AutoDual)]//指示类生成自动接口,未下面com公开调用。
 16    [ComVisible(true)]//指示类型对com是可见的
 17    [UdfClass]//记住在类的上方进行[UdfClass]声明而且每个类只能有一个,作用就是让excel能够识别该类。
 18    public class GetValue
 19    {
 20
 21        private const string ClsId = "EECA83BE-10F0-4041-8CAE-D8DD59D00ABC";
 22        private const string ProgId = "Getproductsalespercentudf.GetValue";
 23
 24        //注册COM程序时调用该方法
 25        [ComRegisterFunction]
 26        public static void RegistrationMethod(Type type)
 27        {
 28            if (typeof(GetValue) != type)
 29            {
 30                return;
 31            }

 32            //在注册表中创建一个安全性的子项(Programmable意思是在注册表中将该类注册为可编程的)
 33            RegistryKey key = Registry.ClassesRoot.CreateSubKey("CLSID\\{"+ClsId+"}\\Programmable");
 34            key.Close();
 35        }

 36
 37        //注销COM程序集事。调用该方法
 38        [ComUnregisterFunction]
 39        public static void UnregisterationMethod(Type type)
 40        {
 41            if (typeof(GetValue) != type)
 42            {
 43                return;
 44            }

 45            // 删除指定的子项
 46            Registry.ClassesRoot.DeleteSubKey("CLSID\\{" + ClsId + "}\\Programmable");
 47 
 48        }

 49    
 50        [UdfMethod]//获取输入产品的当月销售量
 51        public int getsingleproductnum(string Company, string Productname, string Month)
 52        {
 53
 54            DataTable dt_single = new DataTable();
 55            int productnum = 0;
 56            using (SqlConnection con = new SqlConnection("Data Source=mosingserver;DataBase=ExcelServices;Integrated Security=true;"))
 57            {
 58                con.Open();
 59                string strsql1 = "select Number from Productsales where Company='" + Company + "' and Productname='" + Productname + "' and Month='" + Month + "'";
 60                dt_single = table_resualt(strsql1, con);
 61                productnum = Convert.ToInt32(dt_single.Rows[0]["Number"]);
 62                con.Close();
 63
 64            }

 65            return productnum;
 66        }

 67
 68        [UdfMethod]//获取输入产品的总销售量{ 在每个函数上都声明[UdfMethod],表示该函数可以被excel识别,用户定义函数中可以包含多个[UdfMethod]}
 69        public int getallproductnum(string Company, string Productname, string Month)
 70        {
 71            DataTable dt_total = new DataTable();
 72            int producttotalnum = 0;
 73            using (SqlConnection con = new SqlConnection("Data Source=mosingserver;DataBase=ExcelServices;Integrated Security=true;"))
 74            {
 75                con.Open();
 76                string strsql2 = "select Sum(Number)as Total from Productsales where Productname='" + Productname + "' and Month='" + Month + "'";
 77                dt_total = table_resualt(strsql2, con);
 78                producttotalnum = Convert.ToInt32(dt_total.Rows[0]["Total"]);
 79                con.Close();
 80
 81            }

 82            return producttotalnum;
 83        }

 84
 85
 86
 87        [UdfMethod]//获取当前产品所占销售总量的份额
 88        public string Getsalespercent(string Company, string Productname, string Month)
 89        {
 90            float percent = 0.00F;
 91            string percentresualt = "";
 92            percent = (float)getsingleproductnum(Company, Productname, Month) / getallproductnum(Company, Productname, Month);
 93            percentresualt = (percent * 100).ToString("#0.00"+ "%";//四舍五入
 94            return percentresualt;
 95        }

 96
 97        //返回数据
 98        public DataTable table_resualt(string strsql, SqlConnection con)
 99        {
100            DataTable dt_resualt = new DataTable();
101            SqlDataAdapter sda = new SqlDataAdapter(strsql, con);
102            DataSet ds = new DataSet();
103            sda.Fill(ds);
104            dt_resualt = ds.Tables[0];
105            return dt_resualt;
106
107        }

108      
109    
110    
111    }

112}

113
生成项目,用regasm命令注册所生成的项目组件注册为COM组建。
regasm.exe所在的目录为C:\WEINDOWS\Microsoft.Net\Framwork\v2.050727.
具体的注册COM组件语法为 regasm /codebase  用户定义函数.dll  如下图:


注册成功。在客户端新建一个Excel文件,点击最左上角的功能菜单。选中【加载项】 底下角有个管理,下拉框的值选中为【Excel 加载项】

点击按钮【转到】,在弹出的窗体上选择【自动化】,便可看到项目定义的名称。选中然后确定。

这时,在Excel2007客户端就可以像应用它本身自带的那些函数来应用我们开发的自定义函数咯。
在C2,C4,C6分别输入值 C8直接引用自定义函数公式。当输入值时,就会自动显示结果。。。。

对比输入广州,泉州销售分公司时 结果值分别为:10000和1500.
posted @ 2009-08-29 22:52  萍水相逢  阅读(488)  评论(0编辑  收藏  举报