how to copy files(links) from a column in sheets, to a specific folder in drive? - file

I'm trying to, on form submission, copy the files (which appear as links) from google sheets, specifically from column c, only, to a master folder. the links are to the pdfs within a folder, not a folder itself.
I end up with this fail code: Exception: Unexpected error while getting the method or property getFileById on object DriveApp.
copyFilesToMasterFolder # Code.gs:10
My file id is correct. I don't know what to modify?
function copyFilesToMasterFolder() {
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var fileLinks = sheet.getRange(2, 3, lastRow-1, 1).getValues();
var masterFolder =
DriveApp.getFolderById("1y5ezQEbS0fDr2TcOjum5wOy6xWHHJcy1");
for (var i = 0; i < fileLinks.length; i++) {
var fileLink = fileLinks[i][0];
var fileId = fileLink.split("/")[fileLink.split("/").length - 2];
var file = DriveApp.getFileById(fileId);
file.makeCopy(masterFolder);
}
}

1.In Google Sheets, select "Tools" from the top menu, then select "Script editor".
2.In the Script editor, paste the following code:
function copyFilesFromSheetToDrive() {
var sheet = SpreadsheetApp.getActiveSheet();
var folder = DriveApp.getFolderById("FOLDER_ID"); // Replace with the ID of the target folder
var column = 1; // Column number of the links in the sheet
var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i++) {
var file = DriveApp.getFileById(data[i][column - 1]);
folder.addFile(file);
}
}
1.Replace "FOLDER_ID" with the ID of the target folder in Google Drive. You can find the ID in the URL of the folder, e.g., "https://drive.google.com/drive/folders/FOLDER_ID".
2.Save the script and close the Script editor.
3.Back in Google Sheets, select the script from the "Run" menu, or run it by clicking the play button in the Script editor.
This script will copy all the files linked in the first column (column 1) of the active sheet to the specified folder in Google Drive. You can modify the script to copy files from a different column or from a different sheet by changing the column and sheet variables, respectively.

Related

Apps Script to Create TXT Files Based on Data in Rows

I am working through the following script which reads the data in certain rows and columns (from Cell A29 to Cell K150) and produces txt files based on data in Columns A and B. That is, if columns A and B have same items, only 1 file is produced with all data in those rows. The only problem is that the script also reads the blank rows/columns and creates a blank txt file. How can I modify the script to exclude blank rows (For example, data is in rows 29 - 100, I want the script to exclude remaining 50 rows and NOT create any files for blank rows)?
function CreateUploadFiles() {
// Retrieve values from Spreadsheet.
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Summary"); //Set your sheet name.
var [, ...values] = sheet.getRange(28, 1, 150, 11).getValues();
// Create an array.
var csvBalanceArray = [...values.reduce((m, [h1, h2, ...r]) => {
var h = h1 + h2;
var temp = r.map(e => e instanceof Date ? Utilities.formatDate(e, Session.getScriptTimeZone(), "d/MM/yyyy") : e);
var name = `${h1} ${h2}`;
if (h2 == "Balance") {temp = temp.slice(0,3)}
return m.set(h, m.has(h) ? { rows: [...m.get(h).rows, temp], name } : { rows: [temp], name });
}, new Map()).values()];
console.log(csvBalanceArray)
//strip out new lines with space
// Create text files.
// var folder = DriveApp.getFolderById('J3'); // Set your folder ID.
var ss = SpreadsheetApp.getActive(); //Extracting Folder ID from Cell
var folder = ss.getRange("Summary!J3").getValue();
var destinationFolder = DriveApp.getFolderById(folder)
var files = destinationFolder.getFiles();
var GL = sheet.getRange("B2").getValue()
var period = sheet.getRange("B3").getValue()
var FY = sheet.getRange("B4").getValue()
//while (files.hasNext()) files.next().setTrashed(false); //For deleting files already created in your folder
csvBalanceArray.forEach(({ rows, name }) => destinationFolder.createFile(`P${period} FY${FY} ${GL} ${name}.txt`,
rows.map(r => r.join("***") //Join all columns to string value for each row
// replace remove all tab from new lines
.replaceAll("\t"," ").replaceAll("\n"," ").replaceAll("***","\t")).join("\n")));
}

How to extract few cells from a Google Sheet and copy to another sheet using a single statement

