Recibir y controlar datos con funciones personalizadas

Una de las maneras en que las funciones personalizadas mejoran la eficacia de Excel es recibir datos de ubicaciones distintas del libro, como la web o un servidor (a través de WebSockets). Puede solicitar datos externos a través de una API como Fetch o mediante XmlHttpRequest(XHR), una API web estándar que emite solicitudes HTTP para interactuar con los servidores.

Importante

Tenga en cuenta que las funciones personalizadas están disponibles en Excel en las siguientes plataformas.

  • Office en la web
  • Office en Windows
    • Suscripción a Microsoft 365
    • Retail perpetual Office 2016 y versiones posteriores
    • Licencia por volumen perpetua de Office 2021 y versiones posteriores
  • Office en Mac

Las funciones personalizadas de Excel no se admiten actualmente en lo siguiente:

  • Office en iPad
  • versiones perpetuas con licencia por volumen de Office 2019 o versiones anteriores en Windows

GIF de una función personalizada que transmite el tiempo desde una API.

Funciones que devuelven datos de orígenes externos

Si una función personalizada recupera datos de un origen externo, como la web, debe:

  1. Devolver un JavaScript Promise a Excel.
  2. Promise Resuelva con el valor final mediante la función de devolución de llamada.

Ejemplo con fetch

En el ejemplo de código siguiente, la webRequest función llega a una hipotética API externa que realiza el seguimiento del número de personas que se encuentran actualmente en la Estación Espacial Internacional. La función devuelve un JavaScript Promise y usa fetch para solicitar información de la hipotética API. Los datos resultantes se transforman en JSON y la names propiedad se convierte en una cadena, que se usa para resolver la promesa.

Cuando desarrolle sus propias funciones, es recomendable realizar una acción si la solicitud web no se completa de forma oportuna o considerar el procesamiento por lotes de varias solicitudes de API.

/**
 * Requests the names of the people currently on the International Space Station.
 * Note: This function requests data from a hypothetical URL. In practice, replace the URL with a data source for your scenario.
 * @customfunction
 */
function webRequest() {
  let url = "https://www.contoso.com/NumberOfPeopleInSpace"; // This is a hypothetical URL.
  return new Promise(function (resolve, reject) {
    fetch(url)
      .then(function (response){
        return response.json();
        }
      )
      .then(function (json) {
        resolve(JSON.stringify(json.names));
      })
  })
}

Nota:

El uso de fetch evita las devoluciones de llamada anidadas y se prefiere a XHR en ciertos casos.

Ejemplo de XHR

En el ejemplo de código siguiente, la getStarCount función llama a la API de Github para detectar la cantidad de estrellas que se proporcionan al repositorio de un usuario determinado. Se trata de una función asincrónica que devuelve un javascript Promise. Cuando se obtienen datos de la llamada web, se resuelve la promesa que devuelve los datos a la celda.

/**
 * Gets the star count for a given Github organization or user and repository.
 * @customfunction
 * @param userName string name of organization or user.
 * @param repoName string name of the repository.
 * @return number of stars.
 */
async function getStarCount(userName: string, repoName: string) {

  const url = "https://api.github.com/repos/" + userName + "/" + repoName;

  let xhttp = new XMLHttpRequest();

  return new Promise(function(resolve, reject) {
    xhttp.onreadystatechange = function() {
      if (xhttp.readyState !== 4) return;

      if (xhttp.status == 200) {
        resolve(JSON.parse(xhttp.responseText).watchers_count);
      } else {
        reject({
          status: xhttp.status,

          statusText: xhttp.statusText
        });
      }
    };

    xhttp.open("GET", url, true);

    xhttp.send();
  });
}

Crear una función de streaming

Las funciones personalizadas de streaming le permiten enviar datos a celdas que se actualizan continuamente, sin necesidad de que un usuario actualice nada explícitamente. Esto puede resultar útil para comprobar datos en tiempo real desde un servicio en línea, como en la función del tutorial de funciones personalizadas.

