ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享]RibbonX和VBA

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-3-13 09:13 | 显示全部楼层
本帖已被收录到知识树中,索引项:UI界面定制

其它的RibbonX元素、属性和回调
虽然在RibbonX中的大多数元素、属性和回调用于设置控件的属性,但您需要理解更多以完全使用Ribbon。
如果您忽略了定义控件的XML元素,那么完整的RibbonX结构如下所示,其中的省略号(…)表示一个或多个可选的属性,这些元素和它们的属性在下面的小节中介绍。
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" ...>
  <commands>
    <command ... />
  </commands>
  <ribbon ...>
    <officeMenu>
      可用于菜单中的任何控件类型
    </officeMenu>
    <qat>
      <sharedControls>
        <control>,<button> or <separator> 控件类型
      </sharedControls>
      <documentControls>
        <control>,<button> or <separator> 控件类型
      </documentControls>
    </qat>
    <tabs>
      <tab ...>
        <group ...>
          所有控件类型
        </group>
      </tab>
    </tabs>
    <contextualTabs>
      <tabSet idMso="TabSetChartTools">
        <tab ...>
          <group ...>
            所有控件类型
          </group>
        </tab>
      </tabSet>
    </contextualTabs>
  </ribbon>
</customUI>

[此贴子已经被作者于2007-3-13 9:13:30编辑过]

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-3-13 09:14 | 显示全部楼层
在多个工作簿中共享控件
当使用id属性创建自定义的选项卡、组和控件时,您总会获得一个带状的新选项卡、组或控件——即使带有相同ID或标签的已存在。这通常是有利的,因为它避免了多个加载项意外改变彼此的项目。然而,有时您想在多个加载项或工作簿中共享这些项目,例如,有一个创建基本选项卡、组和菜单结构的加载项,并且一些单个的工作簿要添加这些项目,这可通过使用idQ属性提供满足要求的IDs来获得——IDs联系着一个特定的名称空间。名称空间在customUI元素中提供,并且只需要是独立的字符串,可以提供一个别名(本例中为Q)以便于XML更容易阅读:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" xmlns:Q="Excel 2007 VBA Prog Ref">
您想要在工作簿间共享的任何元素接下来使用idQ属性来定义,并且包括在ID中的名称空间别名:
  <ribbon>
    <tabs>
      <tab idQ="Q:rxShared" label="Shared Tab">
        <group id="Group1" label="Group Not Shared">
任何使用相同名称字符串去限定带有相同ID的控件的工作簿将共享那些控件,而不是获取它们自已的副本。在本例中,包括一个名称空间xmls:Q=”Excel 2007 VBA Prog Ref”和限定选项卡ID idQ=”Q:rxShared”的任何工作簿都将为它们的控件使用相同的选项卡。然而,因为您已为组使用了非限定的ID,所以该组不会在工作簿之间共享。这种方法中使用限定的IDs的能力应用于所有容器类型的控件,因此,一个加载项使用限定的IDs可以为所有的选项卡、组和菜单创建一个复杂的菜单结构,并且单个的工作簿能够添加它们的定制到共享的菜单中。

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-3-13 09:15 | 显示全部楼层

运行时更新控件
回调不只是用于在装载工作簿时获取控件的属性,也可以使用它们在任何时间改变属性的值。这可通过使用指定的接口(IRibbonUI)标识一个控件为无效来实现,下次Excel需要显示该控件时,将再次调用所有回调来获取最新值。
通过添加onLoad回调到custom元素中,告诉Excel提供一个IRibbon接口:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"
          xmlns:Q="Excel 2007 VBA Prog Ref"
          onLoad="rxcustomUI_onLoad">
onLoad回调标记包括一个IRibbon参数,存储在一个模块级变量中供以后使用:
Dim moRibbon As IRibbonUI
Sub rxcustomUI_onLoad(ribbon As IRibbonUI)
  Set moRibbon = ribbon
