ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享] 细品RibbonX(1-59) (转)

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-27 19:39 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:UI界面定制
本帖最后由 jiulongpo 于 2012-8-6 21:00 编辑

转自: http://www.excelperfect.com/index.php/2009/12/07/ribbonxstudy44/
细品RibbonX(44):在Office菜单中添加项目


Office菜单就是应用程序窗口左上角的一个小的应用程序按钮,这个按钮被称作Office按钮,包含一些通用的操作或命令,例如打印、保存和发布。定制Office菜单时,其下的命令将影响整个文档,而不是文档的特定部分,例如段落或字体格式。
Office菜单使用下面的XML标记:
  1.         <officeMenu>
  2.             <!--
  3.                 Everything else goes here
  4.             -->
  5.         </officeMenu>
复制代码

下表列出了Office菜单的子元素。

对象用来做什么
control引用通用控件对象,能够表现其它对象例如按钮、拆分按钮、组,等
button引用通过正常的单击就能执行某类操作的按钮控件
checkbox 引用复选框控件
gallery引用库控件
toggleButton引用切换按钮,在True/False值之间切换
menuSeparator引用菜单分隔条项
splitButton引用能够用于容纳其它控件例如按钮控件的拆分按钮
menu引用能够用于容纳其它控件例如按钮控件的菜单控件
dynamicMenu引用动态菜单,能够在运行时接受动态的XML内容

下图为定制Excel中Office菜单的一个示例。在Office菜单中添加了一个拆分按钮My Tools,包含两个组My Toolset1和My Toolset2。

在这个示例中,我们创建了包含菜单(根据特定任务组织的几个按钮)的拆分按钮,XML代码如下:
  1. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  2.   <ribbon startFromScratch="false">
  3.     <officeMenu>
  4.       <splitButton
  5.    id="rxsbtn"
  6.        insertBeforeMso="FilePrintMenu">
  7.        <button
  8.          id="rxbtnSplitMain"
  9.          label="My Tools"
  10.          imageMso="CreateModule"/>
  11.         <menu
  12.           id="rxmnu"
  13.           itemSize="large">
  14.          <menuSeparator
  15.            id="rxsep1"
  16.            title="My Toolset 1"/>
  17.           <button
  18.     id="rxbtnEmailSheet"
  19.     imageMso="FileSendAsAttachment"
  20.     label="E-mail sheet as attachment"
  21.             description="E-mail the active sheet as an attachment"
  22.             onAction="rxshared_click"/>
  23.           <button
  24.     id="rxbtnEmailSupport"
  25.     imageMso="MessageToAttendeesMenu"
  26.     label="E-mail technical support"
  27.             description="E-mail technical support about issues on this application..."
  28.             onAction="rxshared_click"/>
  29.           <button
  30.     id="rxbtnEmailBug"
  31.     imageMso="ResearchPane"
  32.     label="E-mail a bug"
  33.             description="E-mail technical support about bugs found on this application..."
  34.             onAction="rxshared_click"/>
  35.          <menuSeparator
  36.            id="rxsep2"
  37.            title="My Toolset 2"/>
  38.           <button
  39.     id="rxbtnPrintPDF"
  40.     imageMso="FilePrint"
  41.     label="Print to PDF"
  42.             description="Print active sheet to PDF file format"
  43.             onAction="rxshared_click"/>
  44.         </menu>
  45.       </splitButton>
  46.     </officeMenu>
  47.   </ribbon>
  48. </customUI>
复制代码

实际上,菜单控件也可以提供相同的定制而不须像拆分按钮那样的中间步骤,例如上例可以修改如下:
  1. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  2.   <ribbon startFromScratch="false">
  3.     <officeMenu>
  4.         <menu
  5.           id="rxmnu"
  6.           insertBeforeMso="FilePrintMenu"
  7.           label="My Tools"
  8.           imageMso="CreateModule"
  9.           itemSize="large">
  10.          <menuSeparator
  11.            id="rxsep1"
  12.            title="My Toolset 1"/>
  13.           <button
  14.     id="rxbtnEmailSheet"
  15.     imageMso="FileSendAsAttachment"
  16.     label="E-mail sheet as attachment"
  17.             description="E-mail the active sheet as an attachment"
  18.             onAction="rxshared_click"/>
  19.           <button
  20.     id="rxbtnEmailSupport"
  21.     imageMso="MessageToAttendeesMenu"
  22.     label="E-mail technical support"
  23.             description="E-mail technical support about issues on this application..."
  24.             onAction="rxshared_click"/>
  25.           <button
  26.     id="rxbtnEmailBug"
  27.     imageMso="ResearchPane"
  28.     label="E-mail a bug"
  29.             description="E-mail technical support about bugs found on this application..."
  30.             onAction="rxshared_click"/>
  31.          <menuSeparator
  32.            id="rxsep2"
  33.            title="My Toolset 2"/>
  34.           <button
  35.     id="rxbtnPrintPDF"
  36.     imageMso="FilePrint"
  37.     label="Print to PDF"
  38.             description="Print active sheet to PDF file format"
  39.             onAction="rxshared_click"/>
  40.         </menu>
  41.     </officeMenu>
  42.   </ribbon>
  43. </customUI>
复制代码

结果如下图所示:

可以看出,实现的效果并没有太大的差异。如果认真观察,就会发现拆分按钮在箭头和按扭之间有一条分隔线,而菜单则没有。
上面的示例是在Office菜单中添加自已自定义的项目,当然也可以在Office菜单里的内置元素中添加自定义项目或内置项目,此时您需要知道在什么元素中放置项目,下表列出了Office菜单元素。
表:Office菜单元素


元素类型IDMSO应用于
新建按钮FileMenuExcel/Access/Word
打开按钮FileOpenExcel/Word
打开按钮FileOpenDatabaseAccess
保存按钮FileSaveExcel/Word/Access
另存为拆分按钮FileSaveAsMenuExcel/Word
另存为拆分按钮FileSaveAsMenuAccessAccess
打印拆分按钮FilePrintMenuExcel/Word/Access
准备菜单FilePrepareMenuExcel/Word
管理菜单FileManageMenuAccess
发送菜单FileSendMenuExcel/Word
电子邮件按钮FileSendAsAttachmentAccess
发布菜单MenuPublishExcel/Word/Access
关闭按钮FileCloseExcel/Word
关闭数据库按钮FileCloseDatabaseAccess



TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-27 19:45 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 jiulongpo 于 2012-8-6 21:01 编辑

转自: http://www.excelperfect.com/index.php/2009/12/10/ribbonxstudy45/
细品RibbonX(45):在快速访问工具栏(QAT)中添加项目


快速访问工具栏(QAT)是Office 2007新用户界面的一部分,可以使用老的Office工具栏定制方法进行定制。下面,我们主要介绍如何使用XML定制QAT。
概述
QAT可以包含共享控件和特定文档控件,也可以包含整个控件组(内置的和自定义的)以方便地在单一位置存储多个控件。
要定制QAT,必须从头开始设计用户界面,这意味着必须将startFromScratch属性设置为true:
   <ribbon startFromScratch="true">

在处理QAT时,你会注意到有两类图标,一种在其周围有边框而另一种则没有,这种区别表明哪种控件是共享控件,哪种控件是文档控件。
QAT文档控件的XML代码如下:
  1.    <qat>
  2.      <documentControls>
  3.         <control/>
  4.      </documentControls>
  5.    </qat>
复制代码

QAT共享控件的XML代码如下:
  1.     <qat>
  2.         <sharedControls>
  3.             <control/>
  4.         </sharedControls>
  5.     </qat>
复制代码

在QAT中添加自定义和内置命令
快速访问工具栏共享或文档控件的子元素如下表。
表:QAT的子元素

对象用来做什么
control引用可以表现其它对象例如按钮、拆分按钮、组等的普通控件对象
button引用按钮控件
separator引用分隔条控件

如下图所示,在QAT中添加内置控件和自定义按钮。

XML代码如下:
  1.    <qat>
  2.      <documentControls>
  3.   <control
  4.        idMso="Bold"
  5.        screentip="Make it Bold"
  6.        supertip="Click here to make the selected text bold."/>
  7.       <button
  8.        id="rxbtnOpen"
  9.        imageMso="FileOpen"
  10.        screentip="This is Happy"
  11.        supertip="Click here for a happy message"
  12.        onAction="rxbtnOpen_click"/>
  13.      </documentControls>
  14.     </qat>
复制代码

