Como trabalhar com guias

Com o Apps Script para Documentos Google, você pode acessar o conteúdo de qualquer guia do documento.

O que são guias?

Os Documentos Google têm uma camada organizacional chamada guias. O Documentos permite que os usuários criem uma ou mais guias em um único documento, assim como as guias das Planilhas. Cada guia tem um título e um ID próprios (adicionados ao URL). Uma guia também pode ter guias filhas, que são guias aninhadas em outra guia.

Acessar guias

As propriedades e o conteúdo das guias podem ser acessados com Document.getTabs(), que retorna uma lista de Tabs. As seções posteriores oferecem uma breve visão geral da classe Tab. A documentação da classe Tab também fornece informações mais detalhadas.

Propriedades da guia

As propriedades da guia podem ser recuperadas usando métodos como Tab.getId() e Tab.getTitle().

Conteúdo da guia

O conteúdo do documento em cada guia pode ser recuperado usando Tab.asDocumentTab(). A seção Mudanças na estrutura da classe de documento descreve como isso pode ser usado.

Hierarquia de guias

As guias filhas são expostas no Google Apps Script por Tab.getChildTabs(). Para acessar o conteúdo de todas as guias, é necessário percorrer a "árvore" de guias secundárias. Por exemplo, considere um documento que contenha uma hierarquia de guias da seguinte maneira:

Interface de usuário de lista de guias com três guias de nível superior, algumas com guias secundárias

Para acessar a Tabela 3.1.2, faça o seguinte:

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

Confira os blocos de exemplo de código nas seções posteriores, que fornecem exemplos para iterar em todas as guias de um documento.

Outras maneiras de recuperar guias

Há outras duas maneiras de recuperar guias:

Mudanças na estrutura da classe de documento

No passado, os documentos não tinham o conceito de guias. Por isso, a classe Document expunha métodos para acessar e modificar diretamente o conteúdo de texto do documento. Os seguintes métodos se enquadram nessa categoria:

Com a hierarquia estrutural adicional de guias, esses métodos não representam mais semanticamente o conteúdo de texto de todas as guias no documento. O conteúdo de texto agora será representado em uma camada diferente. Todos os métodos de texto mencionados acima podem ser acessados por DocumentTab.

Esses métodos atuais na classe Document acessam ou modificam o conteúdo da guia ativa (em scripts vinculados a um documento específico) ou da primeira guia (se não houver uma ativa).

Acessar conteúdo de texto em uma guia específica

Em vez de usar os métodos de texto de Document, é recomendável usar os métodos disponíveis na classe DocumentTab, que pode ser acessada pelo método Tab.asDocumentTab(). Exemplo:

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

Mudanças na seleção de usuários

Métodos de seleção de texto

A classe Document fornece getters e setters para gerenciar onde no texto o usuário está selecionando, dentro do documento ativo. Esses métodos operam no contexto da guia ativa do usuário que está executando o script.

  • Document.getCursor(): retorna a posição do cursor do usuário na guia ativa.
  • Document.getSelection(): retorna o intervalo de seleção do usuário na guia ativa.
  • Document.setCursor(position): Define a posição do cursor do usuário no documento ativo. Se a posição estiver em uma guia inativa, a guia ativa do usuário também será trocada para a guia associada a essa posição.
  • Document.setSelection(range): define o intervalo de seleção do usuário no documento ativo. Se o intervalo estiver em uma guia inativa, a guia ativa do usuário também será trocada para a guia associada a esse intervalo.

Métodos de seleção de guias e casos de uso

Com a introdução das guias, pode ser útil receber e definir a guia ativa do usuário que está executando o script. Isso pode ser feito usando os seguintes métodos:

A "seleção" holística do usuário é composta por uma combinação da guia ativa com a posição atual do cursor ou o intervalo de seleção. Os dois padrões para trabalhar com uma seleção ativa são modificar explicitamente a guia ativa do usuário para uma guia específica ou usar a guia ativa do usuário.

Para mudar explicitamente a guia ativa do usuário, use Document.setActiveTab(tabId). Como alternativa, chamar Document.setCursor(position) ou Document.setSelection(range) com um Position ou Range de uma guia inativa vai ativar essa guia.

Se o comportamento pretendido do script for usar a guia ativa do usuário sem alterá-la, então Document.setActiveTab(tabId) não é necessário. Os métodos Document.getCursor() e Document.getSelection() já vão operar na guia ativa, com base na guia em que o usuário está executando o script.

Um documento não aceita várias seleções de guias ou várias posições ou intervalos em diferentes guias. Portanto, usar Document.setActiveTab(tabId) vai limpar a posição anterior do cursor ou o intervalo de seleção.

Métodos de posição e intervalo para uma guia específica

A guia específica é o que dá significado aos conceitos de seleção de texto de Position e Range. Em outras palavras, uma posição do cursor ou um intervalo de seleção só fazem sentido se o script souber a guia específica em que a posição ou o intervalo está.

Isso é feito usando os métodos DocumentTab.newPosition(element, offset) e DocumentTab.newRange(), que criam uma posição ou um intervalo que segmenta o DocumentTab específico de onde o método é chamado. Por outro lado, Document.newPosition(element, offset) e Document.newRange() vão construir uma posição ou um intervalo que tem como destino a guia ativa (ou a primeira guia, se o script não estiver vinculado).

Consulte os blocos de exemplo de código nas seções posteriores, que fornecem exemplos para trabalhar com seleções.

Padrões de uso comuns para guias

As amostras de código a seguir descrevem várias maneiras de interagir com guias.

Ler o conteúdo de todas as guias do documento

O código que fazia isso antes do recurso de guias pode ser migrado para oferecer suporte a guias percorrendo a árvore de guias e chamando métodos getter de Tab e DocumentTab em vez de Document. O exemplo de código parcial a seguir mostra como imprimir todo o conteúdo de texto de cada guia em um documento. Esse código de percurso de guias pode ser adaptado para muitos outros casos de uso que não se importam com a estrutura real das guias.

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

Ler o conteúdo da primeira guia do documento

Isso é semelhante a ler todas as guias.

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

Atualizar o conteúdo da primeira guia

O exemplo de código parcial a seguir mostra como segmentar uma guia específica ao fazer atualizações.

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

Atualizar o conteúdo da guia ativa ou selecionada

O exemplo de código parcial a seguir mostra como segmentar a guia ativa ao fazer atualizações.

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

Definir uma posição do cursor ou um intervalo de seleção na guia ativa

O exemplo de código parcial a seguir mostra como atualizar a posição do cursor ou o intervalo de seleção na guia ativa do usuário. Isso só é relevante em scripts vinculados.

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

Definir a guia ativa ou selecionada

O exemplo de código parcial a seguir mostra como mudar a guia ativa do usuário. Isso só é relevante em scripts vinculados.

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