如何使用VBA添加自定义功能区选项卡?

时间:2012-01-13 12:49:54

标签: excel vba excel-vba excel-2007 ribbonx

我正在寻找一种在Excel功能区中添加自定义选项卡的方法,该选项卡带有几个按钮。我偶然发现了一些通过谷歌解决它的资源,但看起来都很狡猾,而且非常复杂。

快速简单的方法是什么?当我的VBA加载到Excel中时,我想要加载新标签..

更新: 我从here尝试了这个例子,但在最后一条指令上得到了“需要对象”错误:

Public Sub AddHighlightRibbon()
Dim ribbonXml As String

ribbonXml = "<mso:customUI xmlns:mso=""http://schemas.microsoft.com/office/2009/07/customui"">"
ribbonXml = ribbonXml + "  <mso:ribbon>"
ribbonXml = ribbonXml + "    <mso:qat/>"
ribbonXml = ribbonXml + "    <mso:tabs>"
ribbonXml = ribbonXml + "      <mso:tab id=""highlightTab"" label=""Highlight"" insertBeforeQ=""mso:TabFormat"">"
ribbonXml = ribbonXml + "        <mso:group id=""testGroup"" label=""Test"" autoScale=""true"">"
ribbonXml = ribbonXml + "          <mso:button id=""highlightManualTasks"" label=""Toggle Manual Task Color"" "
ribbonXml = ribbonXml + "imageMso=""DiagramTargetInsertClassic"" onAction=""ToggleManualTasksColor""/>"
ribbonXml = ribbonXml + "        </mso:group>"
ribbonXml = ribbonXml + "      </mso:tab>"
ribbonXml = ribbonXml + "    </mso:tabs>"
ribbonXml = ribbonXml + "  </mso:ribbon>"
ribbonXml = ribbonXml + "</mso:customUI>"

ActiveProject.SetCustomUI (ribbonXml)
End Sub

8 个答案:

答案 0 :(得分:137)

AFAIK您无法使用VBA Excel在Excel功能区中创建自定义选项卡。但是,您可以使用VBA隐藏/显示功能区组件。此外,您上面提到的链接适用于MS Project而不是MS Excel。

我使用名为Custom UI Editor的免费实用程序为我的Excel应用程序/加载项创建选项卡。


编辑:以适应OP的新请求

教程

这是一个承诺的简短教程:

  1. 安装自定义UI编辑器(CUIE)后,打开它然后单击文件|打开并选择相关的Excel文件。在通过CUIE打开之前,请确保Excel文件已关闭。我使用全新的工作表作为示例。

    enter image description here

  2. 右键单击如下图所示,然后单击“Office 2007自定义UI部件”。它将插入“customUI.xml”

    enter image description here

  3. 下一步单击菜单插入|示例XML |自定义标签。您会注意到基本代码是自动生成的。现在,您已准备好根据自己的要求进行编辑。

    enter image description here

  4. 让我们检查一下代码

    enter image description here

    label="Custom Tab":将“自定义标签”替换为您要为标签指定的名称。暂时让我们称之为“杰罗姆”。

    以下部分添加了自定义按钮。

    <button id="customButton" label="Custom Button" imageMso="HappyFace" size="large" onAction="Callback" />
    

    imageMso:这是将在按钮上显示的图像。 “HappyFace”就是你现在所看到的。 You can download more image ID's here

    onAction="Callback":“回调”是您点击按钮时运行的程序的名称。

  5. 演示

    然后,让我们创建2个按钮并将其命名为“JG Button 1”和“JG Button 2”。让我们保持幸福的面孔作为第一个的形象,让我们保持第二个“太阳”。修改后的代码现在看起来像这样:

    <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
    <ribbon startFromScratch="false">
    <tabs>
    <tab id="MyCustomTab" label="Jerome" insertAfterMso="TabView">
    <group id="customGroup1" label="First Tab">
    <button id="customButton1" label="JG Button 1" imageMso="HappyFace" size="large" onAction="Callback1" />
    <button id="customButton2" label="JG Button 2" imageMso="PictureBrightnessGallery" size="large" onAction="Callback2" />
    </group>
    </tab>
    </tabs>
    </ribbon>
    </customUI>
    

    删除在CUIE中生成的所有代码,然后粘贴上面的代码代替它。保存并关闭CUIE。现在,当您打开Excel文件时,它将如下所示:

    enter image description here

    现在是代码部分。打开VBA编辑器,插入模块,然后粘贴此代码:

    Public Sub Callback1(control As IRibbonControl)
    
        MsgBox "You pressed Happy Face"
    
    End Sub
    
    Public Sub Callback2(control As IRibbonControl)
    
        MsgBox "You pressed the Sun"
    
    End Sub
    

    将Excel文件另存为启用宏的文件。现在,当您点击笑脸或太阳时,您将看到相关的消息框:

    enter image description here

    希望这有帮助!

