Habilitar y deshabilitar comandos de complementos

Cuando es necesario que algunas de las funciones de su complemento estén disponibles solo en ciertos contextos, puede habilitar o deshabilitar los comandos de complemento personalizados mediante programación. Por ejemplo, una función que cambie el encabezado de una tabla solo se debe habilitar si el cursor está en una tabla.

También puede especificar si el comando está habilitado o deshabilitado cuando se abre la aplicación cliente de Office.

Nota:

En este artículo se da por sentado que está familiarizado con la siguiente documentación. Revíselas si no ha trabajado recientemente con los comandos de complemento (elementos de menú personalizados y botones de la cinta de opciones).

Compatibilidad con aplicaciones y plataformas de Office

Las API descritas en este artículo solo están disponibles en Excel. Sin embargo, la compatibilidad con la versión preliminar está disponible actualmente en PowerPoint y Word. Para obtener detalles completos de soporte técnico, consulte el conjunto de requisitos de RibbonApi 1.1 .

Comprobar si la plataforma es compatible con conjuntos de requisitos

Los conjuntos de requisitos son grupos de miembros de la API con nombre. Los complementos de Office usan conjuntos de requisitos especificados en el manifiesto o usan una comprobación en tiempo de ejecución para determinar si una combinación de plataforma y aplicación de Office admite las API que necesita un complemento. Para obtener más información, vea Versiones y conjuntos de requisitos de Office.

Las API enable/disable pertenecen al conjunto de requisitos RibbonApi 1.1 .

Nota:

El conjunto de requisitos RibbonApi 1.1 aún no se admite en el manifiesto, por lo que no se puede especificar en la sección Requisitos> del< manifiesto. Para probar la compatibilidad, el código debe llamar a Office.context.requirements.isSetSupported('RibbonApi', '1.1'). Si , y solo si, esa llamada devuelve true, el código puede llamar a las API enable/disable. Si la llamada de isSetSupported devuelve false, todos los comandos de complemento personalizados se habilitan todo el tiempo. Debe diseñar el complemento de producción y cualquier instrucción desde la aplicación para tener en cuenta cómo funcionará cuando no se admita el conjunto de requisitos RibbonApi 1.1 . Para obtener más información y ejemplos de uso isSetSupportedde , vea Especificar aplicaciones de Office y requisitos de API, especialmente Comprobaciones en tiempo de ejecución para obtener compatibilidad con métodos y conjuntos de requisitos. (La sección Especificar qué versiones y plataformas de Office pueden hospedar el complemento de ese artículo no se aplica a la cinta de opciones 1.1).

Tiempo de ejecución compartido

Las API y el marcado de manifiesto descritos en este artículo requieren que el manifiesto del complemento especifique que debe usar un entorno de ejecución compartido. Para ello, siga estos pasos.

  1. En el elemento Runtimes en el manifiesto, agregue el siguiente elemento secundario: <Runtime resid="Contoso.SharedRuntime.Url" lifetime="long" />. (Si aún no hay un <elemento Runtimes> en el manifiesto, créelo como el primer elemento secundario en el <elemento Host> de la <sección VersionOverrides> ).

  2. En la sección Resources.Urls del manifiesto, agregue el siguiente elemento secundario: <bt:Url id="Contoso.SharedRuntime.Url" DefaultValue="https://{MyDomain}/{path-to-start-page}" />, donde {MyDomain} es el dominio del complemento y {path-to-start-page} es la ruta de acceso a la página de inicio del complemento, por ejemplo: <bt:Url id="Contoso.SharedRuntime.Url" DefaultValue="https://localhost:3000/index.html" />.

  3. En función de si el complemento contiene un panel de tareas, un archivo de función o una función personalizada de Excel, debe realizar uno o varios de los tres pasos siguientes.

    • Si el complemento contiene un panel de tareas, establezca el resid atributo de action.Elemento SourceLocation exactamente la misma cadena que usó para el resid del elemento Runtime> en el< paso 1; por ejemplo, Contoso.SharedRuntime.Url. El elemento debería tener un aspecto similar al siguiente: <SourceLocation resid="Contoso.SharedRuntime.Url"/>.
    • Si el complemento contiene una función personalizada de Excel, establezca el resid atributo de page.Elemento SourceLocation exactamente la misma cadena que usó para el resid del elemento Runtime> en el< paso 1; por ejemplo, Contoso.SharedRuntime.Url. El elemento debería tener un aspecto similar al siguiente: <SourceLocation resid="Contoso.SharedRuntime.Url"/>.
    • Si el complemento contiene un archivo de función, establezca el resid atributo del elemento FunctionFile en exactamente la misma cadena que usó para el resid del elemento Runtime> en el< paso 1; por ejemplo, Contoso.SharedRuntime.Url. El elemento debería tener un aspecto similar al siguiente: <FunctionFile resid="Contoso.SharedRuntime.Url"/>.