可以使用control对象引用内置的按钮(本例中为加粗按钮),接着使用按钮创建自已的定制按钮(可以使用control对象引用其它控件例如按钮或拆分按钮)。
下面的示例创建一个splitButton控件,然后将其添加到QAT。因为QAT没有splitButton子元素,我们必须在QAT之外创建splitButton,然后将其引用到QAT。可以通过以普通的方式添加splitButton来实现——也就是说,通过将其添加到组中开始:
  1.        <group
  2.         id="rxgrp"
  3.         label="My Custom Group">
  4.         <splitButton
  5.          id="rxsbtn"
  6.          size="large">
  7.          <button
  8.           id="rxbtn2"
  9.           imageMso="HappyFace"
  10.           label="My Happy Split"/>
  11.           <menu
  12.            id="rxmnu">
  13.            <button
  14.             id="rxbtn3"
  15.             label="My Happy Menu"
  16.             imageMso="HappyFace"
  17.             onAction="rxbtn3_click"/>
  18.           </menu>
  19.         </splitButton>
  20.         </group>
复制代码

上面已经有splitButton并带有一个菜单,菜单中包含一个按钮。由于QAT使用现有的控件,因此现在可以在QAT中引用已存在的拆分按钮了,XML代码如下:
  1.    <qat>
  2.      <documentControls>
  3.       <control
  4.        id="rxsbtn"
  5.        imageMso="HappyFace"
  6.        screentip="This is Happy"
  7.        supertip="Click here for a happy message"/>
  8.      </documentControls>
  9.     </qat>
复制代码

结果如下图所示。

在QAT中添加自定义和内置组
必须首先创建组,然后从QAT中引用指定该组的id。可以添加组到选项卡中并使其在选项卡中不可见而在QAT中可见。

如上图所示,My QAT Custom Group属于自定义的“Home”选项卡,然而我们将其可见属性设置为False,使其在选项卡上隐藏而在QAT中可见。XML代码如下:
  1. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  2.    <ribbon startFromScratch="true">
  3.      <tabs>
  4.       <tab
  5.        id="rxtabHome"
  6.        label="Home">
  7.        <group
  8.         idMso="GroupClipboard"/>
  9.        <group
  10.         idMso="GroupFont"/>
  11.        <group
  12.         idMso="GroupAlignmentExcel"/>
  13.        <group
  14.         idMso="GroupNumber"/>
  15.        <group
  16.         idMso="GroupStyles"/>
  17.        <group
  18.         idMso="GroupCells"/>
  19.        <group
  20.         idMso="GroupEditingExcel"/>
  21.    <group
  22.     id="rxgrp"
  23.     label="My QAT Custom Group"
  24.         getVisible="rxshared_getVisible">

  25.     <button
  26.      id="rxbtnHappy"
  27.      label="Mr. Happy Face"
  28.      imageMso="HappyFace"
  29.      size="large"
  30.      onAction="rxshared_click" />
  31.     <button
  32.      id="rxbtnHappy2"
  33.      label="Mr. Happy Face 2"
  34.      imageMso="HappyFace"
  35.      size="large"
  36.      onAction="rxshared_click" />
  37.    </group>

  38.       </tab>
  39.      </tabs>

  40.     <qat>
  41.      <documentControls>
  42.   <control
  43.     idMso="GroupInsertChartsExcel"/>
  44.       <control
  45.         idMso="GroupFunctionLibrary"/>
  46.       <control
  47.         id="rxgrp"
  48.         imageMso="FormatCellsDialog"/>
  49.      </documentControls>
  50.     </qat>

  51.   </ribbon>
  52. </customUI>
复制代码

这里,因为要处理QAT,所以我们从头开始定制用户界面,然后以常规方式设置自定义选项卡和组并在自定义组中添加了两个按钮,将自定义组的getVisible属性设置为False,使其不会在选项卡中显示。最后,在QAT标签中,添加了两个自定义组,然后使用通用的control对象来引用想在QAT中显示的自定义组,同时为组赋予了内置的图像。
注意,有时虽然我们在QAT中定制了组,但打开Excel时不会出现,这是QAT中的一个“小问题”,后文将给出解决方法。
重利用QAT控件
当重利用QAT中的控件时,实际上重利用与之相关的命令,然后作为控件在QAT中添加相同的命令。
重利用的一个主要优势是会对该控件产生全局影响。
下面的XML代码重利用Excel中的两个控件——打开和保存:
  1. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"
  2.     onLoad="rxIRibbonUI_onLoad">
  3.     <commands>
  4.      <command
  5.       idMso="FileSave"
  6.       onAction="rxFileSave_repurpose"/>
  7.      <command
  8.       idMso="FileOpen"
  9.       onAction="rxFileOpen_repurpose"/>
  10.     </commands>

  11.    <ribbon startFromScratch="true">
  12.      <qat>
  13.      <documentControls>
  14.   <control
  15.        idMso="FileSave"
  16.        screentip="Repurposed Save"
  17.        supertip="This is a repurposed command"/>

  18.       <control
  19.        idMso="FileOpen"
  20.        screentip="Repurposed File Open"
  21.        supertip="This is a repurposed command"/>
  22.      </documentControls>
  23.     </qat>
  24.   </ribbon>

  25. </customUI>
复制代码

首先,声明希望重利用的命令并赋宏给每个控件,接着在ribbon标记里定义希望在QAT中出现的命令。
注意,这将产生全局影响,也就是说,如果在该命令出现的任一位置单击该命令或者使用指向该命令的快捷键(这里是Ctrl+o和Ctrl+s),该命令将指向赋值给onAction属性的回调。
在Excel中还可以使用不同的方式。Excel有一个名为OnKey的便捷的方法,当按下指定的键或键组合时触发。这是一个应用程序级的方法,因此一旦在某工作簿中禁用了某命令,所有在相同会话中打开的其它工作簿都将禁用该命令。
因此,在Excel中,如果仅仅需要取消包含UI的工作簿中的快捷键,那么在移动到另一个工作簿中时或者当打开工作簿时需要撤销该快捷键的取消。因为这是一个应用程序级的事件,所以需要使用类模块来监控并响应在工作簿间的转换。
在Excel项目中添加一个类模块并命名,本例中命名为clsAppExcelEvents,输入下面的代码:
  1. Public WithEvents appXL As Excel.Application

  2. Private Sub ShortcutsEnabled(ByVal blnEnabled As Boolean)
  3.     Select Case blnEnabled
  4.         Case Is = True
  5.             Application.OnKey "^o"
  6.             Application.OnKey "^s"
  7.         Case Is = False
  8.             Application.OnKey "^o", "commandDisabled"
  9.             Application.OnKey "^s", "commandDisabled"
  10.     End Select
  11. End Sub

  12. Private Sub setEnabled(ByVal Wb As Workbook)
  13.     Select Case Wb.Name
  14.         Case Is = ThisWorkbook.Name
  15.             ShortcutsEnabled False
  16.         Case Else
  17.             ShortcutsEnabled True
  18.     End Select
  19. End Sub
复制代码

注意,在类模块的声明部分声明Excel应用程序。有两个程序来实现这项任务:一个程序检查哪个工作簿是活动工作簿,另一个程序指定OnKey方法。OnKey方法的键组合字符之后,是程序名commandDisabled,该程序必须放置在标准模块中。
在类模块中,可以指定监控的事件。例如,可以监控某工作簿的激活或失活,决定是否取消快捷键:
  1. Private Sub appXL_WorkbookActivate(ByVal Wb As Workbook)
  2.     setEnabled Wb
  3. End Sub

  4. Private Sub appXL_WorkbookDeactivate(ByVal Wb As Workbook)
  5.     setEnabled Wb
  6. End Sub
复制代码

最后,需要在工程打开时设置类,这由包含该工程的工作簿的Open事件来实现:
  1. Dim XL As New clsAppExcelEvents
  2. Private Sub Workbook_Open()
  3.     Set XL.appXL = Application
  4. End Sub
复制代码


TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-27 19:48 | 显示全部楼层
接 细品RibbonX(45):在快速访问工具栏(QAT)中添加项目

使用表驱动(Table-Driven)方式定制QAT
下图是一个自定义QAT的示例,使用表装载详细信息到QAT中。

首先,编写包含UI和QAT菜单按钮的XML代码,这里创建的是文档控件按钮:
  1.      <documentControls>
  2.   <control
  3.     id="rxgrp"
  4.         imageMso="AdvancedFileProperties"/>
  5.       <button
  6.     id="rxbtnShowPopup"
  7.         image="rob"
  8.     screentip="This is Robert's QAT"
  9.     supertip="You can only customize the QAT by starting from scratch. If you do not do that you will not be able to make any changes..."
  10.     onAction="rxbtnShowPopup_Click"
  11.     />
  12.      </documentControls>
复制代码

上述XML代码将产生上图所示的两个QAT按钮,这里的关键是赋给onAction属性的回调,单击该按钮后将显示菜单。
接着,创建包含菜单信息的表,如下图所示。