using JavaScript to access google sheets via google API.
I am copying the entire content of a "google spreadsheet" "Parent sheet" into a two dimension array vaParent
var ssParent = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Parent");
var vaParent = ssParent.getRange(2, 1, ssParent.getLastRow(), ssParent.getLastColumn() ).getValues();
I am extracting 6 array elements
var vaNewParent01 = vaParent[i].slice(3, 9);
Now, I would like to copy vaNewParent01 to a new google "spreadsheet" "company sheet"
ssCompany.getRange( 2, 1 ).setValues( vaNewParent01 );
above code does not work??
I've found that vaNewParent01 is a single dimension array with 6 elements
however, ssCompany.getRange( 2, 1 ).setValues( vaNewParent01
only works if vaNewParent01 is an array of array
question:
a/ how to extract few cells from a sheet and copy to another using a single statement.
thanks in advance for any help
cheers
From your showing script, if your script is like the following script,
var ssParent = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Parent");
var vaParent = ssParent.getRange(2, 1, ssParent.getLastRow(), ssParent.getLastColumn()).getValues();
for (var i = 0; i < vaParent.length; i++) {
var vaNewParent01 = vaParent[i].slice(3, 9);
ssCompany.getRange(2, 1).setValues(vaNewParent01);
}
vaNewParent01 is 1 dimensional array. In order to use setValues(values), values is required to be 2 dimensional array. And about ssCompany.getRange( 2, 1 ).setValues( vaNewParent01 );, in this case, please include the numbers of rows and columns of the values you want to put. If my understanding of your situation is correct, I think that the reason for your issue is due to this.
About how to extract few cells from a sheet and copy to another using a single statement., in this case, how about the following sample script?
Sample script 1:
This script is modified from your showing script by guessing your tested script.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssParent = ss.getSheetByName("Parent");
var ssCompany = ss.getSheetByName("sample"); // Please set the destination sheet name.
var vaParent = ssParent.getRange(2, 1, ssParent.getLastRow(), ssParent.getLastColumn()).getValues();
var values = [];
for (var i = 0; i < vaParent.length; i++) {
var vaNewParent01 = vaParent[i].slice(3, 9);
values.push(vaNewParent01);
}
ssCompany.getRange(2, 1, values.length, values[0].length).setValues(values);
Sample script 2:
As other sample script, how about the following script? In this sample script, copyTo of Class Range is used. From your showing script, I thought that you wanted to copy the values from D2:I of the source sheet to A2 of the destination sheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssParent = ss.getSheetByName("Parent");
var ssCompany = ss.getSheetByName("sample"); // Please set the destination sheet name.
var src = ssParent.getRange("D2:I" + ssParent.getLastRow());
src.copyTo(ssCompany.getRange(2, 1), { contentsOnly: true });
References:
setValues(values)
copyTo(destination, options)
arr is single dimension array
let vs = arr.map(e => [e]); //for a column;
let vs = [arr]; //for a row
Sheet.getRange(1,1,vs.length, vs[0].length).setValues(vs);

Move, Remove, and Replace information from Google Sheets with new entries using Google Script

I have created a Google Form that logs Timestamps, a numerical value, and an image file from its respondents to a Google Sheet. The image files are saved to an "imageFolder", but when I get too many responses, my imageFolder and Google Sheet get too large. Ideally, I want my imageFolder and its Google Sheet to stay below 50 entries.
I want to move the 10 oldest images in imageFolder to waitFolder. I want to save an array of those oldest values from column "How many?" before the entry is deleted. Then I want any new entries to replace the oldest ones who's information I have already save to waitFolder and the howMany() array (myArray10).
I know I have to move 10 images from "imageFolder" to "waitFolder" using functions along the lines of:
var text1 = "Response Form";
var text2 = "imageFolder";
var text3 = "Copy of imageFolder";
var text4 = "Wait Folder"
function moveFiles(sourceFileId, targetFolderId) {
var myFolder = DriveApp;
var files = myFolder.getFileById(sourceFileId).getFiles()
while (files.hasNext()) {
var file = files.next());
var dest = myFolder.getFolderById(targetFolderId);
dest.addFile(file);
var pull = DriveApp.getFolderById(sourceFolderId);
pull.removeFile(file);
}
}
function getMyId(text) {
var Ids = [];
var myFolder = DriveApp;
var folderIter = myFolder.getFoldersByName(text);
var folder = folderIter.next();
var folderIter = folder.getFiles();
while(folderIter.hasNext()) {
var file = folderIter.next();
var fileId = file.getId();
Ids.push(fileId);
}
return Ids
}
function getMyId10(text) {
var Ids = [];
var myFolder = DriveApp;
var folderIter = myFolder.getFoldersByName(text);
var folder = folderIter.next();
var folderIter = folder.getFiles();
for (var i = 0; i < 10; i++) { //Take the first 10
while(folderIter.hasNext()) {
var file = folderIter.next();
var fileId = file.getId();
Ids.push(fileId);
}
}
return Ids
}
function main() {
var imageFolderId = getMyId(text2);
var imageFolderId10 = getMyId10(text2);
var waitFolderId = getMyId(text4);
var Copy_imageFolderId = getMyId(text3);
moveFiles(imageFolderId, Copy_imageFolderId); //make a copy of imageFolder
moveFiles(imageFolderId10, waitFolderId); //Move first 10, remove from original
}
How can I move images from imageFolder to Copy_imageFolder?
How can I move the 10 oldest images from imageFolder to waitFolder?
How can I remove the 10 oldest images from imageFolder?
How can I limit the number of rows in my spreadsheet using Google script?
How can I overwrite my oldest rows with new entries/rows?
edit1: I am getting unexpected tokens in every function, and I am unsure why? It seems to pop up in the while loop of my function getMyId().
edit2: I see now why I was getting unexpected tokens. It seems that I was being irresponsible with my loops. I have replaced my 'while's with 'for's to amend this mistake.
edit3: I removed some unnecessary snippets of code to make it easier to follow.
edit4: Here is what my Form Response looks like in my Spreadsheet. The images are saved to subfolder imageFolder. But I can't grab the 10 array elements I want from the spreadsheet using howMany(). I also can't seem to move any of the files anywhere. When I call on moveFiles(), I get an unexpected error as soon as it asks for my DriveApp. How do I make my moveFiles() move my images from source to target folders?
Perhaps this is what you were looking for:
function moveFiles(sourceFolderId, targetFolderId) {
var srcFolder=DriveApp.getFolderById(sourceFolderId);
var desFolder=DriveApp.getFolderById(targetFolderId);
var files=srcFolder.getFiles();
while(files.hasNext()) {
var file=files.next();
desFolder.addFile(file);
srcFolder.removeFile(file)
}
}

