Google apps script rename file not working - google-apps-script

When running this script I get the error
TypeError: Cannot find function setName in object File. (line 8, file "Code")
function rename() {
var folder = DocsList.getFolder('Folder');
var files = folder.getFiles();
for (var i in files) {
oldName = files[i].getName()
newName = oldName.replace(/\d+/g, '')
newName = newName.replace(/\s/g, '');
files[i].setName(newName)
}

For me worked with setName().
files[i].setName(newName);

function myFunction()
{ **// this worked for me rename files of type CSV to processed**
var sh = SpreadsheetApp.getActiveSheet();
var folder = DriveApp.getFolderById('folderID'); // change accordingly to folder ID
//give me only files that are of type CSV
var files = folder.getFilesByType(MimeType.CSV);
// new name of csv that I want to rename the file within my google drive folder
var newName = "processed";
while(files.hasNext())
{
// iterate throught the csv files available
var file = files.next()
// will rename all csv's to processed
file.setName(newName);
}
}

The method is rename() and not setName()
files[i].rename(newName)

Related

How can i remove the old converted file and replace with a new file using app script?

I am trying to replace the old converted files with the new file. This is because every time i run the script it keeps on duplicating and multiplying in the same folder.
Here is the code:
function ConvertFiles() {
var sheet =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var r= 2;
for(r= 2;r < sheet.getLastRow(); r++){
var fileId= sheet.getRange(r,1).getValues();
var folderID = sheet.getRange(r,8).getValues();
Logger.log(fileId);
var files = DriveApp.getFileById(fileId);
var name = files.getName().split('.')[0];
var blob = files.getBlob();
var destinationFolderId = DriveApp.getFolderById(folderID);
Logger.log(folderID);
var newFile = {
title : name + '_converted', parents: [{id:
destinationFolderId.getId()}]};
Logger.log(newFile);
}
}
My goal is:
To replace/update the old converted file into the latest one everytime the script runs (if it has the same filename)
I would like to push back the converted fileId into the google sheet to be displayed.
How can i solve this issue?
I have added comments to show each part of the code. Kindly check the whole script below:
Script:
function ConvertFiles() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var r= 2;
for(r= 2;r < sheet.getLastRow(); r++){
// Use getValue instead of getValues
var fileId = sheet.getRange(r,1).getValue();
var folderID = sheet.getRange(r,8).getValue();
var files = DriveApp.getFileById(fileId);
var name = files.getName().split('.')[0];
var blob = files.getBlob();
var newFile = {
// Remove '_converted' from name if existing to avoid duplication of the string before adding '_converted'
// This will allow to have newly converted file "replace" the old converted file properly
title: name.replace('_converted','') + '_converted',
parents: [{
id: folderID
}]
};
var destinationFolderId = DriveApp.getFolderById(folderID);
var existingFiles = destinationFolderId.getFilesByName(newFile.title);
// GOAL #1: To replace/update the old converted file into the latest one everytime the script runs (if it has the same filename)
// Find the file with same name of the file to be converted
while(existingFiles.hasNext()) {
// ID of the file with same converted name
var oldConvertedFileWithSameNameID = existingFiles.next().getId();
// Delete before writing
Drive.Files.remove(oldConvertedFileWithSameNameID);
}
// Create new converted file then get ID
var newFileID = Drive.Files.insert(newFile, blob, {
convert: true
}).id;
// Goal #2: I would like to push back the converted fileId into the google sheet to be displayed.
// Add the ID of the converted file
sheet.getRange(r,9).setValue(newFileID);
}
}
Sample sheet:
Sample files:
First run (files):
First run (sheet):
Updated original files:
Run after updating original file (files):
Run after updating original file (sheet):
Note:
This will retain the original file, but will replace the existing converted file of it everytime the script is run.
I have used Drive services.

Stop the function when the folder doesn't have xlsx files in (Google App scripts)