End Sub
IRibbonUI接口仅有两个方法:
(1) InvalidateControl(“ControlID”)方法标记一个单独的控件无效,因此当该控件下次显示时应该被更新。通常,使控件无效是最好的。
(2) Invalidate方法标记整个Ribbon定制无效,因此,每个控件的每次回调都被重新调用。这可能在提供UI语言选择和为每个控件使用getLabel时使用,当用户改变他们的语言选择时,使每个控件无效,因此更新时显示新的文本。
作为一个例子,下面的XML创建一个带有Up、Goto和Down菜单的splitButton,使用了内置的图像,并定义回调可以改变按钮的图像和行为以重复最后所选择的菜单(像Border splitButton)。创建一个新的工作簿,作为加载项保存该工作簿,然后使用自定义UI编辑器添加XML:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="rxcustomUI_onLoad">
  <ribbon>
    <tabs>
      <tab id="rxExcelVBA" label="VBA Prog Ref">
        <group id="rxDemo" label="Demo">
          <splitButton id="rxSplit" size="large">
            <button id="rxButton" getImage="rxButton_getImage" onAction="rxButton_onAction" />
            <menu id="rxMenu">
              <button id="rxMenuOutlineMoveUp" label="Up" imageMso="OutlineMoveUp" onAction="rxMenu_onAction" />
              <button id="rxMenuGoTo" label="Goto" imageMso="GoTo" onAction="rxMenu_onAction" />
              <button id="rxMenuOutlineMoveDown" label="Down" imageMso="OutlineMoveDown" onAction="rxMenu_onAction" />
            </menu>
          </splitButton>
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>
现在,打开上面创建的加载项(忽略任何错误),然后添加下面的VBA代码到标准模块中,执行定义在XML中的所有回调:
'使控件无效的变量
Dim moRibbon As IRibbonUI
'存储当前splitButton样式的变量,与图像名相同
Dim msSplitStyle As String
'customUI.onLoad回调
Sub rxcustomUI_onLoad(ribbon As IRibbonUI)
  Set moRibbon = ribbon
End Sub

'rxButton getImage回调
Sub rxButton_getImage(control As IRibbonControl, ByRef returnedVal)
  'GoTo缺省样式
  If msSplitStyle = "" Then msSplitStyle = "GoTo"
  '返回内置图像名
  returnedVal = msSplitStyle
End Sub

'rxButton onAction回调
Sub rxButton_onAction(control As IRibbonControl)
  DoSplitAction msSplitStyle
End Sub

'所有rxMenu onAction回调
Sub rxMenu_onAction(control As IRibbonControl)
  '从控件ID中获取样式
  msSplitStyle = Mid$(control.ID, 7)
  '告诉ribbon按钮需要被刷新
  moRibbon.InvalidateControl "rxButton"
  '执行合适的操作
  DoSplitAction msSplitStyle
End Sub

'执行操作
Private Sub DoSplitAction(ByVal sStyle As String)
  Select Case sStyle
    Case "OutlineMoveUp": MsgBox "向上"
    Case "GoTo": MsgBox "定位到"
    Case "OutlineMoveDown": MsgBox "向下"
  End Select
End Sub
保存并关闭该加载项工作簿,然后重新打开该工作簿,此时应该有一个名为VBA Prog Ref的选项卡,带有一个单独的大的分割按钮,按钮上的图像和动作变化与所选菜单相匹配。

  图4

[分享]RibbonX和VBA

[分享]RibbonX和VBA

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-3-13 09:16 | 显示全部楼层
挂钩内置控件
鉴于大多数RibbonX集中定制Ribbon的可见的外观,commands和command元素提供了一种机制用来重载任何内置菜单,修改它的开启状态或中止任何按钮单击。可以包括下面的XML去重载Print按钮以便可以建立某种格式:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <commands>
    <command idMso="FilePrint" onAction="rxPrint_onAction" />
  </commands>
