10

Tengo una hoja de cálculo de Google de datos de la parte de horas; tiene una hoja para cada mes, cada hoja tiene una gran cantidad de bloques de columna, un bloque por cliente.Secuencia de comandos para resumir los datos que no se actualizan

He creado una hoja resumen que se va y se pone el total para cada cliente y lo muestra en una lista:

function getClientTotals(sheetname, colcount) 
{ 
    colcount = colcount ? colcount : 6; 
    var res;  
    var ss = SpreadsheetApp.openById('myid_goes_here'); 
    if(ss) 
    { 
    res = []; 
    var totrow = ss.getRange(sheetname + '!A1:ZZ1').getValues()[0]; 
    for(var i = 0; i < totrow.length; i += colcount) 
    { 
     res.push([totrow[i], totrow[i + colcount - 1]]); 
    } 
    } 
    return res; 
} 

He luego se agregó una célula a mi hoja de resumen que contiene =getClientTotals($C$7,$C$8) que pasa en el nombre de la hoja para el mes y el número de columnas para cada cliente (en caso de modificaciones de "esquema"

Todo funciona bien, sin embargo, no se actualiza cuando se cambian los datos de origen. He agregado un disparador onEdit ; no hay alegría. Se actualiza si vas al editor de scripts y pulsas Guardar, pero eso no es útil l. ¿Me estoy perdiendo de algo?

+0

No se ha perdido nada; podría ayudar a subir esta solicitud de función en Google Issue Tracker: https://issuetracker.google.com/issues/36763858 –

Respuesta

28

Te estás perdiendo el fastidioso caché error función. Funciona de esta manera:

Google considera que todas sus funciones personalizadas dependen solo en sus valores de parámetros directamente para devolver su resultado (opcionalmente puede depender de otros datos estáticos).

Dado este prerrequisito, pueden evaluar sus funciones solo cuando cambia un parámetro. p.ej.

Supongamos que tenemos el texto "10" en la celda B1, entonces en algún otro celular que escriba =myFunction(B1)

myFunction será evaluado y su resultado recuperada. Luego, si cambia el valor de la celda B1 a "35", la personalización se volverá a evaluar como se esperaba y el nuevo resultado se recuperará normalmente. Ahora, si cambia la celda B1 nuevamente al "10" original, no hay reevaluación, el resultado original se recupera inmediatamente de la memoria caché.

Por lo tanto, cuando usa el nombre de la hoja como parámetro para recuperarlo dinámicamente y devolver el resultado, está rompiendo la regla de almacenamiento en caché.

Lamentablemente, no puede tener funciones personalizadas sin esta increíble función. Por lo tanto, tendrá que cambiarlo para recibir los valores directamente, en lugar del nombre de la hoja, o no usar una función personalizada. Por ejemplo, podría tener un parámetro en su secuencia de comandos que indique dónde deben ir los resúmenes y tener un onEdit actualizarlos siempre que haya un total de cambios.

+1

Hmmm, eso es molesto, ¡pero gracias por la respuesta! Tengo una solución desagradable añadiendo un parámetro ficticio a la función; si paso una referencia de celda a eso puedo forzar que los datos se actualicen simplemente incrementando un número en esa celda. Supongo que no hay forma de que pueda crear un botón de actualización que lo haga con un clic, ¿verdad? Eso estaría bien, no necesita ser automático realmente, simplemente fácil y obvio. – Whelkaholism

+0

Bueno, puede crear un botón, en realidad un dibujo y asignarle una función de guión, que incrementará su celda de parámetro ficticio que forzará la actualización. –

+0

¡Impresionante, funciona perfectamente, gracias! – Whelkaholism

1

Otra solución al problema del almacenamiento en caché.

tienen una variable ficticia en su método. pase

Filter(<the cell or cell range>,1=1) 

como el valor para ese parámetro.

p. Ej.

=getValueScript("B1","B4:Z10", filter(B4:Z10,1=1)) 

la salida del filtro no se utiliza. sin embargo, indica a la hoja de cálculo que esta fórmula es sensible al rango B4: Z10.

+3

ya no funciona. Verá el error "Esta función no permite hacer referencia a una celda con NOW(), RAND() o RANDBETWEEN()" si intenta hacerlo de esta manera –

-1

Como @Brionius dijo puso un argumento dinamic extra en la función. si usa now() puede tener problemas de tiempo de espera para que la actualización sea un poco más lenta ...

cell A1 = int(now()*1000) 
cell A2 = function(args..., A1) 
+2

ya no funciona. Verás el error "Esta función no permite hacer referencia a una celda con NOW(), RAND() o RANDBETWEEN()" si intentas hacerlo de esta manera –

0

Lo que podría hacer es la creación de otra célula en algún lugar de la hoja de cálculo que se actualiza cada vez que se agrega una nueva hoja. Asegúrese de que no se actualice para cada cambio, sino solo cuando desee hacer el cálculo (en su caso cuando agrega una hoja). Luego pasa la referencia a esta celda a su función personalizada. Como se mencionó, la función personalizada puede ignorar este parámetro.

1

Tuve un problema similar al crear un tablero para el trabajo. La solución de Chamil anterior (es decir, el uso de la función Filtro de hoja pasada como el valor de una variable ficticia en su función) funciona bien, a pesar del comentario más reciente de Arsen. En mi caso, estaba usando una función para monitorear un rango y no pude usar el filtro en el mismo rango ya que creó una referencia circular. Así que sólo tenía una célula (en mi caso E45 en el código de abajo) en el que he cambiado el número en cualquier momento quería que mi función para actualizar:

=myFunction("E3:E43","D44",filter(E45,1=1)) 

Como se indica Chamil, el filtro no se usa en la secuencia de comandos:

function myFunction(range, colorRef, dummy) { 
    variable 'dummy' not used in code here 
} 
0

Dado que la función explicada por Henrique Abreu, se puede probar el fuera de la caja de la función de hoja de cálculo QUERY, que SQL le gusta consulta es lo que utilizo a menudo en el trabajo de datos en bruto, y recuperar los datos como resumen en una pestaña diferente, los datos de resultado se actualizan en tiempo real después del cambio en datos sin procesar.

Mi sugerencia se basa en el hecho de que su secuencia de comandos no ha avanzado el trabajo como búsqueda de URL, solo trabajo de datos, ya que sin datos reales leídos, no puedo dar una solución precisa con QUERY.

En cuanto a la función de caché mencionado por Henrique Abreu (no tengo la reputación suficiente para comentar directamente bajo su respuesta), hice la prueba y se encontró que:

  1. parece que no hay trabajo caché , script de la función de prueba que se muestra a continuación:

    sumador de funciones (base) { Utilities.sleep (5000); base de retorno + 10; }

aplicación que función personalizada sumador() en la hoja llamando a una célula, y luego modificados que valor de la celda adelante y atrás, cada vez que aparece el mensaje de carga y el tiempo total de más de 5 segundos. Podría estar relacionado con la actualización mencionada en este GAS issue:

Este problema ya se ha solucionado. Las funciones personalizadas en Hojas Nuevas ahora tienen en cuenta el contexto y no almacenan en caché los valores de forma tan agresiva.

  1. la emisión que se mencionan en este tema sigue siendo, mis pruebas sugiere que, hoja de Google recalcular función personalizada cada vez SOLAMENTE CUANDO

    • valor directamente llamado por función es cambiado

    función getCellValue (SheetName, fila, col) { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sh = ss.getSheetByName (sheetName); return sh.getRange (row, col) .getValue(); }

    enter image description here
    Un cambio de cualquier valor en las células amarillas dará lugar a un nuevo cálculo de la función personalizada; la función no tiene en cuenta el cambio en el valor real de la fuente de datos.

    • función que contiene la ubicación de la celda se cambia en la hoja. ex. insertar/eliminar una fila/columna arriba o lado izquierdo.
Cuestiones relacionadas