【VSTO】创建 Excel 2007 AddIn (1. CommandBar 以及如何自定义Icon)

之前写过不少VBA来提高工作效率(比如:批量进行设计书格式化等等),但到了Office2007上,VBA就风光不再了,由于安全方面的考虑,VBA需要支持启动宏的Excel(扩展名:xlsm)才能使用。MS推出了VSTO(Visual Studio Tools for Office)来取代VBA,当你熟练掌握VSTO,你会发现它要比VBA开发更快捷——有Office AddIn接口支持,”后台”更强大——可以毫无鸭梨使用.net类库而不是VBA类库,对于Office对象模型来说则没有变化,仍然通过COM对象生成.NET托管对象进行操作,另外还支持 Ribbin 风格的控件。呵呵,是时候更新换代用VSTO取代传统的VBA开发了。

本文将以一个添加CommandBar示例程序介绍VSTO的开发。首先是开发环境的选择:Office 2007 对应的是 Office 2007 PIA Assemblies, VSTO Runtime V3.0 以上。因为 Windows 7 默认安装了 .net 3.5 sp1,所以这里用 VS2010 .net 3.5 开发 VSTO,另外在 .net 3.5 里,C# 仍然没有可选参数可以用(没有可选参数意味着在调用Office COM对象时要写很多System.Reflection.Missing.Value),所以 VB.NET 应该是 .net 3.5 下开发 VSTO 的最佳语言。

【VSTO】创建 Excel 2007 AddIn (1. CommandBar 以及如何自定义Icon)

工程创建成功后,主要的编码都在 ThisAddIn.vb 里。

【VSTO】创建 Excel 2007 AddIn (1. CommandBar 以及如何自定义Icon)

Public Class ThisAddIn Private Sub ThisAddIn_Startup() Handles Me.Startup End Sub Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown End Sub End Class
查看 ThisAddIn.Designer.vb, 你会发现 Excel Application 这个对象(老熟悉老亲切了),它是我们能调用到 Workbook, WorkSheet 的关键。
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "10.0.0.0")> _ Friend WithEvents Application As Microsoft.Office.Interop.Excel.Application
ThisAddIn_Startup 会在 AddIn 被 Excel 加载时被调用,因此利用这个事件加载 CommandBar,然后用 AddHandler 为 CommandButton 添加点击的事件处理。(VBA里是通过 Action 属性绑定方法)
Public Class ThisAddIn Private Sub ThisAddIn_Startup() Handles Me.Startup AddCommandBar() End Sub Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown If mCommandBar IsNot Nothing Then mCommandBar.Delete() End If End Sub Private mCommandBar As Office.CommandBar Private Sub AddCommandBar() Try mCommandBar = Application.CommandBars.Add("VSTOSample", Office.MsoBarPosition.msoBarTop, True, False) If mCommandBar IsNot Nothing Then Dim commandBtn As Office.CommandBarButton = mCommandBar.Controls.Add(Office.MsoControlType.msoControlButton) With commandBtn .Caption = "Command Button" .FaceId = 59 .Style = Microsoft.Office.Core.MsoButtonStyle.msoButtonCaption .Visible = True AddHandler .Click, AddressOf CommandBtn_Click End With mCommandBar.Visible = True End If Catch ex As Exception MsgBox(ex.Message) End Try End Sub Private Sub CommandBtn_Click(control As Office.CommandBarButton, ByRef cancel As Boolean) MsgBox(control.Caption + " Click") End Sub End Class

运行一下:
【VSTO】创建 Excel 2007 AddIn (1. CommandBar 以及如何自定义Icon)
点击左上角的 Excel 图标 > 再选择右下的 "Excel 选项" > 点选 "加载项",可以看到 Excel 通过启动时加载 Excel AddIn 的 .vsto 文件来关联 .net 编译的 AddIn dll:
【VSTO】创建 Excel 2007 AddIn (1. CommandBar 以及如何自定义Icon)

回过头来看看这个CommandButton的图标它使用的是 FaceId 显示的是Excel自带的图标,我们希望换成自定义的图像该怎么做?
自定义图标需要使用 CommandButton.Picture 属性,它需要利用 AxHost.GetIPictureDispFromPicture 方法将 Image 转成 Office 对象可用的stdole.IPictureDisp 对象,但这个方法是 Protected 的,所以这里又做了个类继承与 AxHost,并实现一个静态方法用于转换。
Friend Class CovertImage : Inherits System.Windows.Forms.AxHost Private Sub New() MyBase.New(Nothing) End Sub Public Shared Function Convert(ByVal img As System.Drawing.Image) As stdole.IPictureDisp Return System.Windows.Forms.AxHost.GetIPictureDispFromPicture(img) End Function End Class

往工程的 Resouces 里加入张 Png 图片: Image1。然后在 AddCommandBar 方法的 With 语句块里加上下面的这一句:
.Picture = CovertImage.Convert(My.Resources.Image1)
哦对了,还要把 Style 修改为带Icon的,比如:msoButtonIconAndCaption
With commandBtn .Caption = "Command Button" '.FaceId = 59 .Style = Microsoft.Office.Core.MsoButtonStyle.msoButtonIconAndCaption .Picture = CovertImage.Convert(My.Resources.Image1) .Visible = True AddHandler .Click, AddressOf CommandBtn_Click End With
【VSTO】创建 Excel 2007 AddIn (1. CommandBar 以及如何自定义Icon)这样一个自定义图标就加上去了。