上图所示的表只是一个建议,因为您可以在其中添加更多的选项。现在,使用VBA阅读该表并创建菜单:
  1. Public Const POPNAME As String = "MY POPUP"

  2. Sub loadPopup()
  3.     Dim mnuWs           As Worksheet
  4.     Dim cmdbar          As CommandBar
  5.     Dim cmdbarPopup     As CommandBarPopup
  6.     Dim cmdbarBtn       As CommandBarButton
  7.     Dim nRowCount       As Long

  8.     Call unloadPopup
  9.     Set mnuWs = ThisWorkbook.Sheets("MenuItems")
  10.     Set cmdbar = Application.CommandBars.Add(POPNAME, msoBarPopup)

  11.     nRowCount = 2
  12.     With mnuWs
  13.         Do Until IsEmpty(.Cells(nRowCount, 1))

  14.             Select Case UCase(.Cells(nRowCount, 1))
  15.                 Case "POPUP"
  16.                     Set cmdbarPopup = cmdbar.Controls.Add(msoControlPopup)
  17.                         cmdbarPopup.Caption = .Cells(nRowCount, 2)
  18.                         If .Cells(nRowCount, 3) <> "" Then
  19.                             cmdbarPopup.BeginGroup = True
  20.                         End If

  21.                 Case "BUTTON"
  22.                     Set cmdbarBtn = cmdbarPopup.Controls.Add(msoControlButton)
  23.                         cmdbarBtn.Caption = .Cells(nRowCount, 2)
  24.                         If .Cells(nRowCount, 3) <> "" Then
  25.                             cmdbarBtn.BeginGroup = True
  26.                         End If
  27.                         cmdbarBtn.FaceId = .Cells(nRowCount, 4)
  28.                         cmdbarBtn.OnAction = .Cells(nRowCount, 5)

  29.                 Case "BUTTON_STANDALONE"
  30.                     Set cmdbarBtn = cmdbar.Controls.Add(msoControlButton)
  31.                         cmdbarBtn.Caption = .Cells(nRowCount, 2)
  32.                         If .Cells(nRowCount, 3) <> "" Then
  33.                             cmdbarBtn.BeginGroup = True
  34.                         End If
  35.                         cmdbarBtn.FaceId = .Cells(nRowCount, 4)
  36.                         cmdbarBtn.OnAction = .Cells(nRowCount, 5)

  37.             End Select
  38.             nRowCount = nRowCount + 1
  39.         Loop
  40.     End With

  41. End Sub

  42. Sub unloadPopup()
  43.     On Error Resume Next
  44.     Application.CommandBars(POPNAME).Delete
  45. End Sub

  46. Sub showAbout()
  47.     MsgBox "This is a sample on how to customize the QAT on the fly!!", vbInformation
  48. End Sub

  49. Sub showHelp()
  50.     On Error GoTo Err_Handler
  51.     ThisWorkbook.FollowHyperlink "http://www.msofficegurus.com", , True, True
  52.     Exit Sub

  53. Err_Handler:
  54.     MsgBox Err.Description, vbCritical, Err.Number

  55. End Sub
复制代码

最后,需要编写回调的代码。使用onLoad事件调用loadPopup过程,以便创建弹出菜单,并准备当在QAT中单击该按钮时使用,也包含当发生单击时显示弹出菜单的单击事件代码:
  1. Dim grxIRibbonUI        As IRibbonUI

  2. Sub rxIRibbonUI_onLoad(ribbon As IRibbonUI)
  3.     On Error Resume Next
  4.     Set grxIRibbonUI = ribbon

  5.     Application.Workbooks.Add
  6.     If ActiveWorkbook.Name <> ThisWorkbook.Name Then
  7.         With ActiveWorkbook
  8.             .Saved = True
  9.             .Close
  10.         End With
  11.     End If

  12. '   可以在这个事件或者ThisWorkbook的Open事件中装载弹出菜单
  13.     Call loadPopup
  14. End Sub

  15. Sub rxbtnShowPopup_Click(control As IRibbonControl)
  16.     On Error Resume Next
  17.     Application.CommandBars(POPNAME).ShowPopup
  18. End Sub

  19. Sub rxbtnHappy_Click(control As IRibbonControl)
  20.     MsgBox "This is Mr. Happy Face... hurray!!", vbExclamation
  21. End Sub
复制代码

定制QAT时的一些注意事项
虽然在QAT中可以方便地实现自定义,但也有一些缺陷。
(1)无法装载控件
上文中曾经谈到,在定制好后,例如按钮和组,打开工作簿时,却发现定制的控件没有出现。这种情况在使用sharedControls时非常普遍。
一种解决方法是先最小化工作簿,然后再最大化,通过刷新来使定制的控件出现;或者再打开一个工作簿后,将其关闭,看看定制的控件是否出现。
(2)无法为控件装载自定义图像
共享控件的表现通常无法预料,并且不能提供可信赖且一致的界面,因此建议在共享控件中尽量不要使用自定义图像。
至于文档控件,可以使用下面的过程刷新包含UI的窗口来解决此类问题:
  1. Sub rxIRibbonUI_onLoad(ribbon As IRibbonUI)
  2.     Set grxIRibbonUI = ribbon
  3.     On Error Resume Next
  4.     Application.Workbooks.Add
  5.     If ActiveWorkbook.Name <> ThisWorkbook.Name Then
  6.         With ActiveWorkbook
  7.             .Saved = True
  8.             .Close
  9.         End With
  10.     End If
  11. End Sub
复制代码

上述技巧也能用于无法装载自定义控件中。
(3)复制控件
在QAT中控件的复制通常发生在工作簿或文档之间切换时。假设有一个包含定制的QAT的工作簿,当按Alt+Tab移动到另一个文档,然后返回定制的工作簿时,在QAT中的控件被复制、三次复制、四次复制……这种复制能够被传播到没有包含任何XML定制的其它工作簿和文档。
此时,需要关闭后重新打开文档才能消除这种不应有的复制。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-27 19:50 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 jiulongpo 于 2012-8-6 21:01 编辑

转自: http://www.excelperfect.com/index.php/2009/12/11/ribbonxstudy46/
细品RibbonX(46):在Excel 2007的QAT中以表驱动的方式构建自定义菜单



一、创建在所有工作簿中都能使用的自定义菜单
如果想在所有工作簿中都可以使用自已喜欢的宏,那么可以将这些宏复制到Personal.xlsb工作簿中,或者在XLStart文件夹中使用另一个隐藏的xlsb工作簿(在Excel启动时会打开该文件夹中的每一个文件),也可以创建加载项。
XLSTART文件夹的位置
C:\Documents and Settings\(username)\Application Data\Microsoft\Excel\XLSTART
如果找不到指定的文件或文件夹,则可能是Windows设置将其隐藏了,此时需要在文件夹选项中启动“显示所有文件和文件夹”选项。
如何在Excel2007中创建菜单
在Excel 97-2003中,在已存在的菜单栏中创建一个新菜单或者创建自定义菜单栏一点也不困难。但是在Excel 2007中,定制功能区并不容易。
1) 在下面的地址中下载文件MyMacroFile.zip:
http://www.rondebruin.nl/files/My%20Add-in.zip
2) 解压并复制该文件到XLSTART文件夹中,然后打开Excel(不能看到该文件,因为它是隐藏的)。
3) 在快速访问工具栏(QAT)中单击鼠标右键,选择“自定义快速访问工具栏”。
在“从下列位置选择命令”下拉框中选择“宏”,然后在“自定义快速访问工具栏”下拉框中选择“用于所有文档(默认)”。
选择“DisplayPopUp”宏,按下“添加” ,然后单击“确定”按扭,如图1所示。

图1
在图1中,可以使用“修改”按钮命令来改变图标。
注 : 仅需执行操作一次,因为该按钮被保存在Excel QAT定制文件中。
如果不想再使用该菜单,则从XLSTART文件夹中移除该xlsb文件后,还需手工从QAT中删除该菜单按钮。
4) 如果在QAT中单击该图标,则将弹出自定义的菜单,如图2所示。

图2
编辑该菜单:
在功能区“视图”选项卡中单击“取消隐藏”命令,在弹出的对话框中选择MyMacroFile.xlsb 文件并单击“确定”按钮。
此时,将显示如图3所示隐藏的工作表“MenuSheet”:

图3
Level: 指定菜单项的层级,有效值为2和3。2级代表菜单项,3级代表子菜单项。
Caption: 显现在菜单、菜单项或子菜单里的文本,使用符号(&)来指定加下划线(热键)的字符。
Macro name: 对于2级或3级项目,在选择该项时要执行的宏。如果2级项目有一个或多个3级项,则2级项目可能没有与之相关联的宏。使用Alt+F11键打开VBE编辑器,可以在MacroModule模块中添加或修改宏程序。
Divider: 值为True时,则在菜单项或子菜单项前放置一个分隔条。
FaceID: 可选的。代表显示在项目旁边的内置图形图像的代号数字。
您可以编辑该表中的信息,从而创建自已的菜单。单击“Refresh Menu”按钮来查看是否作出了正确的修改。如果正确,则单击“Hide Save”按钮。
二、创建只在一个工作簿中可用的自定义菜单
本节的内容与上节内容大致相同,主要的区别在于工作簿文件为xlsm工作簿,直接打开该工作簿,并不需要将其放置在特定的文件夹中。
在下面的地址中下载MyWorkbook.xlsm工作簿文件。
http://www.rondebruin.nl/files/MyWorkbook.zip
下载该工作簿后,直接在Excel中打开该工作簿,然后按照上节3)以后的内容进行操作即可。
三、在加载项中存储自定义菜单
可以将带有自定义菜单的工作簿保存为Excel加载项(xlam),然后再在工作簿中启用该加载项。这样,QAT中的按钮将保存在加载项中,并且可以在所有打开的工作簿中使用。
对于上面介绍的示例工作簿,只需将下面的过程中的两行代码删除或注释掉,然后将其保存为Excel加载项。
  1. Sub WBDisplayPopUp()
  2. ' If ActiveWorkbook.Name = ThisWorkbook.Name Then
  3.     On Error Resume Next
  4.     Application.CommandBars(ThisWorkbook.Sheets("MenuSheet").Range("B2").Value).ShowPopup
  5.     On Error GoTo 0
  6. ' End If
  7. End Sub
复制代码

创建带有菜单的加载项,而这些菜单中是您想要分发的宏程序。这是一种很好的方式。

注:本文参考了Ron de Bruin的一系列文章,有兴趣的朋友可以直接参考其网站的文章。
同时,参见:表驱动的方式构建自定义菜单

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-27 19:52 | 显示全部楼层
本帖最后由 jiulongpo 于 2012-8-7 21:57 编辑

转自: http://www.excelperfect.com/index.php/2009/12/14/ribbonxstudy47/
细品RibbonX(47):更改Excel 2007快速访问工具栏中按钮的图标


下面介绍修改QAT中宏按钮或内置按钮图标的方法。
如下图所示,在QAT中添加一个宏。

Excel将QAT的设置保存在名为Excel.qat的文件中,该文件位于:
C:\Documents and Settings\\Local Settings\Application Data\Microsoft\Office\Excel.qat
注意,如果没有自定义QAT,那么该文件不存在。
现在,要修改该宏的图标,虽然可以在自定义选项中进行修改,但只是修改宏按钮的图像,并且只能修改为内置的图标。使用下面的方法可以修改内置按钮或宏按钮的图标。
在记事本或任何XML编辑器中打开Excel.qat文件,将看到下列内容:
  1. <mso:customUI xmlns:x1="http://schemas.microsoft.com/office/2006/01/customui/macro"
  2. xmlns:mso="http://schemas.microsoft.com/office/2006/01/customui">
  3. <mso:ribbon>
  4. <mso:qat>
  5. <mso:sharedControls>

  6. <mso:control idQ="mso:FileNewDefault" visible="false"/>
  7. <mso:control idQ="mso:FileOpen" visible="false"/>
  8. <mso:control idQ="mso:FileSave" visible="true"/>
  9. <mso:control idQ="mso:FileSendAsAttachment" visible="false"/>
  10. <mso:control idQ="mso:FilePrintQuick" visible="false"/>
  11. <mso:control idQ="mso:FilePrintPreview" visible="false"/>
  12. <mso:control idQ="mso:Spelling" visible="false"/>
  13. <mso:control idQ="mso:Undo" visible="true"/>
  14. <mso:control idQ="mso:Redo" visible="true"/>
  15. <mso:control idQ="mso:SortAscendingExcel" visible="false"/>
  16. <mso:control idQ="mso:SortDescendingExcel" visible="false"/>
  17. <mso:button idQ="x1:C:_Documents_and_Settings_Administrator_桌面_ChangeAQTImageSample.xlsm_MyMacro_1" visible="true" label="MyMacro" onAction="C:\Documents and Settings\Administrator\桌面\ChangeAQTImageSample.xlsm!MyMacro" imageMso="ListMacros"/>

  18. </mso:sharedControls>
  19. </mso:qat>
  20. </mso:ribbon>
  21. </mso:customUI>
复制代码

其中,中间部分的前11行是QAT中默认的按钮,可以通过下拉QAT右侧的箭头看到,而最后一行(即下面所示的)是我们添加的按钮。
  1. <mso:button idQ="x1:C:_Documents_and_Settings_Administrator_桌面_ChangeAQTImageSample.xlsm_MyMacro_1" visible="true" label="MyMacro" onAction="C:\Documents and Settings\Administrator\桌面\ChangeAQTImageSample.xlsm!MyMacro" imageMso="ListMacros"/>
复制代码

将imageMso=”ListMacros”修改为imageMso=”M”,即可以修改该按钮的图像。
  1. <mso:button idQ="x1:C:_Documents_and_Settings_Administrator_桌面_ChangeAQTImageSample.xlsm_MyMacro_1" visible="true" label="MyMacro" onAction="C:\Documents and Settings\Administrator\桌面\ChangeAQTImageSample.xlsm!MyMacro" imageMso="M"/>
复制代码

修改后如下图所示。



若要修改内置按钮的图像,同样修改为imageMso=”M”或者其他图像。
当然,你也可以将文件名更改为压缩文件后缀,然后解压缩,修改相应的qat代码来修改按钮的图像。


TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-27 19:55 | 显示全部楼层
本帖最后由 jiulongpo 于 2012-8-6 21:56 编辑

转自: http://www.excelperfect.com/index.php/2009/12/16/ribbonxstudy48/
细品RibbonX(48):在Visual Studio中自定义Office 2007用户界面的快速访问工具栏(QAT)


在Microsoft Office 2007中自定义快速访问工具栏,仅需要几行XML和编程代码。
概述
2007 Microsoft Office Fluent用户界面(UI)使用更简单的设计代替了当前系统的层级菜单、工具栏和任务窗格,使得操作更有效率。Office Fluent Ribbon、快捷菜单、快速访问工具栏和Offce菜单是Office Fluent UI的所有组成部分。可以在Office Fluent Ribbon中添加很多的自定义控件和内置控件,例如按钮、复选框和组合框。
通过使用XML标记元素,在Office Fluent Ribbon中添加组件,并且通过属性来设置这些组件的属性,通过使用任何Microsoft Visual Studio支持的编程语言,例如Visual Basic和Visual C#、以及VBA、Visual C++、Visual Basic 6.0来赋予这些组件功能。
使用XML添加控件
XML提供了Office Fluent用户界面层级的、公开的模型。通过使用XML元素指定组件的类型,可以在功能区中添加控件(例如按钮),例如可以使用button元素添加一个按钮,通过使用属性例如label属性给控件赋属性值。
下面是用于自定义Office Fluent UI的XML的示例,在Excel 2007中通过添加提供内置复制功能的按钮和内置粘贴功能的按钮来自定义QAT。
  1. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  2.   <ribbon startFromScratch="true">
  3.     <qat>
  4.       <sharedControls>
  5.         <button idMso="Copy"/>
  6.         <button idMso="Paste"/>
  7.       </sharedControls>
  8.     </qat>
  9.   </ribbon>
  10. </customUI>
复制代码

该示例首先设置ribbon元素的startFromScratch属性为true,设置该属性使Office Fluent Ribbon在“start from scratch”模式下,隐藏了所有内置选项卡。接着,通过在代码中添加qat元素,创建对QAT的引用。然后,添加sharedControls元素封装QAT中任何自定义控件。最后,添加两个按钮,一个是内置的复制功能,一个是内置的粘贴功能。
结果如下图所示。

注:通过使用idMso属性,可以告诉控件引用内置于Microsoft Office里的功能,包括Mso后缀的属性名称总是指向包含在Microsoft Office里的功能和资源。相反,使用id属性代表自定义控件。
有两种方式来自定义Office Fluent UI:


  • 修改支持Office Fluent UI的Office应用程序所创建的Office Open XML格式文件。
  • 使用加载项。
