Ejercicio: Trabajar con hojas de cálculo y comandos de complemento

Completado

En este ejercicio, aprenderá a inmovilizar la fila de encabezado de la tabla que creó anteriormente, para que permanezca visible incluso cuando el usuario se desplaza hacia abajo en la hoja de trabajo. También aprenderá a activar y desactivar la protección de hojas de cálculo.

Inmovilizar un encabezado de tabla

Cuando una tabla es lo suficientemente larga para que un usuario deba desplazarse para ver algunas filas, la fila de encabezado puede desplazarse fuera de la vista. En esta sección, inmovilizará la fila de encabezado de la tabla que creó anteriormente, para que permanezca visible incluso cuando el usuario se desplace hacia abajo en la hoja de cálculo.

Inmovilizar la fila de encabezado de la tabla

  1. Abra el archivo ./src/taskpane/taskpane.html.

  2. Busque el <button>elemento para el botón crear gráfico y agregue el siguiente marcado después de esa línea:

    <button class="ms-Button" id="freeze-header">Freeze Header</button><br/><br/>
    
  3. Abra el archivo ./src/taskpane/taskpane.js.

  4. Dentro del método Office.onReady(), busque la siguiente línea:

    document.getElementById("create-chart").onclick = createChart;
    

    Agregue el código siguiente inmediatamente después de esa línea:

    document.getElementById("freeze-header").onclick = freezeHeader;
    
  5. Agregue la función siguiente al final del archivo:

    async function freezeHeader() {
      await Excel.run(async (context) => {
    
        // TODO1: Queue commands to keep the header visible when the user scrolls.
    
        await context.sync();
      })
      .catch(function (error) {
        console.log("Error: " + error);
        if (error instanceof OfficeExtension.Error) {
          console.log("Debug info: " + JSON.stringify(error.debugInfo));
        }
      });
    }
    
  6. En la función freezeHeader(), reemplace TODO1 con el código siguiente:

    const currentWorksheet = context.workbook.worksheets.getActiveWorksheet();
    currentWorksheet.freezePanes.freezeRows(1);
    

    Nota:

    • La colección Worksheet.freezePanes es un conjunto de paneles de la hoja de cálculo que se queda anclado o inmovilizado en su lugar mientras el usuario se desplaza por la hoja de cálculo.
    • El método freezeRows() toma como parámetro el número de filas desde la parte superior que se van a anclar en su lugar. Pasamos 1 para anclar la primera fila en su posición.
  7. Compruebe que los cambios se guardan en el proyecto.

Probar el complemento

  1. Si el servidor web local ya está en ejecución y el complemento ya está cargado en Excel, continúe con el paso 2. De lo contrario, inicie el servidor web local y transfiera localmente el complemento:

    • Para probar el complemento en Excel, ejecute el siguiente comando en el directorio raíz del proyecto. Se iniciará el servidor web local (si todavía no está en ejecución) y se abrirá Excel con el complemento cargado.

      npm start
      
    • Para probar el complemento en Excel en la web, ejecute el siguiente comando en el directorio raíz del proyecto. Al ejecutar este comando, se iniciará el servidor web local (si todavía no está en ejecución).

      npm run start:web
      

      Para usar el complemento, abra un nuevo documento en Excel en la Web y, después, transfiera localmente el complemento siguiendo las instrucciones en Transferir localmente complementos de Office en Office en la Web.

  2. Si el panel de tareas del complemento aún no está abierto, en la pestaña Inicio, seleccione Mostrar panel de tareas.

  3. Si la tabla que agregó anteriormente en este tutorial se encuentra en la hoja de cálculo, elimínela.

  4. En el panel de tareas, seleccione Crear tabla.

  5. En el panel de tareas, seleccione Inmovilizar encabezado.

  6. Desplace la hoja de cálculo lo suficiente para ver que el encabezado de tabla permanece visible en la parte superior, aunque las filas más altas se desplacen fuera de la vista.

Captura de pantalla de Congelar el encabezado establecida por el tutorial en Excel.

Proteger una hoja de cálculo

En esta sección, agregará otro botón a la cinta que, cuando se elija, ejecutará una función que definirá para activar y desactivar la protección de la hoja de trabajo.

