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)


No hay comentarios:

Publicar un comentario

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...