Включение и отключение команд надстроек

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

Вы также можете указать, включена или отключена команда при открытии клиентского приложения Office.

Примечание.

В этой статье предполагается, что вы уже ознакомились с приведенной ниже документацией. Просмотрите ее, если вы работали с командами надстроек (настраиваемыми элементами меню и кнопками ленты) некоторое время назад.

Поддержка приложений и платформ Office

Api, описанные в этой статье, доступны только в Excel. Однако предварительная версия поддержки в настоящее время доступна в PowerPoint и Word. Подробные сведения о поддержке см. в разделе Набор обязательных элементов RibbonApi 1.1 .

Тестирование поддержки платформ с использованием наборов обязательных элементов

Наборы требований — это именованные группы элементов API. Надстройки Office используют наборы требований, указанные в манифесте, или проверка среды выполнения, чтобы определить, поддерживает ли сочетание приложений Office и платформы API, необходимые надстройке. Дополнительные сведения см. в разделе Версии Office и наборы требований.

API включения и отключения относятся к набору обязательных элементов RibbonApi 1.1 .

Примечание.

Набор обязательных элементов RibbonApi 1.1 пока не поддерживается в манифесте, поэтому его нельзя указать в разделе Требования> манифеста<. Чтобы проверить поддержку, код должен вызвать Office.context.requirements.isSetSupported('RibbonApi', '1.1'). Если и только в том случае, если этот вызов возвращает true, код может вызывать API включения и отключения. Если вызов isSetSupported возвращает false, то все пользовательские команды надстройки включены все время. Необходимо разработать рабочую надстройку и все инструкции из приложения, чтобы учесть, как она будет работать, если набор обязательных элементов RibbonApi 1.1 не поддерживается. Дополнительные сведения и примеры использования isSetSupportedсм. в разделе Указание приложений Office и требований к API, особенно проверки среды выполнения для поддержки методов и наборов требований. (Раздел Указание версий и платформ Office, которые могут размещать надстройки этой статьи, не применяется к ленте 1.1.)

Необходима общая среда выполнения

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

  1. В элементе манифеста Runtimes добавьте следующий дочерний элемент: <Runtime resid="Contoso.SharedRuntime.Url" lifetime="long" />. (Если в манифесте еще <нет элемента Runtimes> , создайте его в качестве первого дочернего <элемента в элементе Host> в <разделе VersionOverrides> .)

  2. В разделе Resources.Urls манифеста добавьте следующий дочерний элемент:<bt:Url id="Contoso.SharedRuntime.Url" DefaultValue="https://{MyDomain}/{path-to-start-page}" />, где {MyDomain} домен надстройки и {path-to-start-page}путь к начальной странице надстройки; например: <bt:Url id="Contoso.SharedRuntime.Url" DefaultValue="https://localhost:3000/index.html" />.

  3. В зависимости от того, содержит ли надстройка область задач, файл функции или настраиваемую функцию Excel, необходимо выполнить одно или несколько из следующих трех шагов.

    • Если надстройка содержит область задач, задайте resid атрибут Action.Элемент SourceLocation точно в ту же строку, что и для resid<элемента Runtime> на шаге 1, например Contoso.SharedRuntime.Url. Элемент должен выглядеть следующим образом:<SourceLocation resid="Contoso.SharedRuntime.Url"/>.
    • Если надстройка содержит настраиваемую функцию Excel, задайте resid атрибут Page.Элемент SourceLocation точно такой же строке, как для resid<элемента Runtime> на шаге 1, например Contoso.SharedRuntime.Url. Элемент должен выглядеть следующим образом:<SourceLocation resid="Contoso.SharedRuntime.Url"/>.
    • Если надстройка содержит файл функции, задайте resid атрибуту элемента FunctionFile точно ту же строку, которая использовалась для resid<элемента Runtime> на шаге 1, например Contoso.SharedRuntime.Url. Элемент должен выглядеть следующим образом:<FunctionFile resid="Contoso.SharedRuntime.Url"/>.

Установка состояния "Отключено" по умолчанию

По умолчанию при запуске приложения Office любая команда надстройки включается. Если вы хотите, чтобы при запуске приложения Office настраиваемая кнопка или элемент меню были отключены, укажите это в манифесте. Просто добавьте элемент Enabled (со значениемfalse) сразу под (не внутри) элемента Action в объявлении элемента управления. Ниже показана базовая структура.

<OfficeApp ...>
  ...
  <VersionOverrides ...>
    ...
    <Hosts>
      <Host ...>
        ...
        <DesktopFormFactor>
          <ExtensionPoint ...>
            <CustomTab ...>
              ...
              <Group ...>
                ...
                <Control ... id="Contoso.MyButton3">
                  ...
                  <Action ...>
                  <Enabled>false</Enabled>
...
</OfficeApp>

Изменение состояния программными средствами

Ниже приведены основные действия по изменению состояния "Включено" команды надстройки.

  1. Создайте объект RibbonUpdaterData , который (1) указывает команду и ее родительскую группу и вкладку по идентификаторам, объявленным в манифесте; и (2) указывает состояние включенной или отключенной команды.
  2. Перенесите объект RibbonUpdaterData в метод Office.ribbon.requestUpdate().

Ниже приведен простой пример. Обратите внимание, что myButton, OfficeAddinTab1 и CustomGroup111 копируются из манифеста.

function enableButton() {
    Office.ribbon.requestUpdate({
        tabs: [
            {
                id: "OfficeAppTab1", 
                groups: [
                    {
                      id: "CustomGroup111",
                      controls: [
                        {
                            id: "MyButton", 
                            enabled: true
                        }
                      ]
                    }
                ]
            }
        ]
    });
}

