ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 109528|回复: 123

[分享] Ribbon 开发利器-Ribbon Commander

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2015-7-10 16:05 | 显示全部楼层 |阅读模式
一、引子
曾几何时,Office 2003时,经典的菜单开发,几乎已成定式。VBA中,廖廖数行代码,所见即所得的菜单、按钮和FaceId,尽现眼前。更有甚者,如Word中的自定义菜单,可不用一兵一卒一行代码,即可完成自定义菜单项,一个爽字即可概而括之。
然时代在变迁,Office在发展。自Office 2007以后,Menu已被Ribbon不可逆转的颠覆了。从熟悉Office开发者的角度而言,这是一种痛。我也曾彷徨过,也曾迷茫过,但终究得接受。便将Custom UI Editor和细品RibbonX牢牢收藏,时不时温过而知新。玩过Custom UI的朋友都知道,重命名为"*.zip"文件,解压缩到customUI.xml或者customUI14.xml,修改其中的xml代码,尤其是中文字符串,保存后再添加(覆盖)到zip文件中,还原文件名,使用Custom UI Editor检查xml代码是否有效,反反复复,相当麻烦。如果直接在Custom UI Editor中编辑xml代码而同时又打开了这个xlsm文件时,如果保存了xml代码,晕死,刚才在VBA中所作的更改又没了!
作为专业的VBA程序员,我曾开发过一个项目,Ribbon功能区代码相对比较复杂,CustomUI.xml代码约130行,VBA中的回调代码约为400多行,其间少不了N多的模块级变量,UI如图 1所示:

图 1 UI截图

图 1 UI截图
1 UI截图
在这个CustomUI中,涉及的RibbonX有:Box,dropDown,labelControl,gallery,button,separator,checkBox,comboBox,dialogBoxLauncher,menu,menuSeparator等十数种,在Custom UI Editor中,又没有自动列出成员功能,只能一遍一遍翻着"细品RibbonX",翻多了,也便成了专家了。一把泪水和汗水,和成了我们现在看到的这个UI。至于imgMso,更是众里寻他千百度,以至于后来终于下定决心,开发了一个imageMso.xlam的加载宏以便检索内置图标,因与主题无关,便不展开了。
曾几何时,特别希望,有没有这样一个工具,能像Command一样的类,直接在VBA中调用多好啊!省得来回倒腾,可以少走多少冤枉路啊!
记得哲人说过这样一句话,"上帝关上一扇门,同时也会为你打开一扇窗"。所谓万水千山,峰回路转。偶然的机会,我们等到了本文的主人公:Ribbon Commander。
欲知后事如何,且待下文分解。

评分

9

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-7-10 16:06 | 显示全部楼层
本帖最后由 守柔 于 2015-7-11 10:14 编辑

二、自定义功能区的实例对照
以下代码用于比照Excel 2003中的菜单开发,Excel 2007中自定义功能区的开发以及Ribbon Commander对于自定义功能区的开发。
示例目的:为Excel自定义一个工具栏或者选项卡,创建一组按钮,单击按钮以运行相应的宏。
1 Excel 2003下的自定义菜单
模块名:mdlExample
Option Explicit
Private Sub CustomUI2003()
''''创建自定义按钮
    Dim myBar As Office.CommandBar
    Dim myPopup As Office.CommandBarPopup
    Dim myButton As Office.CommandBarButton
    Dim vntButtonNames(1 To 4, 1 To 2) As Variant
    Dim I As Integer
    vntButtonNames(1, 1) = "Access"
    vntButtonNames(2, 1) = "Outlook"
    vntButtonNames(3, 1) = "PowerPoint"
    vntButtonNames(4, 1) = "Word"
    vntButtonNames(1, 2) = 264
    vntButtonNames(2, 2) = 6225
    vntButtonNames(3, 2) = 267
    vntButtonNames(4, 2) = 42
    Set myBar = Application.CommandBars.Add(Name:="Microsoft", Position:=msoBarTop, Temporary:=True)    ''''创建工具栏
    Set myPopup = myBar.Controls.Add(Type:=msoControlPopup)    ''''创建子菜单
    With myPopup
        .Caption = "Office"
        For I = 1 To 4
            Set myButton = .Controls.Add(Type:=msoControlButton)    ''''创建按钮
            With myButton
                .Caption = vntButtonNames(I, 1)
                .Tag = vntButtonNames(I, 1)
                .FaceId = vntButtonNames(I, 2)
                .Style = msoButtonIconAndCaption
                .OnAction = "mySub"
            End With
        Next
    End With
    myBar.Visible = True    ''''显示工具栏
End Sub
Private Sub mySub()
    Select Case UCase$(Application.CommandBars.ActionControl.Tag)
    Case "ACCESS"
        Application.ActivateMicrosoftApp xlMicrosoftAccess
    Case "OUTLOOK"
        Application.ActivateMicrosoftApp xlMicrosoftMail
    Case "POWERPOINT"
        Application.ActivateMicrosoftApp xlMicrosoftPowerPoint
    Case "WORD"
        Application.ActivateMicrosoftApp xlMicrosoftWord
    End Select
End Sub
Private Sub RemoveMenu()
''''删除自定义工具栏
    On Error Resume Next
    Application.CommandBars("Microsoft").Delete