Configure el manifiesto para agregar un segundo botón a la cinta de opciones

  1. Abra el archivo de manifiesto ./manifest.xml.

  2. Busque el elemento <Control>. Este elemento define el botón Mostrar panel de tareas de la cinta de opciones Inicio que ha usado para iniciar el complemento. Vamos a agregar un segundo botón al mismo grupo de la cinta de opciones Inicio.

    Entre la etiqueta Control final (</Control>) y la etiqueta Grupo final (</Group>), agregue la marcación siguiente.

    <Control xsi:type="Button" id="<!--TODO1: Unique (in manifest) name for button -->">
        <Label resid="<!--TODO2: Button label -->" />
        <Supertip>
          <Title resid="<!-- TODO3: Button tool tip title -->" />
          <Description resid="<!-- TODO4: Button tool tip description -->" />
        </Supertip>
        <Icon>
          <bt:Image size="16" resid="Icon.16x16"/>
          <bt:Image size="32" resid="Icon.32x32"/>
          <bt:Image size="80" resid="Icon.80x80"/>
        </Icon>
        <Action xsi:type="<!-- TODO5: Specify the type of action-->">
          <!-- TODO6: Identify the function.-->
        </Action>
    </Control>
    
  3. Dentro del XML que acaba de agregar al archivo de manifiesto, reemplace TODO1 con una cadena que proporciona al botón un identificador único dentro de este archivo de manifiesto. Como nuestro botón va a activar o desactivar la protección de la hoja de cálculo, use ToggleProtection. Cuando haya terminado, la etiqueta de apertura del elemento Control debería tener este aspecto:

    <Control xsi:type="Button" id="ToggleProtection">
    
  4. Los tres TODO siguientes establecen resid propiedades, que son abreviaturas del identificador de recurso. Un recurso es una cadena y creará estas tres cadenas en un paso posterior. Por ahora, debe proporcionar los identificadores a los recursos. El botón label debe leer Toggle Protection, pero el Identificador de esta cadena debe ser ProtectionButtonLabel, por lo que el elemento Label debe tener este aspecto:

    <Label resid="ProtectionButtonLabel" />
    
  5. El elemento SuperTip define la información sobre herramientas del botón. El título de la información sobre herramientas debe ser el mismo que la etiqueta del botón, por lo que usamos el mismo identificador de recurso: ProtectionButtonLabel. La descripción de la información sobre herramientas se Click to turn protection of the worksheet on and off. Pero el Identificador debe ser ProtectionButtonToolTip. Cuando haya terminado, el elemento SuperTip debería tener este aspecto:

    <Supertip>
      <Title resid="ProtectionButtonLabel" />
      <Description resid="ProtectionButtonToolTip" />
    </Supertip>
    

    Nota:

    En un complemento de producción, no querrá usar el mismo icono para dos botones diferentes; pero para simplificar este tutorial, lo haremos. Así que la marcación Icon en nuestro nuevo Control solo es una copia del elemento Icon del existente Control.

  6. El elemento Action incluido en el elemento original Control, que ya estaba presente en el manifiesto, tiene el tipo establecido en ShowTaskpane, pero nuestro nuevo botón no va a abrir un panel de tareas, va a ejecutar una función personalizada que cree en un paso posterior. Así que reemplace TODO5 con que es el tipo de acción para los botones que desencadenan funciones personalizadas. La etiqueta de apertura del elemento Action debe tener este aspecto:

    <Action xsi:type="ExecuteFunction">
    
  7. El elemento original Action tiene elementos secundarios que especifican un identificador de panel de tareas y una dirección URL de la página que debería abrirse en el panel de tareas. Pero un elemento Action del tipo ExecuteFunction tiene un elemento secundario que indica el nombre de la función que el control ejecuta. Creará esa función en un paso posterior y se llamará toggleProtection. Por lo tanto, reemplace TODO6 por la marcación siguiente:

    <FunctionName>toggleProtection</FunctionName>
    

    La marcación completa Control tendrá la siguiente apariencia:

    <Control xsi:type="Button" id="ToggleProtection">
        <Label resid="ProtectionButtonLabel" />
        <Supertip>
          <Title resid="ProtectionButtonLabel" />
          <Description resid="ProtectionButtonToolTip" />
        </Supertip>
        <Icon>
          <bt:Image size="16" resid="Icon.16x16"/>
          <bt:Image size="32" resid="Icon.32x32"/>
          <bt:Image size="80" resid="Icon.80x80"/>
        </Icon>
        <Action xsi:type="ExecuteFunction">
          <FunctionName>toggleProtection</FunctionName>
        </Action>
    </Control>
    
  8. Desplácese hacia abajo hasta la sección Resources del manifiesto.

  9. Agregue la siguiente marcación como elemento secundario del elemento bt:ShortStrings.

    <bt:String id="ProtectionButtonLabel" DefaultValue="Toggle Worksheet Protection" />
    
  10. Agregue el siguiente marcado como elemento secundario del elemento bt:LongStrings.

    <bt:String id="ProtectionButtonToolTip" DefaultValue="Click to protect or unprotect the current worksheet." />
    
  11. Guarde el archivo.

