VSTO 学习笔记(十二)自定义公式与Ribbon
这几天工作中在开发一个Excel插件,包含自定义公式,根据条件从数据库中查询结果。这次我们来做一个简单的测试,达到类似的目的。
即在Excel 2010中添加一个Ribbon,包含4个自定义公式:仅仅是示例公式加减乘除。
最终效果:
1、解决方案包含两个项目:
ExcelAddIn:Excel 插件
ExcelUDF:Excel 自定义公式
2、首先创建一个Excel 2010 Add-in项目:
3、添加一个可视化Ribbon:
4、在Ribbon的设计视图中,设置下RibbonTab的属性:
有个ControlIdType属性,当设置为Custom时,此Ribbon显示为Office中独立的一项;当设置为Office时,此Ribbon作为Add-In中的一项出现。
5、在MyRibbon中添加一个Menu,在其中放置四个按钮:
6、创建一个类库项目:
7、编写加减乘除四个函数和COM注册、反注册函数:
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace ExcelUDF
{
[Guid("E72F44C7-DD4A-4FA2-BC32-4EA9925749DB")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class ExcelUDF
{
public int Add(int a, int b)
{
return a + b;
}
public int Subtract(int a, int b)
{
return a - b;
}
public int Multiply(int a, int b)
{
return a * b;
}
public int Divide(int a, int b)
{
return a / b;
}
#region COM Related
[ComRegisterFunction]
public static void RegisterFunction(Type type)
{
Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type, "Programmable"));
var key = Registry.ClassesRoot.OpenSubKey(GetSubKeyName(type, "InprocServer32"), true);
key.SetValue("", Environment.SystemDirectory + @"\mscoree.dll", RegistryValueKind.String);
}
[ComUnregisterFunction]
public static void UnregisterFunction(Type type)
{
Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type, "Programmable"), false);
}
private static string GetSubKeyName(Type type, string subKeyName)
{
var s = new System.Text.StringBuilder();
s.Append(@"CLSID\{");
s.Append(type.GUID.ToString().ToUpper());
s.Append(@"}\");
s.Append(subKeyName);
return s.ToString();
}
#endregion
}
8、我安装的是Excel x64,需要手动注册自定义公式的程序集,为此在项目属性中的Build Events中写入批处理脚本来自动注册:
%windir%\Microsoft.NET\Framework64\v4.0.30319\regasm /codebase "$(TargetPath)"
这样在每次编译成功后就会自动注册该自定义公式。
9、在生成管理器中配置为 x64:
10、在Ribbon项目中添加调用自定义公式的代码:
namespace ExcelAddIn
{
public partial class RibbonDemo
{
private void RibbonDemo_Load(object sender, RibbonUIEventArgs e)
{
}
private void btnAdd_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.Application.ActiveCell.Formula = "=Add()";
}
private void btnSubtract_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.Application.ActiveCell.Formula = "=Subtract()";
}
private void btnMultiply_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.Application.ActiveCell.Formula = "=Multiply()";
}
private void btnDivide_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.Application.ActiveCell.Formula = "=Divide()";
}
}
11、修改Ribbon项目属性,将 Excel设置为启动的扩展程序:
12、编译、运行,会调用Excel来打开,自动加载我们的插件ExcelAddIn:
13、激活自定义公式:
在【Developer】选项卡中点击【Add-Ins】,再点击【Automation】找到我们编写的自定义公式,【OK】。
14、此时在Excel中就可以使用我们的公式了,EnjoyJ
小结:
本次把自定义Ribbon与自定义公式结合起来使用,具体细节可以参考源代码,在我之前的VSTO 系列文章中也有介绍。
需要注意的是这种方法只适用于Excel 2007、2010,2003不支持,关于Excel 2003的自定义菜单及自定义公式解决方案后面再介绍。
此外,只有Excel 2010 x64需要用批处理脚本来注册自定义公式,Excel 2010 x86不需要,会自动注册。
VSTO 学习笔记(十二)自定义公式与Ribbon的更多相关文章
- VSTO学习笔记(二)Excel对象模型
原文:VSTO学习笔记(二)Excel对象模型 上一次主要学习了VSTO的发展历史及其历代版本的新特性,概述了VSTO对开发人员的帮助和效率提升.从这次开始,将从VSTO 4.0开始,逐一探讨VSTO ...
- python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL
python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...
- Go语言学习笔记十二: 范围(Range)
Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...
- java jvm学习笔记十二(访问控制器的栈校验机制)
欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们 ...
- (C/C++学习笔记) 十二. 指针
十二. 指针 ● 基本概念 位系统下为4字节(8位十六进制数),在64位系统下为8字节(16位十六进制数) 进制表示的, 内存地址不占用内存空间 指针本身是一种数据类型, 它可以指向int, char ...
- Python学习笔记(十二)—Python3中pip包管理工具的安装【转】
本文转载自:https://blog.csdn.net/sinat_14849739/article/details/79101529 版权声明:本文为博主原创文章,未经博主允许不得转载. https ...
- Oracle学习笔记(十二)
十三.存储过程和存储函数1.掌握存储过程(相当于建立一个函数或者方法体,然后通过外部对其调用) 指存储在数据库中供所有程序调用的子程序叫做存储过程或存储函数. 相同点: 完成特定功能的程序 区别: 是 ...
- MYSQL进阶学习笔记十二:MySQL 表分区!(视频序号:进阶_29,30)
知识点十三:MySQL 表的分区(29) 一.什么要采用分区: 分区的定义: 当数据量过大的时候(通常是指百万级或千万级数据的时候),这时候需要将一张表划分几张表存储.一些查询可以得到极大的优化,这主 ...
- ROS学习笔记十二:使用gazebo在ROS中仿真
想要在ROS系统中对我们的机器人进行仿真,需要使用gazebo. gazebo是一种适用于复杂室内多机器人和室外环境的仿真环境.它能够在三维环境中对多个机器人.传感器及物体进行仿真,产生实际传感器反馈 ...
- odoo10学习笔记十二:web controller
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/11189332.html 一:路由 odoo.http.route(route=None, **kw) 装饰器 ...
随机推荐
- B树的实现与源代码二(删除源代码)
int BTreeMaximum( BNode *x ) { if ( x->leaf ) { return x->key[x->size - 1]; } else { return ...
- asp.net2.0安全性(2)--用户个性化设置(1)--转载来自车老师
在Membership表中可以存储一些用户的基本信息,但有的时候,我们需要记录的用户信息远远不止Membership表中提供的这些,如QQ.MSN.家庭住址.联系电话等等.那如何把这些用户信息记录到数 ...
- EasyUI - Tabs 选项卡标签
基本效果: 效果图: html代码: <div id="tab"> <div title="tab1" > <p>tab1& ...
- OO的ALV隐藏工具栏的form
OO的ALV隐藏工具栏: ***展示数据 CALL METHOD gr_alvgrid->set_table_for_first_display EXPORTING is_variant = g ...
- 【ASP.NET Web API教程】2 创建各种Web API
原文 [ASP.NET Web API教程]2 创建各种Web API Chapter 2: Creating Web APIs第2章 创建各种Web API 本文引自:http://www.asp. ...
- KMP poj
题目来自:http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2315188.html KMP算法开始是判断字符串b是否是字符串a的子串,朴素的算法是枚举 ...
- Material Master
02-03 03: 物料主的定义:相同的物料应该是同一个物料号. 在PP放面我们主要关心的是工厂 . 定义公司后在公司下面在定义工厂. spro配置的时候我们可以在.后勤.物料管理.物料.创建: 后勤 ...
- CodeForces 371C Hamburgers
B题又耽误时间了...人太挫了.... C. Hamburgers time limit per test 1 second memory limit per test 256 megabytes i ...
- 解决sqlserver2008 r2 登陆时报错:provider 命名管道提供程序, error40 错误2
错误截图: 这种错误是因为无法启动sqlserver服务,进入命令行,输入 services.msc 进入服务管理,找到sqlserver服务如下图. 在这里启动该服务会报错如下图: 此服务无法启 ...
- 让动态创建的ActiveX控件响应Windows消息
当我们通过 CWnd::CreateControl() 动态创建 ActiveX 控件时, Windows 消息并不会被发送给我 们的由 CWnd 派生得控件类.例如,即使我们为 WM_KIL ...