End Sub
运行结果如图 2所示。

CustomUI 2003

CustomUI 2003

图 2 自定义菜单在Excel 2010中的截图
完成此功能约48行代码。
2 Excel 2007下的自定义功能区
2.1 XML代码
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
  <ribbon>
    <tabs>
      <tab id="tabMicrosoft"  label="Microsoft" >
          <group id="groupOffice" label="Ms Office">
           <gallery id="galOffice"
                                 label="Office"
                                 columns="1"
                                 rows="10"
                                 itemWidth="30"
                                 itemHeight="32"
                                 getItemCount="GetGalleryItemCount"
                                 getItemLabel="GetGalleryItemLabel"
                                 getItemImage="GetGalleryItemImage"
                                
                                 showItemImage="true"
                                 showItemLabel="true"
                                 size="normal" />
          </group>
     </tab>
   </tabs>
  </ribbon>
</customUI>
2.2 VBA中的回调
模块名:mdl2007
Private mvntNames As Variant ''''模块级变量,二维数组,储存按钮名称和图标
Private Sub GetGalleryItemCount(control As IRibbonControl, ByRef returnedVal)
''''Callback for galOffice getItemCount,回调,动态加载列表条目数量
    If IsArray(mvntNames) = False Then LoadItemNames
    returnedVal = UBound(mvntNames)
End Sub
Private Sub GetGalleryItemLabel(control As IRibbonControl, index As Integer, ByRef returnedVal)
''''Callback for galOffice getItemLabel,回调,动态加载列表条目标签
    returnedVal = mvntNames(index + 1, 1) ''''index索引从0开始
End Sub
Private Sub GetGalleryItemImage(control As IRibbonControl, index As Integer, ByRef returnedVal)
''''Callback for galOffice getItemImage,回调,动态加载列表条目图标
    returnedVal = mvntNames(index + 1, 2) ''''index索引从0开始
End Sub
Private Sub mySub(control As IRibbonControl, id As String, index As Integer)
''''Callback for galOffice onAction,回调,单击列表条目时执行的过程
    Select Case UCase$(index)
    Case 0
        Application.ActivateMicrosoftApp xlMicrosoftAccess
    Case 1
        Application.ActivateMicrosoftApp xlMicrosoftMail
    Case 2
        Application.ActivateMicrosoftApp xlMicrosoftPowerPoint
    Case 3
        Application.ActivateMicrosoftApp xlMicrosoftWord
    End Select
End Sub
Private Sub LoadItemNames()
''''动态加载一个二维数组,用于指示加载的按钮名称和图标
    ReDim mvntNames(1 To 4, 1 To 2)
    mvntNames(1, 1) = "Access"
    mvntNames(2, 1) = "Outlook"
    mvntNames(3, 1) = "PowerPoint"
    mvntNames(4, 1) = "Word"
    mvntNames(1, 2) = "MicrosoftAccess"
    mvntNames(2, 2) = "MicrosoftOutlook"
    mvntNames(3, 2) = "MicrosoftPowerPoint"
    mvntNames(4, 2) = IIf(Val(Application.Version) > 12, "MindMapExportWord", "FileSaveAsWordDocx")
End Sub
运行结果如图 3所示。

CustomUI 2007

CustomUI 2007