可以根据定制用户界面的需要来选择技术。例如,修改基于Office Open XML格式文件是文档级定制,所定制的Office Fluent Ribbon仅与特定的文档相关,而不是整个应用程序;通过使用加载项,将获取应用程序级的定制,这意味着定制的Ribbon将应用到整个应用程序中,而不管打开哪个文档。
使用Office Open XML格式文件创建定制的Ribbon
1、通过改变文件的扩展名,使之成为一个压缩文件(.zip),然后打开该文件。
2、添加一个包含XML定制代码的文件夹。
3、修改该文档相联系的文件来指向自定义文件夹。
4、改变该文档的扩展名。
5、在Office应用程序里打开该文档。
6、添加代码到文档中,提供自定义用户界面的功能。
使用加载项
使用加载项定制用户界面也简单。在创建加载项工程后,实现IRibbonExtensibility接口,包括Microsoft.Office.Core命名空间。该接口包含一个名为GetCustomUI方法,使用该方法返回XML定制代码。然后添加编程过程,提供自定义用户界面的功能。
自定义QAT
创建在功能区中添加自定义按钮的加载项解决方案。
1、开启Visual Studio 2008。
2、在“文件”菜单中,单击“新建项目”。
3、在“新建项目”对话框中,在“项目类型”窗格中,展开“Office”节点,并选择“2007”,然后选择“Excel 2007外接程序”。
4、在名称框中,输入CustomQATSample,然后单击“确定”创建项目。
5、在“解决方案资源管理器”中的项目名上单击右键,选择“添加—新建项”。在“添加新项”对话框中选择“功能区(XML)”,使用默认的名称,单击“确定”。
6、在“解决方案资源管理器”中的项目名上单击右键,选择“属性”,打开项目属性窗口,并选择“资源”选项卡。将“解决方案资源管理器”中的Ribbon1.xml拖到资源窗口中。
7、编辑Ribbon1.xml的默认代码为自定义代码:
  1.   <ribbon startFromScratch="true">
  2.     <qat>
  3.       <sharedControls>
  4.         <button idMso="Copy"/>
  5.         <button idMso="Paste"/>
  6.       </sharedControls>
  7.     </qat>
  8.   </ribbon>
复制代码

8、将Ribbon1.vb中顶部声明行中的代码复制到ThisAddIn.vb中,并取消注释。
9、保存并按F5启动调试,结果如上图所示。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-27 19:59 | 显示全部楼层
本帖最后由 jiulongpo 于 2012-8-7 22:06 编辑

转自: http://www.excelperfect.com/index.php/2009/12/17/ribbonxstudy49/
细品RibbonX(49):在功能区中使用上下文控件


上下文选项卡对新UI的功能提供了极大的推进作用。当用户对某对象执行特定的任务时就会出现特定的选项卡。例如,在Excel中处理图表时,一个上下文选项卡提供用于图表处理的额外选项。本文将介绍创建和执行这些特定的选项卡,以及如何修改内置的上下文选项卡,也介绍如何定制或替换内置的弹出菜单,如何创建自已的上下文弹出菜单。最后,探讨创建一个使用多种语言的UI。
使项目上下文
使项目上下文意味着必须响应所做的内容,例如操控表或图片。根据对上下文控件的定义,需要在新Office UI中使用上下文选项卡集合来执行任务。然而,也不总是这样。
下面介绍上下文控件的概念,例如选项卡、组和通用控件。
选项卡
当执行上下文敏感的命令时,立即想到的是上下文选项卡。作为使Ribbon的功能完整的一部分,这些特定的选项卡将根据所选择的对象或这些对象是否获得焦点而从功能区中出现和消失,例如图表、数据透视表或图片。
下图显示了名为“图片工具”的tabSet,包含一个名为“格式”的选项卡。

要实现这样的解决方案,需要使用上下文选项卡集合和tabSet元素。下面的XML标记作为上下文选项卡集和相应的选项卡的容器:
  1. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  2.     <ribbon>
  3.         <contextualTabs>
  4.             <tabSet>
  5.                 <!-- Your contextual tab code goes here -->
  6.             </tabSet>
  7.         </contextualTabs>
  8.     </ribbon>
  9. </customUI>
复制代码

contextualTabs集合是每个tabSet的父对象,同样选项卡的collection对象是选项卡的父对象。可以使用上述代码来创建自已的上下文敏感功能,访问内置的tabSets来修改它们。不巧的是,这样的tabSets扩展不能应用到Excel或Word,仅能对Access的窗体和报表提供这样的扩展。当在Access中使用自定义选项卡tabSets时,需要按下列方式引用扩展的tabSet:

<tabSet idMso=”TabSetFormReportExtensibility”>

在这个tabSet里,创建上下文选项卡UI。
对于Excel和Word,需要通过完全控制内置的上下文选项卡或者通过联合getVisible属性使用事件来使选项卡的行为像上下文选项卡。

例如,当用户处理Excel工作簿中的工作表Sheet1时,希望仅使字体组和插入图表组可见。XML代码:
  1. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"
  2.     onLoad="rxIRibbonUI_onLoad">
  3.     <ribbon startFromScratch="false">
  4.         <tabs>
  5.             <tab idMso="TabHome">
  6.                 <group idMso="GroupFont"
  7.                    getVisible="rxShared_getVisible"/>
  8.             </tab>
  9.             <tab idMso="TabInsert">
  10.                 <group idMso="GroupInsertChartsExcel"
  11.                    getVisible="rxShared_getVisible"/>
  12.             </tab>
  13.          </tabs>
  14.     </ribbon>
  15. </customUI>
复制代码

使用在XML中定义的共享回调,现在能够通过使用想控制的特定工作表的自定义属性来决定属性的返回值。使用下面的代码:
  1. Sub rxShared_getVisible(control As IRibbonControl, ByRef returnedVal)
  2.     Select Case control.ID
  3.         Case "GroupFont"
  4.             returnedVal = Sheet1.rxGroupFontVisible
  5.         Case "GroupInsertChartsExcel"
  6.             returnedVal = Sheet1.rxGroupInsertChartsExcel
  7.     End Select
  8. End Sub
复制代码



根据自定义的属性值设置该属性的值。首先,设置Ribbon对象,这样当文档打开时以便设置该Ribbon为ThisWorkbook对象的属性。下面的代码放置在ThisWorkbook模块中:
  1. Private pRibbonUI As IRibbonUI

  2. Public Property Let rxIRibbonUI(iRib As IRibbonUI)
  3.     Set pRibbonUI = iRib
  4. End Property

  5. Public Property Get rxIRibbonUI() As IRibbonUI
  6.     Set rxIRibbonUI = pRibbonUI
  7. End Property
复制代码

其次,指定想控制的工作表的自定义属性,代码如下所示。自定义属性可读写,以便执行期间的任何时候都能重新赋值。
  1. Private pblnGroupFontVisible As Boolean
  2. Private pblnGroupChartVisible As Boolean

  3. Property Let rxGroupFontVisible(ByVal blnVisible As Boolean)
  4.     pblnGroupFontVisible = blnVisible
  5. End Property

  6. Property Get rxGroupFontVisible() As Boolean
  7.    rxGroupFontVisible = pblnGroupFontVisible
  8. End Property

  9. Property Let rxGroupInsertChartsExcel(ByVal blnVisible As Boolean)
  10.     pblnGroupChartVisible = blnVisible
  11. End Property

  12. Property Get rxGroupInsertChartsExcel() As Boolean
  13.    rxGroupInsertChartsExcel = pblnGroupChartVisible
  14. End Property
复制代码

最后,根据需要修改自定义属性。这里,我们希望当指定工作表是活动工作表时显示这些组,因此使用Worksheet_Activate和Worksheet_Deactivate事件来修改属性值,代码如下:
  1. Private Sub Worksheet_Activate()
  2.     Sheet1.rxGroupFontVisible = True
  3.     Sheet1.rxGroupInsertChartsExcel = True
  4.     ThisWorkbook.rxIRibbonUI.Invalidate
  5. End Sub

  6. Private Sub Worksheet_Deactivate()
  7.     Sheet1.rxGroupFontVisible = False
  8.     Sheet1.rxGroupInsertChartsExcel = False
  9.     ThisWorkbook.rxIRibbonUI.Invalidate
  10. End Sub
复制代码

当激活/取消激活该工作表时,显示或隐藏相应的组。
使用不明显的方法
使用可见性创建上下文敏感的选项卡和组可能有点不正规,但是确实是达到目标的有效的方式。然而,这种方式不是在所有情形下都可用,特别是在处理内置组中的内置控件时。
启用和禁用控件
可以使用enabled属性决定控件是否启用。
下面通过使用getEnabled属性提供上下文敏感的控件。要禁用命令,必须引用该命令本身和按钮或通用控件,例如禁用复制和剪切命令的XML代码如下:
  1. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"
  2.     onLoad="rxIRibbonUI_onLoad">
  3.     <commands>
  4.         <command idMso="Copy" getEnabled="rxShared_getEnabled"/>
  5.         <command idMso="Cut" getEnabled="rxShared_getEnabled"/>
  6.     </commands>
  7. </customUI>
复制代码

下一步,添加共享回调来处理要执行的程序:
  1. Sub rxShared_getEnabled(control As IRibbonControl, ByRef returnedVal)
  2.     Select Case control.ID
  3.         Case "Copy"
  4.             returnedVal = Sheet1.rxCopyEnabled
  5.         Case "Cut"
  6.             returnedVal = Sheet1.rxCutEnabled
  7.     End Select
  8. End Sub
