En este artículo vemos las bases de como automatizar tareas y expandir el funcionamiento de nuestro Google Sheets a partir de código y macros de Google Apps Script.
Les dejo un par de videos donde vemos en detalle las funciones y métodos descritas en este artículo
Google apps Script
Google Apps Script o GAS es el editor de código de Sheets.
Es un programa desde el que puedo escribir código para ampliar la funcionalidad de Sheets
La primera aproximación a GAS es a través de las macros, las cuales ya conocemos
Así mismo, ya vimos una introducción al código de Google Apps Script y a sus posibilidades
Hoy vamos a hablar más específicamente de como conectar GAS con Sheets y hacer tareas básicas como escribir datos en nuestras celdas y leer datos de ellas
Abrir el editor
Para escribir nuestras macros, siempre vamos a «Herramientas»>»Editor de Secuencias de Comandos»
Ya vimos un poco más a fondo como funciona el editor en el artículo de Introducción a Google Apps Script.
Funciones
Por ahora lo más importante a saber de las funciones es que no nos van a funcionar las macros sin funciones.
Siempre nuestros comandos o instrucciones deben estar dentro de una función
Conectrse a Google Sheets
El servicio SpreadsheetApp
Ya dentro de nuestra función podemos empezar a programar
El único comando que por ahora deben aprenderse es «SpreadsheetApp»
Este es el servicio que nos permite conectarnos con Google Sheets
Cualquier cosa que implique Sheets siempre va a pasar con SpreadsheetApp
Pero SpreadsheetApp solo no sirve para nada. Necesito obligatoriamente escoger una de las opciones que me ofrece
Cuando escriben SpreadsheetApp dentro de su función y le ponen un punto, nos empiezan a aparecer todas las posibilidades de Sheets

