Trabaja con pestañas

Apps Script para Documentos de Google te permite acceder al contenido desde cualquier pestaña del documento.

¿Qué son las pestañas?

Documentos de Google cuenta con una capa organizativa llamada pestañas. Documentos permite a los usuarios crear una o más pestañas en un solo documento, de manera similar a como hay pestañas en Hojas de cálculo en la actualidad. Cada pestaña tiene su propio título y un ID (que se agrega en la URL). Una pestaña también puede tener pestañas secundarias, que son pestañas anidadas debajo de otra pestaña.

Pestañas de acceso

Se puede acceder a las propiedades y al contenido de la pestaña con Document.getTabs(), que muestra una lista de Tab. En las secciones posteriores, se proporciona una descripción general breve de la clase Tab. La documentación sobre la clase de pestaña también proporciona información más detallada.

Propiedades de la pestaña

Las propiedades de la pestaña se pueden recuperar con métodos como Tab.getId() y Tab.getTitle().

Contenido de la pestaña

El contenido de documentos dentro de cada pestaña se puede recuperar con Tab.asDocumentTab(). En la sección Cambios en la estructura de la clase de documentos, se describe cómo se puede usar.

Jerarquía de pestañas

Las pestañas secundarias se exponen en Google Apps Script a través de Tab.getChildTabs(). Para acceder al contenido de todas las pestañas, es necesario recorrer el "árbol" de las pestañas secundarias. Por ejemplo, considera un documento que contiene una jerarquía de pestañas como la siguiente:

IU de la lista de pestañas que contiene tres pestañas de nivel superior, algunas de las cuales tienen pestañas secundarias

Para acceder a Tab 3.1.2, podrías hacer lo siguiente:

// Print the ID of Tab 3.1.2.
const doc = DocumentApp.getActiveDocument();
const tab = doc.getTabs()[2].getChildTabs()[0].getChildTabs()[1];
console.log(tab.getId());

Consulta los bloques de código de muestra en las secciones posteriores, que proporcionan código de muestra para iterar en todas las pestañas de un documento.

Otras formas de recuperar pestañas

Existen otras dos formas de recuperar pestañas:

  • Document.getTab(tabId): Muestra la pestaña con el ID especificado.
  • Document.getActiveTab(): Muestra la pestaña activa del usuario. Solo funciona en secuencias de comandos que están vinculadas a un documento. En las secciones posteriores, se describe esto con más detalle.

Cambios en la estructura de las clases de documentos

En el pasado, los documentos no tenían el concepto de pestañas, por lo que la clase Document exponía métodos para acceder directamente al contenido de texto del documento y modificarlo. Los siguientes métodos pertenecen a esta categoría:

Con la jerarquía estructural adicional de las pestañas, estos métodos ya no representan semánticamente el contenido de texto de todas las pestañas del documento. El contenido de texto ahora se representará en una capa diferente. Se puede acceder a todos los métodos de texto mencionados anteriormente a través de DocumentTab.

Estos métodos existentes en la clase Document accederán o modificarán el contenido de la pestaña activa (en secuencias de comandos vinculadas a un documento en particular) o de la primera pestaña (si no hay una activa disponible).

Acceder al contenido de texto dentro de una pestaña específica

En lugar de usar los métodos de texto de Document, se recomienda usar los métodos disponibles a partir de la clase DocumentTab (que están disponibles a través del método Tab.asDocumentTab()). Por ejemplo:

// Print the text from the body of the active tab.
const doc = DocumentApp.getActiveDocument();
const documentTab = doc.getActiveTab().asDocumentTab();
const body = documentTab.getBody();
console.log(body.getText());

Cambios en la selección de usuarios

Métodos de selección de texto

La clase Document proporciona métodos get y set para administrar dónde el usuario está seleccionando en el texto dentro del documento activo. Estos métodos operan dentro del contexto de la pestaña activa del usuario que ejecuta la secuencia de comandos.

  • Document.getCursor(): Muestra la posición del cursor del usuario en la pestaña activa.
  • Document.getSelection(): Muestra el rango de selección del usuario en la pestaña activa.
  • Document.setCursor(position): Establece la posición del cursor del usuario en el documento activo. Si la posición está en una pestaña inactiva, la pestaña activa del usuario también cambiará a la pestaña asociada con esa posición.
  • Document.setSelection(range): Establece el rango de selección del usuario en el documento activo. Si el rango está en una pestaña inactiva, entonces la pestaña activa del usuario también se cambia a la pestaña asociada con ese rango.