Кроме того, мы предоставляем несколько интерфейсов (типов) для упрощения создания объекта RibbonUpdateData. Ниже приводится аналогичный пример в TypeScript, в котором используются эти типы.

const enableButton = async () => {
    const button: Control = {id: "MyButton", enabled: true};
    const parentGroup: Group = {id: "CustomGroup111", controls: [button]};
    const parentTab: Tab = {id: "OfficeAddinTab1", groups: [parentGroup]};
    const ribbonUpdater: RibbonUpdaterData = { tabs: [parentTab]};
    Office.ribbon.requestUpdate(ribbonUpdater);
}

Вы можете await вызвать requestUpdate(), если родительская функция является асинхронной, но обратите внимание, что приложение Office управляет обновлением состояния ленты. Метод requestUpdate() ставит запрос на обновление в очередь. Метод разрешает объект promise сразу же, как только он помещает запрос в очередь, а не при фактическом обновлении ленты.

Изменение состояния в ответ на событие

Обычно состояние ленты необходимо изменить, когда инициированное пользователем событие изменяет контекст надстройки.

Рассмотрим сценарий, в котором кнопка должна быть включена, только когда активирована диаграмма. Во-первых, задайте значение false для элемента Enabled для кнопки в манифесте. Пример см. выше.

Во-вторых, назначьте обработчиков. Обычно это делается в функции Office.onReady , как в следующем примере, которая назначает обработчики (созданные на более позднем шаге) событиям onActivated и onDeactivated всех диаграмм на листе.

Office.onReady(async () => {
    await Excel.run(context => {
        const charts = context.workbook.worksheets
            .getActiveWorksheet()
            .charts;
        charts.onActivated.add(enableChartFormat);
        charts.onDeactivated.add(disableChartFormat);
        return context.sync();
    });
});

В-третьих, определите обработчик enableChartFormat. Ниже приведен простой пример. Более надежный способ изменения состояния элемента управления см. в разделе Рекомендация: проверка на наличие ошибок в состоянии элементов управления ниже.

function enableChartFormat() {
    const button = {
                  id: "ChartFormatButton", 
                  enabled: true
                 };
    const parentGroup = {
                       id: "MyGroup",
                       controls: [button]
                      };
    const parentTab = {
                     id: "CustomChartTab", 
                     groups: [parentGroup]
                    };
    const ribbonUpdater = {tabs: [parentTab]};
    Office.ribbon.requestUpdate(ribbonUpdater);
}

В-четвертых, определите обработчик disableChartFormat. Он будет идентичен enableChartFormat, только для свойства объекта кнопки enabled будет задано значение false.

Одновременное включение видимости вкладки и состояние включенной кнопки

Метод requestUpdate также используется для переключения видимости пользовательской контекстной вкладки. Дополнительные сведения об этом и примере кода см. в статье Создание пользовательских контекстных вкладок в надстройках Office.

Рекомендация: проверка на наличие ошибок в состоянии элементов управления

В некоторых случаях после вызова requestUpdate лента не обновляется, поэтому гиперсостояние элемента управления не изменяется. По этой причине рекомендуется отслеживать состояние элементов управления надстройки. Надстройка должна соответствовать следующим правилам.

  1. При вызове requestUpdate в коде указывается предполагаемое состояние настраиваемых кнопок и элементов меню.
  2. При щелчке пользовательского элемента управления первый код в обработчике проверяет, должна ли кнопка быть интерактивной. Если нет, код сообщит об ошибке или запишет ее в журнал и попробует еще раз установить для кнопок предполагаемое состояние.

В приведенном ниже примере показана функция, с помощью которой можно отключить кнопку и записать ее состояние. Обратите внимание, что chartFormatButtonEnabled — глобальная логическая переменная, которая инициализируется до того же значения, что и элемент Enabled для кнопки в манифесте.

function disableChartFormat() {
    const button = {
                  id: "ChartFormatButton", 
                  enabled: false
                 };
    const parentGroup = {
                       id: "MyGroup",
                       controls: [button]
                      };
    const parentTab = {
                     id: "CustomChartTab", 
                     groups: [parentGroup]
                    };
    const ribbonUpdater = {tabs: [parentTab]};
    Office.ribbon.requestUpdate(ribbonUpdater);

    chartFormatButtonEnabled = false;
}

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

function chartFormatButtonHandler() {
    if (chartFormatButtonEnabled) {

        // Do work here

    } else {
        // Report the error and try again to disable.
        reportError("That action is not possible at this time.");
        disableChartFormat();
    }
}

Обработка ошибок

В некоторых случаях Office не может обновить ленту и возвращает ошибку. Например, если после обновления у надстройки другой набор настраиваемых команд, приложение Office необходимо закрыть и снова открыть. Пока это действие не будет выполнено, метод requestUpdate будет возвращать ошибку HostRestartNeeded. Ниже приведен пример обработки этой ошибки. В этом случае метод reportError выводит сообщение об ошибке для пользователя.

function disableChartFormat() {
    try {
        const button = {
                      id: "ChartFormatButton", 
                      enabled: false
                     };
        const parentGroup = {
                           id: "MyGroup",
                           controls: [button]
                          };
        const parentTab = {
                         id: "CustomChartTab", 
                         groups: [parentGroup]
                        };
        const ribbonUpdater = {tabs: [parentTab]};
        Office.ribbon.requestUpdate(ribbonUpdater);

        chartFormatButtonEnabled = false;
    }
    catch(error) {
        if (error.code == "HostRestartNeeded"){
            reportError("Contoso Awesome Add-in has been upgraded. Please save your work, close the Office application, and restart it.");
        }
    }
}