复制代码

同样,使用自定义属性指定回调的返回值。
修改内置的选项卡集
下图展示了对内置的图表工具上下文选项卡集中添加的自定义选项卡。

然而,有时我们想移除上下文图表选项卡中的所有的内置选项卡,仅在该选项卡集中添加一些非常特别的编辑工具。
首先,我们看看图表工具选项卡集中的选项卡,如下表所示。
表:图表工具选项卡集中默认的选项卡

选项卡名描述
TabChartToolsDesign提供用户设计所选择的图表的工具,例如内置样式选项、数据选择、图表类型,等等。
TabChartToolsLayout指供用户布局所选择的图表的工具,例如标签、趋势线,等等。
TabChartToolsFormat提供用户格式化所选择的图表的工具,例如形状样式、文本填充、文本效果、排列,等等。


选项卡不会像按钮一样提供enabled属性,因而使用其visible属性控制其出现。通过使选项卡不可见,其中的所有对象都将从UI中消失,但不会禁用其中包含的控件。
接着完成上面的示例,其XML代码如下:
  1.   <contextualTabs>
  2.    <tabSet
  3.     idMso="TabSetChartTools">
  4.   <tab
  5.        id="rxtab"
  6.        label="My Chart Tools">
  7.       <group idMso="GroupFont"/>
  8.       <group idMso="GroupInsertChartsExcel"/>
  9.       <group idMso="GroupNumber"/>
  10.   </tab>
  11.   <tab
  12.    idMso="TabChartToolsDesign"
  13.    visible="false" />
  14.   <tab
  15.    idMso="TabChartToolsLayout"
  16.    visible="false" />
  17.   <tab
  18.    idMso="TabChartToolsFormat"
  19.    visible="false" />
  20.    </tabSet>
  21.   </contextualTabs>
复制代码


修改后的图表工具选项卡如下图所示。仅当选择图表时才出现。