</customUI>
command元素仅有一个enabled属性或getEnabled和/或onAction回调。例如,通过包含enabled=”false”来使一个控件失去能力,或视应用程序的状态使用getEnabled回调决定是否开启控件。onAction回调用于中止缺省的行为,允许您去处理一些先前的过程并删除行为:
'为Print onAction回调,带有删除的能力
Sub rxPrint_onAction(control As IRibbonControl, ByRef cancelDefault)
  If CDbl(Time) > 0.5 Then
    MsgBox "打印仅能在早晨进行!"
    cancelDefault = True
  End If
End Sub
不巧的是,用这种方式重载Ribbon控件仅影响用户实际单击该控件或使用Alt+Key快捷键去触发该控件,而不能中止可以使用功能键和Ctrl+Key组合键(如本例中的Ctrl+P)进行的一些操作。
如果两个加载项试图重载相同的控件,则最后装载的加载项有效。
因为上述两个原因,重载一个控件的功能应该谨慎使用。

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-3-13 09:16 | 显示全部楼层
在“独特”应用程序中的RibbonX
大多数独特样式的Excel应用程序典型地以移除所有的Excel菜单并尽可能以一些其它的UI元素开始,以便提供一个向下锁定的界面给用户。这可以使用ribbon元素的startFromScratch属性提供带有新建(New)、打开(Open)、另存为(Save As)、最近打开的文件(Recent Files)和Excel选项(Excel Options)等项的最小的Office菜单:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon startFromScratch="true">
  </ribbon>
</customUI>
(使用上述代码后的界面如图5所示。)
显然,您可以包括更多的XML去创建自定义的选项卡、组,等等。
 
图5

[分享]RibbonX和VBA

[分享]RibbonX和VBA

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-3-13 09:17 | 显示全部楼层
定制Office菜单
Office菜单作为RibbonX定义里一个特定的实例,可以通过officeMenu元素在其中添加控件:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon>
    <officeMenu>
      <button id="rxOMBtn" label="Office Menu" onAction="rxOMBtn_onAction">
    </officeMenu>
  </ribbon>
</customUI>
也可以通过嵌套合适的控件IDs添加按钮到Office菜单的内置项中,例如“发送”菜单。注意,在作这样的处理时,必须使用正确的控件类型而不是一般的control元素:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon>
    <officeMenu>
      <menu idMso="FileSendMenu">
        <button id="rxSend" label="Send Menu" onAction="rxSend_onAction">
      </menu>
    </officeMenu>
  </ribbon>
</customUI>

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-3-13 09:18 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
定制QAT
Office 2007设计原理是QAT属于用户且应用程序决不会直接添加控件到QAT中。如果用户考虑某些功能是有用的,可以将它们放在QAT中。
在某种情况下,能够添加控件到QAT中是非常有利的——诸如用户创建与本文前面的Auditing加载项相似的加载项,通过移走QAT中成组的控件而不是添加自定义的选项卡。不巧的是,Microsoft选择了放弃这项功能,而是设置startFromScratch=”true”来限制QAT定制到“独特的”应用程序。
QAT有两部分——一部分控件被所有打开的控件所共享,而一部分控件则仅当该文档处于活动状态时显示在QAT中。可以使用一般的<control>类型、<button>控件和分隔器添加内置控件到这两个区域中:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon>
    <qat>
      <sharedControls>
        <control>,<button> 或 <separator> 类型
      </sharedControls>
      <documentControls>
        <control>,<button> 或 <separator> 类型
      </documentControls>
    </qat>
  </ribbon>
