Paragonabili all'uso delle Macro in Excel
Bottoni che eseguono script in Spreadsheet con Google Apps Script
Allo stesso modo di come su Excel si associavano delle macro in VBA a bottoni personalizzati inseriti nei fogli di lavoro, con Google Apps Script e Google Spreadsheet è possibile ottenere lo stesso tipo di risultato.
In questo video ti mostro mostro come sia semplice creare un bottone per eseguire una macro!
Iscriviti al mio Canale YouTube per rimanere aggiornato sull'uscita dei miei nuovi video!
Voglio farti un altro esempio descrivendoti di seguito i passaggi.
La creazione di un bottone personalizzato è ancora più semplice della creazione di un menu personalizzato con Google Apps Script, i passaggi da seguire sono descritti di seguito.
In questo tutorial inserirò un bottone personalizzato all'interno di un foglio di lavoro di Google e gli assegnerò una funziona al click (nel caso specifico, al solo scopo illustrativo, l'azione sarà quella di eliminare tutti i dati presenti nel foglio dove il bottone è posizionato previa avviso tramite una finestra di dialogo).
Inserire un'immagine di un bottone personalizzato in un foglio di uno Spreadsheet.
Per farlo basta cliccare sulla voce di menu 'Insert -> Image...' (o anche 'Insert -> Drawing...' se si preferisce apportare alcune modifiche all'immagine o crearne una ex-novo) e scegliere il modo con cui si intende inserire l'immagine in questione (caricamento da disco, caricamento da url, da Google Drive, ecc...). Una volta effettuata l'operazione il risultato sarà qualcosa di simile al seguente (io ho scelto un bottone circolare con la scritta 'RESET' e l'ho posizionato vicino ad un testo presente nelle celle del foglio attivo), Fig. 1:
Una volta che il bottone è stato inserito andiamo a creare la funzione all'interno dell'editor integrato selezionando dal menu principale la voce 'Tools -> Script editor...', la funzione come anticipato cancellerà tutti i dati presenti nel foglio mostrando una finestra di dialogo informativa dell'operazione avvenuta.
Nel foglio di script inserire il seguente codice per la funzione che andremo a chiamare 'resetData':
function resetData(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
sheet.clear();
Browser.msgBox("Tutti i dati presenti in questo Sheet sono stati cancellati!\\nPremi 'OK' per continuare.");
}
N.B.: in Apps Script per fare in modo che il testo in un'alert vada a capo è necessario inserire due simboli di 'escape' seguiti da una lettera 'n' nel punto in cui si intende interrompere la riga.
Dopo le operazioni di salvataggio assegnare tale funzione al clic sul bottone. Cliccare con il tasto destro del mouse sul bottone che si evidenzierà (e che in questo momento potrà essere eventualmente riposizionato all'interno dell'area del foglio attivo) ed appariranno 3 pallini in verticale nell'angolo in alto a destra dell'immagine, cliccare su quei pallini e dal menu contestuale che si aprirà cliccare su 'Assign script…', come mostrato in Fig. 2:
Si aprirà una finestra di dialogo dove dovrà essere inserito il nome della nostra funzione, nel caso specifico 'resetData', e confermare cliccando su 'OK', Fig. 3:
Non resta altro adesso che provare a cliccare sul bottone per osservare che in primo luogo comparirà la finestra di dialogo informativa (Fig. 3) ed alla sua chiusura i dati nel foglio spariranno (Fig. 4):
Quella del tutorial è solo una funzione di esempio ma è possibile applicare funzionalità più utili come ad esempio l'inserimento del timestamp corrente all'interno di una cella prefissata, avviare l'invio di email ad un indirizzo o a una lista di indirizzi definita, ecc...
Queste e molte altre informazioni sui bottoni personalizzati in Google Apps Script continuano nel mio libro "Punta in alto con... Google Apps Script":
Troverai altre informazioni sui bottoni personalizzati di Apps Script come:
- inserimento di immagini e disegni personalizzati;
- cancellazione di dati sulla base della loro tipologia;
- gestione delle formattazioni delle celle;
- parametri opzionali della funzione clear();
- coppie di informazioni chiave-valore da passare ai metodi;
- tutta una serie di informazioni utili con immagini chiare ed esemplificative.
...E QUESTO È SOLO QUANTO RIFERITO AI BOTTONI CHE ESEGUONO SCRIPT PERSONALIZZATI DI APPS SCRIPT!
ACQUISTA ORA IL LIBRO SU AMAZON:
Se sei pronto a diventare un esperto nella programmazione in Google Apps Script non posso fare altro che augurarti una buona lettura e soprattutto... Buon divertimento!
Se sei interessato all'uso di bottoni personalizzati che eseguono script all'interno di uno Spreadsheet probabilmente può esserti utile leggere l'articolo 'Eseguire una funzione al click su un bottone in uno Spreadsheet e far tornare il Focus su una cella'.
Se invece vuoi aggiungere una funzione personalizzata ad un Foglio di Google da utilizzare come qualsiasi altra funzione integrata puoi fare riferimento all'articolo 'Funzioni personalizzate in Google Sheets con Google Apps Script'.
desidero assegnare ad un pulsante lo script che aumenti il valore di una determinata cella, come si può fare?
Grazie
Ciao Nico,
con lo stesso principio di assegnazione di una funzione al pulsante (come spiegato nel tutorial), ti basterà recuperare il valore della cella di tuo interesse, sommarci +1 ed impostare il contenuto della stessa cella con il risultato della somma.
Ti riporto di seguito uno script funzionante che, al clic sul pulsante a cui viene assegnata la funzione, incrementa il valore della cella D3.
Nel caso tu provassi ad usare la funzione che ti scrivo di seguito così com'è, ricordati che devi assegnare preventivamente alla cella un valore numerico (anche 0) in quanto, essendo un codice fatto a scopo esplicativo non ho previsto le varie eccezioni (ad esempio se la cella è vuota o se non contiene un valore numerico)
Spero ti sia stato di aiuto per risolvere il tuo dubbio.
Ciao Michele, io ho semplice tabella e vorrei un pulsante che aggiunga una riga in alto (sotto la iga delle intestazioni). Puoi aiutarmi?
Grazie
Ciao Antonio,
ho avuto recentemente la stessa esigenza, ti riporto di seguito il codice di una funzione che, se richiamata (nel tuo caso tramite clic sul bottone previa sua assegnazione), inserisce una riga vuota sotto l'header (considerando l'intestazione alla prima riga) all'interno del foglio dello Spreadsheet associato:
Se poi hai bisogno di riempire quella riga con dei valori puoi affidarti al metodo getRange:
...dove row dovrà avere valore 2 (che è l'indice della seconda riga dello Sheet).
Ciao Michele,
grazie innanzitutto, funziona perfettamente.
Più che inserire dei valori mi servirebbe che la nuova riga prendesse da quella sottostante formati e formule. Per chiarezza la mia tabella a colori alternati ha 5 colonne, la prima formattata a data le due successive a testo le ultime due a valuta. Solo l'ultima contiene una formula (aggiunge l'IVA al valore della colonna precedente "se" è verificata una condizione in una delle colonne di testo).
E' possibile che la nuova riga generata a clic del pulsante abbia già formati e formula?
Se poi il cursore si posizionasse direttamente nella prima cella dell nuova riga sarebbe perfetto.
Grazie...per la pazienza ;)
Wow Michele ci sono riuscito, non hai idea della felicità.
Partendo dal tuo docice e cercando qua e la ho capito (vagamente) come funziona.
Ci ho provato e...funziona!
Ecco, il cursore non ho proprio idea di come avrei potuto posizionarlo nella prima cella della nuova riga ma direi che posso sorvolare ;)
Ciao Antonio,
mi fa piacere che tu sia riuscito a risolvere in autonomia :)
Per quanto riguarda il posizionamento del cursore nella cella puoi utilizzare i metodi getRange e setActiveRange, come nell'esempio di seguito:
In questo modo, dopo aver cliccato sul bottone, la selezione si sposterà automaticamente nella cella indicata, nel caso specifico la A2.
Tuttavia se l'obiettivo è quello di poter scrivere direttamente da tastiera una volta che la cella è stata selezionata ti anticipo già che non funzionerà, perché il focus, nonostante la selezione, rimane sul bottone cliccato.
Nel caso tu necessitassi effettivamente di questa funzionalità, potresti dare un'occhiata a questa soluzione, non pulitissima ma efficace, che è una sorta di workaround al mancato focus sulla cella dopo il click sul bottone e che ti permetterà di scrivere subito da tastiera nella cella automaticamente selezionata:
Eseguire una funzione al click su un bottone in uno Spreadsheet e far tornare il Focus su una cella
https://www.appsscript.it/tutorial/google-apps-script-eseguire-una-funzione-al-click-su-un-bottone-in-uno-spreadsheet-e-far-tornare-il-focus-su-un-cella/
Buongiorno Michele
in un foglio ho inserito un pulsante che aziona uno script per cancellare alcune celle. Funziona perfettamente nel browser, mentre utilizzando la app fogli su ipad non funziona.
In pratica al clic sull'immagine utilizzata come pulsante nell'app fogli viene semplicemente selezionata l'imagine, però non parte lo script. Ti risulta che non funzioni?
Ti è mai capitato? Hai qualche soluzione?
L'unica che mi è venuta in mente è di provare ad associare lo script ad un testo in una cella, però ... non mi piace molto.
Ciao Domenico,
ho effettuato una prova prendendo come esempio uno Spreadsheet (con bottone personalizzato che al click esegue una funzione) che su desktop funziona correttamente e, su Android (non ho modo al momento di provare con un dispositivo iOS ma credo che la situazione sia la medesima), se provo ad aprirlo con l'applicazione integrata non riesco a visualizzare neanche il bottone stesso.
Se invece, sempre da mobile, lo apro con il browser (nel caso specifico del mio test, Chrome) riesco a visualizzare il bottone ma interagendo con esso non ottengo alcuna reazione (sembra somigliare al caso da te descritto).
Mentre, sempre da mobile, se lo apro con il browser (sempre Chrome) scegliendo tra le impostazioni 'Sito desktop' il bottone, al contatto, esegue correttamente la funzione ad esso associata.
Presumo pertanto che l'anomalia da te descritta sia dovuta ad un'incongruente interpretazione dello Spreadsheet da parte dell'applicazione con cui è stato aperto.
Buonasera, confermo quanto segnalato da Domenico: un foglio contenente un pulsante a cui è associato uno script non funziona nell'app Fogli per iPad. Questo rende l'app abbastanza inutile (ed anche l'iPad). Anche cercando di forzare la visualizzazione e l'editing del foglio da browser (disinstallando l'app Fogli) tutti gli script sono disattivati. :-(
Ciao Roberto,
non ho molta affinità con i sistemi iOS tuttavia sono riuscito a rispolverare un mio vecchio iPhone 4S che utilizzavo come muletto sul quale ho potuto effettuare alcune prove e non posso che confermare quanto indicato sia da te che da Domenico aggiungendo alla lista dei dispositivi iOS che sono in difetto con le funzionalità dello Spreadsheet indicate, nel caso specifico l'esecuzione di una funzione al clic su un bottone personalizzato, non solo gli iPad ma gli iPhone.
Cercando anche in rete è evidente che il problema è diffuso ma anche la documentazione ufficiale del support di Google non si pronuncia in merito.
Ciao , io ho una tabella fatta di celle convalida dati. dovrei associare al tasto reset uno script che resetti quelle celle, eliminarle penso vada bene.
un altra cosa che vorrei ma non riesco a fare è: in una stessa colonna eliminare dalle altre convalida dati i valori gia selezionati nelle righe precedenti o successive, ce l'ho fatta con alcuni if però selezionando per esempio il nome caio in una riga nella seconda non mi compare più nella convalida dati(visto che viene eliminato dalla lista sorgente della convalda) però su quel caio spunta il triangolino rosso di errore, proprio perchè caio non è più in lista. grazie
Ciao Francesco,
per resettare una cella di tipo 'convalida dati' puoi utilizzare la seguente funzione (nel caso specifico svuota la cella in posizione G6):
Ovviamente puoi indicare un range più ampio di celle da svuotare definendo gli opportuni parametri all'interno di getRange.
Grazie mille.! funziona, unico poblema che mi va a cancellare anche i bordi più scuri di alcune celle del range.
Ho risolto con clearcontent. ora lascia i bordi della tabella. Purtroppo non è finita qui . nella convalida ho messo il valore "--------" quando bisogna lasciare un orario vuoto. nel momento in cui uso clearcontent la convalida si cancella proprio perciò mi troverei alcuni vuoti e alcuni --------. Le soluzioni sono due, o metto nelle celle direttamente da script "--------" oppure devo far in modo che nella convalida dati sia presente come scelta anche la cella vuota. Purtroppo non so come fare. grazie
Ciao Francesco,
per quanto riguarda il valore di default all'interno della cella di tipo convalida dati, a mio avviso, la soluzione migliore è quella di inserire direttamente da script la stringa "--------" che utilizzi per indicare un valore non selezionato.
In riferimento invece alla questione di non mostrare i valori già selezionati in precedenti celle di tipo convalida dati come opzioni delle celle non ancora selezionate, una potenziale soluzione (non ho effettuato alcun test, e non conosco come hai attualmente gestito la creazione delle celle convalida dati nel tuo script, ma può valere la pena tentare) potrebbe essere quella di, dopo ciascuna selezione, eliminare tutte le celle convalida dati non selezionate (intendendo l'intera cella e non il singolo valore al suo interno) e ricrearle con i valori rimasti disponibili.
In questo modo, qualora nel tuo Spreadsheet fosse possibile, potresti gestire anche la situazione opposta, ossia se una cella già selezionata venisse per qualche motivo deselezionata potresti rendere nuovamente disponibile tale valore all'interno delle altre celle non ancora valorizzate da parte dell'utente.
Ciao Michele, complimenti per il tuo articolo molto utile, ho applicato lo script a un immagine di un tasto che mi cancella un valore su una cella perfetto! solo un piccolo problemino, mi cancella anche la formattazione del testo e il bordo praticamente tutte le proprietà della cella, sai dirmi se esiste la funzione per cancellare solo il valore dentro la cella ? scusa la domanda banale ma non sono molto pratico di google app script. Grazie mille Giuseppe
Ciao Giuseppe,
per eliminare il contenuto della cella mantenendo il suo stile di formattazione puoi utilizzare il metodo clearContent();.
L'esempio seguente mostra una funzione che effettua quanto appena descritto relativo ad un ipotetico valore presente nella cella B2:
Ciao Michele,
Sarebbe possibile creare una funzione che somma al valore esistente in una cella il valore di un altra? Ho provato a fare qualche test ma riesco solo con un bottone.
Esempio nella cella A1 immetto il valore 2 la funzione immette nella cella B1 il valore 2.
successivamente nella cella A1 metto il valore 3 la funzione nella cella B1 mette il valore 5.
Con la somma classica non si può fare perché si instaura un riferimento circolare.
Grazie
Ciao Davide,
se sei già riuscito a realizzare la funzione, come mi sembra di capire, anziché associarla ad un bottone hai provato a farla eseguire all'onEdit?
Ciao, grazie per la rapida risposta.
Farla eseguire all' OnEdit ??
La mia prova è questa .
Ciao Davide,
banalmente se provi a sostituire il nome della tua funzione 'Incrementa' con 'onEdit' vedrai che otterrai immediatamente il risultato desiderato (ovvio che poi serviranno dei controlli specifici per poter applicare la funzione in un contesto più complesso).
La funzione onEdit() fa parte dei Trigger semplici, ti riporto di seguito il link alla documentazione ufficiale per approfondimenti:
https://developers.google.com/apps-script/guides/triggers/
Buonasera, sono nuovo del forum, premetto che non sono un programmatore, non ho dimestichezza con gli script, linguaggi, ecc.., sono un utente che cerca di creare una piccola gestione fatture sul foglio di google, in modo da poter lavorare in rete in qualsiasi parte mi trovi. Stavo cercando di usare uno script di reset senza che mi venga cancellato la formattazione premendo un bottone, il problema che il reset lo effettua, ma restituisce un errore, questo e lo script
questo e l'errore:
ReferenceError: "shet" non definito
grazie per l'eventuale aiuto.
Ciao Enrico,
il problema è senza ombra di dubbio quello 'shet' scritto prima della parentesi graffa di chiusura.
Non essendo un comando riconosciuto genera quell'errore, forse è rimasto lì per via di qualche copia/incolla, basta semplicemente che lo rimuovi.
Grazie, eliminato l'errore
Buongiorno Michele, ho bisogno di qualcuno che mi aiuti, in particolare uno script, che mi riporti in altro foglio (registro fatture) dello stesso file alcuni dati riportati nelle fatture (esempio, numero, data, cliente, importo, ecc..), naturalmente inserendo una nuova riga, con la verifica che non ci siano righe vuote, e ritornare sul foglio principale (dati). Ho provato ha usare il registratore di macro, il problema che mi sovrascrive negli stessi campi.
Buonasera Enrico,
nella funzione non ci sono istruzioni che aggiungono una nuova riga, è probabile che dipenda da questo (ovvero che il range recuperato è sempre lo stesso) il fatto che i campi vengano sovrascritti.
Buongiorno, usando il registratore di macro, sono riuscito ad aggiungere una riga, sotto la prima, fino a qui tutto bene. al momento che la macro dovrebbe copiare il contenuto di alcune celle da un foglio all'altro, non copia il valore, ma solo il richiamo della formula, dove sbaglio?
Buonasera Enrico,
è probabile che dipenda dalla proprietà utilizzata per il CopyPasteType, trovi la lista di quelle utilizzabili (ad esempio PASTE_VALUES) al seguente link della documentazione ufficiale:
https://developers.google.com/apps-script/reference/spreadsheet/copy-paste-type
Grazie Michele risolto il problema dell'inserimento della riga con la copia dei valori. Mi piacerebbe inserire delle righe di controllo che qualora il campo "numero fattura" sia vuoto oppure che il "numero fattura" sia già inserito nella tabella "archivio fattura", l'aggiunta riga e copia valori non deve avvenire. La mia conoscenza informatica si ferma qui di più non posso fare e comunque il sistemino fin qui fatto, grazie al tuo aiuto, è pronto per funzionare.
Ciao Enrico,
mi fa piacere che sei riuscito a rendere funzionante il tuo progetto, sicuramente quanto ci metti impegno e dedizioni la soddisfazione di ottenere il risultato desiderato è impagabile.
Allo scopo dell'inserimento dei controlli posso darti dei suggerimenti, ti basta recuperare il valore della cella "numero fattura" di tuo interesse con .getValue() e con un'istruzione condizionale, ovvero un "if", far scrivere o meno il tuo valore in tale cella.
Di seguito un esmepio di condizione in Javascript:
Se invece il campo contiene un valore la condizione non sarà rispettata ed il blocco di codice al suo interno non verrà eseguito.
Allo stesso modo, per verificare se nel foglio (o tabella che sia) "archivio fattura" sia già presente o meno il numero di fattura che tenti di inserire, ti basterà recuperare l'intervallo di celle di tuo interesse con .getRange() ed effettuare un ciclo sui valori di ogni cella per verificarne l'eventuale corrispondenza (puoi utilizzare una variabile di tipo boolean da valorizzare in "true" o "false" in base al risultato del controllo, se ad esempio trova corrispondenza la valorizzi con "true"). A questo punto con una condizione if verifichi lo stato della variabile di cui sopra e se risulta "false" scrivi il valore altrimenti no.
Se cerchi nel blog trovi diversi esempi di cicli for su array basati su intervalli di celle recuperati da Spreadsheet e su come gestirli in modo ottimizzato. Se il codice ti restituisce qualche errore puoi consultare la sezione "errori frequenti e soluzioni": https://www.appsscript.it/articoli/google-apps-script-errori-frequenti-e-soluzioni/.
Ciao Michele, per quanto riguarda lo script con la condizione IF funziona bene mi archivia i dati se nella casella "X" trova un valore.
Volevo implementare il sistemino con l'automazione della stampa tramite uno script del foglio attivo, che purtroppo lo spreadsheet di google non prevede. In rete non ho trovato script di stampa, qualche consiglio da darmi per la realizzazione dello script: selezionare il foglio "X", stamparlo e ritornare sul foglio "Y". Grazie
Ciao Enrico,
non credo si possa interagire direttamente con la propria stampante locale tramite Google Apps Script. Tuttavia penso che sia possibile trovare una soluzione utilizzando i servizi di Google Cloud Print, prova a darci un'occhiata:
https://developers.google.com/cloud-print/docs/gadget
Incuriosito dalla tua richiesta e dalla possibilità di utilizzare un servizio Google dedicato con il quale interfacciarsi tramite Apps Script (appunto Google Cloud Print) ho effettuato delle prove e sono riuscito a stampare un documento dalla mia stampante fisica con Apps Script.
Ho realizzato un tutorial allo scopo, nel caso dovesse interessarti puoi trovarlo al seguente indirizzo:
Stampare un documento presente su Drive con Google Apps Script
https://www.appsscript.it/tutorial/stampare-un-documento-presente-su-drive-con-google-apps-script/
Buongiorno, ho realizzato uno script di cancellazione seguendo gli ottomi consigli di michele, vorrei aperò si aprisse una finestra di convalida prima dell'esecuzione della macro, c'è qualcuno che è in grado di aiutarmi?
Ciao Rutinello,
per ottenere quello che richiedi ti basta utilizzare un'alert dialogs. Puoi trovare un chiaro codice di esempio direttamente nella documentazione ufficiale al seguente link: https://developers.google.com/apps-script/guides/dialogs.
In pratica eseguendo l'alert al click sul bottone di tuo interesse verrà mostrata a video una finestra con le opzioni SI/NO ed in base alla scelta effettuata puoi far eseguire di conseguenza l'opportuno codice.
Sarebbe perfetto se prima di fare il reset inviasse un email in formato pdf
Fantascienza? (Email as attachment)
Vi ringrazio.
Ciao OM1,
prova a dare un'occhiata a questo tutorial su come 'Recuperare dati da Gmail con Google Apps Script' (https://www.appsscript.it/tutorial/recuperare-dati-da-gmail-con-google-apps-script/) dove viene fatto un esempio su un caso d'uso che comprende una panoramica dei metodi principali di Gmail Service e uno di questi è proprio l'invio di una mail con allegato un pdf.
Buongiorno Michele,
io sono nuova in materia editor script è per questo che ti contatto io da un foglio di lavoro excel che carico i drive e lo trasformo in foglio di lavoro google devo inserire vari bottoni (fino a qui ci sono arrivata) ora devo dare gli input che se un determinato bottone viene premuto (1 confermato e 1 non confermato) devo dirgli a chi deve essere inviato "diciamo" per la firma e successivamente deve essere inviato ad un'altra persona per la conferma definitiva che a sua volta deve essere inviato alla persona finale che deve registrare e archiviare questo documento però sono molte persone perchè questi documenti sono identificativi a delle categorie di prodotto e a dei clienti diversi gestiti da account diversi.
Come posso creare questo script?
Ciao Daniela,
da quel che credo di aver capito l'invio del documento alle varie persone avviene sempre da un solo utente (ad esempio te), su questa base un approccio che posso suggerirti, avendo sicuramente la lista degli indirizzi definita (ad esempio in un Foglio dello Spreadsheet in celle dedicate), potrebbe essere quello di avere più bottoni ognuno associato ad una cella contenente i vari indirizzi ovvero, un bottone associato alla cella dove è presente l'indirizzo per la firma, un altro associato alla cella dove è presente l'indirizzo per la conferma, e così via.
Lo script in questo caso potrebbe condividere lo Spreadsheet con gli indirizzi in questione (https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#addeditorsemailaddresses) se non lo è già ed inviargli una mail (https://developers.google.com/apps-script/reference/mail/mail-app#sendEmail(String,String,String)) per avvisarlo di controllare il file. Di contro le celle che devono modificare i tuoi collaboratori potrebbero essere controllate lato codice in modo che alla modifica venga inviata una mail al tuo account così da avere un feedback immediato.
Di approcci possono essercene diversi, è necessario valutare il contesto di utilizzo ed ottenere qualcosa di adattabile in modo generico per evitare di apportare continue modifiche allo script.
Ciao, ho bisogno di una cortesia: è possibile far partire uno script utilizzando per esempio l'evento click su una casella di controllo invece che un bottone grafico?
In maniera tale che se mette il flag su true parte la macro?
grazie mille e complimenti
Ciao Antonio,
certo, è possibile. Ti basta utilizzare il trigger onEdit(e) e gestire il valore contenuto al suo interno.
Buongiorno, seguendo i vari post sto cominciando a sperimentare le possibilità che mi si aprono;)
Ho un problema con un codice che fa quello che dovrebbe fare ma ha il problema che lo fa con una lentezza incredibile.
Sicuramente ho fatto uno (forse molti) errori ma non capisco proprio.
Sperando in un suggerimento la ringrazio per il supporto trovato sul suo sito!
Ciao Egon,
la lentezza l'attribuirei sicuramente al fatto che lo script scrive una cella alla volta ad ogni iterazione dei cicli ovvero, effettua una chiamata alle API per ogni valore che scrive in ogni cella.
Puoi ottimizzarlo sicuramente andando a scrivere un set di dati in una sola volta (o poco più in base alle esigenze) in un range di celle più ampio.
Buongiorno Michele e grazie per gli aiuti e spunti!!
Sto tentando di riportare in fogli-drive alcune funzioni che utilizzavo in VisualBasic di Excel.
Non trovo il modo di definire in modo dinamico il numero di riga senza dover ripetere ogni volta il nome variabile. E' possibile?
Il mio scopo è fare un controllo su oltre 100 celle e valorizzarne altre qualora una di queste assuma un valore determinato. Nell'esempio che indico qui vorrei far scrivere il valore della variabile r nella colonna B
trovato!
Per calcolare r2Min in modo dinamico in VB lo facevo con il do-while, qui come lo posso fare?
Ciao Carolina,
trovi tutta una serie di metodi nella documentazione ufficiale di Apps Script relativa ai Fogli di Google, nel caso specifico per rilevare il numero massimo di righe puoi utilizzare il metodo getLastRow():
https://developers.google.com/apps-script/reference/spreadsheet/sheet#getLastRow()
Nella stessa pagina trovi tutti gli altri metodi della Classe Sheet.
Grazie mille Michele, in questi giorni ho altre urgenze ma appena riprendo in mano il programma guardo e ti so dire!
Di niente,
fammi sapere com'è andata :)
Ciao Michele,
grazie! Ho capito come risolvere tramite i cicli (purtroppo non posso semplicemente utilizzare la funzione getLastRow() ).
In realtà ora il problema è che fa tutti i calcoli giusti ma poi non scrive il valore nella cella di destinazione. Ti riporto un piccolo esempio (l'errore è nella riga dove ho messo //sbaglia qui )
Cosa sbaglio?
Grazie,
Carolina
function My3function() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var r = 33
var r2Min = 169
var r2 = r2Min
var c = 3
do {
if (sheet.getRange(r, 6).getValue() == "S") {
for (var r3=1; r3<=10; r++) {
if (sheet.getRange(r2, 3).getValue() >> 0) {
r2++
};
r3++
};
Browser.msgBox(r2);
do {
var dato1 = sheet.getRange(r, c)
var dato2 = sheet.getRange(r2, c)
dato2.setValue(dato1.getValue()) //sbaglia qui :'(
c++
} while (c<=5);
};
r++
} while (r<=35);
};
Ciao Carolina,
lo script non sembra dare errori né sintattici né logici tuttavia se visualizzi il valore della variabile "r" nel punto indicato il risultato è 43 mentre presumo tu ti aspetti che sia 33.
Molto probabilmente si tratta di un errore semantico, il tipo di errore più insidioso, ma dato che lo script è contenuto e velocemente analizzabile posso ipotizzare che l'inghippo sia in questo punto:
r++ o r3++?
Ciao Michele, grazie per tutti questi consigli utilissimi !
Ho fatto uno scritp associato ad un bottone che modifica il valore di una cella.
E' possibile pubblicare il foglio (MENU "File/Pubblica su web") portandosi dietro anche lo script ?
Ho provato ma mi pubblica solo il bottone che però non esegue lo script, invece dal foglio localmente funziona tutto.
Grazie e complimeti.
Ciao Francesco,
grazie dei complimenti :)
La pubblicazione sul web di un Google Sheet fornisce una versione non modificabile del file.
La documentazione ufficiale stessa cita "Se invii l'URL di un file pubblicato ad altre persone, visualizzeranno una versione con un aspetto diverso dalla tua alla quale non è possibile apportare modifiche": https://support.google.com/docs/answer/183965.
Per fare in modo che il bottone possa essere utilizzato da altre persone è necessario condividere il file impostando i dovuti privilegi.
Grazie Michele, sì il problema era banalmente quello. Solo che ne risolvo uno e ne sorgono 3 ma credo sia normale ;-)
Ad esempio perché nel ciclo DO-WHILE non riesco a far funzionare il DO-WHILE NOT ? Oppure che alternativa ho? Sto provando a cercare anche via fb, molto utili anche quelli di post, grazie ;-)
Di niente, direi che è normale che sorgano vari errori durante lo sviluppo... il bello è anche quello :)
Cos'è che vorresti ottenere di preciso con l'operazione che non ti funziona? Giusto per capire se c'è un altro modo per farlo.
Grazie Michele!
devo incrementare un contatore fino al verificarsi della condizione...
do {
r++
} while not (sheet.getRange(r, 3).getValue() == "Numero"); // oppure il simbolo di diverso (senza il "not") ma non so come impostare il simbolo di diverso
Il simbolo del 'diverso' in JavaScript è: !=
Ad esempio:
Intendi questo?
Grazie mille Michele, sì, proprio quello! Come vedi ultimamente riesco a dedicarci zero tempo ma spero di finire presto quella funzione matematica ;-) grazie di tutto!
Grazie a te per il feedback Carolina :)
Ciao Michele,
premetto che non sono un esperto di codice (anzi), ma leggendo il tuo articolo e alcuni commenti penso di aver trovato ciò che mi serve. Il problema è alla fonte...non riesco ad abbinarlo al bottone inserito nel foglio di calcolo.
Ho seguito il tuo esempio e quello suggerito a un altro utente; l'esigenza è cancellare i dati limitatamente ad alcune celle. Dopo aver creato lo script, quando cerco di abbinarlo al bottone Google dice "Si è verificato un problema
La funzione script Pippo non è stata trovata".
FUNZIONE COPIATA E INCOLLATA
function rimuoviConvalidaDatiInCellaG3() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
ss.getRange("G6").clear();
}
Grazie mille
Ciao Roberto,
nel tuo caso al bottone devi associare la funzione con nome 'rimuoviConvalidaDatiInCellaG3', mentre dall'errore che hai scritto sembra che ne hai associata una che si chiama 'Pippo' e che non è presente con quel nome nel file di script.
Super!
Adesso funziona,
Grazie mille
Grazie a te per il feedback Roberto!
Buon proseguimento :)
Ciao Roberto,
mi sono imbattuto in questo interessante blog e desidero chiederti un aiuto. Cerco di inserire uno script in un foglio google creato in un account google "secondario" e non funziona credo per questioni di autorizzazione.
L'account è un account che ho creato per lavoro ed è utilizzato anche da altre persone.
Sto utilizzando un pc windows.
Quando invece inserisco lo script su un foglio google creato con il mio account google personale, tutto funziona perfettamente.
Ti ringrazio in anticipo se vorrai aiutarmi a capire come fare.
Cordiali saluti.
Marco
Ciao Marco,
provo intanto a risponderti io nel caso Roberto non leggesse il messaggio.
Quando esegui lo script con l'account secondario ti compare la finestra di richiesta autorizzazioni? In caso contrario prova a lanciare manualmente una qualsiasi funzione dall'editor di script al solo scopo di far comparire tale richiesta, una volta concesse le autorizzazioni quindi l'esecuzione poi dovrebbe andare a buon fine.
Se il problema invece dovesse essere un altro, e ti viene restituito ad esempio un messaggio di errore in rosso, fammi sapere e fornisci qualche dettaglio in più in modo di capire come risolverlo.
ciao Michele,
grazie della risposta.
Il problema si è risolto utilizzando un browser diverso per il secondo account.
Non so se questo può suggerire qualcosa sul problema iniziale.
In ogni caso ora riesco a fare quello che mi ero prefissato.
Cordiali saluti.
Ciao Marco,
grazie del feedback!
In questo caso allora significa che probabilmente Chrome faceva confusione passando da un account all'altro al momento dell'apertura della pagina, niente a che vedere quindi con un eventuale problema del tuo script.
Un saluto anche a te!
Ciao, mi occorreva sapere gentilmente se era possibile aggiungere uno script su un pdf editabile utilizzando Adobe Acrobat DC, dove sia possibile nel PDF un pulsante che mi permetta di caricare un immagine su un delimitato spazio. Uno script editabile ma non co l'inserimento di testo, ma con l'inserimento di un immagine con azione di upload dal pc.
Ciao Roberto,
uscendo da Google come ambiente di esecuzione non mi sembra un'opzione possibile.
Ciao Michele,
Sono in cerca di quello che sembrebbe semplice (ma non sono riuscito a trovare)
ho bisogno di poter inserire in un foglio google un Link a cartelle riferite alla rete interna e non su web. Purtroppo la funzione (inserisci link) non lo permette, è possibile risolverlo con uno script? se si puoi gentilmente farmi un esempio?
Cordiali Saluti
Giorgio
Ciao Giorgio,
vedi se questa discussione può esserti di aiuto:
https://stackoverflow.com/questions/25565613/add-link-to-open-a-local-file-in-google-docs
Complimenti Michele per i tuoi tutorial. Devo trovare il tempo di leggere il tuo libro! Nel frattempo mi ritrovo con il problema che se dopo aver creato lo script aggiungo una riga al foglio di google a cui lo script fa riferimento mi si sballa tutto. Es: creo lo script sheet.getRange("B2").clearContent(); e successivamente aggiungo alla riga 1 del foglio google un altra riga, il contenuto di "b2" finisce in "b3" mentre il comando continuerà a cancellarmi "b2". Quindi esiste un modo per adattare lo script ai cambiamenti del foglio? Grazie!
Ciao Massimiliano,
certamente puoi adattare lo script alle tue esigenze, devi lavorare con i riferimenti. Specificando in modo esplicito il range B2 inevitabilmente il riferimento sarà sempre e solo quella cella.
Ti consiglio di giocare un po' con i metodi della classe Sheet (https://developers.google.com/apps-script/reference/spreadsheet/sheet), ad esempio getLastRow() consente di recuperare la posizione dell'ultima riga che ha un contenuto. Ce ne sono molti e con un po' di pratica, capendo il meccanismo, si possono ottenere risultati davvero sorprendenti.
La lettura del libro e la consultazione degli esempi al suo interno ti saranno senz'altro di supporto e ti aiuteranno a sciogliere qualche dubbio.
Buongiorno devo trasferire una macro di excel al foglio di drive. La macro deve permettere le modifiche in un intervallo (ad es. B5:J34) quando il valore di una cella (ad es. G2) è SI e bloccare modifiche nello stesso intervallo (B5:J34) quando (G2) è sul NO.
Ho registrato la seguente macro quando il valore è sul SI ma non so come fare per bloccare l'intervallo quando è sul NO:
GRAZIE!
Ciao Davide,
una soluzione può essere quella di proteggere prima l'intero foglio con protection = sheet.protect() e togliere la protezione agli intervalli che vuoi che le persone possano modificare con protection.setUnprotectedRanges([ranges]).
Per altri approcci puoi sempre provare a giocare con i metodi della Classe Protection: https://developers.google.com/apps-script/reference/spreadsheet/protection.
ciao Michele, sono nuovo,
avrei bisogno di aiuto, ho fatto un'app di android, che mi fa vedere una ciclazione di turnii nelle celle, ho creato una macro, e con il pulsante gira , ti spiego, la prima riga scende sotto e poi tutta la ciclazione sale cosi si aggiorna settimanalmente, ora vorrei che ognni inizio settimana si aggiorna in automatico senza che ogni lunedì mattina aggiorno dal pulsante potresti spiegarmi come fare, sto provando con i trigger ma non aggiorna sbaglio qualcosa grazie.
Ciao Mario,
so che l'app Sheet per Android/iOS può non essere del tutto funzionale, nel tuo caso non so come hai realizzato l'app, in ogni caso prova a vedere se questa discussione può esserti di aiuto: https://stackoverflow.com/questions/51846603/how-to-get-google-sheets-script-working-on-mobile-app
Ciao Michele, grazie di avermi risposto, ti mostro la macro
questa dal foglio google con il pulsante funziona, anche l'app funziona legge i turni della settimana, e può anche aggiungere altri nomi in fondo alla lista dei turni, però se io martedì della prossima settimana volevo che senza aprire googlescript e aggiornare con il pulsante si aggiornasse quando apro l'applicazione sul cellulare, grazie.
Ciao Mario,
se controlli nelle esecuzioni probabilmente troverai un errore simile al seguente:
Non puoi eseguire un taglia/incolla su un intervallo che interseca parzialmente un'unione. Ti consigliamo di annullare l'unione oppure di selezionare un intervallo più grande che includa l'intera unione.
A mio avviso è dovuto al fatto che stai utilizzando i range attivi e in una funzione personalizzata si comportano in modo inatteso. Ti consiglio di riscrivere la funzione utilizzando i metodi getRange e setValues.
Per supporto lato codice, qualora tu ne avessi bisogno, prova a lasciare un messaggio nel gruppo su Facebook: https://www.facebook.com/groups/AppsScript
Ciao Michele,
complimenti e tantissimi auguri per tutto il tuo impegno, per tua la passione che metti su queste cose. Le condivido in gran parte!! Ho acquistato il tuo libro. L'ho trovato scritto in maniera semplice e mi piace molto!!! Io sono un amatore dilettante della programmazione.
Quando ho tempo mi diverto a programmare e ho notato che quando crei da PC sul Google fogli un o più pulsanti funzionano correttamente tutti gli script che gli assegni, però i pulsanti creati precedentemente nei smartphone non vengono visualizzati. Perché i stessi file sull'App di Google fogli di calcolo non si attivano dal mio smartphone ? Mi sai spiegare il perché o se ci sono delle soluzioni?
Grazie anticipatamente e buon lavoro
Ciao Andrea, grazie della fiducia e dei complimenti :)
Relativamente a quanto scrivi è un problema condiviso, ovvero né le immagini né le voci di menu personalizzate funzionano nell'app Fogli (provato a suo tempo con Android).
Un'alternativa può essere quella di creare una logica personalizzata sfruttando il trigger onEdit(), in modo che questo si attivi alla modifica sulle celle e con alcune regole definite al suo interno stabilire se eseguire una funzione o meno.
Non è sicuramente lineare come avere un bottone da cliccare, tuttavia l'app nativa non sembra offrire di meglio.
Ciao Michele,
premetto che sono un altro tipo di programmatore (Host / Cobol) , ma insieme ad un amico "Javista" sto mettendo in piedi un programmino su fogli di google.
Anch'io ho riscontrato il problema del click del pulsante, possibile solo da Browser ma non da smartphone. Per ovviare a questo problema, è possibile associare uno script al popolamento di una cella di convalida dati (SI/NO), facendo comparire prima un alert di conferma dell'azione ? Se si mi manderesti un esempio ?
Ti ringrazio già ora .
Buona serata
Francesco
Ciao Francesco,
certo che è possibile assegnare un comportamento al cambio di valore di una cella/casella, non ho codici pronti da passarti ma puoi crearne uno facendo riferimento al trigger semplice onEdit() e alla documentazione sulle dialogs: https://developers.google.com/apps-script/guides/dialogs
Spero di averti dato un valido instradamento, un saluto a te :)
Ciao Michele,
grazie per la risposta.
Per risolvere la questione ho aggiunto un attivatore che al cambio di qualsiasi valore nel foglio faccia partire il mio script (con i controlli opportuni per istradarlo correttamente).
Ora , sempre sul PC la cosa funziona perfettamente, mentre su mobile niente da fare.
Hai altre idee o suggerimenti per fare in modo che da mobile si possa attivare uno script ?
grazie
Francesco
Ciao Francesco,
se utilizzi l'app per Android Fogli Google (Google LLC) l'onEdit() funziona correttamente. Per sicurezza l'ho appena provato.
Ciao Michele,
utilizzo l'app preinstallata ufficiale Fogli di Google sul mio Huawei P Smart 2019.
Ho definito il trigger onEdit come da te specificato e che riporto di seguito.
Su PC funziona, su smartphone no....
function onEdit(e) {
//var spreadsheet = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActive().getSheetByName('PRENOTA UN CAMPO');
var data = sheet.getDataRange().getValues();
var nomePren= data[3][2];
var campo=data[4][2];
var tipo=data[5][2];
var dataPren=data[7][2];
var date2 = new Date(data[7][2]);
var giorno = data[9][10];
var mese = data[10][10];
var anno = data[11][10];
var oraInizioPreno = data[8][2];
var durata = data[9][16];
var campoDesiderato = data[4][2];
var maestroSel = data[6][2];
var cellConferma = data[11][2];
if (cellConferma=="SI"){
// CONTROLLO DI AVER INSERITO TUTTI I CAMPI PER LA PRENOTAZIONE
if (campo==""){
Browser.msgBox("Selezionare il Campo per confermare la Prenotazione");
sheet.getRange('C5').activate();
} else if (tipo==""){
Browser.msgBox("Selezionare la Tipologia per confermare la Prenotazione");
sheet.getRange('C6').activate();
} else if ((tipo=="Lezione")&&(maestroSel=="")){
Browser.msgBox("Selezionare il Maestro per confermare la Prenotazione");
sheet.getRange('C7').activate();
} else if (dataPren==""){
Browser.msgBox("Selezionare il Giorno per confermare la Prenotazione");
sheet.getRange('C8').activate();
} else if (oraInizioPreno==""){
Browser.msgBox("Selezionare l'Ora di Inizio per confermare la Prenotazione");
sheet.getRange('C9').activate();
} else if (durata==""){
Browser.msgBox("Selezionare la Durata per confermare la Prenotazione");
sheet.getRange('C10').activate();
} else {
daEseguireUnaVoltaInseritiDatiPrenotazione()
}
}
};
Se riesci a capire il perchè, grazie mille
F
Ciao Francesco,
a mio avviso è incompatibile Browser.msgBox con l'app Android.
Prova a toglierlo e sostituirlo ad esempio con la scrittura di un messaggio in una cella.
Grazie Michele,
togliendo i browser.msgbox funziona. Ho dovuto anche togliere questa istruzione che faceva apparire la finestra di dialogo per confermare o meno la richiesta:
var result = ui.alert(
'- CONFERMA RICHIESTA -',
'Confermi i dati della Prenotazione ?',
ui.ButtonSet.YES_NO);
Ora i messaggi e questa ui.alert mi servirebbero per dare i corretti messaggi di avvenuta o meno prenotazione, hai idea come si possa farli digerire agli smartphone ?
Grazie mille per i consigli, finora utilissimi.
Buona giornata
F
Aggiungo un altro quesito per ottimizzare.
Ho uno script che faccio eseguire con attivatore all'apertura, per valorizzare una cella con la mail dello user loggato.
Su PC funziona ma su smartphone no.
Questo lo script:
function fissaUser() {
var sheet3 = SpreadsheetApp.getActive();
sheet3.getRange('A2').activate();
sheet3.setActiveSheet(sheet3.getSheetByName('PRENOTA UN CAMPO'), true);
var cell = sheet3.getRange('T2');
cell.setValue(Session.getActiveUser().getEmail())
};
Grazie per il supporto
F
ciao, sto tentando di eseguire uno script che permetta di associare a dei pulsanti presenti su un foglio google (esempio.: stampa foglio 2, stampa foglio 3 eccetera) di stampare altri fogli attivi, è possibile?
Ciao Sebastiano,
avevo creato un po' di tempo fa un articolo dove parlavo di come utilizzare Google Cloud Print per stampare file presenti su Google Drive (https://www.appsscript.it/tutorial/stampare-un-documento-presente-su-drive-con-google-apps-script/), tuttavia il servizio non è più supportato dall'1 Gennaio 2021: https://www.google.com/intl/it_ALL/cloudprint/learn/
Alcuni utenti discutevano tempo fa alcune potenziali alternative sul gruppo di Facebook - Fatti di Apps Script: https://www.facebook.com/groups/AppsScript prova a darci un'occhiata nel caso fossero arrivati ad una conclusione.
ciao Michele,
come faccio a dato un numero inserito da tastiera e inserendo il riferimento della cella sempre da tastiera, come si fa a visualizzarlo in Apps Script?
grazie
Beniamino
Ciao Beniamino,
potresti gentilmente fornirmi maggiori dettagli sulla tua necessità? Non riesco a capire del tutto la finalità, se intendi rilevare da Google Apps Script il valore immesso in una cella (comprese le coordinate della cella dove è stato inserito il valore) devi usare il trigger semplice onEdit(e) compreso del parametro 'e'. Nel blog trovi un articolo dedicato.
Avendo un foglio con una serie infinita di righe... è possibile creare uno script che all'apertura del foglio sposti il cursore sulla prima riga vuota disponibile? Per fare questo premo Ctrl+Invio ma se ci fosse un'automatizzazione sarebbe meglio :D
Ciao Iolanda,
potresti utilizzare il metodo getRange insieme al recupero delle coordinate con getLatRow() per riferirti all'ultima cella valorizzata, a quel punto applichi il metodo activate() che selezionerà la cella indicata.
Salve innanzitutto volevo complimentarmi perché è molto preciso.
Volevo chiederle un codice per inviare una email ad un indirizzo preso su una cella su una riga e come Oggetto dell'email il contenuto di una cella presente sulla stessa riga. Grazie
Salve innanzitutto volevo complimentarmi perché è molto preciso.
Volevo chiederle un codice per inviare una email ad un indirizzo preso su una cella su una riga e come Oggetto dell'email il contenuto di una cella presente sulla stessa riga. Grazie
Salve innanzitutto volevo complimentarmi perché è molto preciso.
Volevo chiederle un codice per inviare una email ad un indirizzo preso su una cella su una riga e come Oggetto dell'email il contenuto di una cella presente sulla stessa riga. Grazie
Salve innanzitutto volevo complimentarmi perché è molto preciso.
Volevo chiederle un codice per inviare una email ad un indirizzo preso su una cella su una riga e come Oggetto dell'email il contenuto di una cella presente sulla stessa riga. Grazie
Salve innanzitutto volevo complimentarmi perché è molto preciso.
Volevo chiederle un codice per inviare una email ad un indirizzo preso su una cella su una riga e come Oggetto dell'email il contenuto di una cella presente sulla stessa riga. Grazie
Buongiorno non riesco a venirne a capo o perlomeno non trovo una guida che mi dia una risposta ho questo semplice script che vorrei che non venga eseguito se una cella specifica in un foglio specifico non e compilato. nel caso sotto se l'input E9.
function TEST() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Movimentazione Abb"); //Form Sheet
var datasheet = ss.getSheetByName("Cronologia Abb"); //Data Sheet
//Input Values
var values = [[formSS.getRange("C7").getValue(),
formSS.getRange("E7").getValue(),
formSS.getRange("E9").getValue(),
formSS.getRange("E11").getValue(),
formSS.getRange("J11").getValue(),
formSS.getRange("N11").getValue(),
formSS.getRange("E13").getValue(),
formSS.getRange("N13").getValue(),
formSS.getRange("E15").getValue(),
formSS.getRange("J15").getValue(),
formSS.getRange("E17").getValue(),]];
datasheet.getRange(datasheet.getLastRow()+1, 1, 1, 11).setValues(values);