Puoi usare due metodi: addFile o makeCopy
Spostare i file tra le cartelle di Google Drive con Google Apps Script
Le classi relative ai file ed alle cartelle, in Google Apps Script, non mettono a disposizione alcun metodo per spostare un file da una cartella ad un'altra in Google Drive, tuttavia è possibile aggiungere lo stesso file in più cartelle. Sfruttando questa caratteristica possiamo ovviare alla mancanza di un metodo dedicato per spostare direttamente un file semplicemente aggiungendolo ad una cartella desiderata ed eliminandolo da quella di origine.
L'esempio di codice che andrò a presentare vuole simulare una classica situazione in cui uno sviluppatore in Apps Script si trova quando è alle prese con la generazione di nuovi file; non riporterò pertanto una isolata porzione di codice bensì una serie di funzioni completa che partono dal recupero della cartella corrente, procedono con la creazione di un nuovo file e terminano con il suo 'spostamento' nella cartella in cui è presente il progetto in corso (ho apostrofato il termine 'spostamento' in virtù del fatto che, nonostante il risultato finale, non si tratta tecnicamente di un vero e proprio spostamento tra cartelle).
Il codice completo del flusso indicato sopra è il seguente:
function getCurrentProjectFolder() {
var thisScriptId = ScriptApp.getScriptId();
var thisFile = DriveApp.getFileById(thisScriptId);
var parentFolders = thisFile.getParents();
var thisFolderId;
while (parentFolders.hasNext()){
thisFolderId = parentFolders.next().getId();
}
// Recupera l'istanza della cartella
var thisFolder = DriveApp.getFolderById(thisFolderId);
return thisFolder;
}
function createNewFile(fileType, fileName) {
var nuovoFile;
switch (fileType) {
case 'spreadsheet':
nuovoFile = SpreadsheetApp.create(fileName);
break;
case 'document':
nuovoFile = DocumentApp.create(fileName);
break;
case 'form':
nuovoFile = FormApp.create(fileName);
break;
default:
nuovoFile = SpreadsheetApp.create('nuovo file');
}
return nuovoFile;
}
function moveFileToFolder(nuovoFile, targetFolder) {
var nuovoFileId = DriveApp.getFileById(nuovoFile.getId());
var parentFolder = nuovoFileId.getParents();
var movedFile = targetFolder.addFile(nuovoFileId);
parentFolder.next().removeFile(nuovoFileId);
return movedFile;
}
function startFunction() {
var cartellaProgettoCorrente = getCurrentProjectFolder();
var nuovoFile = createNewFile('spreadsheet', 'file da spostare nella cartella del progetto');
var movedFile = moveFileToFolder(nuovoFile, cartellaProgettoCorrente);
}
Ho chiamato, per facilità di identificazione, la funzione di inizio con il nome di startFunction(), al suo interno ci sono 3 chiamate a 3 distinte funzioni (riutilizzabili in altri script e contesti), la prima è getCurrentProjectFolder() che si occupa proprio di recuperare il riferimento della cartella (tramite il suo id) nella quale si trova il progetto corrente:
function getCurrentProjectFolder() {
// Recupera l'id dello script corrente
var thisScriptId = ScriptApp.getScriptId();
// Recupera l'istanza del file thisScriptId
var thisFile = DriveApp.getFileById(thisScriptId);
// Recupera il riferimento degli elementi del livello superiore al file
var parentFolders = thisFile.getParents();
var thisFolderId;
while (parentFolders.hasNext()){
// Recupera l'id della cartella del file
thisFolderId = parentFolders.next().getId();
}
// Recupera l'istanza della cartella
var thisFolder = DriveApp.getFolderById(thisFolderId);
return thisFolder;
}
La seconda funzione chiamata è createNewFile(fileType, fileName) che accetta in ingresso due parametri (il tipo di file identificato da una stringa: 'spreadsheet', 'document' o 'form'; il nome del documento, anch'esso ovviamente una stringa), questa funzione crea il file (del tipo e con il nome indicati) nella root di Google Drive e ne restituisce il riferimento:
function createNewFile(fileType, fileName) {
// crea un nuovo documento nella root di Drive
var nuovoFile;
switch (fileType) {
case 'spreadsheet':
nuovoFile = SpreadsheetApp.create(fileName);
break;
case 'document':
nuovoFile = DocumentApp.create(fileName);
break;
case 'form':
nuovoFile = FormApp.create(fileName);
break;
default:
nuovoFile = SpreadsheetApp.create('nuovo file');
}
return nuovoFile;
}
La terza funzione, chiamata moveFileToFolder(nuovoFile, targetFolder), accetta in ingresso due parametri ovvero, il riferimento al file appena creato e quello alla cartella di destinazione recuperata tramite la prima funzione. Questa funzione è il cuore dello 'spostamento' dei file tra cartelle in quanto tramite l'id del file recupera il riferimento degli elementi del suo livello superiore che, come abbiamo definito poco fa, è la root di Google Drive, dopodiché tramite il metodo addFile aggiunge il file alla cartella desiderata (quella passata nei parametri) e successivamente removeFile rimuove l'istanza dello stesso file dalla root di Drive:
function moveFileToFolder(nuovoFile, targetFolder) {
// recupera l'id del nuovo file
var nuovoFileId = DriveApp.getFileById(nuovoFile.getId());
// Recupera il riferimento degli elementi del livello superiore al file (la root di Drive)
var parentFolder = nuovoFileId.getParents();
// Aggiunge l'istanza del file all'interno della cartella desiderata
var movedFile = targetFolder.addFile(nuovoFileId);
// Rimuove il file (la sua istanza) dalla root
parentFolder.next().removeFile(nuovoFileId);
return movedFile;
}
Con questo metodo lo 'spostamento' dei file è quasi indolore, dico quasi perchè all'evidenza l'operazione è del tutto trasparente, non si troverà alcun file nel cestino ed il path di accesso al file spostato è lo stesso di quello originariamente presente nella root, tuttavia il suo id (qualora servisse utilizzarlo come riferimento per particolari operazioni a runtime dalla creazione allo 'spostamento') sarà diverso dal file di partenza.
Un altro metodo che potrebbe essere utilizzato sempre allo scopo di 'spostare' i file tra cartelle di Drive è makeCopy; personalmente non lo preferisco, quantomeno se lo scopo è quello oggetto di questo tutorial semplicemente perché effettuando l'operazione in questione (quindi copia del file nella cartella bersaglio ed eliminazione del file originale dalla root), troverei il file originale nel cestino (il metodo di cancellazione del file non a caso si chiama setTrashed) ma soprattutto il path di accesso al file spostato è diverso di quello originariamente presente nella root per il semplice motivo che è una copia del file (un nuovo file diverso dal precedente se pur identico nel nome e nel contenuto) e non un'istanza dello stesso (come si ottiene invece con il metodo precedentemente spiegato nel tutorial). Anche in questo caso, a maggior ragione, gli id tra i due file saranno diversi. Inoltre, questo metodo non andrà a buon fine se il file che si intende gestire è stato caricato da altro utente e lo script è in esecuzione sotto un utente diverso.
Per approfondimenti su tutti i metodi delle Classi per la gestione di file e cartelle rimando alla documentazione ufficiale della Classe DriveApp.
Salve script molto interesante una domanda e' possibile con il comando createFolder(name) creare una cartella nidificata ? creo una cartella "cartella2" che all'interno di "Cartella1" e poi li sposto i miei file
grazie
Ciao Mauro,
questa porzione di codice che ti riporto di seguito credo sia quello che stai cercando.
In pratica, in base al nome indicato per la cartella padre verifica la sua presenza su Drive, se la trova ne prende il riferimento altrimenti crea una cartella con quel nome, successivamente in base al riferimento della cartella padre crea al suo interno una sottocartella e a sua volta, all'interno di questa sottocartella, crea un file:
Il codice dovrebbe essere abbastanza autoesplicativo, in ogni caso se c'è qualcosa che non ti torna fammi sapere.
Intanto grazie infine per la risposta celere.... ho capito tutto non posso fare altro che ringraziarti e lodare la tua professionalità
Grazie a te Mauro,
è un piacere. Buon proseguimento!
Ciao scusa il disturbo ma da un po questa funzione mi genera un errore hanno cambiato qualcosa sulle funzioni di Google ??
var nuovoFileId = DriveApp.getFileById(nuovoFile.getId());
mi segnala "impossibile chiamare metodo "getid" undefinid "
fino a qualche tempo fa funzionava perfettamente
Ciao Mauro,
probabilmente la tua variabile 'nuovoFile' non contiene effettivamente ciò che ti aspetti.
Ho provato a lanciare questa funzione di test ed il risultato viene restituito nel log senza alcun problema:
Buongiorno, stavo utilizzano il suggerimento (secondo me molto interessante) per potre creare un foglio nuovo con un nuovo nome su una cartella indicata.
ma nella funzione
recupera correttamente l'ID dello script ma poi mi da un errore nella riga in cui deve utilizzarlo ultima riga nell'esempio con il seguente errore
Nessun elemento trovato con l'ID specificato o non disponi di autorizzazioni per accedervi.
Sa mica quale potrebbe essere il motivo?
Ciao Domenico,
l'errore in questione, che in base alle impostazioni di lingua può comparire in questo modo "No item with the given ID could be found, or you do not have permission to access it", viene restituito, come da descrizione, se nessun elemento in Drive è associato a quell'id o se non hai i permessi per accedervi. Nel tuo caso dato che parli di "Fogli" mi viene da pensare che la situazione sia la prima in quanto stai tentando di cercare su Drive il file con l'id dello script incorporato nello Spreadsheet, ma gli script incorporati non si 'trovano' su Drive.
Prova a modificare il codice in modo da recuperare l'id dello Spreadsheet e riferirti a quello.
Ciao.
Devo farti una domanda da inesperto totale.
Se inserisco il codice tale e quale al tuo, mi restituisce l'errore: "Errore
Exception: Invalid argument: id
getCurrentProjectFolder @ Codice.gs:10
startFunction @ Codice.gs:41"
Devo inserire manualmente l'ID della cartella di origine e quello di quella di destinazione per caso?
Ti ringrazio in anticipo per le spiegazione che potrai darmi.
Marco
Ciao Marco,
quelle info le prende in automatico. Quale funzione hai eseguito dall'editor di script?
Sono da cell in questo momento, dove è l'argomento id che non lo vedo nel codice?
Ciao e scusami il ritardo....
La risposta completa dello script "startFunction" è:
12:33:17 Notifica Esecuzione avviata
12:33:18 Errore Exception: Invalid argument: id
getCurrentProjectFolder @ Codice.gs:10
startFunction @ Codice.gs:41
Spero si veda bene.
Grazie per la tua pazienza
riga 10
var thisFolder = DriveApp.getFolderById(thisFolderId);
riga 41
var cartellaProgettoCorrente = getCurrentProjectFolder();
Ciao Marco,
il progetto di script di trova nella root o in una cartella dedicata?
dedicata
Ciao Marco,
ho riprovato personalmente il codice a distanza di anni e ti confermo che funziona correttamente.
Se lato tuo il codice è stato copiato correttamente e hai tutti gli accessi e privilegi ai file del tuo account, proverei semplicemente a creare un nuovo file di script eliminando quello su cui stai lavorando.
Ok. Allora credo di non aver capito dove posizionare il modulko dove far lavorare il tuo script...
Io ho creato una cartella con dei file e il modulo dove applicare il tuo script e un'altra cartella , 2, dove vorrei spostare i file della cartella 1. Cosa sbaglio?
Questo script crea un nuovo file vuoto (nel caso specifico un Google Sheets) all'interno della stessa cartella dove si trova il progetto di script. Per fare quello che desideri il codice deve essere modificato, giocando con i metodi presentati.
Credo di aver capito il mio errore.... dove devo inserire l'ID della cartella di destinazione?
Ciao Marco,
non ho capito la domanda. Questo script effettua esattamente l'azione indicata perché lo script è al solo scopo esemplificativo dei metodi: crea un nuovo file Google Sheets vuoto nella cartella dove si trova il progetto che contiene la funzione. Così com'è, non è fatto per spostare specifici file in specifiche cartelle. Per ottenere il risultato desiderato i metodi da utilizzare sono sicuramente quelli presentati, ma non basta inserire gli id. Per qualsiasi altra personalizzazione è necessario capire bene cosa fanno i metodi e creare una nuova funzione ad hoc.
Ciao e grazie ancora per la tua pazienza.
L'equivoco credo che nasca dalla mia esigenza: io cercavo uno script che mi spostasse, massivamente, tutti i file di una certa cartella in un'altra da me scelta. E' possibile?
Ciao Marco,
ti confermo che è fattibilissimo utilizzando a dovere i metodi presentati nell'articolo. Quantomeno questo scambio di messaggi ha confermato che lo script dell'articolo funziona correttamente, il resto ora è puro divertimento per te. Sono certo che con un po' di prove e consapevolezza riuscirai in breve tempo a ottenere il risultato desiderato :)
Buongiorno Michele ti scrivo per sapere se sia possibile fare questa cosa con app script dato che non ne ho idea.
Ho un database di utenti di cui ho raccolto le iscrizioni tramite il nostro sito web ed attualmente, le foto che hanno caricato gli stessi, sono in una cartella del nostro sito.
Vorremmo spostare tutto l'archivio su drive, ma il problema è ottenere il percorso assoluto di ognuno di questi file ( sono oltre 50mila e manualmente è impraticaabile farlo). Vengo al punto: con l'aiuto di un amico abbiamo creato uno script che partendo dal database utenti presente in sheets e che contiene i link originali al nostro sito, scarica i file in una cartella di drive rinominandoli con nome e cognome.
Ora però il nostro problema è riassociare al database il nuovo link che è su drive. Credi che sia possibile automatizzare il processo, facendo fare una ricerca a DriveApp e ricostruire il link al contrario? cioè cercando cognome e nome dentro la cartella di drive, e farci rendere i relativi link in una colonna di un foglio google?
spero di essermi spiegato :)
grazie
Buongiorno Michele ti scrivo per sapere se sia possibile fare questa cosa con app script dato che non ne ho idea.
Ho un database di utenti di cui ho raccolto le iscrizioni tramite il nostro sito web ed attualmente, le foto che hanno caricato gli stessi, sono in una cartella del nostro sito.
Vorremmo spostare tutto l'archivio su drive, ma il problema è ottenere il percorso assoluto di ognuno di questi file ( sono oltre 50mila e manualmente è impraticaabile farlo). Vengo al punto: con l'aiuto di un amico abbiamo creato uno script che partendo dal database utenti presente in sheets e che contiene i link originali al nostro sito, scarica i file in una cartella di drive rinominandoli con nome e cognome.
Ora però il nostro problema è riassociare al database il nuovo link che è su drive. Credi che sia possibile automatizzare il processo, facendo fare una ricerca a DriveApp e ricostruire il link al contrario? cioè cercando cognome e nome dentro la cartella di drive, e farci rendere i relativi link in una colonna di un foglio google?
spero di essermi spiegato :)
grazie
Buongiorno Michele ti scrivo per sapere se sia possibile fare questa cosa con app script dato che non ne ho idea.
Ho un database di utenti di cui ho raccolto le iscrizioni tramite il nostro sito web ed attualmente, le foto che hanno caricato gli stessi, sono in una cartella del nostro sito.
Vorremmo spostare tutto l'archivio su drive, ma il problema è ottenere il percorso assoluto di ognuno di questi file ( sono oltre 50mila e manualmente è impraticaabile farlo). Vengo al punto: con l'aiuto di un amico abbiamo creato uno script che partendo dal database utenti presente in sheets e che contiene i link originali al nostro sito, scarica i file in una cartella di drive rinominandoli con nome e cognome.
Ora però il nostro problema è riassociare al database il nuovo link che è su drive. Credi che sia possibile automatizzare il processo, facendo fare una ricerca a DriveApp e ricostruire il link al contrario? cioè cercando cognome e nome dentro la cartella di drive, e farci rendere i relativi link in una colonna di un foglio google?
spero di essermi spiegato :)
grazie