处理上下文弹出菜单
当在某对象上右击或者在有弹出菜单的工作环境中右击时,会出现弹出菜单。与上下文选项卡相似,弹出菜单显示与活动对象相关的选项。
弹出菜单的设置基于VBA,不需要XML代码,它们仍然基于命令栏对象。大多数弹出菜单都能够被定制,然而基于新的OfficeArt不能够被定制。下图显示了Excel中内置弹出菜单的示例。
[url=http://www.excelperfect.com/wordpress/wp-content/uploads/2009/12/contextualtab4.png]
上图显示的弹出菜单称为“Cell”,索引值等于36。
不能够定制“Mini工具栏”,然而可以在应用程序选项中控制其是否显现。



TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-27 20:03 | 显示全部楼层
接 细品RibbonX(49):在功能区中使用上下文控件

完全取代内置的弹出菜单
当在Excel工作表单元格中右击时,将得到单元格弹出菜单,如上图所示。然而,可能有一个区域需要合适的自定义弹出菜单,如下图所示。

在编写代码前,让我们先看看该自定义的弹出菜单需要做什么:
  • 必须在单元格弹出菜单的位置显示。
  • 必须仅显示在预先确定的区域。本例中为单元格区域A1:O32。
首先,添加下面的代码到想要取代内置单元格弹出菜单的工作表代码模块中:
  1. Private Sub Worksheet_BeforeRightClick(ByVal Target As Excel.Range, _
  2.     Cancel As Boolean)
  3.     If Union(Target.Range("A1"), Range("A1:O32")).Address = _
  4.         Range("A1:O32").Address Then
  5.         CommandBars(MYPOPUP).ShowPopup
  6.         Cancel = True
  7.     End If
  8. End Sub
复制代码

下一步,需要在工作簿代码窗口添加两个过程。一个过程指工作簿的Open事件,用来创建弹出菜单;另一个过程指工作簿的Close事件,用来删除弹出菜单。
  1. Private Sub Workbook_Open()
  2.     Call mnuPopup
  3. End Sub

  4. Private Sub Workbook_BeforeClose(Cancel As Boolean)
  5.     Call delPopup
  6. End Sub
复制代码

然后,在标准模块中包含产生弹出菜单以及删除该菜单的代码,即编写mnuPopup过程和delPopup过程,通过声明公共常量MYPOPUP开始,以便在工程中的其它过程中可用:
  1. Public Const MYPOPUP As String = "MY POPUP"

  2. Sub mnuPopup()
  3.     Dim cmdBar As CommandBar
  4.     Dim mnu As CommandBarButton

  5.     delPopup

  6.     Set cmdBar = CommandBars.Add _
  7.       (Name:=MYPOPUP, Position:=msoBarPopup, Temporary:=True)

  8.     Set mnu = cmdBar.Controls.Add(Type:=msoControlButton)
  9.     With mnu
  10.         .Caption = "Bold"
  11.         .OnAction = "bold"
  12.         .FaceId = 113
  13.     End With

  14.     Set mnu = cmdBar.Controls.Add(Type:=msoControlButton)
  15.     With mnu
  16.         .Caption = "Italics"
  17.         .OnAction = "italics"
  18.         .FaceId = 114
  19.     End With

  20.     Set mnu = cmdBar.Controls.Add(Type:=msoControlButton)
  21.     With mnu
  22.         .Caption = "Underline"
  23.         .OnAction = "underline"
  24.         .FaceId = 115
  25.     End With

  26.     Set mnu = cmdBar.Controls.Add(Type:=msoControlButton)
  27.     With mnu
  28.         .Caption = "&About..."
  29.         .OnAction = "about"
  30.         .FaceId = 326
  31.         .BeginGroup = True
  32.     End With

  33.     Set mnu = cmdBar.Controls.Add(Type:=msoControlButton)
  34.     With mnu
  35.         .Caption = "&Help"
  36.         .OnAction = "help"
  37.         .FaceId = 984
  38.         .BeginGroup = True
  39.     End With

  40. End Sub

  41. Sub delPopup()
  42.     On Error Resume Next
  43.     CommandBars(MYPOPUP).Delete
  44. End Sub
复制代码

当打开工作簿时,执行第一个过程;当关闭工作簿时,执行第二个过程。
最后,添加弹出菜单中按钮的功能,代码如下:
  1. Sub bold()
  2.     Selection.Font.bold = Not Selection.Font.bold
  3. End Sub

  4. Sub italics()
  5.     Selection.Font.Italic = Not Selection.Font.Italic
  6. End Sub

  7. Sub underline()
  8.     If Selection.Font.underline = xlUnderlineStyleSingle Then
  9.        Selection.Font.underline = xlUnderlineStyleNone
  10.     Else
  11.         Selection.Font.underline = xlUnderlineStyleSingle
  12.     End If
  13. End Sub
复制代码

在弹出菜单中添加单独的项目
自定义内置弹出菜单的另一种有用的方式是添加新功能。如下图所示,我们在工作表标签右击后出现的弹出菜单中添加新的功能,只需单击该功能应能按字母顺序对工作表排序。

在标准模块中输入下面的代码:

  1. Sub addButton()
  2.     Dim cmdbar As CommandBar
  3.     Dim btn As CommandBarButton

  4.     resetPopup
  5.     On Error GoTo Err_Handler
  6.     Set cmdbar = Application.CommandBars("Ply")

  7.     Set btn = cmdbar.Controls.Add(Type:=msoControlButton, Before:=1)

  8.     With btn
  9.         .Style = msoButtonIconAndCaption
  10.         .Caption = "Order sheet tabs"
  11.         .FaceId = 210
  12.         .OnAction = "orderTabs"
  13.     End With
  14.     Exit Sub
  15. Err_Handler:
  16.     MsgBox Err.Description, vbCritical, Err.Number
  17. End Sub
复制代码

与上例一样,如果想在打开工作簿时自动实现该功能,则在工作簿的打开事件中添加调用该过程,此外,在工作簿的关闭事件中添加调用恢复原菜单的功能。恢复菜单的代码如下:
  1. Sub resetPopup()
  2.     Application.CommandBars("Ply").Reset
  3. End Sub
复制代码

下面,编写代码实现当单击添加的按钮时所实现的功能:
  1. Sub orderTabs()
  2.     Dim i As Long
  3.     Dim j As Long
  4.     Dim n As Long

  5.     n = ActiveWorkbook.Sheets.Count

  6.     If n = 1 Then
  7.         MsgBox "这个工作簿中仅有一个工作表!", _
  8.         vbInformation
  9.         Exit Sub
  10.     End If

  11.     For i = 1 To n - 1
  12.         For j = i + 1 To n
  13.             If Sheets(j).Name < Sheets(i).Name Then
  14.                 Sheets(j).Move Before:=Sheets(i)
  15.             End If
  16.         Next
  17.     Next
  18. End Sub
复制代码

使用多种语言的UI
本例的目的是让用户能够选择他们喜欢的语言。示例中将提供两种语言,下图显示了我们将在Excel中创建的示例。

实现上述目的需要完成四项任务:

  • 每个控件的标签必须在运行时修改,因此使用getLabel属性。
  • 因为这是在所有控件中共享的属性,所以我们使用一个共享的回调来处理变化。这也避免了许多代码量。
  • 使用工作表保持控件的名字和翻译。可以隐藏该工作表,以便用户不容易访问它。
  • 使用VLookup函数搜索列表中的控件,返回标签值。
控件名和翻译是实现该解决方案的关键元素,一个工作表示例如下图所示。

可以为包含翻译的区域定义动态区域,也可以将区域转换为表,但是在里只是提供一个示例,所以使用固定区域。下面开始编写VBA代码。
首先,定义一些需要使用的变量。在标准模块声明部分声明下列全局变量:
  1. Public grxIRibbonUI As IRibbonUI
  2. Public giColControls As Integer
  3. Public gWS As Worksheet
复制代码

第一个变量是Ribbon对象,第二个变量指向语言版本所在的列;第三个变量指向包含翻译的工作表对象。
接着,使用onLoad事件设置这些变量以便后面使用:
  1. Sub rxIRibbonUI_onLoad(ribbon As IRibbonUI)
  2.     Set grxIRibbonUI = ribbon
  3.     giColControls = 2
  4.     Set gWS = ThisWorkbook.Sheets("Languages")
  5.     Application.SendKeys "%UN{RETURN}"
  6. End Sub
复制代码

这段代码执行下列任务:
  • 设置ribbon对象
  • 决定翻译位于的初始列
  • 设置包含翻译的工作表
  • 向应用程序发送快捷键Alt+UN,以便当打开该工作簿时选择自定义选项卡
当打开文档时将装载初始标签,因此需要处理共享的getLabel回调,代码如下:
  1. Sub rxshared_getLabel(control As IRibbonControl, ByRef returnedVal)
  2.     On Error Resume Next
  3.     returnedVal = Application.WorksheetFunction.VLookup( _
  4.         control.ID, gWS.Range("A1:C200"), giColControls, 0)
  5. End Sub
复制代码

当用户从UI的splitButton/menu中选择不同语言时调用代码。当用户单击所选择的语言命令时,需要使功能区无效以便重新装载值到UI中,代码如下:
  1. Sub rxbtnshared_Click(control As IRibbonControl)
  2.     Select Case control.ID
  3.         Case "rxbtnSpanish"
  4.             giColControls = 3
  5.         Case "rxbtnEnglish"
  6.             giColControls = 2
  7.     End Select
  8.     grxIRibbonUI.Invalidate
  9. End Sub
复制代码

使用Select语句选择两种可用的语言。如果选择的是Spanish,查找的列被设置为3;如果选择English,该列被设置为2(缺省值)。


TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-27 20:16 | 显示全部楼层
本帖最后由 jiulongpo 于 2012-8-6 21:58 编辑

转自: http://www.excelperfect.com/index.php/2009/12/18/ribbonxstudy50/
细品RibbonX(50):如何共享Ribbon定制之Excel部署技术


下面介绍Excel中可用于部署定制的三种方法:工作簿、模板、加载项。
分发工作簿
到目前为止,我们所创建的Excel解决方案都可以称之为“工作簿级的部署”,每个创建的工作簿都以xlsx或xlsm(启用宏)的文件格式保存,这是最常用的格式。所有必需的xml和VBA代码都保存在这样的文件中。
与其它部署方法相比,工作簿级部署有很多优势,只需要简单地将工作簿发送给用户。最终用户只需要使用安全设置许可运行任何代码,并且VBA代码能够正确地随环境而变化调整,例如可变的文件路径。但这种部署方法也存在缺点,最大的问题是文件的维护,因为它违反了最佳的实践原则:逻辑与数据分离。还有一个缺点是会导致大量相同定制工作簿的副本,这样很难再更新代码。
使用模板
将文件存储为模板,这样可以在指定的内在结构上快速创建新文件。
模板的目的是在调用模板文件时,提供“新鲜干净的”工作簿,简单到只需开发者正确地设置工作簿,然后将其保存为模板。一旦将文件安装到最终用户的模板(templates)文件夹中,只需简单地选择“Office菜单——新建——我的模板”,然后双击合适的文件,就会按所选模板创建新工作簿。应该为新文件提供新名称,以免覆盖模板。
创建模板比想象的更容易。下面来创建模板文件,使用以前的示例editBox – Rename Worksheet.xlsm。打开该文件,选择“Office菜单——另存为”,从“保存类型”下拉列表中选择“Excel启用宏的模板”并提供文件名,将其保存到默认的目录下。在Windows XP中,保存模板的缺省目录为:
C:\Documents And Settings\username\Application Data\Microsoft\Templates
就这么简单!关闭该文件。
接着,单击“Office菜单——新建”,在“我的模板”中选择并打开刚保存的文件。文件打开后,看起来像保存时的样子,但注意到应用程序标题栏中文件的名字,在模板文件名后自动添加了数字1,并且没有扩展名。如果此时再以该模板新建文字,添加的数字将递增。

实际上,因为该文件还没有保存,所以缺少扩展名。一旦单击“保存”按钮,就会提示输入文件名和选择类型。该文件不会覆盖模板文件。
由于能够将模板存储在用户自已的模板目录里或者网络目录里,所以可以容易地发布和更新工作簿模板,确保都从模板中创建所有的新文件。
然而,如果模板使用了VBA,那么要保证在基于该模板创建的文件中VBA仍然起作用,必须保存为启用宏的工作簿,否则会删除VBA代码。
创建和部署加载项
加载项将数据与代码分离,并且加载项能够使定制对所有的文件都可见并可访问。
下面,以前面文章中的示例dynamicMenu-CreateFromTemplate.xlsm来介绍Excel中加载项的构建。
当准备转换某文件为加载项时,确保所有的VBA代码无缝地转移。如果文件中含有VBA代码,那么需要检查代码中ThisWorkbook的引用,以及子过程和函数前面没有加上关键字Public或Private。
因为加载项主要是xlsm文件,这些文件在代码中大都引用ThisWorkbook对象,这对于代码和数据都在相同的工作簿中没有任何问题,但是一旦该文件被转换成加载项,将要处理的数据几乎不会存储在实际的加载项中。因此,最好的方法是加载项仅仅作为代码的容器。这样,就不会担心在更新加载项时会覆盖掉用户设置和数据。
现在,打开dynamicMenu-CreateFromTemplate.xlsm文件,并打开VBE,搜索代码中的ThisWorkbook,然后决定是否应该将其替换为ActiveWorkbook。注意,大多数工作簿中的代码的目标是处理在活动工作簿(ActiveWorkbook)中的数据,而不是代码所在的工作簿(ThisWorkbook)。
然而,还需要注意代码中潜在的对ThisWorkbook对象的引用。
其次,需要注意区分Public、Private和不确定的过程和函数。默认情况下,所有没有加上Public或Private关键字的过程和函数都被视为Public。这意味着,按下Alt+F8键后出现的“宏”对话框中可以看到它们。
使程序尽可能Private,是一个良好的编程实践。创建公共的过程,以便它们能够被用户运行,然而,如果过程仅从其它过程或函数中调用,那么它们应该被声明为Private。
代码编写并修改完成后,就可以将其转换为加载项了。
转换工作簿成为加载项是非常简单的。单击“Office菜单—另存为—其他格式”,在出现的对话框的保存类型中,选择“Excel加载宏”格式(*.xlam)。此时,文件夹位置改变至“AddIns”文件夹。对于本例来说,将其命名为“createFromTemplate.xlam”,单击“保存”按钮。
下面,来安装加载项。
前面已经在系统中创建了加载项,它被存储在本地的AddIns目录中。如果发送该加载项给其他用户,并且想他们能够尽可能容易地安装加载项,那么应该直接将该加载项保存到用户的AddIns文件夹中。在Windows XP中,该文件夹位于:
C:\Documents And Settings\username\Application Data\Microsoft\AddIns
打开Excel,单击“Office菜单—Excel选项—加载项—转到”,出现如下图所示的对话框。

如果将加载项保存到本地的AddIns文件夹,那么该加载项就会出现在这个对话框中。如果在其他位置存储加载项,那么需要单击“浏览”按钮来找到该文件。为了完成加载项的装载,只需简单地选中加载项名称前的复选框,并单击“确定”。
正如所看到的,创建加载项能够共享定制,而不管打开了哪个文件。
那么,如何卸载和移除加载项呢?
当装载加载项时,需要内存,因此在需要时装载加载项,不需要时卸载是一项经常使用的操作。卸载加载项非常容易,但是移除加载项则需要更进一步的操作。
要卸载加载项,但仍需要在以后能够使用该加载项,则调出上图所示的对话框后,取消加载项名称前复选框的选择。此时,该加载项并没有从系统中移除,仍然存在于加载项列表中以便需要时装载。
要彻底从系统中移除加载项,首先按上述方法将其卸载。然后,关闭Excel,找到实际的加载项文件,将其移动到其他位置或者删除。接着,打开Excel并返回加载项对话框界面,你会注意到该加载项仍然在列表中,单击该加载项前面的复选框,将出会出一条消息,提供你将会从列表中删除该加载项。选择“是”,然后关闭Excel。这是重要是,因为当关闭Excel会在维护加载项列表的注册表中设置修改。
IsAddin属性
如果需要在加载项的工作表中添加一些数据以便于使用,那该怎么办呢?此时,可以通过设置加载项的IsAddin属性为False,临时打开该工作表。
在VBE中,选择加载项工程的ThisWorkbook模块,在工程属性窗口中,将IsAddin属性设置为False。
将IsAddin属性修改为False,告诉Excel将该文件视作常规工作簿。此时所有的工作表都将可见,并且能够被修改。要再次将该文件转换为加载项,只须按上面的操作将IsAddin属性设置为True。
注意,在定制功能区时使用Personal.xlsb工作簿往往会带来一些不可预见的问题,因此推荐使用单独的加载项来存储跨Excel工作簿共享的定制。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-27 20:20 | 显示全部楼层
本帖最后由 jiulongpo 于 2012-8-6 21:58 编辑

转自: http://www.excelperfect.com/index.php/2009/12/20/ribbonxstudy51/
细品RibbonX(51):如何共享Ribbon定制之跨文件共享Ribbon项目


下面主要介绍创建包含共享选项卡和组的宿主文件,以及添加自已的命令到宿主文件的选项卡中的单独的附属文件。所演示的技术主要用于创建加载项时,操作如下:

  • 在宿主UI文件中为共享选项卡创建功能区定制。
  • 在此文件中添加所期望的全局的组或命令。
  • 另外的上下文定制或命令被包含在其它文件或加载项格式中。
  • 在需要时装载其他文件,附加其命令到宿主文件的定制中。
要创建共享的选项卡和组,必须先看看如何在XML代码中创建共享的命名空间。
创建共享的命名空间
每个UI定制都需要与一个命名空间相联系。先看看标准的customUI标记:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">

已经给customUI元素提供了xmlns属性,其值为一个URL。URL是希望使用的XML命名空间的名称。这个特殊的URL只是Microsoft决定使用的文本值,没有对应的网页页面,意味着功能区定制不需要Internet访问。
Microsoft原先为预定义的命名空间使用名称“CustomRibbon”或任何其他单词,但是他们最终选择使用URL。对于我们来说,重要的是如果希望处理Microsoft的选项卡、组和控件,那么必须指向这个命名空间,包含所有内置的RibbonX元素。
Microsoft也为我们提供了创建自已的命名空间的能力,能够使我们以同样的方式共享选项卡和组。此时,需要在customUI标记中添加另一个xmlns属性:
  1. <customUI
  2.     xmlns="http://schemas.microsoft.com/office/2006/01/customui"
  3.     xmlns:Q="Custom Namespace">
复制代码

注意到,Microsoft的默认命名空间仍保留在customUI标记中。同时,这确保仍然能够访问所有Microsoft的默认选项卡、组和其他控件。除了默认的命名空间外,我们也添加了xmlns:Q属性。
在上述代码中,Q是为命名空间声明的本地名称,当然可以使用其他你喜欢的名称,建议在本地名称前加上前缀“ns”,以符合命名规范。同时,建议命名应该易识别和简短,以方便使用。
假设决定使用本地名称“Custom”,那么自定义xmlns:Q应该如下:
xmlns:nsCustom="Custom Namespace"

双引号之间的部分用于跨文件引用定制,完全是纯文本。例如,如果希望定制看起来像官方的一样,那么可以放置一个指向自已站点的URL。这是一个文本引用,而不管该引用页是否存在。
关键是在每个文件开始的引用应附加到自定义的命名空间。创建xmlns:Q属性是跨多个文件共享选项卡和组的基础。
在Excel中共享选项卡和组
本示例被分成两部分:宿主Excel加载项文件的创建,附加到宿主的自定义选项卡的文件的创建。
首先,打开Excel并以加载项(xlam)文件格式保存新工作簿,将其命名为UIHost.xlam并保存在默认的加载项目录。创建完毕后,关闭Excel。
在CustomUI Editor中打开UIHost.xlam文件,输入下列代码:
  1. <customUI
  2.     xmlns="http://schemas.microsoft.com/office/2006/01/customui"
  3.     xmlns:nsHost="My Shared Ribbon">
  4.     <ribbon startFromScratch="false">
  5.         <tabs>
  6.             <tab idQ="nsHost:rxTabUI"
  7.               label="UI Test"
  8.               insertBeforeMso="TabHome">
  9.               <group idQ="nsHost:rxGrpUI"
  10.                  label="UI Host">
  11.                  <button id="rxHost_Btn1"
  12.                     label="Host UI Button"
  13.                     onAction="rxHost_Buttons"
  14.                     imageMso="HappyFace"/>
  15.               </group>
  16.             </tab>
  17.         </tabs>
  18.     </ribbon>
  19. </customUI>
复制代码

注意到,我们为共享的功能区控件创建了一个名为nsHost的自定义命名空间。再看看tab元素,使用idQ属性代替id属性,确保选项卡被创建在共享的命名空间中,并允许其他文件在其中放置组。
idQ属性总是采用下面的形式:
idQ="localname:id"

对于本示例来说,本地名为nsHost。本地名后面是“:”表示名称结束,然后是控件的唯一标识符。
接下来的代码中,group元素也使用idQ属性声明,允许组被共享,因此能够使开发人员在其中添加单独的控件。
最后代码创建了一个按钮,注意到没有使用idQ属性声明,而是使用了标准的id属性,因为:

  • 该按钮被存储在加载项中,因此它将总是可见的。
  • 任何期望的动态功能都能够通过与该按钮元素相关的回调来设置。
  • 没有在按钮中嵌套控件的方法,因此不需要共享。
验证代码并保存后,生成回调签名并复制,关闭CustomUI Editor,然后重新打开Excel。按照前面文章所介绍的方法安装加载项,打开VBE,导航到UIHost.xlam工程,添加一个新标准模块,粘贴回调签名,并输入代码:
  1. Private Sub rxHost_Buttons(Control As IRibbonControl)
  2.     '管理按钮事件
  3.     Select Case Control.ID
  4.         Case Is = "rxHost_Btn1"
  5.             MsgBox "调用至" & ThisWorkbook.Name
  6.         Case Else
  7.             '放置其它宏
  8.     End Select
  9. End Sub
复制代码

该过程的目的是反馈调用它的工作簿的名称。
回到Excel界面,测试按钮,如下图所示。

你应该注意到上述代码中,定义共享的命名空间与在UIHost.xlam文件中一样。只是将命名空间的名字修改为nsLeech,而文本标识符仍然是“My Shared Ribbon”。当然,命名空间的名称可以是任意的,修改的目的只是为了更清晰。相反,自定义命名空间“My Shared Ribbon”必须与UIHost.xlam文件中指定的相同,这是允许我们将文件链接在一起的工具。
完成代码输入并验证后,保存代码,复制回调签名,关闭CustomUI Editor。
在Excel中重新打开Leech.xlsm文件,打开VBE,插入一个新的标准模块,粘贴回调签名,并修改代码如下:
  1. Sub rxSharedCallControl_Click(control As IRibbonControl)
  2.     '响应按钮单击并通知用户在哪里调用的过程
  3.     MsgBox "单击的 " & control.ID & " 来自 " & ThisWorkbook.Name
  4. End Sub
复制代码

现在,打开Leech.xlsm文件后的界面如下图所示。

在“UI Test”选项卡中添加了Leech组,以及我们创建的所有控件。
现在,创建一个新工作簿,UI将会更新,如下图所示。
[url=http://www.excelperfect.com/wordpress/wp-content/uploads/2009/12/sharedUICustome3.png]
我们创建的带有id属性的控件消失了,仅剩下带有idQ声明的控件。
然而,当单击按钮Button1和Button2时,什么也没有发生,为什么呢?
使用idQ属性声明的控件,不会触发任何回调,其原因与存在和不存在命名空间之间的差别相关,没有办法允许对创建在不存在的命名空间中带有idQ属性的控件触发回调。这限制了共享的选项卡和组的使用。

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-5-19 19:08 , Processed in 0.043897 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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