答案 1 :(得分:26)

我能够在Excel 2013中使用VBA完成此操作。无需特殊编辑器。您只需要Visual Basic代码编辑器,可以在Developer选项卡上访问它。默认情况下,“开发者”选项卡不可见,因此需要在“文件”&gt;“选项”&gt;“自定义功能区”中启用它。在“开发工具”选项卡上,单击“Visual Basic”按钮。代码编辑器将启动。右键单击左侧的Project Explorer窗格。单击插入菜单,然后选择模块。将以下两个潜艇添加到新模块中。

Sub LoadCustRibbon()

Dim hFile As Long
Dim path As String, fileName As String, ribbonXML As String, user As String

hFile = FreeFile
user = Environ("Username")
path = "C:\Users\" & user & "\AppData\Local\Microsoft\Office\"
fileName = "Excel.officeUI"

ribbonXML = "<mso:customUI      xmlns:mso='http://schemas.microsoft.com/office/2009/07/customui'>" & vbNewLine
ribbonXML = ribbonXML + "  <mso:ribbon>" & vbNewLine
ribbonXML = ribbonXML + "    <mso:qat/>" & vbNewLine
ribbonXML = ribbonXML + "    <mso:tabs>" & vbNewLine
ribbonXML = ribbonXML + "      <mso:tab id='reportTab' label='Reports' insertBeforeQ='mso:TabFormat'>" & vbNewLine
ribbonXML = ribbonXML + "        <mso:group id='reportGroup' label='Reports' autoScale='true'>" & vbNewLine
ribbonXML = ribbonXML + "          <mso:button id='runReport' label='PTO' "   & vbNewLine
ribbonXML = ribbonXML + "imageMso='AppointmentColor3'      onAction='GenReport'/>" & vbNewLine
ribbonXML = ribbonXML + "        </mso:group>" & vbNewLine
ribbonXML = ribbonXML + "      </mso:tab>" & vbNewLine
ribbonXML = ribbonXML + "    </mso:tabs>" & vbNewLine
ribbonXML = ribbonXML + "  </mso:ribbon>" & vbNewLine
ribbonXML = ribbonXML + "</mso:customUI>"

