編輯

共用方式為


Change the availability of add-in commands

When some functionality in your add-in should only be available in certain contexts, you can programmatically configure your custom add-in commands to only be available in these contexts. For example, a function that changes the header of a table should only be available when the cursor is in a table.

Note

  • This article assumes that you're familiar with the basic concepts for add-in commands. Please review it if you haven't worked with add-in commands (custom menu items and ribbon buttons) recently.

Supported capabilities

You can programmatically change the availability of an add-in command for the following capabilities.

  • Ribbon buttons, menus, and tabs.
  • Context menu items.

Office application and requirement set support

The following table outlines the Office applications that support configuring the availability of add-in commands. It also lists the requirement sets needed to use the API.

Add-in command capability Requirement set Supported Office applications
Ribbon buttons, menus, and tabs RibbonApi 1.1
  • Excel
  • PowerPoint
  • Word
Context menu items ContextMenuApi 1.1
  • Excel
  • PowerPoint
  • Word

Tip

To learn how to test for platform support with requirement sets, see Office versions and requirement sets.

Configure a shared runtime

To change the availability of a ribbon or context menu control or item, the manifest of your add-in must first be configured to use a shared runtime. For guidance on how to set up a shared runtime, see Configure your Office Add-in to use a shared runtime.

Programmatically change the availability of an add-in command

Deactivate ribbon controls at launch

Note

Only the controls on the ribbon can be deactivated when the Office application starts. You can't deactivate custom controls added to a context menu at launch.

By default, a custom button or menu item on the ribbon is available for use when the Office application launches. To deactivate it when Office starts, you must specify this in the manifest. The process depends on which type of manifest your add-in uses.

Unified manifest for Microsoft 365

Note

The unified manifest for Microsoft 365 can be used in production Outlook add-ins. It's available only as a preview for Excel, PowerPoint, and Word add-ins.

Just add an "enabled" property with the value false to the control or menu item object. The following shows the basic structure.

"extensions": [
    ...
    {
        ...
        "ribbons": [
            ...
            {
                ...
                "tabs": [
                    {
                        "id": "MyTab",
                        "groups": [
                            {
                                ...
                                "controls": [
                                    {
                                        "id": "Contoso.MyButton1",
                                        ...
                                        "enabled": false
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

Add-in only manifest

Just add an Enabled element immediately below (not inside) the Action element of the control item. Then, set its value to false.

The following shows the basic structure of a manifest that configures the <Enabled> element.

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

Change the availability of a ribbon control

To update the availability of a button or menu item on the ribbon, perform the following steps.

  1. Create a RibbonUpdaterData object that specifies the following:
    • The IDs of the command, including its parent group and tab. The IDs must match those declared in the manifest.
    • The availability status of the command.
  2. Pass the RibbonUpdaterData object to the Office.ribbon.requestUpdate() method.

The following is a simple example. Note that "MyButton", "OfficeAddinTab1", and "CustomGroup111" are copied from the manifest.

function enableButton() {
    const ribbonUpdaterData = {
        tabs: [
            {
                id: "OfficeAppTab1",
                groups: [
                    {
                      id: "CustomGroup111",
                      controls: [
                        {
                            id: "MyButton",
                            enabled: true
                        }
                      ]
                    }
                ]
            }
        ]
    };

    Office.ribbon.requestUpdate(ribbonUpdaterData);
}

There are several interfaces (types) to make it easier to construct the RibbonUpdateData object.

The following is the equivalent example in TypeScript and it makes use of these types.

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);
}

Tip

You can await the call of requestUpdate() if the parent function is asynchronous, but note that the Office application controls when it updates the state of the ribbon. The requestUpdate() method queues a request to update. The method will resolve the promise object as soon as it has queued the request, not when the ribbon actually updates.

Toggle tab visibility and the enabled status of a button at the same time

The requestUpdate method is also used to toggle the visibility of a custom contextual tab. For details about this and example code, see Create custom contextual tabs in Office Add-ins.

Change the state in response to an event

A common scenario in which the state of a ribbon or context menu control should change is when a user-initiated event changes the add-in context. Consider a scenario in which a button should be available when, and only when, a chart is activated. Although the following example uses ribbon controls, a similar implementation can be applied to custom items on a context menu.

  1. First, set the <Enabled> element for the button in the manifest to false. For guidance on how to configure this, see Deactivate ribbon controls at launch.

  2. Then, assign handlers. This is commonly done in the Office.onReady function as in the following example. In the example, handlers (created in a later step) are assigned to the onActivated and onDeactivated events of all the charts in an Excel worksheet.

    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();
        });
    });
    
  3. Define the enableChartFormat handler. The following is a simple example. For a more robust way of changing a control's status, see Best practice: Test for control status errors.

    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);
    }
    
  4. Define the disableChartFormat handler. It's identical to the enableChartFormat handler, except that the enabled property of the button object is set to false.

Best practice: Test for control status errors

In some circumstances, the ribbon or context menu doesn't repaint after requestUpdate is called, so the control's clickable status doesn't change. For this reason it's a best practice for the add-in to keep track of the status of its controls. The add-in should conform to the following rules.

  • Whenever requestUpdate is called, the code should record the intended state of the custom buttons and menu items.
  • When a custom control is selected, the first code in the handler should check to see if the button should have been available. If it shouldn't have been available, the code should report or log an error and try again to set the buttons to the intended state.

The following example shows a function that deactivates a button on the ribbon and records the button's status. In this example, chartFormatButtonEnabled is a global boolean variable that's initialized to the same value as the Enabled element for the button in the add-in's manifest. Although the example uses a ribbon button, a similar implementation can be applied to custom items on a context menu.

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;
}

The following example shows how the button's handler tests for an incorrect state of the button. Note that reportError is a function that shows or logs an error.

function chartFormatButtonHandler() {
    if (chartFormatButtonEnabled) {

        // Do work here.

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

Error handling

In some scenarios, Office is unable to update the ribbon or context menu and will return an error. For example, if the add-in is upgraded and the upgraded add-in has a different set of custom add-in commands, then the Office application must be closed and reopened. Until it is, the requestUpdate method will return the error HostRestartNeeded. The following is an example of how to handle this error. In this case, the reportError method displays the error to the user. Although the example uses a ribbon button, a similar implementation can be applied to custom items on a context menu.

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.");
        }
    }
}

See also