Javascript, HTML, CSS e... !
40 commenti

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.
Per fare un esempio, 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).

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.

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:



immagine di un bottone aggiunta ad uno spreasheet

Fig. 1 - Immagine di un bottone aggiunta ad uno Spreasheet


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:



menu contestuale di un bottone personalizzato aggiunto ad uno spreasheet

Fig. 2 - Menu contestuale di un bottone personalizzato aggiunto ad uno Spreasheet


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:



assegnare una funzione ad un bottone aggiunto ad uno spreasheet

Fig. 3 - Assegnare una funzione ad un bottone aggiunto ad uno Spreasheet


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):



finestra di dialogo definita nell'editor di script

Fig. 4 -Finestra di dialogo definita nell'editor di script




dati cancellati dallo spreadsheet come definito nell'editor di script

Fig. 5 - Dati eliminati dal foglio di Spreadsheet come definito nell'editor di script


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

L'uso di bottoni personalizzati, come è evidente, è semplice ed utile tuttavia c'è anche un piccolo inconveniente da tenere in considerazione ovvero, non è possibile inserire il pulsante all'interno di una cella.
Il pulsante sarà pertanto un elemento presente su un livello immaginario al di sopra del foglio di calcolo, come se vi fluttuasse, pertanto anche selezionando un gruppo di celle da spostare in altra posizione, i contenuti delle varie celle saranno riposizionati mentre il bottone rimarrà dove si trovava prima (per spostarlo, come spiegato precedentemente, dovrà prima essere selezionato con il tasto destro del mouse e spostato singolarmente).

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

Tags

Michele Pisani

Michele Pisani

Sviluppatore Javascript ed esperto in Digital Analytics

L'esperienza nel settore Digital Analytics unita ad anni di sviluppo in Javascript ha trovato la massima espressione in Google Apps Script che mi ha permesso, con estrema facilità e poche righe di codice, di realizzare potenti applicazioni interattive e processi automatizzati integrati con i prodotti della G Suite.

Come contattarmi
scrivi un commento

