Apps Script tem teto
Como fazer o Apps Script continuar depois do teto de seis minutos: um script que processa as linhas de uma planilha em lotes, para antes de estourar o teto de tempo, guarda onde parou, agenda a própria volta e limpa tudo quando termina.
- Apps Script
- Google Planilhas
- código de exemplo
Publicado em
Leia antes: o limite deste guia
As cotas e os limites do Apps Script mudam. A própria página do Google diz: "sujeitas a eliminação, redução ou alteração a qualquer momento, sem aviso prévio". Os números deste guia são os da página oficial em 10/11/2026; confira na página antes de depender deles. O código deste guia foi testado uma vez no Google Apps Script, em 10/11/2026, numa planilha de exemplo com 200 linhas e com o limite reduzido para dez segundos, para provocar a parada. O limite de cinco minutos do código e planilhas grandes não foram testados: o teste de verdade é seu. Rode primeiro numa planilha de teste, com dados de exemplo, nunca na planilha que você usa de verdade.
O que é cada coisa
- Execução: cada vez que o script roda do começo ao fim (ou até ser interrompido). Segundo a página de limites do Google, o tempo de execução é de seis minutos por execução, tanto na conta pessoal quanto na Workspace.
- O que acontece ao passar do limite: a página diz "If you exceed a quota or limitation, your script throws an exception and execution stops." A página não traz a mensagem exata do teto de seis minutos, por isso este guia não cita nenhuma.
- Lote: um pedaço da planilha (no exemplo, vinte linhas) processado de uma vez, em vez de uma linha por vez.
- Propriedades do script (PropertiesService): onde o script guarda dados simples em pares chave e valor. A página diz "Allows scripts to store simple data in key-value pairs". Aqui guardam a próxima linha a processar.
- Gatilho de tempo: faz uma função rodar depois de um intervalo ou em um horário. Dá para criar e apagar por código ("Create and delete triggers programmatically with the Script service."). O método
after(milissegundos)"Specifies the minimum duration (in milliseconds) after the current time that the trigger runs." - Outros limites da mesma página (conta pessoal e Workspace): destinatários de e-mail por dia, 100 e 1.500 (veja o aviso sobre contas de teste abaixo); tempo total de execução dos gatilhos por dia, 90 minutos e 6 horas; gatilhos por usuário por script, 20 nas duas.
Planilha de exemplo (dados inventados, EXEMPLO)
Use uma planilha nova, só para teste. Abra Extensões, Apps Script (o script fica ligado à planilha). Cole o código abaixo e rode a função criarDadosDeExemplo uma vez: ela cria a aba Exemplo com duzentas linhas, colunas item, valor e resultado, tudo inventado.
O código para copiar
Arquivo completo. Cole no editor do Apps Script no lugar do que estiver lá.
const NOME_ABA = 'Exemplo';
const TAMANHO_LOTE = 20;
const LIMITE_MS = 5 * 60 * 1000;
const CHAVE = 'proximaLinha';
const FUNCAO = 'processarEmLotes';
function criarDadosDeExemplo() {
const planilha = SpreadsheetApp.getActiveSpreadsheet();
const aba = planilha.getSheetByName(NOME_ABA) || planilha.insertSheet(NOME_ABA);
aba.clear();
const linhas = [['item', 'valor', 'resultado']];
for (let i = 1; i <= 200; i++) {
linhas.push(['Item ' + i, i, '']);
}
aba.getRange(1, 1, linhas.length, 3).setValues(linhas);
}
function apagarGatilhos() {
ScriptApp.getProjectTriggers().forEach(function (gatilho) {
if (gatilho.getHandlerFunction() === FUNCAO) {
ScriptApp.deleteTrigger(gatilho);
}
});
}
function agendarContinuacao() {
ScriptApp.newTrigger(FUNCAO).timeBased().after(60 * 1000).create();
}
function iniciar() {
PropertiesService.getScriptProperties().deleteProperty(CHAVE);
apagarGatilhos();
processarEmLotes();
}
function processarEmLotes() {
const inicio = Date.now();
const propriedades = PropertiesService.getScriptProperties();
const aba = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(NOME_ABA);
const ultimaLinha = aba.getLastRow();
let linha = Number(propriedades.getProperty(CHAVE)) || 2;
apagarGatilhos();
while (linha <= ultimaLinha) {
if (Date.now() - inicio > LIMITE_MS) {
agendarContinuacao();
return;
}
const quantidade = Math.min(TAMANHO_LOTE, ultimaLinha - linha + 1);
const valores = aba.getRange(linha, 2, quantidade, 1).getValues();
const resultados = valores.map(function (celula) {
return [celula[0] * 2];
});
aba.getRange(linha, 3, quantidade, 1).setValues(resultados);
Utilities.sleep(2000);
linha += quantidade;
propriedades.setProperty(CHAVE, String(linha));
}
propriedades.deleteProperty(CHAVE);
}Como testar
- Rode
criarDadosDeExemplo. Autorize o script quando o Google pedir (é a sua própria planilha de teste). - Para ver o gatilho funcionando sem esperar cinco minutos, troque a linha do limite por
const LIMITE_MS = 10 * 1000;(dez segundos). O sleep de dois segundos por lote simula trabalho pesado. - Rode a função
iniciar. Ela zera o marcador, apaga gatilhos antigos desta função e processa até passar do limite. Depois de uns dez segundos, ela para e agenda a volta. - Em Gatilhos (o ícone de relógio na barra lateral), deve aparecer um gatilho de tempo para
processarEmLotes. Em Configurações do projeto, Propriedades do script, deve aparecer a chaveproximaLinhacom a próxima linha a processar. - Espere cerca de um minuto, ou mais: o gatilho roda sozinho e continua de onde parou. Repita a conferência até a coluna resultado estar preenchida nas duzentas linhas.
- No fim, não deve sobrar gatilho para
processarEmLotesnem a chaveproximaLinha. - Volte
LIMITE_MSpara5 * 60 * 1000(cinco minutos, uma margem de um minuto abaixo do teto de seis) e troque o cálculo do exemplo (valor vezes dois) pelo seu trabalho de verdade, ainda numa cópia.
Como o código funciona
processarEmLotesanota a hora de início e lê a próxima linha guardada nas propriedades do script (se não houver, começa na segunda linha, logo abaixo do cabeçalho).- Apaga gatilhos antigos da própria função, para não acumular.
- Processa um lote por vez e grava o resultado na planilha. Depois de cada lote, salva a próxima linha. Se o Google interromper de repente: como a escrita na planilha vem antes de salvar a propriedade, o lote em andamento pode ser repetido na próxima execução.
- Antes de cada lote, confere se já passou do limite. Se passou, agenda um gatilho de tempo para um minuto depois e termina limpo.
- Quando as linhas acabam, apaga a propriedade. Como o gatilho antigo é apagado no começo de cada execução, não sobra nenhum no fim.
Regra de bolso
Trabalho que pode passar de seis minutos nunca roda em uma execução só: divida em lotes, confira o relógio a cada lote, guarde onde parou e agende a volta. Pare com uma margem (no exemplo, um minuto) e não no último segundo.
Antes de levar para o seu projeto
- Teste numa cópia da planilha, não no arquivo original.
- O script do exemplo é ligado à planilha. Em script solto, troque
SpreadsheetApp.getActiveSpreadsheet()porSpreadsheetApp.openById('ID_DA_PLANILHA')com o ID da sua planilha de teste. - Gatilhos instalados rodam na conta de quem os criou: "Installable triggers always run under the account of the person who created them."
- O tempo total dos gatilhos conta por dia (90 minutos na conta pessoal e 6 horas na Workspace, segundo a página em 10/11/2026). Um trabalho muito grande pode bater nesse limite também.
- Se o seu lote envia e-mail, a cota de destinatários por dia vale (100 na conta pessoal e 1.500 na Workspace, segundo a página). A página cita o método
MailApp.getRemainingDailyQuota()para ver o que sobra. A página diz: "Limites adicionais são aplicados a contas de teste." Para contas de teste convertidas em assinatura, ela diz que os limites aumentam se o domínio tiver pago pelo menos USD 100 de forma cumulativa e depois de passarem pelo menos 60 dias desse mínimo. Veja o seu caso na página. A tabela também tem a linha "Destinatários de e-mail por dia no domínio": 100 na coluna de contas de consumidor e 2.000 na coluna Workspace, segundo a página em português. - Ler e gravar um lote inteiro de uma vez, como o código faz, costuma ser mais rápido que célula por célula. É cuidado geral de planilha, não tirado da página do Google.
- Se um lote falhar no meio, o marcador ainda aponta para o início dele: confira se reprocessar as mesmas linhas não causa dano (por exemplo, e-mail enviado duas vezes). Depois de um erro, rodar
processarEmLotesde novo continua da linha salva (useiniciarsó para recomeçar do zero). Depois de um erro nenhum gatilho fica agendado, então a retomada é manual. - O código não usa LockService. Não rode a função à mão enquanto uma execução do gatilho estiver em andamento, para duas execuções não processarem as mesmas linhas.
- O
after()define o tempo mínimo até o gatilho rodar, não um horário exato. - O limite de cinco minutos é uma recomendação deste guia (margem de um minuto abaixo do teto), não um número da página.
Fontes
Páginas do Google for Developers abertas em 10/11/2026: Quotas for Google Services (inglês), Quotas for Google Services (português), Installable Triggers, ClockTriggerBuilder, PropertiesService e Properties.
Código: testado no Google Apps Script em 10/11/2026, numa planilha de exemplo com 200 linhas e com o limite reduzido para dez segundos: a execução parou no limite, guardou a próxima linha nas propriedades do script, o gatilho de tempo continuou sozinho e, no fim, não sobrou gatilho nem propriedade.
Fechamento do guia
Agora você sabe montar um script que processa a planilha em lotes, para antes do teto de seis minutos e continua sozinho de onde parou.
Seguir @drasdiegotechSalve este guia nos favoritos do navegador e salve o reel no Instagram para voltar quando precisar.
Este site conta visitas com o Vercel Web Analytics, de forma anônima e agregada, sem cookies de terceiros. Aviso de privacidade