Cree la función que proteja la hoja

  1. Abra el archivo .\commands\commands.js.

  2. Agregue la siguiente función justo después de la función action(). Tenga en cuenta que especificamos un parámetro args para la función y la última línea de la función llama a args.completed. Este es un requisito para todos los comandos de complemento de tipo ExecuteFunction. Indica la aplicación de host de Office que ha terminado la función y la interfaz de usuario puede ser receptiva de nuevo.

    async function toggleProtection(args) {
      await Excel.run(async (context) => {
    
        // TODO1: Queue commands to reverse the protection status of the current worksheet.
    
        await context.sync();
      })
      .catch(function (error) {
        console.log("Error: " + error);
        if (error instanceof OfficeExtension.Error) {
          console.log("Debug info: " + JSON.stringify(error.debugInfo));
        }
      });
      args.completed();
    }
    
  3. Agregue la línea siguiente al final del archivo:

    Office.actions.associate("toggleProtection", toggleProtection);
    
  4. En la función toggleProtection(), reemplace TODO1 con el siguiente código. Este código utiliza la propiedad de protección del objeto de hoja de cálculo en un patrón de alternancia estándar. Se explicará el TODO2 en la sección siguiente.

    const sheet = context.workbook.worksheets.getActiveWorksheet();
    
    // TODO2: Queue command to load the sheet's "protection.protected" property from
    //        the document and re-synchronize the document and task pane.
    
    if (sheet.protection.protected) {
      sheet.protection.unprotect();
    } else {
      sheet.protection.protect();
    }
    

Agregue código para recuperar las propiedades del documento en los objetos del script del panel de tareas

En cada una de las funciones que creó en este tutorial, puso en cola comandos para escribir en el documento de Office. Cada función finalizó con una llamada al método context.sync() que envía los comandos puestos en cola al documento que se ejecutará. Pero el código que agregó en el último paso llama a la propiedad sheet.protection.protected, que se trata de una diferencia significante con respecto a las funciones anteriores que escribió, porque el objeto sheet solo es un proxy que existe en el script del panel tareas. No sabe cuál es el estado de protección real del documento, así que su propiedad protection.protected no puede tener un valor real. Es necesario obtener primero el estado de protección del documento y usarlo con el valor de sheet.protection.protected. Solo en ese momento se puede llamar a sheet.protection.protected sin que se produzca una excepción. Este proceso de obtención consta de tres pasos:

  1. Ponga a la cola un comando para cargar (es decir, obtener) las propiedades que el código necesita leer.
  2. Llame al método sync() del objeto de contexto para enviar el comando en cola al documento para la ejecución y devolución de la información solicitada.
  3. Como el método sync() es asincrónico, asegúrese de que ha finalizado antes de que el código llame a las propiedades que se obtuvieron.

