Mostrando entradas con la etiqueta Editar. Mostrar todas las entradas
Mostrando entradas con la etiqueta Editar. Mostrar todas las entradas

lunes, 18 de septiembre de 2023

Cambiar el título de un gráfico dinámicamente

 Gracias a Ben Collins podemos utilizar esta función de código para que el título de un gráfico esté unido al contenido de una celda


function changeChartTitle() {

// apunta al gráfico
// Suponemos, en este caso, que solamente hay un gráfico en la pestaña. En caso necesario, ajustaremos el index [0] al gráfico en cuestión

const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Hoja 1');

const chart = sheet.getCharts()[0];

// get the chart title from the cell
const newTitle = sheet.getRange('A1').getValue();

// actualiza el título del gráfico
const chartBuilder = chart.modify();
chartBuilder.setOption('title', newTitle);
const updatedChart = chartBuilder.build();
sheet.updateChart(updatedChart);
}


Aparte del código necesitamos crear un activador que se lance cada vez que se edita la celda

martes, 12 de junio de 2018

Convertir casillas de verificación ☑️ en selección múltiple 🔘

No hace mucho, Google creó la opción de incluir casillas de verificación en las hojas de cálculo. Os muestro un ejemplo:






En este caso utilizo las casillas para que el usuario decida si un correo se manda en castellano, en euskera o en bilingüe.
Pero, mi problema es que, como son casillas de verificación, no quiero que me marquen mas de una, sino que cuando marquen una las restantes se desmarquen.

Las casillas no tienen por defecto dicho comportamiento, ya que puedes marcar una, varias o todas.

Mediante código podemos conseguir que se comporten como selección múltiple (según el lenguaje de los formularios de drive) o radio buttons ( según html), es decir como:
🔘


Para conseguirlo vamos a utilizar la función onEdit(event) que viene por defecto en Google Script

Esta función corre cada vez que hay un cambio en la hoja de cálculo, por lo que, con una estructura condicional, haremos que cada vez que hagamos clic en una casilla de verificación los valores de todas las demás pasen a "false"

function onEdit(event) {
// Gracias al argumento "event" pillamos la celda que cambia en cada momento
     var celda_cambiada= event.source.getActiveRange().getA1Notation();
//  Enlazamos a la hoja de cálculo activa y la pestaña que nos interesa    
     var aplicacion = SpreadsheetApp.getActiveSpreadsheet()
     var pestana = aplicacion.getRangeByName('correo_plantilla').getSheet()
 

// Por medio de switch tenemos un condicional con más de dos opciones, más claro y eficaz que IF   
     switch(celda_cambiada) { // comparamos la celda cambiada y creamos tres casos
    case 'C15':
        pestana.getRange('c16').setValue(false) // hacemos que la c16 se desmarque
        pestana.getRange('c17').setValue(false)
// hacemos que la c17 se desmarque 
       break; // Salimos del código condicional
    case 'C16':
        pestana.getRange('c15').setValue(false)
        pestana.getRange('c17').setValue(false)
        break;
    case 'C17':
        pestana.getRange('c15').setValue(false)
        pestana.getRange('c16').setValue(false)
        break;
    default:
        Browser.msgBox('Mala puntería')
}
}

domingo, 20 de mayo de 2018

Crear formulario de varias líneas dentro de una hoja de cálculo

 Este código nos va a servir para poder tener los datos que vienen de un formulario (grabados en una pestaña normalmente llamada 'Respuestas de formulario') en una pestaña diferente a la que los recoge  y que podamos cambiarlos, de tal forma que se cambien a la vez en la pestaña 'Respuestas de formulario'.
Google Script tiene alguna función configurada por defecto. Una de ellas es onEdit(event)
La función onEdit(event) tiene una potencia muy grande, tanta que necesita llenarla con condicionales que la frenen. Esta función se dispara en cuanto se cambia el contenido de cualquier celda de la hoja de cálculo. Por lo tanto para domarla podemos hacer esto:

// Primero pillamos la referencia de la celda que se ha editado
  var celda_cambiada= event.source.getActiveRange().getA1Notation();
// Y luego creamos un condicional como este
   if (celda_cambiada=="B4") {}

Así, solamente correrá el código que metamos dentro del condicional y en el caso que editemos B4

Imaginaros que en B4 ponemos una lista desplegable de poblaciones. Y en la pestaña de respuestas de formulario tenemos datos sobre centros públicos y una de las columnas (La B) nos da la población donde está dicho centro. Si escribimos lo siguiente:

function onEdit(event){
   var celda_cambiada= event.source.getActiveRange().getA1Notation();
   if (celda_cambiada=="B4") {
       formulario.getRange('A7').setValue('=filter('Respuestas de formulario'!a:h;datos!B:B=B4)')
                                             }
               } 

... conseguimos un filtro con los datos de la población elegida en B4. No muy sorprendente.
Pero, una vez conseguidos los datos, como estamos en la función onEdit, cualquier cambio que hagamos en estos datos podemos pillarlos y, con código, hacer que cambien también en la pestaña respuestas de formulario, con lo que tendríamos en una segunda pestaña la posibilidad de cambiar datos en todos los sitios a la vez, como si fuera un formulario interno.

Uno de los problemas de esta técnica es que nos molesta la fórmula que hemos puesto en A7. Nos vendría bien tener los datos filtrados, pero sin la fórmula.
¿Cómo? Metemos los datos dados por la fórmula en una variable, limpiamos la fórmula y pegamos los datos otra vez. El código quedaría algo así:
function onEdit(event){
var pestana = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('pestana')
   var celda_cambiada= event.source.getActiveRange().getA1Notation();
   if (celda_cambiada=="B4") {
pestana.getRange('A7:H').clearContent() // Hay que limpiar antes, ya que si no da error
       pestana.getRange('A7').setValue('=filter('Respuestas de formulario'!a:h;datos!B:B=B4)')
var valores = pestana.getRange('A7:H').getValues()
pestana.getRange('A7:H').setValues(valores)
                                              }
               }

Ahora vamos al proceso de conseguir cambiar en respuestas de formulario justo el mismo dato que cambiamos en donde hemos hecho el filtro. Necesitamos saber la fila donde está en respuestas de formulario el dato que queremos cambiar. Se me ocurre meter en respuestas de formulario una columna que gracias a la fórmula row() nos escriba el número de cada fila y que recuperemos este número dentro del filtro.
 Con el siguiente código ya tendríamos hecho todo, siempre que las columnas de una y otra pestaña (datos y respuestas de formulario) coincidan:
//Conseguimos lo que hemos cambiado
var dato_cambiado=event.source.getActiveRange().getValue()
// Pillamos la columna que se ha cambiado
 var Col_celda_cambiada=event.source.getActiveRange().getColumn()
//  Pillamos la fila donde se ha cambiado algo, que nos servirá para conseguir el valor de la fila donde está el mismo contenido en respuesta de formulario
 var Fila_celda_cambiada=event.source.getActiveRange().getRow()
 var fila_resp_formulario=pestana.getRange(Fila_celda_cambiada,8).getValue() //ya que el número de fila lo tenemos, en este caso, en la columna H ú 8

// con los estos datos ya podemos apuntar a respuestas de formulario y cambiar el contenido adecuado
var datos =SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Respuestas de formulario')
datos.getRange(fila_resp_formulario,Col_celda_cambiada).setValue(dato_cambiado)


Crear PDF horizontal

El código que vamos a mostrar aquí no ha sido creado por nosotros, sino que lo hemos encontrado en Internet. Objetivo: Publicar una pesta...