Как добавить пользовательскую вкладку ленты с помощью VBA? - PullRequest
91 голосов
/ 13 января 2012

Я ищу способ добавить пользовательскую вкладку на ленте Excel, которая будет содержать несколько кнопок. Я случайно наткнулся на некоторые ресурсы, обращающиеся к нему через Google, но все выглядят хитроумно и безумно сложно.

Какой быстрый и простой способ сделать это? Мне бы хотелось, чтобы новая вкладка загружалась при загрузке моего VBA в Excel.

ОБНОВЛЕНИЕ : Я попробовал этот пример из здесь , но получил ошибку "Требуется объект" в последней инструкции:

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

Ответы [ 6 ]

140 голосов
/ 13 января 2012

AFAIK, вы не можете использовать VBA Excel для создания настраиваемой вкладки на ленте Excel.Однако вы можете скрыть / сделать видимым компонент ленты, используя VBA.Кроме того, ссылка, которую вы упомянули выше, предназначена для MS Project, а не для MS Excel.

Я создаю вкладки для приложений и надстроек Excel с помощью этой бесплатной утилиты Custom UI Editor .


Редактировать: для удовлетворения нового запроса от OP

Учебное пособие

Вот краткое обещанное руководство:

  1. После того, как вы установили Custom UI Editor (CUIE), откройте его и затем нажмите File |Откройте и выберите соответствующий файл Excel.Пожалуйста, убедитесь, что файл Excel закрыт, прежде чем открывать его через CUIE.В качестве примера я использую новый лист.

    enter image description here

  2. Щелкните правой кнопкой мыши, как показано на рисунке ниже, и выберите «Часть пользовательского интерфейса Office 2007»,Будет вставлено «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» - это то, что вы увидите в данный момент. Вы можете загрузить дополнительные идентификаторы изображений здесь .

    onAction="Callback": «Обратный вызов» - это название процедуры, которая запускается при нажатии на кнопку.

Демо

Итак, давайте создадим 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

Надеюсь, это поможет!

26 голосов
/ 17 июня 2015

Мне удалось сделать это с VBA в Excel 2013. Никаких специальных редакторов не требовалось.Все, что вам нужно, это редактор кода Visual Basic, который можно открыть на вкладке Разработчик.Вкладка «Разработчик» по умолчанию не отображается, поэтому ее необходимо включить в меню «Файл»> «Параметры»> «Настройка ленты».На вкладке Разработчик нажмите кнопку 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

Вызовите саб LoadCustRibbon в открытой книге Wookbook и вызовите саб ClearCustRibbon в событии Before_Close файла кода ThisWorkbook.

19 голосов
/ 20 марта 2014

Я боролся как сумасшедший, но это на самом деле правильный ответ.Что бы это ни стоило, я упустил следующее:

  1. Как говорят другие, невозможно создать ленту CustomUI с VBA, однако , вам не нужноto!
  2. Идея состоит в том, чтобы создать код ленты xml с помощью файла Excel> Параметры> Настройка ленты, а затем экспортировать ленту в файл .customUI (это просто текстовый файл с xml в нем)
  3. Теперь приходит хитрость : вы можете включить код .customUI в ваш файл .xlsm, используя инструмент MS, на который они ссылаются здесь, скопировав код из .customUIfile
  4. Как только он включен в файл .xlsm, каждый раз, когда вы его открываете, определенная вами лента добавляется к ленте пользователя, но используйте Или вы потеряете остаток ленты.При выходе из книги лента удаляется.
  5. Теперь все просто, создайте ленту, скопируйте код XML, характерный для вашей ленты, из файла .customUI и поместите его в файл.обертка, как показано выше (... ваш xml </ tabs ...) </li>

Кстати, страница, объясняющая это на сайте Рона, теперь находится на 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

17 голосов
/ 17 марта 2015

Ответы здесь специфичны для использования редактора пользовательского интерфейса. Я потратил некоторое время на создание интерфейса без этой замечательной программы, поэтому я документирую решение здесь, чтобы помочь другим решить, нужен ли им этот пользовательский редактор пользовательского интерфейса.

Я наткнулся на следующую веб-страницу справки Microsoft - https://msdn.microsoft.com/en-us/library/office/ff861787.aspx. Здесь показано, как настроить интерфейс вручную, но у меня возникли некоторые проблемы при указании моего кода надстройки.

Чтобы кнопки работали с вашими собственными макросами, настройте макрос в своих подпрограммах .xlam так, чтобы он вызывался, как описано в этом ответе SO - Вызов макроса Excel с ленты . По сути, вам нужно добавить этот параметр «control As IRibbonControl» в любой модуль, указанный в вашей ленте xml. Кроме того, ваша лента XML должна иметь синтаксис onAction = "myaddin! Mymodule.mysub", чтобы правильно вызывать любые модули, загруженные надстройкой.

