miércoles, 27 de febrero de 2019

Referencias a pestañas y/o celdas en código

No es inusual que en el código metamos líneas tal como esta: 

var herramienta = SpreadsheetApp.getActiveSpreadsheet()
var pestana = herramienta.getSheetByName('guardias')
var dato = pestana.getRange('A3').getValue()

 Estas dos líneas funcionarán solamente mientrás no se cambie el nombre de la pestaña y/o mientrás no se meta ninguna fila o columna antes de la fila 3 o de la columna A.

Pero en cuanto un usuario cambie el nombre de la pestaña... el código dejará de funcionar.
Y,  metiendo una fila nueva antes de la 3, el código dará otro valor.

Ante este problema, tenemos la solución:
En vez de utilizar getSheetByName
crearemos un intervalo con nombre llamado "Educa_profesor" en la pestaña que queremos referenciar y en el código utilizaremos esta línea para conseguir la pestaña
herramienta. getRangeByName('Educa_profesor').getSheet()
Con esto logramos que no nos afecte el cambio de nombre de pestaña.

En el caso de pestana.getRange('A3').getValue() podemos utilizar el mismo proceso, es decir, crear un intervalo con nombre que apunte a A3 y en el código:

herramienta. getRangeByName('rangoA3').getValue()


========================================================

========================================================

En mi caso tengo un problema añadido ya que utilizo fórmulas dentro del código tal que así:

  pestana.getRange('I11').setValue('=sort(unique('guardias'!A:A))') 

Si cambiasen el nombre de la pestaña guardias o metiesen una columna nueva antes de A, la fórmula escrita daría error al no encontrar dicho nombre de pestaña.

Para evitarlo la solución es un poco más larga.
Nos apoyaríamos también en un intervalo con nombre que cogiese toda la fila A de la pestaña guardias y escribiríamos esta línea de código:

  var mi_columna = "'"+herramienta.getRangeByName('columnaAA').getSheet().getName()+"'!"+herramienta.getRangeByName('columnaAA').getA1Notation()
Y la línea de escribir la fórmula quedaría así:

  pestana.getRange('I11').setValue('=sort(unique('+mi_columna+'))')

viernes, 22 de febrero de 2019

Problemas con fechas (Hoy no es igual a hoy)

Más problemas con fechas.
Queremos comparar una fecha con hoy y así hacer un condicional para que si hoy es la fecha que queremos haga algo. Pues... curiosamente pasa esto:

if (mifecha > hoy){logger.log('funciona')}
if (mifecha < hoy){logger.log('funciona')}

Pero si ponemos
if (mifecha == hoy){logger.log('funciona?')}
nunca entra en el condicional, ya que para ser igual, al llevar "hoy" la hora, el minuto, el segundo y el milisegundo nunca llega a ser igual a mi fecha (por ejemplo, a 22/02/2019)

Un buen truco:

Definimos hoy así:
var Hoy = new Date().setHours(0,0,0,0);

Problemas con fechas (Más soluciones)

Otro problema que me he encontrado con fechas es que queremos utilizar una fecha como argumento de un filter y no funciona.  Saber porqué pasa, a veces, se me hace imposible y, además, después de encontrar la solución, me quedan pocas ganas de seguir investigando. Por lo que solamente os voy a dar la solución.

Probando y probando, he descubierto que tiene que ver con el formato de la celda, que si le quitamos dicho formato funciona. Por lo tanto, desde el código, vamos a quitarle el formato, vamos a conseguir el resultado de la fórmula filter y, después, le volvemos a colocar el formato.

  1.  Quitamos formato --->    pestana_asignaciones.getValue('b2:b').setNumberFormat('@')
  2.  Escribimos la fórmula ----> .setValue('=filter(asignaciones!e:e;asignaciones!b:b="25/12/2018)') 
  3. Volvemos a poner el formato ---->
    pestana_asignaciones.getValue('b2:b').setNumberFormat('d/MM/yyyy')


lunes, 18 de febrero de 2019

Al editar una celda

Podemos crear una función que se ponga en marcha cada vez que se cambia algo. Necesitaremos entrar en "Activadores del proyecto activo" y configurar un activador que corra cuando se edita algo.

En la siguiente función vemos como se puede recoger información sobre el cambio

function cambios(e) {
// Información que podemos pillar cuando cambiamos algo en una celda

// 1.- La hoja de cálculo 
        var herramienta = e.source
// 2.- El valor que hemos escrito nuevo  
        var cambio = e.value
// 3.- El valor antiguo  
        var anterior = e.oldValue
// 4.- El correo de quien lo ha cambiado  
        var user = e.user
}

Con la primera (la hoja de cálculo --- e.source) podremos acceder a muchos más datos utilizando esta combinación e.source.getActiveRange()
Por ejemplo:
e.source.getActiveRange().getColumn()
e.source.getActiveRange().getRow()

viernes, 15 de febrero de 2019

Líneas demasiado largas en código

Creo que acabo de descubrir como partir líneas largas de código en varias cortas
En otros lenguajes, cuando se acaba una declaración se pone alguna marca para dejarlo claro.
Tanto en Javascript como en PHP se utiliza el punto y coma.

En  Google Script no es necesario acabar las líneas de ninguna manera. Pero si admite el punto y coma. Pero, claro, si no es necesario... ¿Para que escribir de más?

Bueno, pues resulta que puedes jugar con dicho punto y coma para separar en varias filas cortas una declaración.

Un ejemplo:
function larga() {
  var herramienta = SpreadsheetApp.
                    getActiveSpreadsheet().
                    getSheetByName('datos').
                    getRange('F1').
                    setNumberFormat('@'); 
// Al poner aquí el punto y coma conseguimos que una todas las anteriores líneas
 var herramienta2 =   SpreadsheetApp.
                    getActiveSpreadsheet().
                    getSheetByName('datos').
                    getRange('F1').getValue(); 
// Aquí va otro punto y coma          
  Logger.log(herramienta2) 
//Aquí se nos ha olvidado, pero no importa
 
}


Resumiendo: Si necesitamos partir una línea larga de código, bastará con poner al final, en la última línea resultante, un punto y coma.

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