Hay muchas formas de pasar lista de asistencia en un grupo, puede ser un salón de clases o una oficina. Las formas más prácticas serán siempre las que permitan que sean las mismas personas quienes registren su asistencia en un sistema y todo se maneje automáticamente, sin complicar este registro. Usar un código QR para lograr este propósito es ideal, ya que simplemente pediremos a las personas que lo escaneen, y así no tendrán que escribir ni validar nada más. Hoy veremos cómo combinar los códigos QR para escribir información automáticamente en una hoja de cálculo de Google Sheets, logrando el objetivo de tener un sistema de registro de asistencia, que es un tutorial que han pedido muchísimo.
Preparar nuestros datos en una hoja de cálculo
Lo primero que haremos será, como siempre, preparar nuestra hoja de cálculo con las columnas necesarias. Para este ejemplo usaremos dos hojas, una con la información de cada persona, por ejemplo un identificador, que puede ser un número, su nombre, y su código QR. Llamamos a esta hoja simplemente QR. Podemos tener tantas columnas como queramos, pero yo sugiero que mantengas al mínimo la información que codificaremos en el código QR.
Luego tendremos otra hoja llamada Asistencia, donde registraremos la información de cada persona asociada a una hora y fecha en la que se realizó el registro de asistencia, así como el correo que registró la asistencia, para llevar un control. Esta es la hoja que se llenará sola cada vez que alguien registre su asistencia escaneando el código QR.
Preparando los parámetros
Las columnas siguientes nos servirán para comprender lo que está ocurriendo en cada registro. Primero tendremos una columna llamada Parámetros, que contendrá la misma información que queremos codificar de las columnas que acabamos de crear, pero en este formato:
?parametro1=valor1¶metro2=valor2
Cada columna será un parámetro y cada valor de la celda corresponderá a ese mismo parámetro. La razón de que esto sea así es que tenemos que darle a una URL la información de las columnas que queremos codificar en cada QR, y esta es la forma estándar de pasar parámetros con sus valores a una URL. Se empieza con un signo de interrogación, se lista el primer parámetro con su valor después del signo de igual, y los parámetros siguientes se separan con un signo de ampersand (&).
Para nuestro ejemplo, será algo así para la columna D:
="?id="&A2&"&nombre="&B2&correo="&C2
Crear una web app con Google Sheets (doGet)
Para poder llenar las columnas siguientes, primero tenemos que explicar una funcionalidad muy útil disponible para nosotros en las Hojas de Cálculo de Google Sheets. Esta funcionalidad es el concepto de las web apps en Google Sheets, y realmente es muy sencillo. Solo necesitamos dos cosas: una URL que reciba la información y la función doGet en código de Apps Script, con la que procesaremos esta información.
Entonces, primero vamos al menú Extensiones – Apps Script
Ahora usaremos un poco de código que hará todo el trabajo por nosotros, entonces reemplazamos el código por default por este:
function doGet(e) {
// Cambia aquí tu idioma-país y zona horaria
const fecha = new Date().toLocaleString("es-MX", {timeZone:"America/Mexico_City"});
// Registramos la asistencia usando el correo y los parámetros que vienen en la URL
registrarAsistencia(e.parameter.correo, e.parameter.id, e.parameter.nombre);
// Damos retroalimentación sobre lo que sucedió:
return HtmlService.createHtmlOutput(`
Asistencia registrada correctamente. <br><br>
Correo que registró: ${e.parameter.correo}<br>
Fecha: ${fecha}<br>
ID: ${e.parameter.id}<br>
Nombre: ${e.parameter.nombre}`);
}
function registrarAsistencia(correo, id, nombre) {
// Debes cambiar este identificador por el de tu documento de hoja de cálculo
const sheet = SpreadsheetApp.openById("1G-prWyWzgjf9IFtKPryxlMXn0XfOieEhK3P3Sgto");
const asistencia = sheet.getSheetByName("Asistencia");
const lastRow = asistencia.getLastRow() + 1;
asistencia.getRange(lastRow, 1).setValue(correo);
asistencia.getRange(lastRow, 2).setValue(id);
asistencia.getRange(lastRow, 3).setValue(nombre);
asistencia.getRange(lastRow, 4).setValue(new Date());
}
Lenguaje del código: JavaScript (javascript)
Como puedes ver, tenemos dos funciones principales: doGet
y registrarAsistencia
. La función doGet recibe un objeto (e
) que contiene los parámetros que vendrán contenidos en la URL codificada en el código QR: el correo, el ID y el nombre. También definimos la fecha con el formato de nuestra zona horaria, idioma y país de preferencia. Después usamos la otra función, registrarAsistencia
, pasándole los parámetros, para que se cree un registro nuevo en la hoja de cálculo. Tambien aquí en doGet, generamos el HTML necesario para dar un poco de retroalimentación sobre lo que sucedió:
function doGet(e) {
// Cambia aquí tu idioma-país y zona horaria
const fecha = new Date().toLocaleString("es-MX", {timeZone:"America/Mexico_City"});
// Registramos la asistencia usando el correo y los parámetros que vienen en la URL
registrarAsistencia(e.parameter.correo, e.parameter.id, e.parameter.nombre);
// Damos retroalimentación sobre lo que sucedió:
return HtmlService.createHtmlOutput(`
Asistencia registrada correctamente. <br><br>
Correo que registró: ${e.parameter.correo}<br>
Fecha: ${fecha}<br>
ID: ${e.parameter.id}<br>
Nombre: ${e.parameter.nombre}`);
}
Lenguaje del código: JavaScript (javascript)
En esta función de registrarAsistencia
, primero abrimos la hoja de cálculo correspondiente a través de su identificador. Este lo debemos obtener de la URL de nuestro documento. Es lo que está entre /d/
y /edit
:
Después, en la hoja de Asistencia, obtenemos la última fila vacía y en ella escribimos los datos en las columnas correspondientes: el correo, el id de la persona, su nombre y la fecha y hora actual.
function registrarAsistencia(correo, id, nombre) {
// Debes cambiar este identificador por el de tu documento de hoja de cálculo
const sheet = SpreadsheetApp.openById("1G-prWyWzgjf9IFtKPpyLryxlMXn0XfOieEhK3P3Sgto");
const asistencia = sheet.getSheetByName("Asistencia");
const lastRow = asistencia.getLastRow() + 1;
asistencia.getRange(lastRow, 1).setValue(correo);
asistencia.getRange(lastRow, 2).setValue(id);
asistencia.getRange(lastRow, 3).setValue(nombre);
asistencia.getRange(lastRow, 4).setValue(new Date());
}
Lenguaje del código: JavaScript (javascript)
Publicar web app
Lo siguiente que haremos será publicar nuestra web app para hacer posible que se ejecute este código cada vez que alguien visite la URL de la app. Para lograrlo, primero guardamos nuestro código y vamos al botón de Implementar – Nueva implentación. Y seleccionamos el tipo de implementación como Aplicación web
La descripción que elijas aquí es solo para llevar un control interno, no te preocupes mucho por ella, incluso la puedes dejar como está.
En el apartado de ‘Quién tiene acceso’ nosotros usaremos la opción de ‘Cualquier usuario’, porque queremos que se pueda registrar con cualquier celular.
Al terminar, damos click en el botón de Implementar, y nos pedirá autorizar el acceso a los datos de la hoja de cálculo en nuestra cuenta, entonces, se lo permitimos.
Una vez que eso está terminado, tendremos finalmente la URL de la web app o aplicación web que nos corresponde:
Construir la URL de doGet
Ahora, copiamos esta URL y regresamos a nuestra hoja de cálculo. Aquí, concatenamos la URL de nuestra web app en la columna de URL doGet con la columna de los parámetros, y así para todas las celdas hacia abajo:
="https://script.google.com/macros/s/AKfycbxILqA6gKs9xkqwxkdbOAi21Y2BnoC7LLxuxmImo-bE-yVbzPqJ0ojyA9SvOfp58HwjJALtSg/exec"&D2
Cada una de estas URLs corresponde a una petición que haremos al código que vimos hace unos momentos, que registra en la hoja de Asistencia la información de los parámetros junto con una fecha y una hora exacta. Si probamos copiando y pegando alguna de estas URLs en el navegador, veremos cómo habrá ejecutado correctamente nuestro código y nos habrá dado la retroalimentación correspondiente:
Creando los códigos de QR de asistencia
Bueno, ahora que ya tenemos nuestra URL de doGet lista, lo último que nos queda es construir la URL del código QR, tal como hemos aprendido en guías anteriores, ya sea con la API oficial de Google o con otros servicios que permiten más tipos de códigos.
Recordemos que debemos encapsular la información de la URL doGet en la fórmula ENCODEURL, para no tener problemas si tenemos caracteres especiales como acentos, eñes, etcétera.
="https://api.qrserver.com/v1/create-qr-code/?size=500x500&data="&ENCODEURL(E2)
Actualización 2024: Google retiró el servicio chart.googleapis.com, por lo que se debe usar una alternativa como api.qrserver.com
Y finalmente, usamos la fórmula IMAGE para mostrar el código en pantalla:
=IMAGE(E2)
Estos códigos podemos imprimirlos para que puedan ser escaneados con cualquier celular. Cada vez que alguno sea escaneado, se creará un nuevo registro en la hoja de Asistencia, justo como queríamos. ¿No te parece genial? 🙂
Consideraciones especiales: cambios en el código
Hay algunas cosas que hay que tomar en cuenta. Es importante saber que si por alguna razón tenemos que cambiar el código para que registre otro dato más, tendremos que crear una nueva implementación de nuestra web app y esto necesariamente nos cambiará la URL base, que habrá que actualizar. Esto está diseñado así para poder hacer cambios en el código y hacer pruebas sin tenerlos que publicar antes de tiempo, pero también hace que debamos tener más cuidado con el control de qué código de Apps Script es el que ejecutan nuestros usuarios. Esto es muy relevante con los códigos QR, pues si hacemos esto, tendremos que imprimirlos de nuevo, porque la imagen del código habrá cambiado.
Podemos revisar cada versión de nuestra web app publicada en el botón de Implementar – Gestionar implementaciones
¡Y listo! Ahora ya sabes cómo crear un sistema de registro de asistencia para tomar lista fácil y automáticamente usando Google Sheets y códigos QR. Este ejemplo fue sencillo, pero te recomiendo revisar más sobre la documentación de las web apps y la función doGet para generar HTML propio desde las mismas, ya que las posibilidades son realmente infinitas.
Plantilla terminada para descargar
Guía en video
Si tienes dudas puedes ver esta misma guía explicada en video:
¡Espero que te haya sido útil esta guía! No olvides seguirnos en YouTube para más tips, trucos y guías de productividad.
Alekz es un apasionado de la tecnología y los videojuegos. Además de ser locutor comercial, disfruta de la expresión artística más sastisfactoria y técnica que existe: programar (y pintar algo de pixel art). Fundó Tesel para ayudar a empoderar a las empresas a desarrollar su máximo potencial mediante la tecnología. Es un absoluto nerd de Star Trek.
Alekz es un apasionado de la tecnología y los videojuegos. Además de ser locutor comercial, disfruta de la expresión artística más sastisfactoria y técnica que existe: programar (y pintar algo de pixel art). Fundó Tesel para ayudar a empoderar a las empresas a desarrollar su máximo potencial mediante la tecnología. Es un absoluto nerd de Star Trek.
hola, tengo problema con el código, me dice que:
Error
TypeError: Cannot read property ‘parameter’ of undefined
doGet @ Código.gs:6
y aca me supuestamente esta el error: registrarExpediente(correo, e.parameter.id, e.parameter.nombre);
hola Tengo el mismo error. Lo pudo solucionar??
Hola.
Este error es porque estas ejecutando el código desde la misma consola, el error es porque las variables o parámetros están vacíos, por eso te dice “parameter” of undefined, el código lo que hace es que cuando se ejecuta el link o qr, estos campos se llenan con la información del QR.
Espero haberte ayudado.
Alex ante todo agradecerte este tutorial pero a mi me sale ese error y no sé cómo solucionarlo, te explico:
Quiero crear de un formulario google una base da datos que genere automáticamente una hoja de google sheets. Utilizar tu tutorial para crear desde esa hoja códigos Qr de la información de todas las filas pero sólo de algunas columnas. He seguido todos tus pasos pero cuando genero el código QR al visualizarlo me sale en todos los paremetros “undefined” (teniendo todos los parámetros con caracteres). Cuando en el App script ejecuto para saber dónde está el fallo me sale
TypeError: Cannot read property ‘parameter’ of undefined
doGet @ Código.gs:6
Gracias Alex. Un saludo. Espero respuesta por favor!! 😉
hola a mi tambien me sale el mismo error…..help meee
Al parecer el error esta en en nombre del archivo donde se aloja el código. En mi caso decía “código” lo cambie a “code” (o cualquier cosa sin tilde) y funcionó.
Saludos!
¿en donde puedo ingresar para cambiarlo?
Hola!. Saludos!. Está genial la idea. Lo he probado y funciona. Pero tengo un inconveniente, no obtiene el correo de las personas que escanean. En la prueba del código funciona perfecto, pero cuando pruebo escaneando con el celular, no se obtiene el correo. Alguna sugerencia?? Gracias!
tengo el mismo error cuando escanean no sale el correo, nombre podrian ayudarme
Tengo el mismo problema, reviso el código y todo parece estar bien, pero en el HTML de confirmacion no muestra el email y tampoco lo guarda en la planilla de calculo.
sin embargo funciona la restriccion de acceder con una sesion iniciada, no se de donde vendra el error.
Que tal saludos!, agregue al código el campo “cargo” pero al ejecutar me envía este mensaje “ReferenceError: cargo is not defined (line 25, file “Code”)” podrías ayudarme por favor?
Hola, seguí todos los pasos y funciona pero no me registra la hora, alguna idea de que podría ser? gracias de ante mano
hola buenas tardes a mi me hacia lo mismo y tuve que cambiar el formato de las celdas de general a formato fecha y hora y con esto se corrigió chécalo tal vez te sirva el tip
¡Excelente! Sirve bastante, ¡muchas gracias por el tip! 😀
Hola, estoy tratando de grabar, antes de implementar y me sale el siguiente error: Error de sintaxis: SyntaxError: Unexpected identifier, línea: 27, archivo: Código.gs
Que hago? Gracias
alguna solución para
Error TypeError: Cannot read property ‘parameter’ of undefined
doGet @ Código.gs:6
Hola buenas tardes, se puede saber también en el lugar que estaba la persona cuando se hizo el escaneo del código?
Gracias!
Alex, esto mismo consulto y sería de mucha utilidad si se puede obtener la ubicación. Gracias y Saludos
si encuentra la forma seria bueno que abajo dejen un link de como hacerlo :’)
HOLA, TODO BIEN PERO EL DETALLE LA HORA ME SALE 1 HORA DE MAS , AL MOMENTO DE ESCANEAR EL QR EN EL CELULAR SI ME SALE LA HORA CORRECTA , PERO CUANDO REVISO EN EXCEL LA HORA SALE ERRADA CON UNA HORA MAS.
Debes cambiar la configuración regional desde Archivo/configuración, de la GSheet
buenas noches a mi no me aparecen los datos el qr ni el nombre o me aparece indefi
Alex buenas tardes. Primero agradecerte por el tutorial me funciono a la perfección, segundo es posible modificar el código para que al registrar una segunda vez en el mismo días se registre una salida? También estaba pensando en limitar el registro a 2 veces por días para poder limitar un poco.
La verdad no se si puedes ayudarme con eso pero de lo que ya explicaste esta buenísimo felicitaciones.
A pesar de seguir el paso a paso, no me permite ejecutar con usuarios diferentes al creador, mil gracias por su ayuda
Sobre el correo… alguien encontró solución? No me registra el correo
Como puedo hacer si quiero registrar la ubicación o ip donde se utilizo la cámara del movil al momento de escanear el Qr, espero me puedan ayudar.
Hola Alonso. Con este método no es posible obtener la IP porque el método doGet no lo provee por cuestiones de privacidad. Usando un servidor externo para hacer la petición sí podrías 😀
Hola que tal genial este tutorial, logre hacer todo, sin problema, pero no me escanean los codigos de barra
Hola tengo este error a la hora de leer el QR
TypeError: Cannot read property ‘getLastRow’ of null (línea 21, archivo “Código”)
HOLA TODO BIEN , SOLO QUE CUANDO ESCANEO EL CODIGO QR EN LA HOJA DE ASISTENCIA SOLO ME MARCA LA FECHA
Hola, me sale este error
Google no ha verificado esta aplicación
La aplicación está solicitando acceso a información sensible de tu cuenta de Google. No deberías utilizar esta aplicación hasta que el desarrollador (chsgestionestrategica@gmail.com) la verifique con Google
alguna solución para
Error TypeError: Cannot read property ‘parameter’ of undefined
doGet @ Código.gs:6
Buen dia tengo un error todo funciona pero me sale de la siguiente manera:
Asistencia registrada correctamente.
Fecha: Sun Nov 27 2022 22:24:02 GMT-0500 (hora estándar de Perú)
ID: 4######Nombre=Arturo Flores PolarTipo_Entrada=BOX
Nombre: undefined
Tipo_Entrada: undefined
Hola, buenas noches.
Antes que nada un agradecimiento por tu explicación bien clara y precisa.
Tengo una duda.
¿Se puede programar el script para que no se abra la pagina e inserte directamente los datos en las hojas de google?
TypeError: No se pueden leer las propiedades de null (leyendo ‘getLastRow’) (línea 24, archivo “Codigo”)
Hola!. Saludos!. Está genial la idea. Lo he probado y funciona. Pero tengo un inconveniente, no obtiene el correo de las personas que escanean.
pusite resolverlo ?
registro.getRange(lastRow, 4).setValue(vigencia); como puedo hacerle para que me registre este dato en formato fecha
a mi me funciono con este codigo lo modifique viendo el del video:
function doGet(e) {
const correo = Session.getActiveUser().getEmail();
// Cambia aquí tu idioma-país y zona horaria
// Registramos la asistencia usando el correo y los parámetros que vienen en la URL
registrarAsistencia(correo, e.parameter.id, e.parameter.nombre);
// Damos retroalimentación sobre lo que sucedió:
return HtmlService.createHtmlOutput(
Asistencia registrada correctamente. <br><br>
);Correo que registró: ${correo}<br>
Fecha: ${new Date}<br>
ID: ${e.parameter.id}<br>
Nombre: ${e.parameter.nombre}
}
function registrarAsistencia(correo, id, nombre) {
// Debes cambiar este identificador por el de tu documento de hoja de cálculo
const sheet = SpreadsheetApp.openById(“1Cg7_81dKAThaNZA38CPhBXbKUDGyFLtvmwKZE9i-wYU”);
const asistencia = sheet.getSheetByName(“Asistencia”);
const lastRow = asistencia.getLastRow() + 1;
asistencia.getRange(lastRow, 1).setValue(correo);
asistencia.getRange(lastRow, 2).setValue(id);
asistencia.getRange(lastRow, 3).setValue(nombre);
asistencia.getRange(lastRow, 4).setValue(new Date());
}
Si entro desde el url doGet me funciona genial, pero cuando lohago desde el QR me dice esto:
Google drive
No se puede abrir el archivo en estos momentos.
Compruebe la dirección e inténte de nuevo.
me sale el mismo error, lograste solucionarlo, cuando ingreso por el qr