图 3 自定义功能区在Excel 2010中的截图
完成此功能约需58行代码(XML+VBA)。
3 利用Ribbon Commander库生成自定义功能区
模块名:mdlRC
Option Explicit
''''引用 "IlvdaUK Ribbon Commander V1.1"
Private Sub CustomUIRC()
''''自定义功能区
    Dim myUI As RibbonCommander.rxCustomUI
    Dim myTab As RibbonCommander.rxTab
    Dim myGroup As RibbonCommander.rxGroup
    Dim myGallery As RibbonCommander.rxGallery
    Dim oItem As RibbonCommander.rxItem
    Dim astrNames(1 To 4, 1 To 2) As String
    Dim I As Integer
    astrNames(1, 1) = "Access"
    astrNames(2, 1) = "Outlook"
    astrNames(3, 1) = "PowerPoint"
    astrNames(4, 1) = "Word"
    astrNames(1, 2) = "MicrosoftAccess"
    astrNames(2, 2) = "MicrosoftOutlook"
    astrNames(3, 2) = "MicrosoftPowerPoint"
    astrNames(4, 2) = IIf(Val(Application.Version) > 12, "MindMapExportWord", "FileSaveAsWordDocx")
    Set myUI = RibbonCommander.rxCustomUI.Create("MS", "Example for RC", DispatchScope_global)     ''''创建一个功能区(全局)
    With myUI
        .Clear    ''''清空
        Set myTab = .ribbon.tabs.Add(New rxTab)   ''''创建一个Tab(选项卡)
        myTab.Label = "MS"
        Set myGroup = myTab.groups.Add(New rxGroup)    ''''创建一个Group(组)
        myGroup.Label = "Ms Office"
        Set myGallery = myGroup.galleries.Add(New rxGallery)   ''''创建一个Gallery(库)
        With myGallery
            .Label = "Office.RC"
            .Columns = 1
            .itemWidth = 30
            .itemHeight = 32
            .showImage = rxFalse
            .OnAction = myUI.make_delegate("mySub3")
            For I = 1 To UBound(astrNames, 1)    ''''遍历数组行
                Set oItem = .items.Add(New rxItem)
                oItem.Label = astrNames(I, 1)
                oItem.imageMso = astrNames(I, 2)
            Next
        End With
        .Refresh    ''''刷新功能区
    End With
End Sub
Private Sub mySub3(control As IRibbonControl, id As String, index As Integer)
''''回调,单击列表条目时执行的过程
    Select Case UCase$(index)
    Case 0
        Application.ActivateMicrosoftApp xlMicrosoftAccess
    Case 1
        Application.ActivateMicrosoftApp xlMicrosoftMail
    Case 2
        Application.ActivateMicrosoftApp xlMicrosoftPowerPoint
    Case 3
        Application.ActivateMicrosoftApp xlMicrosoftWord
    End Select
End Sub
Private Sub RemoveCustomUI()
''''删除自定义功能区
    On Error Resume Next
    Dim oUI As RibbonCommander.rxCustomUI
    For Each oUI In rxCustomUI.globalCustomUIs
        If (oUI.contextId = "MS") Then rxCustomUI.globalCustomUIs.Remove oUI
    Next
End Sub
运行结果如图 4所示。

CustomUI RC

CustomUI RC

图 4 自定义功能区在Excel 2010中的截图
完成此功能约需60行代码(XML+VBA)。
从上述几个实例对比,可以看出Ribbon Commander(RC)具有以下优点:
RC创建CustomUI时,完全脱离CustomUI.xml文件,直接在VBA中进行,所见即所得;
RC创建CustomUI的VBA代码写法,与Office 2003时的自定义工具栏极为相似。
另外,通过RC创建的CustomUI,具有大量的属性和方法,可以直接进行动态控制或者访问。

Custom UI Example.zip

26.5 KB, 下载次数: 2591

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-7-10 16:08 | 显示全部楼层
本帖最后由 守柔 于 2015-7-12 06:28 编辑

三、动态创建菜单(Ribbon Commander学习笔记之三)
在CustomUI.xml中,要创建一个动态的菜单,不能直接使用Menu控件,而应该使用dynamicMenu,通过VBA回调反馈给控件XML代码从而实现在运行时创建菜单。反观利用RC组件创建动态菜单时,方法与Office 2003无异。
模块名:mdlRCDynamicMenu
''''引用 "IlvdaUK Ribbon Commander V1.1"
Private Sub RCDynamicMenu()
''''自定义功能区之动态菜单
    Dim myUI As RibbonCommander.rxCustomUI
    Dim myTab As RibbonCommander.rxTab
    Dim myGroup As RibbonCommander.rxGroup
    Dim myMenu As RibbonCommander.rxMenu
    Dim myButton As RibbonCommander.rxButtonRegular
    Dim astrNames(1 To 4, 1 To 2) As String
    Dim I As Integer
    astrNames(1, 1) = "Access"
    astrNames(2, 1) = "Outlook"
    astrNames(3, 1) = "PowerPoint"
    astrNames(4, 1) = "Word"
    astrNames(1, 2) = "MicrosoftAccess"
    astrNames(2, 2) = "MicrosoftOutlook"
    astrNames(3, 2) = "MicrosoftPowerPoint"
    astrNames(4, 2) = IIf(Val(Application.Version) > 12, "MindMapExportWord", "FileSaveAsWordDocx")
    Set myUI = RibbonCommander.rxCustomUI.Create("MS", "Example for RC", DispatchScope_global)     ''''创建一个功能区(全局)
    With myUI
        .Clear    ''''清空
        Set myTab = .ribbon.tabs.Add(New rxTab)   ''''创建一个Tab(选项卡)
        myTab.Label = "MS"
        Set myGroup = myTab.groups.Add(New rxGroup)    ''''创建一个Group(组)
        myGroup.Label = "Ms Office"
        Set myMenu = myGroup.Menus.Add(New rxMenu)    ''''创建一个Menu(菜单)
        With myMenu
            .Label = "Office.RC"
            .Size = rxsLarge
            .itemSize = rxsLarge
            .imageMso = "ShareProjectOnline"
            .menuSeparators.Add(New rxMenuSeparator).Title = "Microsoft Office"    ''''创建一个菜单分隔条
            For I = 1 To UBound(astrNames, 1)    ''''遍历数组行
                Set myButton = .Buttons.Add(New rxButtonRegular)    '''创建一个按钮
                With myButton
                    .Label = astrNames(I, 1)
                    .Tag = .Label
                    .imageMso = astrNames(I, 2)
                    .OnAction = myUI.make_delegate("mySub4")
                End With
            Next
        End With
        .Refresh    ''''刷新功能区
    End With