Estos pasos deben completarse cuando el código necesite leer información del documento de Office.

  1. En la función toggleProtection(), reemplace TODO2 con el siguiente código:

    sheet.load('protection/protected');
    await context.sync();
    

    Nota:

    • Cada objeto de Excel tiene un método load(). Especifique las propiedades del objeto que desea leer en el parámetro como una cadena de nombres delimitada por comas. En este caso, la propiedad que quiere leer es una subpropiedad de la propiedad protection. Hace referencia a la subpropiedad casi exactamente como lo haría en cualquier otro lugar de su código, con la excepción de que usa un carácter de barra diagonal ("/") en lugar de un carácter ".".
    • Para asegurarse de que la lógica de alternancia, que lee sheet.protection.protected, no se ejecuta hasta que sync se complete y sheet.protection.protected se haya asignado el valor correcto que se captura del documento, debe ir después del await operador .

    Cuando haya terminado, la función completa debería parecerse a la siguiente:

    async function toggleProtection(args) {
        await Excel.run(async (context) => {
          const sheet = context.workbook.worksheets.getActiveWorksheet();
          sheet.load('protection/protected');
    
          await context.sync();
    
          if (sheet.protection.protected) {
              sheet.protection.unprotect();
          } else {
              sheet.protection.protect();
          }
    
          await context.sync();
        })
        .catch(function (error) {
          console.log("Error: " + error);
          if (error instanceof OfficeExtension.Error) {
            console.log("Debug info: " + JSON.stringify(error.debugInfo));
          }
        });
        args.completed();
    }
    
  2. Compruebe que guardó todos los cambios que realizó en el proyecto.

Probar el complemento

  1. Cierre todas las aplicaciones de Office, Excel incluido.

  2. Elimine la memoria caché de Office al eliminar el contenido de la carpeta de caché. Esto es necesario para borrar completamente la versión anterior del complemento del host.

    • Para Windows: %LOCALAPPDATA%\Microsoft\Office\16.0\Wef\.

    • Para macOS: ~/Library/Containers/com.Microsoft.OsfWebHost/Data/.

      Nota:

      Si esta carpeta no existe, compruebe si hay alguna de las siguientes carpetas y, si las encuentra, elimine el contenido de la carpeta:

      • ~/Library/Containers/com.microsoft.{host}/Data/Library/Caches/ donde {host} es el host de Office (por ejemplo, Excel)
      • ~/Library/Containers/com.microsoft.{host}/Data/Library/Application Support/Microsoft/Office/16.0/Wef/ donde {host} es el host de Office (por ejemplo, Excel)
      • com.microsoft.Office365ServiceV2/Data/Caches/com.microsoft.Office365ServiceV2/
  3. Si el servidor web local ya se está ejecutando, para detenerlo, escriba el siguiente comando en el símbolo del sistema.

    npm stop
    
  4. Debido a que el archivo de manifiesto se ha actualizado, debe volver a instalar localmente el complemento con el archivo de manifiesto actualizado. Inicie el servidor web local y transfiera localmente el complemento:

    • Para probar el complemento en Excel, ejecute el siguiente comando en el directorio raíz del proyecto. Se iniciará el servidor web local (si todavía no está en ejecución) y se abrirá Excel con el complemento cargado.

      npm start
      
    • Para probar el complemento en Excel en la web, ejecute el siguiente comando en el directorio raíz del proyecto. Al ejecutar este comando, se iniciará el servidor web local (si todavía no está en ejecución).

      npm run start:web
      

      Para usar el complemento, abra un nuevo documento en Excel en la Web y, después, transfiera localmente el complemento siguiendo las instrucciones en Transferir localmente complementos de Office en Office en la Web.

  5. En la pestaña Inicio de Excel, elija el botón Activar o desactivar la protección de la hoja de cálculo. La mayoría de los controles de la cinta están desactivados (y visualmente atenuados) como se ve en la siguiente captura de pantalla.

    Captura de pantalla de la cinta de opciones en Excel con la protección de hojas de cálculo activada.

  6. Seleccione una celda como lo haría si quisiera cambiar su contenido. Excel muestra un mensaje de error que indica que la hoja de cálculo está protegida.

  7. Seleccione el botón Alternar la protección de la hoja de cálculo otra vez para habilitar de nuevo los controles y volver a cambiar los valores de la celda.

Resumen

En este ejercicio, ha aprendido a inmovilizar la fila de encabezado de la tabla que creó anteriormente, para que permanezca visible incluso cuando el usuario se desplace hacia abajo en la hoja de cálculo. También ha aprendido a activar y desactivar la protección de la hoja de cálculo.

Comprobar sus conocimientos

1.

¿Cuál de las siguientes opciones mostrará la siguiente hoja de cálculo en un libro?

2.

Para llamar a una función de JavaScript desde un botón de la cinta de opciones de la aplicación de Office definida en el manifiesto del complemento, ¿cuál de las siguientes acciones debe hacer?