Establecer el estado predeterminado en deshabilitado

De forma predeterminada, cualquier comando de complemento está habilitado cuando se inicia la aplicación de Office. Si desea que un botón o un elemento de menú personalizado se deshabilite cuando se inicie la aplicación de Office, especifíquelo en el manifiesto. Solo tiene que agregar un elemento habilitado (con el valor false) inmediatamente debajo (no dentro) del elemento Action en la declaración del control. A continuación se muestra la estructura básica.

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

Cambiar el estado mediante programación

Los pasos esenciales para cambiar el estado de habilitado de un comando de complemento son:

  1. Cree un objeto RibbonUpdaterData que (1) especifique el comando, y su grupo y pestaña primarios, por sus identificadores como se declara en el manifiesto; y (2) especifica el estado habilitado o deshabilitado del comando.
  2. Pase el objeto RibbonUpdaterData al método Office.ribbon.requestUpdate().

A continuación puede ver un ejemplo simple. Tenga en cuenta que "MyButton", "OfficeAddinTab1" y "CustomGroup111" se copian del manifiesto.

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

También proporcionamos varias interfaces (tipos) para facilitar la construcción del objeto RibbonUpdateData. El siguiente es el ejemplo equivalente de TypeScript y usa estos tipos.

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

Puede await llamar a requestUpdate() si la función primaria es asincrónica, pero tenga en cuenta que la aplicación de Office controla cuando actualiza el estado de la cinta de opciones. El método requestUpdate() coloca una solicitud en la cola de actualización. El método resolverá el objeto de promesa tan pronto como haya puesto en cola la solicitud, no cuando la cinta de opciones se actualice realmente.

Cambiar el estado en respuesta a un evento

Un escenario habitual en el que el estado de la cinta de opciones debería cambiar es cuando un evento iniciado por el usuario cambia el contexto del complemento.

Considere un escenario en el que se debe habilitar un botón cuando, y solo cuando, se activa un gráfico. El primer paso es establecer el elemento activado para el botón del manifiesto en false. Vea más arriba un ejemplo.

En segundo lugar, asigne controladores. Esto suele hacerse en la función Office.onReady , como en el ejemplo siguiente, que asigna controladores (creados en un paso posterior) a los eventos onActivated y onDeactivated de todos los gráficos de la hoja de cálculo.

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

En tercer lugar, defina el controlador de enableChartFormat. El siguiente es un ejemplo sencillo, pero consulte procedimiento recomendado: probar errores de estado de control más adelante para obtener un método más robusto para cambiar el estado de un control.

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

En cuarto lugar, defina el controlador de disableChartFormat. Es idéntico a enableChartFormat excepto en que la propiedad enabled del objeto de botón se establecería en false.

Alternar la visibilidad de tabulación y el estado habilitado de un botón al mismo tiempo

El método requestUpdate también se usa para alternar la visibilidad de una pestaña contextual personalizada. Para obtener más información sobre este código y de ejemplo, vea Crear pestañas contextuales personalizadas en complementos de Office.

Procedimiento recomendado: probar errores de estado de control

En algunas circunstancias, la cinta de opciones no se vuelve a dibujar una vez que se llama a requestUpdate, por lo que el estado de clic el control no cambia. Por este motivo, se recomienda que el complemento realice un seguimiento del estado de sus controles. El complemento debe cumplir las reglas siguientes.

  1. Siempre que se llama a requestUpdate, el código debe registrar el estado deseado de los botones personalizados y los elementos del menú.
  2. Cuando se hace clic en un control personalizado, el primer código del controlador debe comprobar si se debería poder hacer clic en el botón. Si no es así, el código debería notificar o registrar un error y volver a establecer los botones en el estado deseado.

En el ejemplo siguiente se muestra una función que deshabilita un botón y registra el estado del botón. Tenga en cuenta que chartFormatButtonEnabled es una variable booleana global que se inicializa en el mismo valor que el elemento Enabled para el botón del manifiesto.

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

En el ejemplo siguiente se muestra cómo comprueba el controlador del botón si el botón está en un estado incorrecto. Tenga en cuenta que reportError es una función que muestra o registra un error.

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

Control de errores

En algunas situaciones, Office no puede actualizar la cinta de opciones y devolverá un error. Por ejemplo, si el complemento se actualiza y el complemento actualizado tiene un conjunto de comandos de complemento personalizado distinto, la aplicación de Office tiene que cerrarse y volver a abrirse. Hasta que sea así, el método requestUpdate devolverá el error HostRestartNeeded. El siguiente es un ejemplo de cómo controlar este error. En este caso, el método reportError muestra el error al usuario.

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