ribbonXML = Replace(ribbonXML, """", "")

Open path & fileName For Output Access Write As hFile
Print #hFile, ribbonXML
Close hFile

End Sub

Sub ClearCustRibbon()

Dim hFile As Long
Dim path As String, fileName As String, ribbonXML As String, user As String

hFile = FreeFile
user = Environ("Username")
path = "C:\Users\" & user & "\AppData\Local\Microsoft\Office\"
fileName = "Excel.officeUI"

ribbonXML = "<mso:customUI           xmlns:mso=""http://schemas.microsoft.com/office/2009/07/customui"">" & _
"<mso:ribbon></mso:ribbon></mso:customUI>"

Open path & fileName For Output Access Write As hFile
Print #hFile, ribbonXML
Close hFile

End Sub

在Wookbook中调用LoadCustRibbon sub打开,并在ThisWorkbook代码文件的Before_Close事件中调用ClearCustRibbon子。

答案 2 :(得分:19)

我疯狂地挣扎,但这实际上是正确的答案。对于它的价值,我错过的是:

  1. 正如其他人所说,无法使用VBA创建CustomUI功能区,但是,您不需要!
  2. 您的想法是使用Excel的文件&gt;创建xml功能区代码。选项&gt;自定义功能区,然后将功能区导出到.customUI文件(它只是一个txt文件,其中包含xml)
  3. 现在就是诀窍:您可以使用他们在此处引用的MS工具包含 .xustomUI代码,方法是复制代码。 customUI文件
  4. 一旦它包含在.xlsm文件中,每次打开它时,您定义的功能区都是 添加到用户的功能区 - 但请使用&lt; ribbon startFromScratch =“false”&gt;或者你丢失了剩下的功能区。退出工作簿时,将删除功能区。
  5. 从这里开始很简单,创建功能区,从.customUI文件中复制特定于功能区的xml代码,然后将其放在一个包装器中,如上所示(...&lt; tabs&gt; your xml&lt; ; / tabs ...)
  6. 顺便说一下在Ron的网站上解释它的页面现在是 http://www.rondebruin.nl/win/s2/win002.htm

    以下是关于如何在功能区上启用/禁用按钮的示例 http://www.rondebruin.nl/win/s2/win013.htm

    对于其他xml色带示例,请参阅 http://msdn.microsoft.com/en-us/library/office/aa338202%28v=office.12%29.aspx

答案 3 :(得分:16)

此处的答案特定于使用自定义UI编辑器。我花了一些时间创建没有这个精彩程序的界面,所以我在这里记录解决方案,以帮助其他人决定是否需要自定义UI编辑器。

我遇到了以下微软帮助网页 - https://msdn.microsoft.com/en-us/library/office/ff861787.aspx。这显示了如何手动设置界面,但在指向我的自定义加载项代码时遇到了一些麻烦。

要使按钮与您的自定义宏一起使用,请按照此SO答案 - Calling an excel macro from the ribbon中的说明设置.xlam潜艇中的宏。基本上,您需要添加&#34;控制为IRibbonControl&#34;从您的功能区xml指向的任何模块的参数。另外,你的功能区xml应该有onAction =&#34; myaddin!mymodule.mysub&#34;正确调用add in加载的任何模块的语法。

使用这些说明,我能够创建一个excel添加(.xlam文件),当我的VBA加载到Excel中时加载了自定义选项卡以及添加。按钮执行来自添加和自定义的代码删除添加时,标签会卸载。

答案 4 :(得分:7)

除了Roi-Kyi Bryant的回答,此代码完全适用于Excel 2010.按ALT + F11并弹出VBA编辑器。双击左侧的ThisWorkbook,然后粘贴此代码:

Private Sub Workbook_Activate()

Dim hFile As Long
Dim path As String, fileName As String, ribbonXML As String, user As String

hFile = FreeFile
user = Environ("Username")
path = "C:\Users\" & user & "\AppData\Local\Microsoft\Office\"
fileName = "Excel.officeUI"

ribbonXML = "<mso:customUI      xmlns:mso='http://schemas.microsoft.com/office/2009/07/customui'>" & vbNewLine
ribbonXML = ribbonXML + "  <mso:ribbon>" & vbNewLine
ribbonXML = ribbonXML + "    <mso:qat/>" & vbNewLine
ribbonXML = ribbonXML + "    <mso:tabs>" & vbNewLine
ribbonXML = ribbonXML + "      <mso:tab id='reportTab' label='My Actions' insertBeforeQ='mso:TabFormat'>" & vbNewLine
ribbonXML = ribbonXML + "        <mso:group id='reportGroup' label='Reports' autoScale='true'>" & vbNewLine
ribbonXML = ribbonXML + "          <mso:button id='runReport' label='Trim' " & vbNewLine
ribbonXML = ribbonXML + "imageMso='AppointmentColor3'      onAction='TrimSelection'/>" & vbNewLine
ribbonXML = ribbonXML + "        </mso:group>" & vbNewLine
ribbonXML = ribbonXML + "      </mso:tab>" & vbNewLine
ribbonXML = ribbonXML + "    </mso:tabs>" & vbNewLine
ribbonXML = ribbonXML + "  </mso:ribbon>" & vbNewLine
ribbonXML = ribbonXML + "</mso:customUI>"

ribbonXML = Replace(ribbonXML, """", "")

Open path & fileName For Output Access Write As hFile
Print #hFile, ribbonXML
Close hFile

End Sub

Private Sub Workbook_Deactivate()

Dim hFile As Long
Dim path As String, fileName As String, ribbonXML As String, user As String

hFile = FreeFile
user = Environ("Username")
path = "C:\Users\" & user & "\AppData\Local\Microsoft\Office\"
fileName = "Excel.officeUI"

ribbonXML = "<mso:customUI           xmlns:mso=""http://schemas.microsoft.com/office/2009/07/customui"">" & _
"<mso:ribbon></mso:ribbon></mso:customUI>"

Open path & fileName For Output Access Write As hFile
Print #hFile, ribbonXML
Close hFile

End Sub

不要忘记保存并重新打开工作簿。希望这有帮助!

答案 5 :(得分:2)

多个加载项试图修改功能区时,我在Roi-Kyi Bryant的解决方案中遇到了困难。我的工作计算机上也没有管理员权限,因此无法安装Custom UI Editor。因此,如果您与我同在一条船上,那么这是一个示例的替代方法,可以仅使用Excel自定义功能区。请注意,我的解决方案源自Microsoft guide


  1. 创建要自定义功能区的Excel文件。就我而言,我已经创建了两个.xlamChart Tools.xlam Priveleged UDFs.xlam文件,以演示多个加载项如何与功能区交互。
  2. 为您刚创建的每个文件创建一个具有任何文件夹名称的文件夹。
  3. 在您创建的每个文件夹中,添加一个customUI_rels文件夹。
  4. 在每个customUI文件夹中,创建一个customUI.xml文件。 customUI.xml文件详细说明Excel文件如何与功能区交互。 Part 2 of the Microsoft guide涵盖了customUI.xml文件中的元素。

我用于customUI.xml的{​​{1}}文件看起来像这样

Chart Tools.xlam

我用于<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" xmlns:x="sao"> <ribbon> <tabs> <tab idQ="x:chartToolsTab" label="Chart Tools"> <group id="relativeChartMovementGroup" label="Relative Chart Movement" > <button id="moveChartWithRelativeLinksButton" label="Copy and Move" imageMso="ResultsPaneStartFindAndReplace" onAction="MoveChartWithRelativeLinksCallBack" visible="true" size="normal"/> <button id="moveChartToManySheetsWithRelativeLinksButton" label="Copy and Distribute" imageMso="OutlineDemoteToBodyText" onAction="MoveChartToManySheetsWithRelativeLinksCallBack" visible="true" size="normal"/> </group > <group id="chartDeletionGroup" label="Chart Deletion"> <button id="deleteAllChartsInWorkbookSharingAnAddressButton" label="Delete Charts" imageMso="CancelRequest" onAction="DeleteAllChartsInWorkbookSharingAnAddressCallBack" visible="true" size="normal"/> </group> </tab> </tabs> </ribbon> </customUI> 的{​​{1}}文件看起来像这样

customUI.xml
  1. 对于在步骤1中创建的每个文件,在文件名后缀Priveleged UDFs.xlam。就我而言,我将<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" xmlns:x="sao"> <ribbon> <tabs> <tab idQ="x:privelgedUDFsTab" label="Privelged UDFs"> <group id="privelgedUDFsGroup" label="Toggle" > <button id="initialisePrivelegedUDFsButton" label="Activate" imageMso="TagMarkComplete" onAction="InitialisePrivelegedUDFsCallBack" visible="true" size="normal"/> <button id="deInitialisePrivelegedUDFsButton" label="De-Activate" imageMso="CancelRequest" onAction="DeInitialisePrivelegedUDFsCallBack" visible="true" size="normal"/> </group > </tab> </tabs> </ribbon> </customUI> 重命名为.zip,并将Chart Tools.xlam重命名为Chart Tools.xlam.zip
  2. 打开每个Privelged UDFs.xlam文件,然后导航到Priveleged UDFs.xlam.zip文件夹。将.zip文件复制到您在步骤3中创建的_rels文件夹中。使用文本编辑器编辑每个 .rels文件。来自Microsoft guide
  

最后一个_rels元素和结尾之间   .rels元素,添加创建关系的行   在文档文件和自定义文件之间。确保你   正确指定文件夹和文件名。

<Relationship>

我用于<Relationships>的{​​{1}}文件看起来像这样

<Relationship Type="http://schemas.microsoft.com/office/2006/
  relationships/ui/extensibility" Target="/customUI/customUI.xml" 
  Id="customUIRelID" />

我的.rels的{​​{1}}文件看起来像这样。

Chart Tools.xlam
  1. 将每个<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/> <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/> <Relationship Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="/customUI/customUI.xml" Id="chartToolsCustomUIRel" /> </Relationships> 文件中的.rels文件替换为您在上一步中修改的Priveleged UDFs个文件。
  2. 将您创建的<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/> <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/> <Relationship Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="/customUI/customUI.xml" Id="privelegedUDFsCustomUIRel" /> </Relationships> 文件夹复制并粘贴到.rels个文件的主目录中。
  3. 从创建的Excel文件中删除.zip文件扩展名
  4. 如果您已经创建了.rels个文件,请返回Excel,将其添加到Excel加载项中。
  5. 如果适用,请在每个外接程序中创建回调。在第4步中,我的按钮中有.customUI个关键字。 .zip关键字表示,当触发包含元素时,Excel应用程序将立即在.zip关键字之后触发用引号引起来的子例程。这称为回调。在我的.xlam文件中,有一个名为onAction的模块,其中包含了回调子例程。

CallBacks Module

我的onAction的{​​{1}}模块看起来像

onAction

我的.xlam的{​​{1}}模块看起来像

显式选项

CallBacks

不同的元素具有不同的回调子例程签名。对于按钮,必需的子例程参数为CallBacks。如果您不符合要求的回调签名,则在编译VBA项目时会收到​​错误消息。 Part 3 of the Microsoft guide定义所有回调签名。


这是我完成的示例的样子

Finished Product


一些结束提示

  1. 如果您希望外接程序共享功能区元素,请使用Chart Tools.xlamOption Explicit Public Sub MoveChartWithRelativeLinksCallBack(ByRef control As IRibbonControl) MoveChartWithRelativeLinks End Sub Public Sub MoveChartToManySheetsWithRelativeLinksCallBack(ByRef control As IRibbonControl) MoveChartToManySheetsWithRelativeLinks End Sub Public Sub DeleteAllChartsInWorkbookSharingAnAddressCallBack(ByRef control As IRibbonControl) DeleteAllChartsInWorkbookSharingAnAddress End Sub 关键字。在我的示例中,CallBacksPriveleged UDFs.xlam都可以访问Public Sub InitialisePrivelegedUDFsCallBack(ByRef control As IRibbonControl) ThisWorkbook.InitialisePrivelegedUDFs End Sub Public Sub DeInitialisePrivelegedUDFsCallBack(ByRef control As IRibbonControl) ThisWorkbook.DeInitialisePrivelegedUDFs End Sub 等于ByRef control As IRibbonControlidQ的元素。为此,xlmns:是必需的,并且我已经在我的Chart Tools.xlam文件Priveleged UDFs.xlam的第一行中定义了其命名空间。 Microsoft guide中的自定义Fluent UI的两种方法部分提供了更多详细信息。
  2. 如果您希望外接程序访问Excel附带的Ribbon功能区,请使用idQ关键字。 Microsoft guide中的自定义Fluent UI的两种方法部分提供了更多详细信息。

答案 6 :(得分:1)

另一种方法是从以下页面下载Jan Karel Pieterse的免费Open XML类模块:Editing elements in an OpenXML file using VBA

将其添加到VBA项目后,您可以解压缩Excel文件,使用VBA修改XML,然后使用该类重新压缩文件。

答案 7 :(得分:0)

这是一个适用于 Excel 365 的简单解决方案。

先将此代码输入到空白工作簿中。

Option Explicit

Sub sbHelloWorld()
 MsgBox "Hello World!"
End Sub

这是基本自定义功能区的 XML。我使用记事本将此 XML 粘贴到一个名为“rb_HelloWorld.txt”的文件中,然后将其保存并将其复制到文件夹 - “C:\Users\david\AppData\Local\Microsoft\Office”该文件夹被隐藏以开始它需要取消隐藏。

<mso:customUI      xmlns:mso='http://schemas.microsoft.com/office/2009/07/customui'>
    <mso:ribbon>
        <mso:qat/>
        <mso:tabs>
        <mso:tab idQ="mso:TabDrawInk" visible="false"/>
        <mso:tab id="mso_c1.2A492F1" label="New Tab">
            <mso:group id="mso_c2.2A492F1" label="New Group" autoScale="true">
                <mso:button id="sbHelloWorld" label="sbHelloWorld" imageMso="ListMacros" onAction="sbHelloWorld" visible="true"/>
            </mso:group>
        </mso:tab>
        </mso:tabs>
    </mso:ribbon>
</mso:customUI>

这两个例程用于将新功能区复制到位,然后在工作簿退出时将其删除。

Sub sbCopyFile()
 Dim sOfficeUIDir As String
 Dim sHWFile As String
 Dim sUIFile As String
 Dim sTest As String
 sOfficeUIDir = "C:\Users\david\AppData\Local\Microsoft\Office\"
 sHWFile = sOfficeUIDir & "rb_HelloWorld.txt"
 sUIFile = sOfficeUIDir & "Excel.officeUI"
 sTest = Dir(sHWFile)
 If Not sTest = "" Then
  FileCopy sHWFile, sUIFile
 End If
End Sub



Sub sbDeleteFile()
 Dim sOfficeUIDir As String
 Dim sUIFile As String
 Dim sTest As String
 sOfficeUIDir = "C:\Users\david\AppData\Local\Microsoft\Office\"
 sUIFile = sOfficeUIDir & "Excel.officeUI"
 sTest = Dir(sUIFile)
 If Not sTest = "" Then
  Kill (sUIFile)
 End If
End Sub

可以使用内置过程 Workbook_Activate 和 Workbook_Deactivate 添加和删除自定义功能区。

Private Sub Workbook_Activate()
 Call sbCopyFile
End Sub

Private Sub Workbook_Deactivate()
 Call sbDeleteFile
End Sub

从自定义功能区上的按钮调用例程 sbHelloWorld()。