Google Sheets: SUMIFS para durações (horas), parte 2
Vinicius Basilio
Posted on August 16, 2024
Esses dias fiz um post mostrando como criar duas fórmulas personalizadas para o Google sheets para somar horas com base em critérios (aqui). O problema delas na minha opinião é que elas não eram flexiveis. E se eu quiser N critérios? Bom, agora você pode!
Agora a fórmula toma 3 conjuntos de dados: as durações, os critérios, e as instruções para filtrar. Vamos de novo a planilha de testes:
Título | Duração | Categoria | Status | Curti |
---|---|---|---|---|
Perdido em Marte | 01:00:00 | Filme | Já assisti | Sim |
Interestelar | 02:49:00 | Filme | Já assisti | Não |
John Wick | 01:30:00 | Filme | Já assisti | Não |
Vingadores: Ultimato | 03:00:00 | Filme | Quero assistir | |
Stranger Things | 00:45:00 | Série | Assistindo | |
The Witcher | 01:00:01 | Série | Assistindo | |
O Mandaloriano | 00:40:00 | Série | Assistindo | |
Breaking Bad | 00:50:00 | Série | Já assisti | Sim |
A Casa de Papel | 00:55:00 | Série | Quero assistir | |
Game of Thrones | 01:10:00 | Série | Quero assistir |
Vamos atualizar nosso app script, sugiro criar outra planilha de testes e começar um novo, lembrando que as horas devem estar como “texto simples”. O código está aqui:
/**
* Converte uma string no formato HH:MM:SS para o total em segundos.
*
* @param {string} hms - A string no formato HH:MM:SS.
* @returns {number} O total em segundos.
*/
function converterHMSParaSegundos(hms) {
const partes = String(hms).split(":");
const [horas, minutos, segundos] = partes;
return Number(horas) * 3600 + Number(minutos) * 60 + Number(segundos);
}
/**
* Converte um número de segundos para o formato HH:MM:SS.
*
* @param {number} segundos - O total de segundos.
* @returns {string} O tempo no formato HH:MM:SS.
*/
function converterSegundosParaHMS(segundos) {
const horas = Math.floor(segundos / 3600);
const minutos = Math.floor((segundos % 3600) / 60);
const segundosRestantes = segundos % 60;
return `${String(horas).padStart(2, "0")}:${String(minutos).padStart(
2,
"0"
)}:${String(segundosRestantes).padStart(2, "0")}`;
}
/**
* Filtra as linhas da matriz de dados com base nos critérios fornecidos e retorna as durações correspondentes.
*
* @param {Array<string>} duracoes - Array de durações em formato de texto.
* @param {Array<Array<string>>} dados - Matriz de dados onde cada linha corresponde a um conjunto de valores.
* @param {Array<string>} criterios - Array de critérios para filtrar as linhas da matriz de dados.
* @returns {Array<string>} Retorna as durações que correspondem aos critérios.
*/
function filtroDeLinhas(duracoes, dados, criterios) {
const linhas_na_matriz = duracoes.length;
const matriz_de_criterios_concatenada = [];
for (let linha = 0; linha < linhas_na_matriz; linha++) {
let incluirLinha = true;
for (let coluna = 0; coluna < dados[linha].length; coluna++) {
if (!criterios.includes(dados[linha][coluna])) {
incluirLinha = false;
break; // Sai do loop se algum critério não for atendido
}
}
if (incluirLinha) {
matriz_de_criterios_concatenada.push(duracoes[linha]);
}
}
return matriz_de_criterios_concatenada;
}
/**
* Soma as horas filtradas de acordo com os critérios fornecidos.
*
* @param {Array<string>} duracoes - Array de durações em formato de texto.
* @param {Array<Array<string>>} intervalo_de_criterios - Matriz de dados onde cada linha corresponde a um conjunto de valores.
* @param {...string} criterios - Um ou mais critérios para filtrar as linhas da matriz de dados.
* @returns {string} A soma das durações no formato HH:MM:SS.
*/
function somarHorasComCriterios(
duracoes,
intervalo_de_criterios,
...criterios
) {
// Verifica se todos os argumentos são arrays
if (
!Array.isArray(duracoes) ||
!Array.isArray(intervalo_de_criterios) ||
!Array.isArray(criterios)
) {
return "Passe os intervalos para o cálculo!";
}
const horasParaSomar = filtroDeLinhas(
duracoes,
intervalo_de_criterios,
criterios.flat(Infinity)
);
const horasEmSegundos = horasParaSomar.map((n) =>
converterHMSParaSegundos(n)
);
const somaDosSegundos = horasEmSegundos.reduce(
(acumulador, valorAtual) => acumulador + valorAtual,
0
);
return converterSegundosParaHMS(somaDosSegundos);
}
Vamos dizer que eu passe:
Filme | Já assisti | Não
Minha soma seria: 04:19:00
E lembrando que posso envolver isso com a função nativa: =VALOR
e formatar como “duração” e o sheets volta a trabalhar somas como se tivesse usando uma fórmula nativa!
Como disse no último post, deixem seu comentários de sugestões, ou dúvidas. Abraços.
Posted on August 16, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 21, 2024