How to copy multiple rows (value Only) within the same sheet by Google App Script for Google Sheet

I like to copy multiple rows value from and to the same google sheet by a script, but I failed to get it to work.
My script:
function Copymultiplerows() {
var ss = SpreadsheetApp.openByUrl("Spreadsheeturl");
Logger.log(ss.getName());
var mysheet = ss.getSheetByName('Sheet1');
var source = ss.getRange ('72:350');
var tss =SpreadsheetApp.openByUrl("Spreadsheeturl");
var ts = tss.getSheetByName('Sheet1');
ts.getRange('73:351');
}
You also need to get and set the values
ts.getRange("73:351").setValues(source.getValues());

sort files by datecreated and remove old files with google apps script

Trying to make a simple google apps script to get files by name and order them by date created. If there are more than 5 files by the same name, delete all but the 5 newest files.
function tryme(){
var files = DriveApp.getFilesByName('thisFile');
var created = files.getDateCreated();
for(i in created) {
if(created[i] > 4){
file.setTrashed(true);}
}
}
You're trying to use a File method on a File Iterator (returns from getFilesByName() method).
Here is a solution for your issue:
function tryme(){
// Get the file Iterator
var files = DriveApp.getFilesByName('New Text File');
var fileArray = [];
// Put file on array
while(files.hasNext()){
var file = files.next();
fileArray.push([file, file.getDateCreated()]);
}
//While you have more than 5 files
while(fileArray.length>5){
var older = ["",new Date()];
var olderIndex;
// Get the older file
for(var i in fileArray){
if(fileArray[i][1].getTime() < new Date(older[1]).getTime()){
olderIndex = i;
older = fileArray[i];
}
}
// Delete the older file
fileArray.splice(olderIndex,1);
older[0].setTrashed(true);
}
}
Edit: I made a mistake by using DriveApp.removeFile() instead of File.setTrashed(true)

Resources