End Sub
Private Sub mySub4(control As IRibbonControl)
''''回调,单击按钮时执行的过程
    Select Case UCase$(control.Tag)
    Case "ACCESS"
        Application.ActivateMicrosoftApp xlMicrosoftAccess
    Case "OUTLOOK"
        Application.ActivateMicrosoftApp xlMicrosoftMail
    Case "POWERPOINT"
        Application.ActivateMicrosoftApp xlMicrosoftPowerPoint
    Case "WORD"
        Application.ActivateMicrosoftApp xlMicrosoftWord
    End Select
End Sub
Private Sub RemoveCustomUI()
''''删除自定义功能区
    On Error Resume Next
    Dim oUI As RibbonCommander.rxCustomUI
    For Each oUI In rxCustomUI.globalCustomUIs
        If (oUI.contextId = "MS") Then rxCustomUI.globalCustomUIs.Remove oUI
    Next
End Sub
运行后的结果如图 5所示。
CustomMenu.jpg
图 5 RC动态创建菜单

上附件:
Custom UI Example.zip (31.9 KB, 下载次数: 974)

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-7-10 16:09 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 taller 于 2015-7-20 09:47 编辑

四 Ribbon Commander的下载、安装与部署
借助Ribbon Commander框架,Office专业开发人员和普通Excel用户都可以使用自定义的、互动的Ribbon界面来增强Office/Excel可用性。
定制动态直观的功能区的复杂程度大大降低。VBA不再需要使用复杂的XML就可以成功地构建Ribbon。Ribbon菜单还可以使用保存在OpenXML中的自定义图像。
由于RC并非是一款免费插件(非喜勿喷),但它提供了一个月的试用期。感兴趣的坛友可以下载并安装这款软件,从我的实际试用情况来看,除了本身的对象库的使用外,也学习到了很多有益的启发,比如软件的架框处理,软件的界面设计等,这部分的体会,可以在后续的开发实践中进行应用。
1 下载
软件下载地址:http://www.ribboncommander.com/
2 安装
&#61550; 双击“RibbonCommander.msi”或者右击后选择“安装”即可。
&#61550; 仔细阅读许可协议选中复选框,如果您愿意接受安装的话。
&#61550; 点击“经典”推荐安装所有组件或“定制”来选择排除一个或多个可选组件。
&#61550; 点击“安装”(需要管理员权限)。
3 部署
对于部署到客户计算机中时,可以考虑不安装以下加载项,这样可以禁止EXCEL中出现无关项目。
&#61550; Ribbon Commander Framework add-in;
&#61550; Ribbon Commander Framework Add-in (UI)
4 RC Tab
OK了之后,我们可以看到在Excel功能区出现了如图 6所示的RC选项卡。

RC选项卡

RC选项卡

图 6 RC选项卡
通过Add-in Manager(加载宏管理器),RC还为我们提供了游戏类、模板类、引用类、开发类等六大类共18款产品供下载使用。此处重点罗列一下开发类的产品,如图 7所示。

