1、工具安装包:UI、打包助手、mso镜像、2003-2016绿色版、VB 6.0企业版、Setup等。 2、项目代码:演示VBA代码、自定义菜单XML、demo.xlsm3。 打包文件:demo.dll、demo.exe
我的探索背景介绍
处理数据的同学在导出时一定要处理Excel或者PPT图表。 处理图表格式是一项相对重复且乏味的任务。
所以我研究Excel插件的出发点是:如何一键美化图表,避免重复工作? 通过Excel宏肯定可以解决,但是如何更优雅地工具化呢?
经过一番探索,最终结果如下:
本文并不是为了展示我的插件,而是为了抽象我的学习过程,总结一些常用的方法。 在我的学习过程中,我在网上查找了很长时间,但没有找到系统的教程,比较碎片化。 这里我尝试填补这个空白,希望对新人有所帮助。
明确需求
1、该功能制作成Excel插件,带有交互式菜单。 2、共享时对VBA代码进行封装和保护。 3.插件易于共享,用户无需思考即可安装。
四个步骤
本文将通过以下四个步骤对上述三个需求提供一些答案。 希望读过本文的同学能够快速上手,DIY一个属于自己的插件。
1.如何制作Excel菜单 2.如何编写VBA代码 3.如何打包VBA代码 4.如何打包EXE安装包
1. 创建Excel菜单
从2007版开始,菜单更换为新菜单,比2003版的经典菜单更加美观。 但其底层实现也发生了很大变化。
2003版本中的自定义菜单可以直接通过VBA添加,但在2007及以上版本中,它们是从xml文件中读取的。
您可以复制项目包的demo.xlsm,将文件扩展名由.xlsm更改为.zip,然后打开压缩包。 如果有自定义菜单,压缩包中有一个文件夹。
里面有一个.xml文件,里面存放了DIY菜单的内容。 因此,创建Excel菜单最关键的是创建xml文件。
制作菜单的三种方法
一般来说,创建菜单有3种方法:
•Excel直接新建一个
文件-选项-自定义功能区-(右下角)新选项卡-重命名并保存。
总结:方法简单,修改对所有Excel文件都生效。 但批量修改和补充子菜单不方便,调用自定义函数也不方便。
•全新压缩包
准备 .xml 文件并将其放置在新创建的文件夹中。 将任意 Excel 文件的 .xlsx 后缀更改为 .zip,解压并将该文件夹添加到主目录中。 进入_rels文件夹,用记事本打开.rels文件,在最后一句前插入以下代码。 最后,重新压缩并将 .zip 修改回 .xlsx 格式。
< Relationship Id="customUIRelID" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml" />
总结:该方法直接编辑xml文件,比方法1直接新建更灵活; 但是,将其集成到Excel文件中的过程比较繁琐。 并且此修改仅对单个文件有效,打开其他Excel文件时不会显示菜单。
•新的菜单编辑工具
使用UI For工具编辑xml文件,检查xml语法的正确性。 最后点击保存,菜单就会在Excel文件中生效。
总结:这种方法简单方便,编辑xml文件的方式灵活。 推荐使用此方法。 不过和方法2新建压缩包一样,该菜单只对当前修改的单个文件有效。 dll封装图文教程第三部分会讲常见的代码块,解决全局作用的问题。
工具介绍
这是工具栏的第四个和第五个按钮:
:验证xml以确保没有语法问题;
:在xml中为每个创建回调函数头。 回调函数有固定的格式。 可以直接将生成的函数头复制到主程序中,并在Sub和End Sub之间插入执行代码。
使用该工具打开一个Excel文件,添加该工具自带的示例菜单来尝试一下效果。
XML 菜单语法
XML()是一种可扩展标记语言,主要用于传输和存储数据,数据内容是结构化的。
为了写这篇文章,我单独准备了一个demo菜单文件,涵盖了最常见的菜单样式,如下:
代码如下所示:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<tab id="customTab" label="Demo插件" visible="true">
<group idMso="GroupMacros"/>
<group id="demo_part1" label="最常用button样式">
<button id="demo_button0" label="功能示范" size="large" imageMso="AutoFormatChange" onAction="run_sub_case1" keytip="dm" screentip="屏幕显示更多提示" supertip="超级丰富的提示,可以输入详细介绍。不过简单考虑都可以省略,参考下面的例子"/>
<button id="demo_button1" label="功能1" size="normal" imageMso="AcceptInvitation" onAction="run_sub_notReady"/>
<button id="demo_button2" label="功能2" size="normal" imageMso="AdpPrimaryKey" onAction="run_sub_notReady" />
<button id="demo_button3" label="功能3" size="normal" imageMso="AnimationGallery" onAction="run_sub_notReady"/>
group>
<group id="demo_part2" label="其他样式">
<gallery id="demo_gallery" label="gallery示范" size="large" imageMso="AppointmentColorDialog" onAction="run_sub_case2" columns="2" rows="2" itemWidth="30" itemHeight="30">
<item id="demo_item1" label="选择1" imageMso="AppointmentColor1"/>
<item id="demo_item2" label="选择2" imageMso="AppointmentColor2"/>
<item id="demo_item3" label="选择3" imageMso="AppointmentColor3"/>
<item id="demo_item4" label="选择4" imageMso="AppointmentColor4"/>
<button id="demo_gallery_button" label="更多..." imageMso="AppointmentColorDialog" onAction="run_sub_notReady"/>
gallery>
<checkBox id="demo_checkBox" label="勾不勾选"/>
<dropDown id="demo_dropdown" label="下拉示范" onAction="run_sub_dropdown">
<item id="dropdown_item1" label="配置0"/>
<item id="dropdown_item2" label="配置1"/>
<item id="dropdown_item3" label="配置2"/>
dropDown>
<editBox id="demo_editBox" label="输入内容"/>
group>
<group id="demo_part3" label=" 关于本工具">
<button id="demo_about" label="关于" imageMso="Info" size="large" onAction="About"/>
group>
tab>
tabs>
ribbon>
customUI>
结合整体结构,我们逐层看看具体含义:
•标签
相应的选项卡。 一个xml文件可以在tabs标签中写入多个tab内容,从而生成多个tab。 一般我们设置一个tab就够了。
•团体
选项卡下的子菜单分组。 我们可以根据功能类型对它们进行分组,并将它们放在不同的组中。 子菜单组下还有子类型,包括:按钮()、下拉列表()、下拉框()等。
•
命令按钮。 单击执行操作是最常用的单位。 参数如下:
< button id="toolAbout" label="关于" size="large" imageMso="Info" onAction="MyAbout" />
id:保证xml文件中的唯一性;
label:向用户显示的按钮名称;
size:可以设置为大或者;
:按钮图标。 Excel有很多内置的图标,它们都有对应的图标(可以理解为图标id)。 只需要填写图标id即可调用。 示例中的信息是一个内置的蓝色感叹号。
那么问题来了:如何知道Excel中内置了哪些图标以及它们的ID是什么?
借助工具:mso image.xlsm,收集Excel内置图标和id之间的映射关系。 打开我提供的项目包中的工具试试。
:打回来。 指定单击后 Excel 需要执行的操作。 这里例子中的函数名称是,这是我自定义的函数,它的作用是在弹窗中显示插件介绍。 回调函数的格式示例如下:
Sub funcName(control As IRibbonControl)
xxxx
End Sub
这里我们重点关注括号里的参数:As,这告诉Excel我的函数只能通过菜单按钮来控制。 不同的菜单模块有不同的回调函数。 可以参考UI回调函数函数来生成格式。
•
选项的下拉列表,图标旁边有一个下拉三角形。 单击它不会执行任何操作,但会展开下拉列表,该列表可以是项目选项或 .
< gallery id="otherTheme" label="其他主题" imageMso="AppointmentColorDialog" size="large" columns="2" rows="4" itemWidth="64" itemHeight="32" >
参数基本相同,只是行列多了一些。 如果是以下全部,那么行和列不会生效。 如果是item,则按照行列参数显示。
•其他
其他类型还有、、等,在demo中简单演示。 如果有兴趣或者想使用更丰富的交互菜单,可以参考微软官方的菜单介绍文档[1],这里不再详细介绍。 使用要点是:准确配合回调函数。
2.VBA主要代码
其实说实话,这个问题太大了。 如果你想深入学习VBA语法,你应该看一本书。 我的VBA学习大概仅限于我需要使用的功能。 本节简单介绍几个例子,以便从未接触过VBA的同学能够快速理解大纲。 当你想要实现一些比较复杂的功能时,就需要付出额外的努力。
一些想法
•简单的VBA知识
网上搜索“X分钟入门VBA”,快速学习基础概念,上手基本操作。
•录制宏
这是一个很棒且有用的功能。 当您想要实现某个功能但不知道Excel操作哪些对象或参数时,录制宏通常会有所帮助。
点击录制宏,然后用鼠标操作想要实现的功能,然后点击录制结束。 选择宏并单击“编辑”以查看录制的 VBA 代码。
•学习别人的代码
充分利用论坛(学习 VBA 的论坛很少,但许多最好的帖子都是几年前的)。 上面收集了很多优秀的帖子和作品。 你可以搜索你想要实现的功能,学习前人的代码。
分享一下我在学习期间搜到的几部作品:
1. 高亮Excel行列[2] 2. 读取本地文件夹目录[3] 3. VBA实现屏幕取色[4]
有兴趣的同学可以看一下这些作品。 我在修补时发现了这个。 在制作最终插件时,我们还参考了作品1的调色板用户界面(作者:); 以及工作3中颜色拾取功能的实现(作者:LEWZ)。 这次真是万分感谢。
演示示例
在项目包中的demo.xlsm中,我准备了几种情况,a)直接弹出窗口; b) 单元格指定输入; c) 单元格交互式填充颜色。 这里有一个简单的解释:
•直接弹出窗口
这个很简单,用函数就可以了
Sub About(control As IRibbonControl)
MsgBox "这是个很厉害的工具 blabla..."
End Sub
•单元格指定输入
有两种类型的单元格引用。 Cells(1,1):指单元格A1,相当于Range(A1)函数; 范围(A2,B3):A2至B3单元格,共4个单元格。
让我们在单元格 A1 中输入官方帐户的名称。 同时我们还修改了字体、粗细,修改了单元格的行数和宽度大小。 具体代码如下:
Sub run_sub_case1(control As IRibbonControl)
With Cells(1, 1) 'Range("A1") 等效,都是第一个单元格
.Value = "零一数据笔记"
.Font.Name = "Arial"
.Font.Size = 12
.Font.Bold = True
.ColumnWidth = 22
.RowHeight = 100
.HorizontalAlignment = xlCenter '设置居中对齐
End With
End Sub
•单元格交互填充颜色
填充颜色由..Color参数修改,颜色由RGB(255, 255, 255)指定。 结合这里的菜单,用户可以交互地选择不同的颜色来填充单元格A1。 代码如下所示:
Sub run_sub_case2(control As IRibbonControl, id As String, index As Integer)
cell_color = Array(RGB(255, 144, 128), RGB(128, 152, 224), RGB(160, 216, 96), RGB(224, 224, 208))
Range("A1").Interior.Color = cell_color(index)
End Sub
这里,回调函数中的index参数用于区分用户选择了哪种颜色。 您可以打开项目包中的demo.xlsm,测试菜单的功能。
复杂的函数都是基于这些基本操作,但是VBA最重要的是知道对象有哪些属性,比如案例3中的背景颜色是如何表示的。也许最方便的方法是记录一个宏。
3.封装DLL文件
主功能代码完成后,这一步我们将VBA代码封装成dll文件,主要可以保护代码。 这里使用的工具:VB 6.0企业版。 dll打包过程分为2步:
1.代码修改 2.封装成dll
代码修改
宏代码在Excel中通过了测试,但并不意味着打包成dll就可以直接运行。 由于该dll与Excel宏编辑页面分离,并且引用了Excel对象,因此需要告诉程序这是一个Excel对象,否则生成的dll将无法工作。 例如:
Range("A1") = 1
封装前需要修改:
xlApp.Range("A1") = 1
这里的xlApp其实可以替换成其他字符,但是需要统一,和封装时的声明一致。下面我会提到封装中有一个公共的代码块。 这是一个声明:
Public xlApp As Excel.Application
这是xlApp的声明。 只要确保与主程序代码一致即可。
那么哪些对象需要在前面添加xlapp呢?
这里有一个工具,Excel打包助手。 这是一个Excel插件。 首先将要修改的代码放入.txt文件中,随意打开一个Excel文件,使用开发工具——打包助手,打开.txt文件,然后运行,就会生成一个新的.txt文件。 txt文件,自动修改已经完成,非常方便。
开始包装
封装前,需要提前准备以下文件:
1..xml菜单代码; 2、修改主程序代码; 3.常用代码块(包中提供图文教程,或者直接查看项目包)
由于打包教程相对独立,为了让这篇文章看起来更简洁,我单独放到了另一篇文章中。 点击查看。
4.打包EXE安装包
最后一步也是最简单的一步。
之前,我们已经将VBA代码封装到了dll文件中。 如果此时不封装成EXE,也是可行的。 dll类型的com接口插件在注册表中注册后即可被Excel识别。 直接使用终端命令行安装:
•菜单-附件-命令提示符; •右键--以管理员身份运行; •输入D:\addin.dll
最后记得改成实际dll的文件路径。 打开 Excel,您将看到一个新的插件菜单。 如果觉得上述步骤繁琐,也可以将命令放入txt文件中,将后缀改为.bat,双击运行。
接下来主要介绍如何将dll文件封装成EXE可执行文件,这样大大提高了用户体验。
打包工具: SetUp 9.0
具体图文教程请继续点击红色标题查看。
结论
至此,DIY一个Excel插件的基本流程就结束了。 本文主要帮助大家整理插件制作过程中的一些非核心工作。 您只需要关注插件功能的VBA实现。 借助VBA录制宏,门槛还是比较低的,但是语法比较繁琐。
工具化是一个非常有趣的过程,值得一试。 如果尝试过程中遇到问题,可以在公众号后台留言。 祝大家DIY过程顺利。
[1]菜单介绍文档:
[2] 突出显示 Excel 行和列:
[3]读取本地文件夹目录:
[4]VBA实现屏幕取色: