JavaScript, HTML, CSS e... !
101 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.

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:



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

Queste e molte altre informazioni sui bottoni personalizzati in Google Apps Script continuano nel mio libro "Punta in alto con... Google Apps Script":



punta in alto con google apps script - bottoni personalizzati

Fig. 6 - Il libro in italiano - Punta in alto con... Google Apps Script - pag 170 e 171


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:

punta in alto con google apps script libro italiano

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

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

101 Commenti

  1. Tuesday, February 6, 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
    • Tuesday, February 6, 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. Sunday, February 18, 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
    • Sunday, February 18, 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
      • Wednesday, February 21, 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 ;)

        • Wednesday, February 21, 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 ;)

      • Wednesday, February 21, 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
        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/

  3. Thursday, March 1, 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
    • Thursday, March 1, 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
      • Wednesday, March 14, 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. :-(

        • Tuesday, March 20, 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. Monday, March 19, 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
    • Wednesday, March 21, 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
      • Wednesday, March 21, 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.

        • Wednesday, March 21, 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

      • Thursday, March 22, 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. Monday, April 23, 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
    • Monday, April 23, 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. Wednesday, June 27, 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
    • Thursday, June 28, 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
      • Thursday, June 28, 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);
        }

        • Thursday, June 28, 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. Sunday, July 1, 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
    • Monday, July 2, 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
      • Monday, July 2, 2018 alle ore 11:36 Enrico

        Grazie, eliminato l'errore

  8. Monday, July 2, 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
    • Tuesday, July 3, 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
      • Tuesday, July 3, 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. Wednesday, July 4, 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
    • Thursday, July 5, 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": https://www.appsscript.it/articoli/google-apps-script-errori-frequenti-e-soluzioni/.

      Rispondi a questo commento
  10. Saturday, July 7, 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. Wednesday, August 8, 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
    • Thursday, August 9, 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. Wednesday, August 22, 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. Tuesday, November 20, 2018 alle ore 11:50 Dani

    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
    • Wednesday, November 21, 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
  14. Wednesday, February 6, 2019 alle ore 19:04 Antonio Abaco

    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

    Rispondi a questo commento
    • Wednesday, February 6, 2019 alle ore 22:30 Michele PisaniAutore

      Ciao Antonio,
      certo, è possibile. Ti basta utilizzare il trigger onEdit(e) e gestire il valore contenuto al suo interno.

      Rispondi a questo commento
  15. Friday, February 15, 2019 alle ore 15:24 Egon Angeli

    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!

    function ordina() {
    var sheetOLD = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0]; // sheets are counted starting from 0
    var sheetNEW = SpreadsheetApp.getActiveSpreadsheet().getSheets()[1];
    var cellOLD
    var count
    var incremento=0;

    var cell0 = sheetOLD.getRange(1, 1) .getValue();
    for (count=1; count<300 ; count++) //RIGHE
    {if (sheetOLD.getRange(count, 1).getValue() == 0) break

    for (var c=1; c<27 ; c++) //COLONNE
    sheetNEW.getRange(count+incremento, c).setValue(sheetOLD.getRange(count, c).getValue())

    if (sheetOLD.getRange(count, 27).getValue() == "Si")
    {incremento++
    for (var col=1; col<6 ; col++)
    sheetNEW.getRange(count+incremento, col+11).setValue(sheetOLD.getRange(count, col+27).getValue())
    for (var col=1; col<9 ; col++)
    sheetNEW.getRange(count+incremento, col+18).setValue(sheetOLD.getRange(count, col+32).getValue())
    }
    }

    }



    Rispondi a questo commento
    • Friday, February 15, 2019 alle ore 20:27 Michele PisaniAutore

      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.

      Rispondi a questo commento
  16. Monday, April 15, 2019 alle ore 15:14 Carolina

    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

    var r2Min = 150
    for (r=10;r<r2Min;r++) {
    sheet.getRange("B" & r).setValue(r)
    };

    Rispondi a questo commento
    • Monday, April 15, 2019 alle ore 15:22 Carolina

      trovato!

      sheet.getRange(r, 2).setValue(r)



      Per calcolare r2Min in modo dinamico in VB lo facevo con il do-while, qui come lo posso fare?

      Rispondi a questo commento
      • Monday, April 15, 2019 alle ore 22:51 Michele PisaniAutore

        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.

        • Tuesday, April 16, 2019 alle ore 16:56 Carolina

          Grazie mille Michele, in questi giorni ho altre urgenze ma appena riprendo in mano il programma guardo e ti so dire!

    • Tuesday, April 16, 2019 alle ore 21:56 Michele PisaniAutore

      Di niente,
      fammi sapere com'è andata :)

      Rispondi a questo commento
      • Tuesday, April 23, 2019 alle ore 13:56 Carolina

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

      • Wednesday, April 24, 2019 alle ore 01:31 Michele PisaniAutore

        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:

        for (var r3=1; r3<=10; r++) { // <-- 


        r++ o r3++?

  17. Saturday, April 20, 2019 alle ore 00:40 Francesco

    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.

    Rispondi a questo commento
    • Saturday, April 20, 2019 alle ore 16:15 Michele PisaniAutore

      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.

      Rispondi a questo commento
  18. Wednesday, May 8, 2019 alle ore 10:59 Carolina

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

    Rispondi a questo commento
    • Thursday, May 9, 2019 alle ore 00:24 Michele PisaniAutore

      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.

      Rispondi a questo commento
      • Thursday, May 9, 2019 alle ore 10:36 Carolina

        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

      • Thursday, May 9, 2019 alle ore 21:44 Michele PisaniAutore

        Il simbolo del 'diverso' in JavaScript è: !=
        Ad esempio:

        do {
        r++
        } while (sheet.getRange(r, 3).getValue() != "Numero");


        Intendi questo?

      • Friday, June 14, 2019 alle ore 14:32 Carolina

        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!

      • Friday, June 14, 2019 alle ore 23:50 Michele PisaniAutore

        Grazie a te per il feedback Carolina :)

  19. Monday, September 30, 2019 alle ore 17:31 Roberto

    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

    Rispondi a questo commento
    • Monday, September 30, 2019 alle ore 21:47 Michele PisaniAutore

      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.

      Rispondi a questo commento
      • Tuesday, October 1, 2019 alle ore 15:50 Roberto

        Super!
        Adesso funziona,
        Grazie mille

        • Tuesday, October 1, 2019 alle ore 21:56 Michele PisaniAutore

          Grazie a te per il feedback Roberto!
          Buon proseguimento :)

  20. Thursday, November 14, 2019 alle ore 07:48 Marco

    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

    Rispondi a questo commento
    • Thursday, November 14, 2019 alle ore 21:51 Michele PisaniAutore

      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.

      Rispondi a questo commento
      • Saturday, November 16, 2019 alle ore 19:22 Marco

        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.

        • Sunday, November 17, 2019 alle ore 01:50 Michele PisaniAutore

          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!

  21. Monday, November 25, 2019 alle ore 15:43 Roberto

    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.

    Rispondi a questo commento
  22. Wednesday, December 11, 2019 alle ore 14:47 Giorgio

    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

    Rispondi a questo commento
  23. Thursday, March 19, 2020 alle ore 17:29 Massimiliano

    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!

    Rispondi a questo commento
    • Thursday, March 19, 2020 alle ore 23:49 Michele PisaniAutore

      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.

      Rispondi a questo commento
  24. Sunday, May 3, 2020 alle ore 13:22 Davide

    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:

    function bloccacelle() {
    var spreadsheet = SpreadsheetApp.getActive();
    spreadsheet.getRange('G2').activate();
    spreadsheet.getCurrentCell().setValue('SI');
    spreadsheet.getRange('B5:J34').activate();
    var protection = spreadsheet.getRange('B5:J34').protect();
    protection.setDescription('blocca celle')
    .removeEditors(['solo io']);
    };


    GRAZIE!

    Rispondi a questo commento
  25. Saturday, November 14, 2020 alle ore 18:12 Mario

    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.

    Rispondi a questo commento
    • Saturday, November 14, 2020 alle ore 22:17 Michele PisaniAutore

      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

      Rispondi a questo commento
      • Sunday, November 15, 2020 alle ore 10:58 Mario

        Ciao Michele, grazie di avermi risposto, ti mostro la macro

        function avanti2() {
        var spreadsheet = SpreadsheetApp.getActive();
        spreadsheet.getRange('B163').activate();
        spreadsheet.getRange('B1:H1').moveTo(spreadsheet.getActiveRange());
        spreadsheet.getRange('B1:H162').activate();
        spreadsheet.getRange('B2:H163').moveTo(spreadsheet.getActiveRange());
        };



        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.

      • Sunday, November 15, 2020 alle ore 11:35 Michele PisaniAutore

        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

  26. Sunday, January 10, 2021 alle ore 09:43 Andrea

    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

    Rispondi a questo commento
    • Monday, January 11, 2021 alle ore 00:57 Michele PisaniAutore

      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.

      Rispondi a questo commento
  27. Thursday, February 4, 2021 alle ore 19:35 FRANCESCO

    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

    Rispondi a questo commento
  28. Friday, February 12, 2021 alle ore 11:51 FRANCESCO

    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

    Rispondi a questo commento
    • Friday, February 12, 2021 alle ore 22:06 Michele PisaniAutore

      Ciao Francesco,
      se utilizzi l'app per Android Fogli Google (Google LLC) l'onEdit() funziona correttamente. Per sicurezza l'ho appena provato.

      Rispondi a questo commento
  29. Saturday, February 13, 2021 alle ore 01:12 FRANCESCO

    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

    Rispondi a questo commento
    • Saturday, February 13, 2021 alle ore 11:46 Michele PisaniAutore

      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.

      Rispondi a questo commento
  30. Monday, February 15, 2021 alle ore 08:47 FRANCESCO

    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

    Rispondi a questo commento
  31. Monday, February 15, 2021 alle ore 09:14 FRANCESCO

    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

    Rispondi a questo commento
  32. Sunday, March 14, 2021 alle ore 09:57 SEBASTIANO

    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?

    Rispondi a questo commento
  33. Monday, February 21, 2022 alle ore 10:35 Beniamino

    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

    Rispondi a questo commento
    • Monday, February 21, 2022 alle ore 22:27 Michele PisaniAutore

      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.

      Rispondi a questo commento
  34. Monday, March 21, 2022 alle ore 22:25 Iolanda

    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

    Rispondi a questo commento
    • Tuesday, March 22, 2022 alle ore 00:06 Michele PisaniAutore

      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.

      Rispondi a questo commento
  35. Thursday, March 2, 2023 alle ore 16:29 Fabio

    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

    Rispondi a questo commento
  36. Thursday, March 2, 2023 alle ore 16:30 Fabio

    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

    Rispondi a questo commento
  37. Thursday, March 2, 2023 alle ore 16:30 Fabio

    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

    Rispondi a questo commento
  38. Thursday, March 2, 2023 alle ore 16:32 Fabio

    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

    Rispondi a questo commento
  39. Thursday, March 2, 2023 alle ore 16:32 Fabio

    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

    Rispondi a questo commento
  40. Tuesday, August 8, 2023 alle ore 11:17 marco

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

    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]https://www.appsscript.it[/url] se devi riferirti ad un indirizzo web