40 Commenti

  1. martedì 6 febbraio 2018 alle ore 19.14 NICO

    desidero assegnare ad un pulsante lo script che aumenti il valore di una determinata cella, come si può fare?

    Grazie

    Rispondi a questo commento
    • martedì 6 febbraio 2018 alle ore 20.06 Michele PisaniAutore

      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)

      function incrementaValoreCellaD3() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var cell = sheet.getRange(3, 4);
      cell.setValue(cell.getValue() + 1);
      }


      Spero ti sia stato di aiuto per risolvere il tuo dubbio.

      Rispondi a questo commento
  2. domenica 18 febbraio 2018 alle ore 22.19 Antonio Mignini

    Ciao Michele, io ho semplice tabella e vorrei un pulsante che aggiunga una riga in alto (sotto la iga delle intestazioni). Puoi aiutarmi?

    Grazie

    Rispondi a questo commento
    • domenica 18 febbraio 2018 alle ore 23.04 Michele PisaniAutore

      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:

      function inserisciRigaDopoIntestazione() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      sheet.insertRowBefore(2);
      }


      Se poi hai bisogno di riempire quella riga con dei valori puoi affidarti al metodo getRange:


      sheet.getRange(row, column, numRows, numColumns).setValues([array])


      ...dove row dovrà avere valore 2 (che è l'indice della seconda riga dello Sheet).

      Rispondi a questo commento
      • mercoledì 21 febbraio 2018 alle ore 10.47 Antonio

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

        • mercoledì 21 febbraio 2018 alle ore 15.04 Antonio

          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!

          function inserisciRigaDopoIntestazione() {
          var ss = SpreadsheetApp.getActiveSpreadsheet();
          var sheet = ss.getActiveSheet();
          var range = sheet.getRange(3,3,1,6);
          var formulas = range.getFormulas();
          sheet.insertRowBefore(3);
          var newRange = sheet.getRange(3,3,1,6);
          range.copyTo(newRange);
          newRange.setFormulas(formulas);
          }



          Ecco, il cursore non ho proprio idea di come avrei potuto posizionarlo nella prima cella della nuova riga ma direi che posso sorvolare ;)

      • mercoledì 21 febbraio 2018 alle ore 18.59 Michele PisaniAutore

        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:

        function setCursorInA2() {
        var sheet = SpreadsheetApp.getActiveSheet();
        var range = sheet.getRange("A2");
        sheet.setActiveRange(range);
        }



        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
        http://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/

  3. giovedì 1 marzo 2018 alle ore 11.53 Domenico

    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.

    Rispondi a questo commento
    • giovedì 1 marzo 2018 alle ore 23.20 Michele PisaniAutore

      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.

      Rispondi a questo commento
      • mercoledì 14 marzo 2018 alle ore 19.55 Roberto

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

        • martedì 20 marzo 2018 alle ore 23.44 Michele PisaniAutore

          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.

  4. lunedì 19 marzo 2018 alle ore 00.39 francesco

    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

    Rispondi a questo commento
    • mercoledì 21 marzo 2018 alle ore 00.09 Michele PisaniAutore

      Ciao Francesco,
      per resettare una cella di tipo 'convalida dati' puoi utilizzare la seguente funzione (nel caso specifico svuota la cella in posizione G6):

      function rimuoviConvalidaDatiInCellaG3() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      ss.getRange("G6").clear();
      }

      Ovviamente puoi indicare un range più ampio di celle da svuotare definendo gli opportuni parametri all'interno di getRange.

      Rispondi a questo commento
      • mercoledì 21 marzo 2018 alle ore 00.51 FRANCESCO

        Grazie mille.! funziona, unico poblema che mi va a cancellare anche i bordi più scuri di alcune celle del range.

        • mercoledì 21 marzo 2018 alle ore 01.24 FRANCESCO

          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

      • giovedì 22 marzo 2018 alle ore 00.50 Michele PisaniAutore

        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.

  5. lunedì 23 aprile 2018 alle ore 14.34 Giuseppe

    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

    Rispondi a questo commento
    • lunedì 23 aprile 2018 alle ore 23.42 Michele PisaniAutore

      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:

      function resetB2DataWithoutFormatting() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      sheet.getRange("B2").clearContent();
      }

      Rispondi a questo commento
  6. mercoledì 27 giugno 2018 alle ore 18.39 Davide

    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


    Rispondi a questo commento
    • giovedì 28 giugno 2018 alle ore 00.23 Michele PisaniAutore

      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?

      Rispondi a questo commento
      • giovedì 28 giugno 2018 alle ore 12.22 Davide

        Ciao, grazie per la rapida risposta.
        Farla eseguire all' OnEdit ??

        La mia prova è questa .

         function Incrementa() {

        var ss = SpreadsheetApp.getActiveSpreadsheet();
        var sheet = ss.getActiveSheet();
        var celltot = sheet.getRange("B1");
        var cellsom = sheet.getRange("A1");
        celltot.setValue(celltot.getValue() + cellsom.getValue());
        cellsom.setValue(0);
        }

        • giovedì 28 giugno 2018 alle ore 13.05 Michele PisaniAutore

          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/

  7. domenica 1 luglio 2018 alle ore 20.08 Enrico

    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

    function resetB2DataWithoutFormatting() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getActiveSheet();
    sheet.getRange("B2").clearContent();
    sheet.getRange("B3").clearContent();
    sheet.getRange("B5").clearContent();
    sheet.getRange("A16").clearContent();
    sheet.getRange("A17").clearContent();
    sheet.getRange("A18").clearContent();
    sheet.getRange("A19").clearContent();
    sheet.getRange("A20").clearContent();
    sheet.getRange("A21").clearContent();
    sheet.getRange("A22").clearContent();
    sheet.getRange("A23").clearContent();
    sheet.getRange("A24").clearContent();
    sheet.getRange("A25").clearContent();
    sheet.getRange("A26").clearContent();
    sheet.getRange("A27").clearContent();
    sheet.getRange("A28").clearContent();
    sheet.getRange("A29").clearContent();
    sheet.getRange("A30").clearContent();
    sheet.getRange("B16").clearContent();
    sheet.getRange("B17").clearContent();
    sheet.getRange("B18").clearContent();
    sheet.getRange("B19").clearContent();
    sheet.getRange("B20").clearContent();
    sheet.getRange("B21").clearContent();
    sheet.getRange("B22").clearContent();
    sheet.getRange("B23").clearContent();
    sheet.getRange("B24").clearContent();
    sheet.getRange("B25").clearContent();
    sheet.getRange("B26").clearContent();
    sheet.getRange("B27").clearContent();
    sheet.getRange("B28").clearContent();
    sheet.getRange("B29").clearContent();
    sheet.getRange("B30").clearContent();
    sheet.getRange("C16").clearContent();
    sheet.getRange("C17").clearContent();
    sheet.getRange("C18").clearContent();
    sheet.getRange("C19").clearContent();
    sheet.getRange("C20").clearContent();
    sheet.getRange("C21").clearContent();
    sheet.getRange("C22").clearContent();
    sheet.getRange("C23").clearContent();
    sheet.getRange("C24").clearContent();
    sheet.getRange("C25").clearContent();
    sheet.getRange("C26").clearContent();
    sheet.getRange("C27").clearContent();
    sheet.getRange("C28").clearContent();
    sheet.getRange("C29").clearContent();
    sheet.getRange("C30").clearContent();
    shet
    }


    questo e l'errore:
    ReferenceError: "shet" non definito

    grazie per l'eventuale aiuto.

    Rispondi a questo commento
    • lunedì 2 luglio 2018 alle ore 00.46 Michele PisaniAutore

      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.

      Rispondi a questo commento
      • lunedì 2 luglio 2018 alle ore 11.36 Enrico

        Grazie, eliminato l'errore

  8. lunedì 2 luglio 2018 alle ore 12.18 Enrico

    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.

    function Registrafattura() {
    var spreadsheet = SpreadsheetApp.getActive();
    spreadsheet.getRange('A16').activate();
    spreadsheet.setActiveSheet(spreadsheet.getSheetByName('registro fatture'), true);
    spreadsheet.getRange('A3').activate();
    spreadsheet.getCurrentCell().setValue('=fattura!A8');
    spreadsheet.getRange('B3').activate();
    spreadsheet.getCurrentCell().setValue('=fattura!B8');
    spreadsheet.getRange('C3').activate();
    spreadsheet.getCurrentCell().setValue('=fattura!E2');
    spreadsheet.getRange('D3').activate();
    spreadsheet.getCurrentCell().setValue('=fattura!G28');
    spreadsheet.getRange('E3').activate();
    spreadsheet.getCurrentCell().setValue('=fattura!G30');
    spreadsheet.setActiveSheet(spreadsheet.getSheetByName('dati'), true);
    };

    Rispondi a questo commento
    • martedì 3 luglio 2018 alle ore 13.18 Michele PisaniAutore

      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.

      Rispondi a questo commento
      • martedì 3 luglio 2018 alle ore 13.19 Enrico

        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?

        function archiviaFattura() {
        var spreadsheet = SpreadsheetApp.getActive();
        spreadsheet.getRange('F24').activate();
        spreadsheet.setActiveSheet(spreadsheet.getSheetByName('registro fatture'), true);
        spreadsheet.getRange('1:1').activate();
        spreadsheet.getActiveSheet().insertRowsAfter(spreadsheet.getActiveRange().getLastRow(), 1);
        spreadsheet.getActiveRange().offset(spreadsheet.getActiveRange().getNumRows(), 0, 1, spreadsheet.getActiveRange().getNumColumns()).activate();
        spreadsheet.setActiveSheet(spreadsheet.getSheetByName('dati'), true);
        spreadsheet.getCurrentCell().offset(12, -5, 1, 6).activate();
        spreadsheet.setActiveSheet(spreadsheet.getSheetByName('registro fatture'), true);
        spreadsheet.getCurrentCell().activate();
        spreadsheet.getRange('dati!A36:F36').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
        spreadsheet.setActiveSheet(spreadsheet.getSheetByName('dati'), true);
        spreadsheet.getCurrentCell().offset(-31, 2).activate();
        };

  9. mercoledì 4 luglio 2018 alle ore 20.05 Enrico

    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.

    function archiviaFattura() {
    var spreadsheet = SpreadsheetApp.getActive();
    spreadsheet.getRange('B8').activate();
    spreadsheet.setActiveSheet(spreadsheet.getSheetByName('registro fatture'), true);
    spreadsheet.getRange('A1').activate();
    spreadsheet.getActiveSheet().insertRowsAfter(spreadsheet.getActiveRange().getLastRow(), 1);
    spreadsheet.getActiveRange().offset(spreadsheet.getActiveRange().getNumRows(), 0, 1, spreadsheet.getActiveRange().getNumColumns()).activate();
    spreadsheet.setActiveSheet(spreadsheet.getSheetByName('dati'), true);
    spreadsheet.getRange('A33:f33').activate();
    spreadsheet.setActiveSheet(spreadsheet.getSheetByName('registro fatture'), true);
    spreadsheet.getRange('dati!A33:f33').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
    spreadsheet.setActiveSheet(spreadsheet.getSheetByName('dati'), true);
    spreadsheet.getRange('B2').activate();
    spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
    spreadsheet.getRange('B16:C30').activate();
    spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
    };

    Rispondi a questo commento
    • giovedì 5 luglio 2018 alle ore 23.08 Michele PisaniAutore

      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:

      // codice per recuperare lo Spreadsheet attivo
      //codice per recuperare il foglio attivo
      //...
      var valore_cella = sheet.getRange("B5").getValue(); // recupero il valore della cella B5
      if (valore_cella.length == 0) {
      // codice per scrivere il valore nella cella
      }


      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": http://www.appsscript.it/articoli/google-apps-script-errori-frequenti-e-soluzioni/.

      Rispondi a questo commento
  10. sabato 7 luglio 2018 alle ore 19.49 Enrico

    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

    Rispondi a questo commento
  11. mercoledì 8 agosto 2018 alle ore 11.49 rutinello

    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?

    Rispondi a questo commento
    • giovedì 9 agosto 2018 alle ore 00.36 Michele PisaniAutore

      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.

      Rispondi a questo commento
  12. mercoledì 22 agosto 2018 alle ore 16.32 om1

    Sarebbe perfetto se prima di fare il reset inviasse un email in formato pdf
    Fantascienza? (Email as attachment)
    Vi ringrazio.

    Rispondi a questo commento
  13. martedì 20 novembre 2018 alle ore 11.50 Daniela Corna

    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?

    Rispondi a questo commento
    • mercoledì 21 novembre 2018 alle ore 00.34 Michele PisaniAutore

      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.

      Rispondi a questo commento

Scrivi un commento

Il tuo indirizzo email non sarà pubblicato.I campi contrassegnati da un * sono obbligatori
Puoi utilizzare i seguenti tag nei commenti:
[bold]testo[/bold] se vuoi evidenziare un testo con il grassetto[code]function helloworld() { }[/code] se vuoi pubblicare una porzione di codice[url]http://www.appsscript.it[/url] se devi riferirti ad un indirizzo web