</customUI>

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-3-13 09:18 | 显示全部楼层
控制选项卡、选项设置和组
<tabs>、<tab>、<contextualTabs>、<tabSet>和<group>全都用于提供Ribbon的结构。本文中,您已经用各种方式使用了选项卡和组。tabSet元素提供对内置上下文选项卡的访问,例如,选取图表时,Excel显示三组上下文相关的图表工具选项卡。您可以使用下面的XML添加一个自定义组到图表工具设计选项卡中:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon>
    <contextualTabs>
      <tabSet idMso="TabSetChartTools">
        <tab idMso="TabChartToolsDesign">
          <group id="MyChartGroup">
            <! -- All control types -->
          </group>
        </tab>
      </tabSet>
    </contextualTabs>
  </ribbon>
</customUI>
Microsoft对处理选项卡、上下文相关选项卡和组设置了一些限制,包括:
(1) 不能创建自已的上下文相关的tabSet,但仅可以指向内置的
(2) 能添加自定义选项卡到选项卡组中以及自定义组到内置选项卡中
(3) 不能添加控件到内置组中
(4) 能添加内置组到不同的选项卡(内置或自定义的)
(5) 能使内置选项卡或组不可见
(6) 能移动选项卡或组到另一个之前或之后
可以通过设置<tab>和<group>元素合适的属性来获得:
(1) visible=”false”隐藏选项卡或组
(2) insertAfterMso=”TabData”移动或添加选项卡或组到一个内置的选项卡或组之后
(3) insertBeforeMso=”GroupZoom”移动或添加选项卡或组到一个内置的选项卡或组之前
(4) insertAfterQ=”Q:SharedTab”移动或添加选项卡或组在一个限定的自定义选项卡或组之后
(5) insertBeforeQ=”Q:SharedGroup”移动或添加选项卡或组在一个限定的自定义选项卡或组之前

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-3-13 09:19 | 显示全部楼层
动态控件
Ribbon被设计成为一个包含选项卡、组和控件的静态的结构,在处理Excel时,Ribbon中所有的控件都在相同的地方且有相同的结构、尺寸和动作。Ribbon中唯一可以被考虑为动态的部分是上下文相关的选项卡、Window列表和File MRU——仅改变上下文选项卡可见性,结构仍然保持不变。
在RibbonX设计中反映的原理是XML定制的限制,必须在前面进行定义且硬编码到文档文件中,在VBA中没有运行时提供XML的机制。事实上,如果赞同该原理,则不需要在运行时提供XML,因为getLabel、getImage和其它的回调对任何局部需求都是足够的。
然而,有时候该原理也不适用——Window菜单是一个例子。如果当打开或关闭工作簿,或者添加和删除工作表时,如果代码改变了命令条结构,当移动CommandBar代码去使用Ribbon时可能也有问题。
幸运的是,Microsoft认识到在UIs方面的某些实质性的需求,并且提供了四个控件,这些控件的内容能在运行时提供。它们是comboBox、dropDown、gallery和dynamicMenu控件,使用一组回调提供内容,控件开始显示时调用并且它们会明确地标记为无效。它们也有相当有用的invalidateContentOnDrop属性,如果设置为true则每次都调用回调,否则只是在控件下拉前调用。

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-3-13 09:20 | 显示全部楼层
dropDown,comboBox和gallery
这些控件实质上是三种下拉控件的样式,gallery下拉显示一个二维栅格图像和/或标签,dropDown控件和comboBox控件可以是静态的,在XML中以<item>控件包含它们的内容。可以在运行时通过使用getItemCount、getItemID、getItemLabel、getItemImage、getItemScreentip或getItemSupertip回调放置所有三个控件。至少,必须使用getItemCount提供列表中的项目数。剩下的getItem回调将使用项目索引值传递调用,需要为每个项目使用getItemID提供一个ID,且使用getItemImage或getItemLabel将分别提供图像或标签。dropDown和comboBox控件通常带有图像和标签会看起来更好,而gallery被设计成作为一组栅格图像会看起来更好。在各种情况下,dropDown或gallery的onAction回调提供所选项目的ID和索引号作为参数(comboBox仅有一个onChange回调提供文本)。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

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

GMT+8, 2024-4-26 12:03 , Processed in 0.044642 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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