Используя эти инструкции, я смог создать надстройку Excel (файл .xlam), в которую загружалась пользовательская вкладка, когда мой VBA загружался в Excel вместе с надстройкой. Кнопки выполняют код из надстройки и пользовательской вкладка удаляется при удалении надстройки.

7 голосов
/ 01 июля 2016

В дополнение к ответу Рой-Ки Брайант этот код полностью работает в 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

Не забудьте сохранить и снова открыть книгу.Надеюсь, это поможет!

3 голосов
/ 16 февраля 2019

Я столкнулся с трудностями с решением Рой-Ки Брайант, когда несколько надстроек пытались изменить ленту. У меня также нет доступа администратора на моем рабочем компьютере, что исключает установку Custom UI Editor. Итак, если вы находитесь в одной лодке со мной, вот альтернативный пример для настройки ленты с использованием только Excel. Обратите внимание, что мое решение взято из руководства Microsoft .


  1. Создание файла / файлов Excel, ленты которых вы хотите настроить. В моем случае я создал два файла .xlam, Chart Tools.xlam и Priveleged UDFs.xlam, чтобы продемонстрировать, как несколько надстроек могут взаимодействовать с лентой.
  2. Создайте папку с любым именем папки для каждого файла, который вы только что создали.
  3. Внутри каждой из созданных вами папок добавьте папки customUI и _rels.
  4. Внутри каждой папки customUI создайте файл customUI.xml. Файл customUI.xml подробно описывает, как файлы Excel взаимодействуют с лентой. Часть 2 руководства Microsoft охватывает элементы в файле customUI.xml.

Мой customUI.xml файл для 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>

Мой customUI.xml файл для 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>
  1. Для каждого файла, созданного на шаге 1, добавьте суффикс .zip к имени файла. В моем случае я переименовал Chart Tools.xlam в Chart Tools.xlam.zip и Privelged UDFs.xlam в Priveleged UDFs.xlam.zip.
  2. Откройте каждый файл .zip и перейдите в папку _rels. Скопируйте файл .rels в папку _rels, созданную на шаге 3. Измените файл каждый .rels в текстовом редакторе. Из руководства Microsoft

Между последним <Relationship> элементом и завершающим <Relationships> элемент, добавьте строку, которая создает отношения между файлом документа и файлом настройки. Убедитесь, что вы правильно укажите имена папок и файлов.

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

Мой .rels файл для Chart Tools.xlam выглядит следующим образом

<?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 выглядит следующим образом.

<?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>
  1. Замените .rels файлы в каждом .zip файле на .rels файл / файлы, которые вы изменили на предыдущем шаге.
  2. Скопируйте и вставьте созданную вами папку .customUI в домашний каталог .zip file / files.
  3. Удалите расширение .zip из созданных вами файлов Excel .
  4. Если вы создали .xlam файлов, вернитесь в Excel и добавьте их в свои надстройки Excel.
  5. Если применимо, создайте обратных вызовов в каждой из ваших надстроек. На шаге 4 в моих кнопках есть onAction ключевые слова. Ключевое слово onAction указывает, что при запуске содержащего элемента приложение Excel запускает подпрограмму, заключенную в кавычки, сразу после ключевого слова onAction. Это известно как обратный вызов . В моих .xlam файлах у меня есть модуль под названием CallBacks, в который я включил свои подпрограммы обратного вызова.

CallBacks Module

Мой CallBacks модуль для Chart Tools.xlam выглядит как

Option 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

Мой CallBacks модуль для Priveleged 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 IRibbonControl. Если вы не соответствуете требуемой подписи обратного вызова, вы получите сообщение об ошибке при компиляции вашего проекта / проектов VBA. Часть 3 руководства Microsoft определяет все сигнатуры обратного вызова.


Вот как выглядит мой законченный пример

Finished Product


Несколько заключительных советов

  1. Если вы хотите, чтобы надстройки совместно использовали элементы ленты, используйте ключевые слова idQ и xlmns:. В моем примере оба Chart Tools.xlam и Priveleged UDFs.xlam имеют доступ к элементам с idQ, равными x:chartToolsTab и x:privelgedUDFsTab. Чтобы это работало, требуется x:, и я определил его пространство имен в первой строке моего customUI.xml файла, <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" xmlns:x="sao">. В разделе Два способа настройки пользовательского интерфейса Fluent в руководстве для Microsoft приведены некоторые дополнительные сведения.
  2. Если вы хотите, чтобы надстройки имели доступ к элементам ленты, поставляемым с Excel, используйте ключевое слово isMSO. В разделе Два способа настройки пользовательского интерфейса Fluent в руководстве для Microsoft приведены некоторые дополнительные сведения.
...