Triggers en Google Apps Script: onOpen y onEdit
🟢 onOpen
Se ejecuta automáticamente cada vez que alguien abre el Google Sheet. Se usa para preparar el entorno antes de que el usuario trabaje: crear menús personalizados, mostrar mensajes de bienvenida, revisar el estado de la hoja, etc.
Solo se dispara una vez, al abrir el archivo.
function onOpen() {
SpreadsheetApp.getUi().createMenu('⚙️ Mi Menú').addItem('👋 Saludar', 'saludar').addToUi();
}
function saludar() {
SpreadsheetApp.getUi().alert('¡Hola! Bienvenido a la hoja.');
}
Más usos de onOpen
Menú con submenús
function onOpen() {
var ui = SpreadsheetApp.getUi();
var submenu = ui
.createMenu('📊 Reportes')
.addItem('Reporte diario', 'reporteDiario')
.addItem('Reporte mensual', 'reporteMensual');
ui.createMenu('🛠️ Herramientas')
.addSubMenu(submenu)
.addSeparator()
.addItem('⚙️ Configuración', 'abrirConfig')
.addToUi();
}
Sidebar (panel lateral con HTML)
function onOpen() {
SpreadsheetApp.getUi().createMenu('📋 Mi App').addItem('🔧 Abrir Panel', 'mostrarSidebar').addToUi();
}
function mostrarSidebar() {
var html = HtmlService.createHtmlOutputFromFile('Sidebar').setTitle('Panel de Control');
SpreadsheetApp.getUi().showSidebar(html);
}
Menú personalizado según el usuario
function onOpen() {
var usuario = Session.getActiveUser().getEmail();
var ui = SpreadsheetApp.getUi();
var menu = ui.createMenu('🔐 Panel');
if (usuario === 'admin@empresa.com') {
menu.addItem('👑 Opciones Admin', 'panelAdmin');
}
menu.addItem('📄 Ver Reporte', 'verReporte').addToUi();
}
Revisar y avisar el estado de la hoja al abrir
function onOpen() {
var hoja = SpreadsheetApp.getActiveSheet();
var filas = hoja.getLastRow();
SpreadsheetApp.getUi().createMenu('📋 Mi App').addItem('👋 Saludar', 'saludar').addToUi();
if (filas < 2) {
SpreadsheetApp.getUi().alert('⚠️ La hoja está vacía. Agrega datos para comenzar.');
}
}
🟡 onEdit
Se ejecuta automáticamente cada vez que alguien edita una celda. Se usa para reaccionar en tiempo real: validar datos, poner colores según valores, registrar fechas de cambio, etc.
Puede dispararse muchas veces mientras se trabaja en la hoja.
El objeto e (evento) trae información clave:
e.range→ la celda editadae.value→ el nuevo valore.oldValue→ el valor anteriore.source→ la hoja de cálculo completa
function onEdit(e) {
var celda = e.range;
// Si se edita la columna A, poner la fecha en la columna B
if (celda.getColumn() === 1) {
e.source.getActiveSheet().getRange(celda.getRow(), 2).setValue(new Date());
}
}
Más usos de onEdit
Alertar stock bajo con color (inventario)
function onEdit(e) {
var celda = e.range;
if (celda.getColumn() === 3 && celda.getRow() > 1) {
var valor = celda.getValue();
if (valor < 10) {
celda.setBackground('#ff0000').setFontColor('#ffffff');
} else {
celda.setBackground(null).setFontColor('#000000');
}
}
}
Validar que solo se ingresen números
function onEdit(e) {
var celda = e.range;
if (celda.getColumn() === 2) {
var valor = celda.getValue();
if (isNaN(valor)) {
SpreadsheetApp.getUi().alert('⚠️ Solo se permiten números en esta columna.');
celda.setValue(e.oldValue || '');
}
}
}
Registrar quién hizo el cambio
function onEdit(e) {
var hoja = e.source.getActiveSheet();
var usuario = Session.getActiveUser().getEmail();
var fila = e.range.getRow();
hoja.getRange(fila, 5).setValue(usuario + ' - ' + new Date());
}
Marcar tareas completadas (checklist)
function onEdit(e) {
var celda = e.range;
if (celda.getColumn() === 4 && celda.getValue() === 'Completado') {
var fila = e.source.getActiveSheet().getRange(celda.getRow(), 1, 1, 4);
fila.setBackground('#d9ead3');
}
}
Bloquear edición fuera de un rango permitido
function onEdit(e) {
var celda = e.range;
if (celda.getRow() === 1) {
SpreadsheetApp.getUi().alert('🚫 No puedes editar la fila de encabezados.');
celda.setValue(e.oldValue || '');
}
}
⚠️ Diferencia importante
Ambos son “triggers simples” por defecto y no pueden enviar correos ni acceder a servicios externos por seguridad. Si necesitas eso, hay que crear un trigger instalable desde el menú Triggers (⏰) del editor de Apps Script.
🎯 Resumen
- onOpen → se ejecuta al abrir el archivo, ideal para menús.
- onEdit → se ejecuta al editar una celda, ideal para validaciones y automatizaciones.