Métodos y casos de uso de la selección de pestañas

Con la introducción de las pestañas, puede ser útil obtener y configurar la pestaña activa del usuario que ejecuta la secuencia de comandos. Esto se puede hacer con los siguientes métodos:

La "selección" integral del usuario consta de una combinación de la pestaña activa junto con la posición actual del cursor o el rango de selección. Los dos patrones para trabajar con una selección activa son modificar explícitamente la pestaña activa del usuario a una pestaña específica o usar la pestaña activa del usuario.

Para cambiar de forma explícita la pestaña activa del usuario, usa Document.setActiveTab(tabId). Como alternativa, llamar a Document.setCursor(position) o Document.setSelection(range) con un Position o Range desde una pestaña inactiva hará que esa pestaña se active.

Si el comportamiento previsto de la secuencia de comandos es usar la pestaña activa del usuario sin cambiarla, entonces Document.setActiveTab(tabId) no es necesario. Los métodos Document.getCursor() y Document.getSelection() ya operarán en la pestaña activa, según la pestaña desde la que el usuario ejecuta la secuencia de comandos.

Ten en cuenta que un documento no admite varias selecciones de pestañas ni varias posiciones o rangos en diferentes pestañas. Por lo tanto, si usas Document.setActiveTab(tabId), se borrará la posición del cursor o el rango de selección anteriores.

Métodos de posición y rango para una pestaña específica

La pestaña específica es lo que le da significado a los conceptos de selección de texto de Position y Range. En otras palabras, una posición del cursor o un rango de selección solo tienen sentido si la secuencia de comandos conoce la pestaña específica en la que se encuentra la posición o el rango.

Esto se logra con los métodos DocumentTab.newPosition(element, offset) y DocumentTab.newRange(), que construyen una posición o un rango que se orienta a la DocumentTab específica desde la que se llama al método. En cambio, Document.newPosition(element, offset) y Document.newRange() construirán una posición o un rango que se oriente a la pestaña activa (o a la primera pestaña, si la secuencia de comandos no está vinculada).

Consulta los bloques de código de muestra en las secciones posteriores, que proporcionan código de muestra para trabajar con selecciones.

Patrones de uso comunes para pestañas

En las siguientes muestras de código, se describen varias formas de interactuar con las pestañas.

Lee el contenido de todas las pestañas del documento

El código existente que hacía esto antes de que se pudiera migrar la función de pestañas para admitir pestañas a través del árbol de pestañas y llamar a métodos get de Tab y DocumentTab en lugar de Document. En el siguiente ejemplo de código parcial, se muestra cómo imprimir todo el contenido de texto de cada pestaña de un documento. Este código de recorrido de pestañas se puede adaptar a muchos otros casos de uso a los que no les importa la estructura real de las pestañas.

/** Logs all text contents from all tabs in the active document. */
function logAllText() {
  // Generate a list of all the tabs in the document, including any
  // nested child tabs. DocumentApp.openById('abc123456') can also
  // be used instead of DocumentApp.getActiveDocument().
  const doc = DocumentApp.getActiveDocument();
  const allTabs = getAllTabs(doc);

  // Log the content from each tab in the document.
  for (const tab of allTabs) {
    // Get the DocumentTab from the generic Tab object.
    const documentTab = tab.asDocumentTab();
    // Get the body from the given DocumentTab.
    const body = documentTab.getBody();
    // Get the body text and log it to the console.
    console.log(body.getText());
  }
}

/**
 * Returns a flat list of all tabs in the document, in the order
 * they would appear in the UI (i.e. top-down ordering). Includes
 * all child tabs.
 */
function getAllTabs(doc) {
  const allTabs = [];
  // Iterate over all tabs and recursively add any child tabs to
  // generate a flat list of Tabs.
  for (const tab of doc.getTabs()) {
    addCurrentAndChildTabs(tab, allTabs);
  }
  return allTabs;
}

/**
 * Adds the provided tab to the list of all tabs, and recurses
 * through and adds all child tabs.
 */