En esta ocasión vamos a ver los básicos necesarios para poder conectarnos con los diferentes elementos de nuestros Libros
Conectarse a un archivo
Método getActiveSpreadsheet()
Una vez estamos «conectados» con Sheets es hora de conectarnos con un archivo o libro. Hay dos maneras más usadas. Escoger el libro que tengo abierto, o el «activo» o escoger un libro por su identificación
Veamos el primero:
const libro = SpreadsheetApp.getActiveSpreadsheet();
o
const ss= SpreadsheetApp.getActiveSpreadsheet();
Al guardarlo en una variable, solo tenemos que llamar el método una vez, y después usamos la variable «libro» o «ss» (de «spreadsheet»), 0 la que quieran, en realidad.
Método openById()
Otra posibilidad es la de abrir un archivo específico.
Para esto necesitamos tener la identificación del archivo la cual se encuentra en la URL
const libro = SpreadsheetApp.openById("1TpWYcwWpITOgIw3jzVNw7GvaGZzBi2hgxzTJ8jgWdbY");
Una vez tengamos ese «libro», podemos acceder a métodos específicos dentro del libro
Por ejemplo puedo:
- Compartir el archivo
- Borrar el archivo
- Borrar hojas
- Agregar hojas
Conectarse a una pestaña
Método getActiveSheet()
Una vez ya estemos «conectados» al libro nos podemos conectar a una pestaña específica bien sea la pestaña en la que estamos ubicados en ese momento o una pestaña especifica identificada por nombre
Con .getActiveSheet() por ejemplo nos podemos conectar a la hoja que el usuario actualmente tiene seleccionada
Método getSheetByName()
Con este método podemos escoger una pestaña especifica
Conectarse con una celda
Método getRange()
Una vez dentro de la hoja, podemos «jugar» con las celdas, filas y columnas de la misma
Uno de los métodos que más vamos a usar es el getRange() ya que con este es que podemos acceder a una celda o a un grupo de celdas específicas.
Simplemente entre comillas le damos la dirección del rango como lo hariamos en Sheets:
var celda = hoja.getRange('A1')
Otra forma de usarla es con el numero de la columna y de la fila asi
var celda = hoja.getRange(1,1)
Metodo getValue()
Una vez tenemos acceso a una celda, podemos querer saber que valor tiene esa celda
Para esto usamos getValue();
var valorCelda =celda.getValue();
Esto me devuelve un numero o un texto o una fecha, dependiendo de lo que haya en la celda
Método setValue()
Si por el contrario quiero escribir un dato en la celda usamos el setValue
celda.setValue(2);
celda.setValue("Hola mundo");
fecha = newDate();
celda.setValue(fecha);
Una ultima forma es llamar a un rango iniciando con la fila y la columna de inicio y dandole las filas y columnas o el largo del rango
El mismo rango del ejemplo anterior (A1:B20) quedaíra asi
hoja.getRange(1,1,20,2);
Conectarse con un rango
Ya aprendimos a conectarnos con una celda individual
Ahora nos vamos a conectar con un rango
Los metodos son muy similares
getRange() para rangos
los rangos los llamamos de la misma mnera que lo hacemos en Sheets
var rango = getRange("A1:C20")
Método getValues()
Una vez tengamos el rango, podemos llamar los valores, esta vez con el método getValues();
getValues() «graba» los valores del rango en una rreglo
var arreglo = rango.getValues();
Metodo setValues()
Al igual que cuando «imprimimos un solo valor en Sheets usamos setValues(arreglo) para incluir valores en Sheets
Es importante que el arreglo este ordenado como Sheets quiere (un arreglo dentro de otro arreglo para cada fila).
También es extremadamente importante que el rango que seleccionamos tenga el mismo tamaño en filas y columnas que el arreglo que vamos a imprimir
Aqui les dejo un ejemplo.
//Arreglo de 3 columnas y 2 filas
var arreglo = [["Nombre","Apellido","Edad"],["Juan Sebastian","Guzman",37]]
//Lo imprimimos en un rango de 3 columnas y dos filas
libro.getRange('A1:C2');
Conclusión
Programar en Google Apps Scripy y Google Sheets no es dificil. Es cuestion de practiva.
Entonces, los invito a practicar con sencillos codigos para poco a poco ir poniendonos mas complejos
Como siempre, quedo pendientes de sus preguntas y comentarios
Buenos días desde México, tengo una duda, deseo que cuando una celda en Google Sheets tenga un valor x ejecute un script hecho en GAS ¿Qué instrucción debo utilizar? Pues no lo encuentro. De antemano gracias.
Hola!
Se hace con la función onEdit
Saludos!
Hola consulta: tengo una tabla en donde se van llenando registros, y se copian en otra hoja. Pero varían en el largo de filas, y mi macro grabado quedo por predeterminado asi:
function test1() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange(‘A5’).activate();
var currentCell = spreadsheet.getCurrentCell();
spreadsheet.getSelection().getNextDataRange(SpreadsheetApp.Direction.DOWN).activate();
currentCell.activateAsCurrentCell();
currentCell = spreadsheet.getCurrentCell();
spreadsheet.getActiveRange().getDataRegion(SpreadsheetApp.Dimension.COLUMNS).activate();
currentCell.activateAsCurrentCell();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName(‘Guardado de las rotacioes’), true);
spreadsheet.getRange(‘A3’).activate();
** spreadsheet.getRange(‘INGRESO1!A5:AP6’).copyTo(spreadsheet.getActiveRange(), **SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
Esto hace que toma toda la filas y columnas de esos datos, pero queda fijo en A5:AP6
Ahora bien, se puede hacer que copie los datos desede A5: hasta la ultima fila con datos? (los **) ; una suerte de
** spreadsheet.getRange(‘INGRESO1!A5:getLastRow’).copyTo(spreadsheet.getActiveRange(), **
Pd: Esto es para mi práctica universitaria :c
Cambia esto
spreadsheet.getRange(‘INGRESO1!A5:AP6’)
por esto
spreadsheet.getRange(5,1,spreadsheet.getLastRow()-5,50)
Saludos!
hola amigo tengo una duda sobre la secuencia de comandos para registrar información quería saber como puedo hacer para el momento en el que copie la información lo haga en la fila de arriba
Hola!
Si, tienes que insertar una fila con hoja.insertRow(2) y después pegas la info en la recién creada fila 2 así
hoja.getRange(2,1,1,hoja.getLastColumn()).setValues(arregloAPegar)
Saludos!
Hola buenas noches, agradecerle por su información acerca de esta nueva plataforma. me ha servido de mucha ayuda.
Sin embargo tengo una duda, me gustaría saber como seria el código para saber cuando un numero es primo y cuando no lo es para un rango de números y la verdad es que no tengo idea de como plantearlo.
De antemano, muchas gracias.
Hola!
Bien complejo
Podrias intentar dividir por todos los numeros y si el residuo no es 0 en ninguna de las divisiones entonces ya sabemos que es primo
Algo asi
function esprimo(num){
if(num%2!=0 && num%3!=0 && num%4!=0) return true
return false
}
Algo asi
Y esa funcion la pones dentro de un filter
Saludos!
Hola Juan, antes de todo eres un máquina programando.
Mi pregunta es poco dificultosa, tengo hecho un registro de paquetería creando un código app script. En el paquete escribo el número de registro y fecha de salida. Lo que quiero conseguir es que cuando mensajería entregue el paquete en el destino el operario que lo reciba escriba el número de registro de dicho paquete y en su hoja de registro y le aparezca toda la información de dicho registro y simultanemete yo reciba el aviso de llegada mediante una fecha. No sé si me puedes dar una solución.
Hola JAvier
No se si entiendo bien tu caso
Un gran saludo!
Buenos días Juan,
estoy intentando hacer que un un rango, independientemente de como se escriba (mayúsculas o minúsculas) siempre se quede en mayúsculas, encontré la forma de que se aplique a toda la hoja, pero no soy capaz de modificar el script que solo aplique solo el rango con este script:
function onEdit(e) {
if (typeof e.value != ‘object’) {
e.range.setValue(e.value.toUpperCase());
}
}
¿que deberia modificar para que solo aplique sobre el rango B14:B42?
Puedes usar los siguientes métodos
e.range.getColumn()==2
e.range.getLastColumn==2
e.range.getRow()>=14
e.range.getLastRow()<=42 Saludos!
Hola Juan.
Tus videos me han ayudado bastante, ahora, tengo dos dudas, la primera es, tengo este codigo:
function onEdit() {
var archivo = SpreadsheetApp.getActiveSpreadsheet();
var hojaDatos = archivo.getSheetByName(«Reembolsos 15/10/2021»);
var filaActiva = hojaDatos.getActiveCell().getRow();
var columnaActiva = hojaDatos.getActiveCell().getColumn();
var hojaListas = archivo.getSheetByName(«Base de listas»);
if(filaActiva>1 && columnaActiva ==1) {
var detalles = hojaListas.getRange(2,8,hojaListas.getLastRow());
var desplegable = SpreadsheetApp.newDataValidation().requireValueInRange(detalles).build();
hojaDatos.getActiveCell().offset(0,29).setDataValidation(desplegable);
}
Pero necesito que en el if también tome en cuenta que sea solo fecha, eso es posible?
Por otro lado, se puede resaltar toda la fila de la celda seleccionada? Como en excel.
Gracias de antemano
Saludos.
Aquí te respondo la primera pregunta
if(filaActiva>1 && columnaActiva ==1 typeOf hojaDatos.getActiveCell().getValue()==’Object’ )
Saludos!
Hola Juan, cómo estás?
Se puede mover una fila de un documento a otro?
He visto en tus videos cómo copiar o mover la fila de una pestaña o otra. Esto también se puede entre documentos?
Hola Miguel
Claro que si
Aquí te dejo un video
https://youtu.be/iHO6aFqB2t8
Saludos!
Saludos!
Amigos me ayudan con algo porfa,
Resulta que tengo un script con casilla de verificación, resulta que cuando le pongo que la casilla esta entre A a Z me corre sin problema, pero cuando pongo AA deja de funcionar
Este es el archivo
https://docs.google.com/spreadsheets/d/123UJrFT4X7xX95xq7mEPkwGgyKFfHLyvQFI0nLT0MUE/edit#gid=0
function HOnEdit(e)
{
var ss = SpreadsheetApp.getActive().getActiveSheet();
//Obtiene la ubicación donde el usuario hace clic en la hoja
var selection = ss.getActiveCell().getA1Notation().split(«»);
//Obtiene el valor de la casilla
var checkBoxValue = ss.getActiveCell().getValue().toString();
//Acá es donde no me funciona
if(selection[0] != ‘AA’) return;
switch(checkBoxValue){
case checkBoxValue = «true»:
Browser.msgBox(‘La acción ha sido realizada’, Browser.Buttons.OK);
break;
}
}
Hola!
Porque cuando haces el split, es como si volvieras a tener A
Saludos!
Hola, tengo una consulta si se puede hacer o no.
Tengo un formulario hecho en google y quiero colocar un cuadro de alerta cuando la persona llene «SI» tres veces en diferentes preguntas.
Se puede hacer?
Saludos y gracias
Hola!
Hasta donde se no se puede
Saludos!
Juan Buen dia, en cuanto a tu video de APP SCRIPT Y GOOGLE SHEETS
URL(https://www.youtube.com/watch?v=q0S6rHUqi4w)
Me quedo dos dudas:
1. Como realizar la seuencia para borrar o limpiar varias celdas especificas.
2. Como poder guardar varias celdas especificas.
Pf me comentas o si es posible que subas un video con esos detalles.
Te dejo mi contacto. WSP: +51 914 523 774
Sin mas me despido.
Saludos.
Hola Cesar.
A que te refieres con guardar celdas específicas
Saludos!
Hola Juan,
Entiendo que es el mismo problema que tengo yo, necesito que el script se aplique, por ejemplo, en la celda A8, en la B15 y en la C4 al mismo tiempo. ¿Cómo se indica esto en el script?
Gracias,
Albert
Buenas noches Cesar tengo una duda al respecto estoy usando un código para generar qr pero no se como es la escritura para cambiar la zona horaria const fecha = new Date().toLocaleString(«es-MX», {timeZone:»America/Mexico_City»}); quiero cambiarla de México por la de Colombia si puedes ayudar con eso mil gracias
Hola Cesar, te dejo una parte de un script que use yo y me funcionó muy bien.
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange(‘C4:F4’).activate();
spreadsheet.getActiveRangeList().clearContent();
spreadsheet.getRange(‘I4:K4’).activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getRange(‘H8’).setValue(false);
Mil gracias por el aporte!
Hola Juan Salvador
Genial toda la info q pasas!
Estoy trabada en una parte. Quiero obtener datos de un rango del cual la cantidad de filas dependa de la información que tenga cargada. O sea que me traiga todas las filas que tengan datos. Cómo hago?
Muchas gracias
Saludos!
Hola!
Mil gracias por tus palabras!
Te refieres a un rango seleccionado, o quieres seleccionar el rango hasta la última fila que haya datos?
Saludos!
Hola Juan, tienes una playlist de videos consecutivos sobre apps script en Google sheets? Me interesa por como explicas de bien . Saludos
Hola Ezequiel
Mil gracias por tus palabras!
Pues no tenía, pero gracias a tus comentarios acabo de crear una
Me cuentas que tal te parece
https://www.youtube.com/playlist?list=PLvrIQ0wr2BTKUu5fD-fXRlkXMj0KFpIA9
Saludos!
Hola Juan Salvador
Quisiera preguntarte algo tan sencillo como esto.
Estoy en la celda A2 y necesito saltar a la linea 3.
Es decir quiero hacer un while que a cada paso lea una linea y haga otras cosas.
Cual sería la orden ¿next?, no lo veo por ningún sitio
Hola José
Algo asi?
for(i=2;i<20;i++){
hoja.getRange("A"+i).activate()
}
Saludos!
Hola Juan
muchas gracias por tus videos y conocimientos
es increíble como lo enseñas.
Quería consultarte lo siguiente que no puedo entender:
Tengo este código que funciona muy bien en una tabla
de debito crédito y saldo:
function borrarRangoEspecificoA1(){
SpreadsheetApp.getActiveSpreadsheet().getSheetByName(«Agosto»).getRange(«A2:E32»).clearContent()
}
En su ejecución borra bien todos los números y no toca los encabezados,
pero borra la siguiente formula:
=E2+C3-D3
Como puedo hacer para que esta formula no se borre, como asi tampoco
la automatización de la misma en el resto de la columna de saldo?
muchas gracias de antemano
Abrazo
Marcelo
Hola Marcelo
Donde esta tu fórmula, en que columna
Un gran saludo!
Hola Juan, estoy haciendo el ejercicio del video «Generar un documento de Google Docs a partir de mis datos de Google Sheets», sin embargo, cuando voy ejecutar para verificar si esta generando copia del documento, me sale el error: TypeError: archivoPlantilla.makeCopy is not a function, Pregunta: como habilito el comando o funciona makecopy? quedo atento a tus comentarios.
Hola!
El truco esta en archivoPlantilla
Hazle un logger log para asegurarte que efectivamente es un archivo
Saludos!
Hola !!! como hago el logger y donde puedo verlo…?
tengo el mismo problema y llevo 3 dias sin poder resolverlo… jajaj
el video es genial ! grax por ayudar a la comunidad !
Hola
USas Logger.log(«Hola!»)
Automaticamente te abre el registro cuando haces la ejecución
Saludos!
Hola Juan,
Antes de nada quiero darte las gracias por todo lo que he podido aprender con tus videos.
Luego quisiera saber cómo puedo hacer un código en apps script para que una vez seleccionada area y configurados márgenes etc (lo extraje de tu video sobre hacer un Pdf de nuestro sheets) lo que haga sea dejarme con la pantalla de impresión.
Asi yo puedo decirle si imprimir o si guardar archivo.
Muchas gracias de antemanp
Hola Manuel
Varios me lo han pedido ya
No se si se pueda.
Has podido resolver?
Un gran saludo!
Hola, estoy haciendo un programa el cual compare los valores de la misma fila entre dos columnas (A y B), si B > A deberá mostrar un mensaje mediante la función «ui».
Logré que esto sucediera, pero al hacer la corrección en las celdas (A > B) vuelve a mostrar el mensaje, aun y cuando la condición no se cumple.
Para que funcionará use un activador en el cual el tipo de evento es al editarse, pero si no uso el activador el programa no funciona.
Hola Natalia
Me imagino que primero lo hacías con onEdit y después pasaste a activador instalable
Parece que el onEdit es incompatible con los cuadros de dialogo, pero yo pensé que el activador también lo sería
Raro que te funcione con el activador y no con el onEdit…la verdad no debería funcionar con ninguno
Un gran saludo y gracias por compartir!
Disculpa Juan, formule mal el comentario…
Cuando mencione «para que funcionara» me refería a para que para lograr que mostrara el cuadro de dialogo tuve que usar el activador, sin embargo no he podido lograr que lo deje de mostrar cuando la condición no se cumple.
¿Puede ser por la incompatibilidad que mencionas?
(espero ser un poco más clara)
Hey!, bro he estado viendo tus videos y me han servido mucho, pero tengo un tema especifico.
No se que disparador puedo utilizar para desencadenar el codigo, tengo una integración con active campaign la cual cuando llega un nuevo contacto me lo pasa a google sheet.
El disparador onedit no me funciona y no se cual podría ser
Buen dia, podrias apoyarme con la siguiente duda: tengo un script en mi hoja de Google Sheet, al momento de compartir el archivo a otro usuario, como le puedo hacer para que tambien el pueda ejecutarlo.
saludos
Hola Gabriel
Hay dos formas
Una es empaquetarlo en un complemento
La otra es poner un botón para que les pida el permiso y las demás funciones puedan funcionar
Saludos!
Hola Juan Salvador, solicito tu apoyo para este problema: en un archivo tengo tres pestañas: P1 es la base de datos que alimento cada mes; P2 se genera «automáticamente» de la información de P1 y una P3 que contiene el acumulado de la información generada cada mes en P2….
No se cómo hacer para seleccionar la información en P2, que cada mes se borra y se genera de nuevo con diferente número de filas, solo copiar los valores y pegarlos en P3, al final de esa tabla resumen acumulada que se ha ido generando a lo largo de los meses….. no sé como indicar que coloque los valores copiados a partir de la primera celda vacía de P3…Gracias
Hola Carlos
Yo creo que se debe hacer con una macro que corra cada mes, o de pronto cada semana o día que copie y pegue
Pronto haré un video entrando más a detalle en este tema de copiar y pegar automáticamente
Un gran saludo!
Hola!
Intento pasar varios campos de un sheet a otro (no entre dos hojas, sino entre dos archivos diferentes) pero siempre me salta un error diciendo que no tengo los permisos, aunque me pide la autorización la primera vez que lo corro, aún haciendolo como biblioteca. Sabes si es posible conectar dos archivos en un mismo proyecto? o ya me rindo jajaja
Hola!
Claro que si se puede
Los dos archivos son tuyos?
Saludos!
Hola. Yo tuve el mismo problema. Como no pude resolver el tema de los permisos, tuve que generar el sheets en archivo nuevo directamente y ahí sí me anduvo. No le encontré la vuelta al error se autorización.
Hola!
Y los dos archivos eran tuyos?
Que error te generaba?
buen dia, estoy buscando el app script para insertar un buscador dentro del spreadsheet, sucede que estoy armando un cotizador y requiero aplicar un filtro avanzando utilizando el dato ingresado en una celda y que filtre por columna «A» pero que muestro informacion desde columna «A» hasta columna «Q», sera posible? y tener el app script para que lo exporte en pdf con el nombre del valor de una celda
gracias
Hola Santiago
No se si entiendo bien tu consulta
Pero la forma más fácil de crear un buscador es con un listado desplegable de los productos y no necesitarias AppsScript
Un gran saludo!
Como estas, quiero utilizar la fórmula SI con BUSCARV por ejemplo, tengo un Forms en donde tengo opciones de Compra o Venta, en función de eso voy a otra sección donde están los productos. Bueno lo que quiero es que Si elijo compra me arroje un precio y obviamente si elijo venta me arroje otro, distinguiendo también el productos seleccionado. Necesito ingresar en esa fórmula en App Scrip para poder automatizarlo. Cabe destacar que en otra hoja aparte tengo una tabla con el detalle de los productos, precio de compra y precio de venta, para utilizar como matriz o rango de datos.
Saludos muy buena la página
Hola Santiago
Mil gracias por escribir
Dejame ver si te entendí bien
Te refieres a un BUSCARV si el artículo es de venta, y aotro buscarv diferente si es compra?
Si es así, sería algo asi
SI(A2=»Venta»;BUSCARV DE VENTA;BUSCARV DE COMPRA)
Me cuentas
Saludos!