10

Ho un foglio di calcolo Google dei dati della scheda attività; ha un foglio per ogni mese, ogni foglio è composto da sei blocchi di colonne, un blocco per client.Script per riepilogare i dati che non si aggiornano

ho creato una scheda riassuntiva che va e ottiene il totale per ogni cliente e lo visualizza in un elenco:

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; 
} 

ho poi appena aggiunto una cella per la mia scheda riassuntiva contenente =getClientTotals($C$7,$C$8) che passa nel nome del foglio per il mese e il numero di colonne per ciascun cliente (in caso di modifiche dello schema.

Tutto funziona correttamente, tuttavia, non si aggiorna quando i dati di origine vengono modificati. Ho aggiunto un trigger onEdit Nessuna gioia, si aggiorna se vai all'editor degli script e premi Salva, ma non è usefu l. Mi sto perdendo qualcosa?

+0

Non manca nulla; potrebbe aiutare ad andare su questa richiesta di funzionalità in Google Issue Tracker: https://issuetracker.google.com/issues/36763858 –

risposta

28

Ti manca la funzione di cache fastidiosa bug. Funziona in questo modo:

Google ritiene che tutte le funzioni personalizzate dipendano dallo solo sui valori dei parametri direttamente per restituire il risultato (è possibile dipendere facoltativamente da altri dati statici).

Dato questo prerequisito possono valutare le funzioni solo quando un parametro cambia. per esempio.

Supponiamo di avere il testo "10" sulla cella B1, poi su qualche altra cellula digitiamo =myFunction(B1)

myFunction sarà valutata e il suo risultato recuperate. Quindi, se si modifica il valore della cella B1 su "35", le personalizzazioni verranno rivalutate come previsto e il nuovo risultato verrà recuperato normalmente. Ora, se si modifica nuovamente la cella B1 nell'originale "10", non c'è alcuna rivalutazione, il risultato originale viene recuperato immediatamente dalla cache.

Quindi, quando si utilizza il nome del foglio come parametro per recuperarlo in modo dinamico e restituire il risultato, si interrompe la regola di memorizzazione nella cache.

Sfortunatamente, non è possibile avere funzioni personalizzate senza questa fantastica funzionalità. Quindi dovrai cambiarlo per ricevere direttamente i valori, invece del nome del foglio, o non usare una funzione personalizzata. Ad esempio, potresti avere un parametro sul tuo script che indica dove dovrebbero andare i sommari e avere un onEdit aggiornarli ogni volta che un totale cambia.

+1

Hmmm, che è fastidioso, ma grazie per la risposta! Ho una brutta soluzione aggiungendo un parametro dummy alla funzione; se poi passo un riferimento di cella a quello posso forzare i dati per aggiornare semplicemente incrementando un numero in quella cella. Non supponiamo che ci sia comunque un pulsante di aggiornamento che lo farà con un clic, vero? Ciò andrebbe bene, non ha bisogno di essere automatico davvero, solo facile e ovvio. – Whelkaholism

+0

Bene, puoi creare un pulsante, in realtà un disegno e assegnargli una funzione di script, che incrementerà la tua cella di parametri fittizia che imporrà l'aggiornamento. –

+0

Fantastico, funziona perfettamente, grazie! – Whelkaholism

1

un'altra soluzione al problema di memorizzazione nella cache.

hanno una variabile fittizia nel metodo. passaggio

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

come valore di tale parametro.

ad es.

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

l'uscita del filtro non viene utilizzata. tuttavia indica al foglio di calcolo che questa formula è sensibile all'intervallo B4: Z10.

+3

non funziona più. Verrà visualizzato l'errore "Questa funzione non è consentita per fare riferimento a una cella con NOW(), RAND() o RANDBETWEEN()" se si tenta di farlo in questo modo –

-1

Come ha detto @Brionius, ha aggiunto un argomento dinamico aggiuntivo alla funzione. se usi ora() potresti avere problemi di timeout rendere l'aggiornamento un po 'più lento ...

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

non funziona più. Vedrai l'errore "Questa funzione non può fare riferimento a una cella con NOW(), RAND() o RANDBETWEEN()" se provi a farlo in questo modo –

0

Che cosa si potrebbe fare è quello di impostare un altro cellulare da qualche parte nel foglio di calcolo che verrà aggiornato ogni volta che viene aggiunto un nuovo foglio. Assicurati che non venga aggiornato per ogni modifica ma solo quando vuoi eseguire il calcolo (nel tuo caso quando aggiungi un foglio). Quindi passa il riferimento a questa cella alla tua funzione personalizzata. Come accennato, la funzione personalizzata può ignorare questo parametro.

1

Ho avuto un problema simile creando un dashboard per lavoro. La soluzione di Chamil sopra (vale a dire l'uso della funzione Filter's Sheet passata come valore a una variabile fittizia nella tua funzione) funziona bene, nonostante il commento più recente di Arsen. Nel mio caso, stavo usando una funzione per monitorare un intervallo e non potevo usare il filtro sullo stesso intervallo poiché ha creato un riferimento circolare. Così ho appena avuto una cella (nel mio caso E45 nel codice seguente) in cui ho cambiato il numero ogni volta che volevo la mia funzione per l'aggiornamento:

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

Come Chamil indicato, il filtro non viene utilizzato nello script:

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

Dato che caratteristica spiegato da Henrique Abreu, si può provare il out-of-box funzione di foglio di calcolo QUERY, che SQL è piaciuto query è quello che io uso spesso nel lavoro sui dati grezzi, e ottenere dati come riassunto in una scheda diversa, i dati dei risultati vengono aggiornati in tempo reale in seguito al cambiamento in dati grezzi.

Il mio suggerimento si basa sul fatto che lo script non ha lavoro avanzato come il recupero dell'URL, solo i dati funzionano, poiché senza la lettura dei dati reali, non riesco a dare una soluzione precisa con QUERY.

Per quanto riguarda la funzione di cache menzionato da Henrique Abreu (non ho abbastanza fama di commentare direttamente sotto la sua risposta), ho fatto il test e ha scoperto che:

  1. sembra non v'è la cache di lavoro , testare lo script della funzione mostrato di seguito:

    funzione sommatore (base) { Utilities.sleep (5000); base di ritorno + 10; }

applicazione di tale funzione personalizzata vipera() in lamiera chiamando il cellulare, e poi cambiato il valore delle cellule avanti e indietro, ogni volta che vedo il messaggio di carico e tempo totale più di 5 secondi. Potrebbe essere correlato all'aggiornamento menzionati in questo GAS issue:

Questo problema è stato risolto. Le funzioni personalizzate in Nuovi fogli sono ora a conoscenza del contesto e non memorizzano i valori in modo aggressivo.

  1. il problema menzionato in questo argomento rimane, il mio test suggerisce che, foglio di Google ricalcolare funzione personalizzata ogni volta SOLO QUANDO

    • valore direttamente chiamato da funzione è cambiato.

    funzione getCellValue (SheetName, riga, colonna) { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sh = ss.getSheetByName (sheetName); return sh.getRange (row, col) .getValue(); }

    enter image description here
    Un cambiamento di qualsiasi valore in celle gialle porterà alla rideterminazione della funzione personalizzata; la vera modifica del valore della sorgente dati viene ignorata dalla funzione.

    • la funzione contenente la posizione della cella viene modificata nel foglio. ex. inserisci/rimuovi una riga/colonna sopra o sul lato sinistro.
Problemi correlati