I have the next function on Google App Script:
function remove(){
var folder = DriveApp.getFolderById('folderID');
var files = DriveApp.getFilesByType(MimeType.MICROSOFT_EXCEL);
while (files.hasNext()){
var file = files.next();
folder.removeFile(file);
}
}
I want stop/break/exit the function when the folder does not have/contains xlsx files.
How I do that?
Greetings
Your function should work fine. Including stopping if there are no more excel files.
But you do need to change this:
var files = DriveApp.getFilesByType(MimeType.MICROSOFT_EXCEL);
(this searches the entire Drive)
to
var files = folder.getFilesByType(MimeType.MICROSOFT_EXCEL);
Here is the code:
function remove(){
var folder = DriveApp.getFolderById(''folder's id'');
var files = folder.getFilesByType(MimeType.MICROSOFT_EXCEL);;
while (files.hasNext()){
var file = files.next();
folder.removeFile(file);
}

Copying sheets using appscript pulls through forms

I have a script that pulls the ID of a file within a specific folder, then takes a copy and puts that into another folder then deletes it from the original folder.
However when the takes a copy it then copies any attached google forms and places them in the folder also.
Is there a way to only copy the sheet?
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Copies")
var folder = DriveApp.getFolderById('FOLDER_ID'); //Latest Copy ID
var list = [];
list.push(['Name','ID','Size']);
var files = folder.getFiles();
while (files.hasNext()){
file = files.next();
var row = []
row.push(file.getName(),file.getId(),file.getSize())
list.push(row);
}
sh.getRange(1,1,list.length,list[0].length).setValues(list);
var value = SpreadsheetApp.getActiveSheet().getRange(2, 2).getValue();
var archive = DriveApp.getFolderById("ARCHIVE_ID"); // Backup Folder
var file = DriveApp.getFileById(value);
var name = file.getName();
// makes copy of "file" with "name" at the "destination"
file.makeCopy(name, archive);
file.setTrashed(true); // sets the file in the trash of the user's Drive
}
Issue:
All files in your folder are found and processed, you're not checking for a specific file type.
Modifications:
Check the file type before you write to the array.
if (file.getMimeType() === 'application/vnd.google-apps.spreadsheet') {
var row = [];
row.push(file.getName(),file.getId(),file.getSize());
list.push(row);
}
Reference:
getMimeType()

Cannot find method (class)addFile

I have way to much code to paste in, so I created the simplest version of my problem.
I get the error "Cannot find method (class)addFile($Proxy1084). (line 96, file "Macros")"
For the record, line 96 is the folder.addFile(copySS). It creates the sheet. Logger data will give me the name of the folder. If anyone has any clue why this isn't rolling I could use the assist.
function test2(){
var folders = DriveApp.getFolders();
var file = "Testy McFile";
while(folders.hasNext()){
var folder = folders.next();
// find all the NFL folders
if(folder.getName() === 'NFL'){
var copySS = SpreadsheetApp.create(file);
Logger.log(folder.getName());
folder.addFile(copySS);
//this is test code so in case it works... don't make a dozen copies
break;
}
}
}
copySS here is an Spreadsheet object, not file Object. However addFile method expects a file object from Drive app. That is why you are getting this error.
Here is modified code which works fine.
function test2(){
var folders = DriveApp.getFolders();
var file = "Testy McFile";
while(folders.hasNext()){
var folder = folders.next();
// find all the NFL folders
if(folder.getName() === 'Imp'){
var fileId = SpreadsheetApp.create(file).getId();
var file = DriveApp.getFileById(fileId);
Logger.log(folder.getName());
folder.addFile(file);
break;
}
}
}

Creating a zip file inside Google Drive with Apps Script

I have a folder in Google Drive folder containing few files. I want to make a Google Apps Script that will zip all files in that folder and create the zip file inside same folder.
I found a video that has Utilities.zip() function, but there is no API reference for that. How do I use it? Thanks in advance.
Actually it's even easier than that. Files are already Blobs (anything that has getBlob() can be passed in to any function that expects Blobs). So the code looks like this:
var folder = DocsList.getFolder('path/to/folder');
folder.createFile(Utilities.zip(folder.getFiles(), 'newFiles.zip'));
Additionally, it won't work if you have multiple files with the same name in the Folder... Google Drive folders support that, but Zip files do not.
To make this work with multiple files that have the same name:
var folder = DocsList.getFolder('path/to/folder');
var names = {};
folder.createFile(Utilities.zip(folder.getFiles().map(function(f){
var n = f.getName();
while (names[n]) { n = '_' + n }
names[n] = true;
return f.getBlob().setName(n);
}), 'newFiles.zip'));
As DocsList has been deprecated, You can use the following code to zip an entire folder containing files and sub-folders and also keep its structure:
var folder = DriveApp.getFolderById('<YOUR FOLDER ID>');
var zipped = Utilities.zip(getBlobs(folder, ''), folder.getName()+'.zip');
folder.getParents().next().createFile(zipped);
function getBlobs(rootFolder, path) {
var blobs = [];
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
file.setName(path+file.getName());
blobs.push(file);
}
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var fPath = path+folder.getName()+'/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}
getBlobs function makes an array of all files in the folder and changes each file name to it's relative path to keep structure when became zipped.
To zip a folder containing multiple items with the same name use this getBlob function:
function getBlobs(rootFolder, path) {
var blobs = [];
var names = {};
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
var n = file.getName();
while(names[n]) { n = '_' + n }
names[n] = true;
blobs.push(file.setName(path+n));
}
names = {};
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var n = folder.getName();
while(names[n]) { n = '_' + n }
names[n] = true;
var fPath = path+n+'/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}
I was able to use the code that #Hafez posted but I needed to modify it because It was not working for me. I added the first three lines because I needed the folder ID which is a string value and is not the name of the folder.
var folderName = DriveApp.getFoldersByName("<folderName>");
var theFolder = folderName.next();
var folderID =theFolder.getId();
var folder = DriveApp.getFolderById(folderID);
var zipped = Utilities.zip(getBlobs(folder, ''), folder.getName()+'.zip');
folder.getParents().next().createFile(zipped);
function getBlobs(rootFolder, path) {
var blobs = [];
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
file.setName(path+file.getName());
blobs.push(file);
}
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var fPath = path+folder.getName()+'/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}
The only weird thing that I'm experiencing is that when I run the script it says TypeError: Cannot call method "getFiles" of undefined. (line 10, file "Code"). When I happened to look at the place where this script lives there was also 5 zip files that were complete. It works but I still get that error. Weird...but this code works for me. Thanks to everyone on this thread. Cheers!
There's no API reference indeed. You could open an issue request regarding this on Apps Script issue tracker. But deducing from what the code-completion shows, here is my understanding:
var folder = DocsList.getFolder('path/to/folder');
var files = folder.getFiles();
var blobs = [];
for( var i in files )
blobs.push(files[i].getBlob());
var zip = Utilities.zip(blobs, 'newFiles.zip');
folder.createFile(zip);
But I have not tested this code, so I don't know if it will work. Also, it may work only for files not converted to Google's format, or maybe only for those or a subset of it. Well, if you try it out and find something, please share here with us. One limit that you'll sure face is the filesize, it will probably not work if the zip file gets "too" big... yeah, you'll have to test this limit too.
If Hafez solution didn't worked out, and you get this error
TypeError: Cannot read property 'getFiles' of undefined
Try doing this
/**
* Creates a zipFile of the mentioned document ID and store it in Drive. You can search the zip by folderName.zip
*/
function createAndSendDocument() {
var files = DriveApp.getFolderById("DOCUMENT ID CAN BE FIND IN THE URL WHEN A DOCUMENT IS OPENED");
var folder = files;
var zipped = Utilities.zip(getBlobs(folder, ''), folder.getName() + '.zip');
folder.getParents().next().createFile(zipped);
}
function getBlobs(rootFolder, path) {
var blobs = [];
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
file.setName(path+file.getName());
blobs.push(file);
}
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var fPath = path+folder.getName() + '/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}