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 ...
- 吴恩达《机器学习》学习笔记十二——机器学习系统
吴恩达<机器学习>学习笔记十二--机器学习系统 一.设计机器学习系统的思想 1.快速实现+绘制学习曲线--寻找重点优化的方向 2.误差分析 3.数值估计 二.偏斜类问题(类别不均衡) 三. ...
- OpenCV学习笔记(十二)——图像分割与提取
在图像处理的过程中,经常需要从图像中将前景对象作为目标图像分割或者提取出来.例如,在视频监控中,观测到的是固定背景下的视频内容,而我们对背景本身并无兴趣,感兴趣的是背景中出现的车辆.行人或者其他对象. ...
- Mr.J-- jQuery学习笔记(十九)--自定义动画实现图标特效
之前有写过自定义动画Mr.J-- jQuery学习笔记(十八)--自定义动画 这次实现一个小demo 图标特效 页面渲染 <!DOCTYPE html> <html lang=&qu ...
- ROS学习笔记十二:使用roswtf
ROS学习笔记十二:使用roswtf 在使用ROS过程中,roswtf工具可以为我们提供ROS系统是否正常工作的检查作用. 注意:在进行下列操作之前,请确保roscore没有运行. 检查ROS是否安装 ...
- Python语言入门这一篇就够了-学习笔记(十二万字)
Python语言入门这一篇就够了-学习笔记(十二万字) 友情提示:先关注收藏,再查看,12万字保姆级 Python语言从入门到精通教程. 文章目录 Python语言入门这一篇就够了-学习笔记(十二万字 ...
- Polyworks脚本开发学习笔记(十二)-输出和读取文本文件
Polyworks脚本开发学习笔记(十二)-输出和读取文本文件 Polyworks作为一个测量工具,将测量的数据方便的导出到文本文件则是一项必须的功能.在DATA_FILE这个命令下提供了很多子命令用 ...
- 【现代机器人学】学习笔记十二:轮式移动机器人
目录 轮式机器人类型 全向轮式机器人 建模 单个全向轮是怎么运动的 多个全向轮是如何带动底盘运动的 运动规划和反馈控制 非完整约束轮式移动机器人 建模 独轮车 差速驱动机器人 车型机器人 非完整移动机 ...
- 【theano-windows】学习笔记十二——卷积神经网络
前言 按照进度, 学习theano中的卷积操作 国际惯例, 来一波参考网址 Convolutional Neural Networks (LeNet) 卷积神经网络如何应用在彩色图像上? 卷积小知识 ...
- Vue.js 学习笔记 十二 Vue发起Ajax请求
首先需要导入vue-resource.js,可以自己下载引入,也可以通过Nuget下载,它依赖于Vue.js. 全局使用方式: Vue.http.get(url,[options]).then(suc ...
最新文章
- Laravel Predis Error while reading line from the server.
- vim编辑器----常用命令
- boost::statechart模块实现无效转换测试
- 张正友相机标定Opencv实现以及标定流程标定结果评价图像矫正流程解析(附标定程序和棋盘图)
- LeetCode 2063. 所有子字符串中的元音(数学)
- 基于狄利克雷-多项式分布做文档聚类代码(dirichlet multinomial mixture model)
- 程序员如何解决并发冲突的难题?
- Ubuntu 8.04 Hardy LTS 软件源设置
- 一路风景之川藏线徒步笔记
- spring事务传播机制源码学习笔记
- 在线音乐网站毕业设计
- EagleEye:一种用模型剪枝的快速衡量子网络性能的方法
- spring-advisor-advised
- 能测试手机信号不好的软件,买手机别只看性能!教你测试手机信号好坏
- C语言中task的用法,C++11中std::packaged_task的使用详解
- 微信支付出现故障,程序员的高薪理所当然
- 直播的下个关键词会是“美好”吗?
- 导出PDF里的指定章节(页数)到Word
- Journal of Electronic Imaging 投稿分享
- 操作系统4小时速成:进程管理占考试40%,进程状态,组织,通信,线程拥有调度,进程拥有资源,进程和线程的区别