开发工具类产品列表

开发工具类产品列表

图 7 开发工具类产品列表
5 开发工具介绍
各开发工具的功能概述如图 8所示。

开发工具及其功能概述

开发工具及其功能概述

图 8 RC 开发工具及其功能概述
因本文英文水平太次,不作具体翻译了。
5.1 Dynamic Icon Browser
动态图标浏览,内置7849个imageMso,主要用于Ribbonx中的imageMso调用,UI如图 9所示。

Dynamic Icon Browser

Dynamic Icon Browser

图 9 Dynamic Icon Browser选项卡
5.2 Macro Mover
在工作簿间移动VBA工程,UI如图 10所示。

Macro Mover

Macro Mover

图 10 Macro Mover选项卡
5.3 Password Protection Remover Pro
删除密码,UI如图 11所示。

Protection Remover Pro

Protection Remover Pro

图 11 Protection Remover Pro选项卡
5.4 Password Recovery
密码恢复,UI如图 12所示。

Password Recovery

Password Recovery

图 12 Password Recovery选项卡
5.5 Unviewable+ VBA
深度隐藏VBA代码,UI如图 13所示。。

Unviewable+ VBA

Unviewable+ VBA

图 13 Unviewable +选项卡
5.6 VBA RC Toolkit
VBA工具包,UI如图 14所示。

VBA RC Toolkit

VBA RC Toolkit

图 14 VBA RC Toolkit选项卡

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-7-10 16:10 | 显示全部楼层
本帖最后由 守柔 于 2015-7-18 14:44 编辑

至此,Ribbon 开发利器-Ribbon Commander的介绍告一个段落,无论对各位看官是否有所帮助,也算一个功德。不敢独享,将学习文档保存成Word文档,一并上传。并附上Ribbon Commander内置VBA示例文档,供参考。
Ribbon 开发利器.zip (431.22 KB, 下载次数: 3557)
VBA_Ribbon_Samples.rar (17.96 KB, 下载次数: 2392)

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-7-12 06:39 | 显示全部楼层
本帖最后由 守柔 于 2015-7-12 06:41 编辑
liucqa 发表于 2015-7-10 22:46
如果方便的话,能否将那个130行的xml文件发上来,供会员参考。

其实ribbon开发并不难,只是在论坛缺少现 ...


liucqa兄说得很好!
之所以在学习Ribbon Commander,真心觉得这是一款非常好用的软件。从一般VBAer的角度,无非是知道有这么一款软件而已。但作为专业程序员,如果有了好的工具,开发起来就可以更加得心应手,事半而功倍。作为开发者,都有这样的经历,每每要用到一些组件,比如ADO,DAO,RegExp等等,哪怕是Office组件之间的相互调用,也是需要学习的。学多了,自然也成了路,也有了心得。
从我学习这个软件的角度来说,基本没有什么特别的障碍,与Office 2003的自定义菜单思路无异。但话说回来,倘若对Office 2007后的Ribbonx没有深入理解的话,自然也很难谈到正确使用Ribbon Commander.这与普通VBA爱好者,如果对于Office 2003的菜单结构理解不深,则自然也很难开发出较为复杂的自定义菜单是一致的。
多一个思路,可能就会多一片光明。
至于软件需要激活,据我所知,是有试用期的。诚如MS Excel一样,好的东西,收费是正常的,关键看,这个软件对使用者而言,有无必要付出,譬如我而言,我愿意购买正版Office,也愿意付费使用RC,于我工作有益。

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-7-18 07:29 | 显示全部楼层
liucqa 发表于 2015-7-17 10:07
问几个问题
1、如何部署,是不是要给每个用户买一份授权,会不会提高开发成本
2、如果excel升级导致软 ...


liucqa兄的问题问到点子上了。
[1],我也很关心这个情况,就在前几天,我还委托taller版主致信给软件作者,希望能否有这样的方式:
VBA开发人员购买使用正版Ribbon Commander进行相应开发,此处主要指UI;而客户计算机上,只要注册一下相关控件即可(类似于如MSCOMCTL.OCX)。
后来收到回复说,由于RC是基于VSTO开发的,目标计算机上必须具有相关环境后,才能支持控件运行。故基本否定了这种想法。即每个客户端均需要安装RC程序。
但可以考虑购买企业版,以减少成本(这个我不太确定)。
[2],RC具有在线自动升级功能,应该可以及时更新的。
注意:RC产品是年付费方式,而非一次性购买的。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-3-29 02:46 , Processed in 0.088397 second(s), 11 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表