VBA的密码保护很容易破解,因此,在需要保护代码时,一般都用其它编程工具生成COM加载宏,然后再让Excel加载,这样就没有办法查看到原代码了。Excel吧一向主张都是知识分享,所有的文件都没有进行保护(非本站原创的作品,原作者有保护的除外),但做为一项技术与知识点,这里我们通过创建一个COM加载宏的过程来了解怎么创建COM加载宏。
首先说明一下编程的环境。我使用的是VB6.0企业版与Excel2003,在Winxp中测试通过,操作系统一般影响不大,而编程工具还可以选择其它,不过基本过程类似,但代码就不一样了,而Excel版本如果是2007版的话,下面这个例子生成的工具栏会在加载项菜单中出现。
接下来就开始动手了,创建一个Excel工作表目录的COM加载宏,而Excel加载宏版的Excel各页名,大家可以参见一下http://www.excelba.com/Soft/Html/5.html。
1、创建工程:打开VB6.0,新建一个外接程序,这时程序就创建一个新的工程,这里我们删除新建工程中自己创建的我们这不需要的窗体。然后在工程菜单中的最后一项“XXXX”属性里,把工程的名称修改为:ExcelAllSheets;在工程描述中中加入说明。
2、添加引用:在“工程”菜单中点击“引用”,然后选上“Microsoft Excel 11.0 Object Libray”这个选项,因为我用的是Excel2003版,其它版本的版本号就不是11.0,选择对应的即可。引用后,在代码编写过程中,就可以自动完成对象的属性、方法了。
3、设置设计器属性:在工程资源管理器中双击“Connect(Connect)”,打开设计器设计窗口。在设计器中的外接程序显示名称输入你想要的名称(这里为“ExcelAllSheets”);外接程序描述中输入外接程序的描述;应用程序选择“Microsoft Excel”;应该程序版本取决于你的电脑装了什么版本的Office,这里使用Excel2003,故选“Microsoft Excel 11.0”;初始化加载行为选择“Startup”。
4、连接Excel:添加一个模块“mduMain”,在模块中定义一个全局变量xlApp,代码如下:
Public xlApp As Excel.Application
这样我们就创建了一个Application 对象,用它我们就可以操控Excel了。
5、定义响应按钮事件的类:创建一个类模块,并把它重命名为ButtonEvent,这个名称在后面有用到,然后添加一个响应事件的变量Button,代码如下。
Public WithEvents Button As Office.CommandBarButton
之后就可以创建其响应按钮的事件Button_Click,在这个事件中就可以加入我们的代码:
Private Sub Button_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean) On Error Resume Next Dim AWB As Excel.Workbook Dim ASH As Excel.Worksheet Dim i As Integer Select Case Ctrl.Tag '根据按钮的 Tag 属性决定执行什么动作。 Case "ExcelbaZy" xlApp.ActiveWorkbook.FollowHyperlink "http://www.excelba.com" Case "ExcelAllSheets" If Not (xlApp.ActiveWorkbook Is Nothing) Then xlApp.Application.ScreenUpdating = False Set AWB = xlApp.ActiveWorkbook With AWB If .Worksheets("目录") Is Nothing Then .Worksheets.Add .ActiveSheet.Name = "目录" End If Set ASH = .Worksheets("目录") ASH.Move Before:=.Worksheets(1) End With With ASH .Range("A:B").Clear .Range("B:B").NumberFormatLocal = "@" .Range("A1").Value = "序号" .Range("B1").Value = "名称" .Range("A1:B1").Font.Bold = True .Range("A:A").HorizontalAlignment = xlLeft For i = 2 To AWB.Worksheets.Count .Cells(i, 1).Value = i .Cells(i, 2).Value = AWB.Worksheets(i).Name .Hyperlinks.Add Anchor:=.Cells(i, 2), Address:="", _ SubAddress:="'" & AWB.Worksheets(i).Name & "'!A1", _ TextToDisplay:=AWB.Worksheets(i).Name Next End With xlApp.Application.ScreenUpdating = True Else MsgBox "没有活动工作簿", , "提示" End If End Select End Sub
6、添加ButtonEvent的类集合:为了更好的扩展性,这里用一个集合类“ButtonEventCol”来管理“ButtonEvent”类。添加一个类模块并重命名为“ButtonEventCol”,“ButtonEventCol”类的代码如下:
Private mCol As Collection '集合,用来存放“ButtonEvent”类。 Private Sub Class_Initialize() Set mCol = New Collection '类实例化时实例化集合 End Sub
Private Sub Class_Terminate() Set mCol = Nothing '类销毁时销毁集合 End Sub
Public Sub Add(ByRef Button As Office.CommandBarButton) '添加按钮 Dim objNew As New ButtonEvent '创建“ButtonEvent”类新实例 Set objNew.Button = Button '连接事件 mCol.Add objNew '将类添加到集合中,只要“ButtonEventCol”类生存期未完,所有添加的“ButtonEvent”类就一直生存。 Set objNew = Nothing End Sub
7、定义一个工具栏对象与"ButtonEventCol"类实例:右击设计器“Connect”,点查看代码进入代码编程,册除除了第一行的“Option Explicit”之外的代码的其它代码,然后加入下面的代码:
'定义一个变量用于存放工具栏对象。
Private mMyBar As Office.CommandBar
'定义一个变量用于存放"ButtonEventCol"类实例
Private mButtonEventCol As New ButtonEventCol
8、添加加载时的代码:在“对象框”中选择“AddinInstance”,“过程/事件框”中选择“OnConnection”。创建工具栏与按钮,并把按钮和响应事件的类连接起来:
在Private Sub AddinInstance_OnConnection过程中加入
Private Sub AddinInstance_OnConnection(ByVal Application As Object, ByVal ConnectMode As AddInDesignerObjects.ext_ConnectMode, ByVal AddInInst As Object, custom() As Variant) Dim MyControl As Office.CommandBarButton Set xlApp = Application Set mMyBar = xlApp.CommandBars.Add(Name:="Excel吧工具栏", Position:=msoBarTop, Temporary:=True) mMyBar.Visible = True Set MyControl = mMyBar.Controls.Add(Type:=msoControlButton, Temporary:=True) With MyControl .BeginGroup = False .Caption = "Excel吧主页" .Enabled = True .Visible = True .FaceId = 263 .Style = msoButtonIconAndCaption .Tag = "ExcelbaZy" End With mButtonEventCol.Add MyControl Set MyControl = mMyBar.Controls.Add(Type:=msoControlButton, Temporary:=True) With MyControl .BeginGroup = False .Caption = "创建Excel目录" .Enabled = True .Visible = True .FaceId = 11 .Style = msoButtonIconAndCaption .Tag = "ExcelAllSheets" End With mButtonEventCol.Add MyControl Set MyControl = Nothing End Sub
9、添加卸载后的代码。在AddinInstance_OnDisconnection事件中加入如下代码:
Private Sub AddinInstance_OnDisconnection(ByVal RemoveMode As AddInDesignerObjects.ext_DisconnectMode, custom() As Variant) Set mButtonEventCol = Nothing mMyBar.Delete Set xlApp = Nothing End Sub
10、调试和编译:关闭Excel,设计器代码窗口中的“AddinInstance_OnConnection”事件中,在“Set xlApp = Application”这句代码设置断点。按“F5”运行,然后打开 Excel 。这时,代码执行到“Set xlApp = Application”这里就暂停了。你可以一步一步按“F8”进行跟踪调试,看看加载项的工作方法,找到错误的地方并改正。当调试没什么问题之后,编译就比较简单了,按“文件”菜单?“ExcelAllSheets.DLL”。然后生成就行了。
11、加载与卸载:我们可以利用RegSvr32.exe 来加载与卸载Dll文件,为了方便使用,我们可以把下面的代码另存为Bat文件。
打开“记事本”,输入加载代码:
RegSvr32.exe ExcelAllSheets.DLL
然后另存为,保存类型选“所有文件”,文件名“安装.BAT”,保存到生成的DLL文件目录中。打开“记事本”,输入卸码代码:
RegSvr32.exe ExcelAllSheets.DLL /U
。另存为,保存类型选“所有文件”,文件名“卸载.BAT”,保存到生成的DLL文件目录中。 之后我们就可以运行“安装.BAT”来加载这个COM加载宏,用“卸载.BAT”来卸载。