Para declarar una función de streaming, puede usar cualquiera de las dos opciones siguientes.

  • Etiqueta @streaming JSDoc.
  • Parámetro CustomFunctions.StreamingInvocation de invocación.

El siguiente ejemplo es una función personalizada que agrega un número al resultado cada segundo. Tenga en cuenta lo siguiente sobre este código.

  • Excel muestra cada valor nuevo automáticamente con el método setResult.
  • El segundo parámetro de entrada, invocation, no se muestra a los usuarios finales de Excel cuando seleccionan la función en el menú de autocompletar.
  • La onCanceled devolución de llamada define la función que se ejecuta cuando se cancela la función.
  • El streaming no está necesariamente asociado a la realización de una solicitud web. En este caso, la función no realiza una solicitud web, pero sigue obteniendo datos a intervalos establecidos, por lo que requiere el uso del parámetro de streaming invocation .
/**
 * Increments a value once a second.
 * @customfunction INC increment
 * @param {number} incrementBy Amount to increment
 * @param {CustomFunctions.StreamingInvocation<number>} invocation
 */
function increment(incrementBy, invocation) {
  let result = 0;
  const timer = setInterval(() => {
    result += incrementBy;
    invocation.setResult(result);
  }, 1000);

  invocation.onCanceled = () => {
    clearInterval(timer);
  };
}

Nota:

Para obtener un ejemplo de cómo devolver una matriz de desbordamiento dinámico de una función de streaming, vea Devolver varios resultados de la función personalizada: Ejemplos de código.

Cancelar una función

Excel cancela la ejecución de una función en las situaciones siguientes.

  • Cuando el usuario edita o elimina una celda que hace referencia a la función.
  • Cuando cambia uno de los argumentos (entradas) para la función. En este caso, se activa una nueva llamada de función después de la cancelación.
  • Cuando el usuario desencadena manualmente un nuevo cálculo. En este caso, se activa una nueva llamada de función después de la cancelación.

También puede considerar la posibilidad de configurar un valor de streaming predeterminado para administrar casos en los que se realice una solicitud sin que esté conectado.

Nota:

También hay una categoría de funciones denominadas funciones cancelables que usan la @cancelable etiqueta JSDoc. Las funciones cancelables permiten finalizar una solicitud web en medio de la solicitud.

Una función de streaming no puede usar la @cancelable etiqueta, pero las funciones de streaming pueden incluir una onCanceled función de devolución de llamada. Solo las funciones personalizadas asincrónicas que devuelven un valor pueden usar la @cancelable etiqueta JSDoc. Consulte Autogenerate JSON metadata: @cancelable para obtener más información sobre la @cancelable etiqueta.

Uso de un parámetro de invocación

El parámetro invocation es el último de cualquier función personalizada de forma predeterminada. El invocation parámetro proporciona contexto sobre la celda (como su dirección y contenido) y permite usar el método y onCanceled el setResult evento para definir lo que hace una función cuando transmite (setResult) o se cancela (onCanceled).

El controlador de invocación debe ser de tipo CustomFunctions.StreamingInvocation o CustomFunctions.CancelableInvocation procesar solicitudes web.

Consulte Parámetro Invocation para obtener información sobre otros posibles usos del invocation argumento y cómo se corresponde con el objeto Invocation .

Recibir datos a través de WebSockets

En una función personalizada, puede usar WebSockets para intercambiar datos a través de una conexión persistente con un servidor. Con WebSockets, la función personalizada puede abrir una conexión con un servidor y, a continuación, recibir automáticamente mensajes del servidor cuando se producen determinados eventos, sin tener que sondear explícitamente los datos del servidor.

Ejemplo de WebSockets

El ejemplo de código siguiente establece una conexión WebSocket y, a continuación, registra todos los mensajes entrantes del servidor.

let ws = new WebSocket('wss://bundles.office.com');

ws.onmessage(message) {
    console.log(`Received: ${message}`);
}

ws.onerror(error){
    console.err(`Failed: ${error}`);
}

Siguientes pasos

Vea también