function addCurrentAndChildTabs(tab, allTabs) {
  allTabs.push(tab);
  for (const childTab of tab.getChildTabs()) {
    addCurrentAndChildTabs(childTab, allTabs);
  }
}

Leer el contenido de la pestaña de la primera pestaña del documento

Esto es similar a leer todas las pestañas.

/** 
 * Logs all text contents from the first tab in the active 
 * document. 
 */
function logAllText() {
  // Generate a list of all the tabs in the document, including any
  // nested child tabs.
  const doc = DocumentApp.getActiveDocument();
  const allTabs = getAllTabs(doc);

  // Log the content from the first tab in the document.
  const firstTab = allTabs[0];
  // Get the DocumentTab from the generic Tab object.
  const documentTab = firstTab.asDocumentTab();
  // Get the body from the DocumentTab.
  const body = documentTab.getBody();
  // Get the body text and log it to the console.
  console.log(body.getText());
}

Actualiza el contenido de la primera pestaña

En la siguiente muestra de código parcial, se muestra cómo segmentar una pestaña específica cuando se realizan actualizaciones.

/** Inserts text into the first tab of the active document. */
function insertTextInFirstTab() {
  // Get the first tab's body.
  const doc = DocumentApp.getActiveDocument();
  const firstTab = doc.getTabs()[0];
  const firstDocumentTab = firstTab.asDocumentTab();
  const firstTabBody = firstDocumentTab.getBody();

  // Append a paragraph and a page break to the first tab's body
  // section.
  firstTabBody.appendParagraph("A paragraph.");
  firstTabBody.appendPageBreak();
}

Actualizar el contenido de la pestaña en la pestaña activa o seleccionada

En la siguiente muestra de código parcial, se muestra cómo segmentar la pestaña activa cuando se realizan actualizaciones.

/**
 * Inserts text into the active/selected tab of the active
 * document.
 */
function insertTextInActiveTab() {
  // Get the active/selected tab's body.
  const doc = DocumentApp.getActiveDocument();
  const activeTab = doc.getActiveTab();
  const activeDocumentTab = activeTab.asDocumentTab();
  const activeTabBody = activeDocumentTab.getBody();

  // Append a paragraph and a page break to the active tab's body
  // section.
  activeTabBody.appendParagraph("A paragraph.");
  activeTabBody.appendPageBreak();
}

Establecer una posición del cursor o un rango de selección en la pestaña activa

En el siguiente ejemplo de código parcial, se muestra cómo actualizar la posición del cursor o el rango de selección dentro de la pestaña activa del usuario. Esto solo es relevante en las secuencias de comandos vinculadas.

/**
 * Changes the user's selection to select all tables within the tab
 * with the provided ID.
 */
function selectAllTables(tabId) {
  const doc = DocumentApp.getActiveDocument();
  const tab = doc.getTab(tabId);
  const documentTab = tab.asDocumentTab();

  // Build a range that encompasses all tables within the specified
  // tab.
  const rangeBuilder = documentTab.newRange();
  const tables = documentTab.getBody().getTables();
  for (let i = 0; i < tables.length; i++) {
    rangeBuilder.addElement(tables[i]);
  }
  // Set the document's selection to the tables within the specified
  // tab. Note that this actually switches the user's active tab as
  // well.
  doc.setSelection(rangeBuilder.build());
}

Cómo establecer la pestaña activa o seleccionada

En el siguiente ejemplo de código parcial, se muestra cómo cambiar la pestaña activa del usuario. Esto solo es relevante en las secuencias de comandos vinculadas.

/**
 * Changes the user's selected tab to the tab immediately following
 * the currently selected one. Handles child tabs.
 *
 * 

Only changes the selection if there is a tab following the * currently selected one. */ function selectNextTab() { const doc = DocumentApp.getActiveDocument(); const allTabs = getAllTabs(doc); const activeTab = doc.getActiveTab(); // Find the index of the currently active tab. let activeTabIndex = -1; for (let i = 0; i < allTabs.length; i++) { if (allTabs[i].getId() === activeTab.getId()) { activeTabIndex = i; } } // Update the user's selected tab if there is a valid next tab. const nextTabIndex = activeTabIndex + 1; if (nextTabIndex < allTabs.length) { doc.setActiveTab(allTabs[nextTabIndex].getId()); } }