【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 的最佳语言。
工程创建成功后,主要的编码都在 ThisAddIn.vb 里。
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
运行一下:
点击左上角的 Excel 图标 > 再选择右下的 "Excel 选项" > 点选 "加载项",可以看到 Excel 通过启动时加载 Excel AddIn 的 .vsto 文件来关联 .net 编译的 AddIn dll:
回过头来看看这个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
这样一个自定义图标就加上去了。