I am looking for a script that loops through a google sheet and renames the files in a folder on google drive.
The sheet has the location of the file in drive and the name of the original file and the new name of the file.
Since I am a complete beginner at google script and javascript i would be enternal grateful if someone could help me with this.
Rename All of the Files in a Folder
From data in a Spreadsheet
I didn't have anything to do so I thought I'd give it a try. I only tested it once and it doesn't interact with the user. So here it is.
function renameFiles(shname){
//var shname=shname||'bullSheet';
if(shname){
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName(shname);
var rg=sh.getDataRange();
var vA=rg.getValues();
var folderId=getFolderId(shname);
if(vA.length>2){
var nameA=[];
var idA=[];
var fldr=DriveApp.getFolderById(folderId);
var files=fldr.getFiles();
while(files.hasNext()){
var file=files.next();
nameA.push(file.getName());
idA.push(file.getId());
}
for(var i=2;i<vA.length;i++){
var idx=nameA.indexOf(vA[i][0]);
if(!vA[i][2] && vA[i][1] && vA[i][0] && idx>-1){
DriveApp.getFileById(idA[idx]).setName(vA[i][1]);
vA[i][2]='RENAMED';
}
}
rg.setValues(vA);
}else{
var fA=[];
var fldr=DriveApp.getFolderById(folderId);
var files=fldr.getFiles();
while(files.hasNext()){
var file=files.next();
sh.appendRow([file.getName()]);
}
}
}
}
function getFolderId(shname){
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName(shname);
var rg=sh.getDataRange();
var vA=rg.getValues();
return vA[0][1];
}
Here's the spreadsheet when you start. It has the folder id in B1 and three headers on line 2 and nothing else.
Then you run renameFiles the first time and it reads the files in the directory whose id is in B2 and puts them on the spreadsheet.
Then you enter the new names for these files in column 2 under the headers.
Then run the program again and it renames the files to your new names and puts "RENAMED" in column 3 which keeps the program from doing anything if you run it again.
There's still quite a bit that you might wish to add like dialogs that tell the user what's going on but I'll leave that as an exercise for you.
If you have a lot of files in a directory you may have to add page tokening to the process. I chose not to do that because I'm basically lazy.
If your wondering where to get the folder id then go to the folder in google drive and look at the url. It's the longest section in the url
Related
I am a beginner in creating Scripts in Google Sheets, so I would like some help to reference a folder that is inside the spreadsheet folder.
I would like to create a script that checks if there are more than 3 files in a given folder, if so, I would like it to return an error on the screen.
Important point: the files that need to be checked will always be in a folder that is inside the spreadsheet folder, so I would need to reference this, in the CMD it would be something like .\FolderWithFiles.
In this case, I cannot use the ID a of the folder which I want to be checked, because this is a model worksheet that will be duplicated several times.
Any idea how I can do this?
I believe your goal is as follows.
You want to check the number of files in the folder including the active Spreadsheet you are using.
When the number of files is more than 3, you want to show an error.
In this case, how about the following sample script?
Sample script:
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet(); // This is your active Spreadsheet.
const parentFolder = DriveApp.getFileById(ss.getId()).getParents();
if (parentFolder.hasNext()) {
const files = parentFolder.next().getFiles();
let count = 0;
while (files.hasNext()) {
const file = files.next();
// console.log(file.getName()); // When you use this line, you can see the filename of the files.
count++;
}
if (count >= 3) {
throw new Error("Your expected error.");
}
} else {
throw new Error("Spreadsheet has no parent folder.");
}
}
When this script is run, the number of files in the folder including the active Spreadsheet is checked. When the number of files is more than 3, an error like Your expected error. occurs.
If you want to use another Spreadsheet instead of the active Spreadsheet, please modify const ss = SpreadsheetApp.getActiveSpreadsheet(); to const ss = SpreadsheetApp.openById("###spreadsheetId###");.
Reference:
getParents()
I would like to save Documents into a open folder in Google Drive from another person.
I tried the following code but it doesnt work if i´m not the owner of the code.
function saveToFolder() {
var folder = DriveApp.getFolderById("###");
//var destSpreasheet = SpreadsheetApp.open(DriveApp.getFolderById(SpreadsheetApp.getActiveSpreadsheet().getId()).moveTo(folder))
//var ss = SpreadsheetApp.getActiveSpreadsheet().
//get active Sheet
var sSpreadsheet = SpreadsheetApp.getActive;
var sheetname = sSpreadsheet().getActiveSheet().getName();
var sSheet = sSpreadsheet().getSheetByName(sheetname);
//var destSpreadsheet = SpreadsheetApp.open(DriveApp.getFileById(sSpreadsheet().getId()).makeCopy("test",folder))
var destSpreadsheet = DriveApp.getFileById(sSpreadsheet().getId()).makeCopy(SpreadsheetApp.getActiveSpreadsheet().getName(), folder)
}
The goal is that a lot of people can safe there google sheets to the same folder in google drive by using a button.
Thanks a lot for your help
You have some typos in your code like getActive() and using sSpreadsheet() instead of sSpreadsheet (please refer to the documentation linked). Here is your "fixed code" that takes a Spreadsheet and creates a copy of it in a Drive folder (the code has self-explanatory comments):
function myFunction() {
// Get folder by ID
var folder = DriveApp.getFolderById("FOLDER ID");
// Get active Spreadsheet (if this script is not bounded use openById or openByUrl)
var sSpreadsheet = SpreadsheetApp.getActive();
// Make copy
DriveApp.getFileById(sSpreadsheet.getId()).makeCopy(SpreadsheetApp.getActive().getName(), folder)
}
Also bare in mind that in order to use DriveApp you must first enable the Drive API service.
Say, I have 100 google spreadsheets file and I need to merge into one file with 100 tabs(sheets). Is it possible with app script. Currently I have a code below,
function popForm() {
var ss = SpreadsheetApp.getActive();
for(var b = 0; b<100; b++){
var sheet = ss.getSheetByName('Sheet '+b);
var numberRows = sheet.getDataRange().getNumRows();
....
....
The above code will work with spreadsheets with 100 tabs(Sheets). But I have 100 sreadsheets with one tab(Sheet).
Explanation:
You have a folder with FolderId that contains all the spreadsheet
files. You find this folder using the getFolderById() method.
You get the files of this folder using the getFiles() method and
you use a while loop to iterate over these files.
For every file, you get the first sheet and you copy it using the
copyTo() method to the source (active) spreadsheet file.
The newly create sheet will be named after the name of the spreadsheet file that it came from. Feel free to change this part or let me know so I can modify it.
Solution:
You must be looking for this:
function myFunction() {
const source_sh = SpreadsheetApp.getActive();
const folder = DriveApp.getFolderById('FolderId');
const files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
var target_ss = SpreadsheetApp.openById(file.getId());
var target_sh = target_ss.getSheets()[0];
target_sh.copyTo(source_sh).setName(file.getName());
}
}
Trying to get a list of folders (not sub folders or files) in a Gsuite shared drive to populate a Google Sheet worksheet, but the script below fails after first time and will not overwrite the list when I re-run.
I have tried quite a few variations, but my problem is:
1. I would love to have a 3rd column produced showing the html
2. Script works once, but when I refresh or place a trigger on the sheet it no longer works or updates.
Here is my current code:
function listFilesInFolder(folderName) {
var sheet = SpreadsheetApp.getActiveSheet();
sheet.appendRow(["Name", "File-Id"]);
//change the folder ID below to reflect your folder's ID (look in the URL when you're in your folder)
var folder = DriveApp.getFolderById("0ADTcDD3ZSaa5Uk9PVA");
var contents = folder.getFolders()
var cnt = 0;
var file;
while (contents.hasNext()) {
var file = contents.next();
cnt++;
data = [
file.getName(),
file.getId(),
];
sheet.appendRow(data);
};
};
Any suggestions on how to:
1. Get the folder list to update each hour on the Google sheet?
2. Fix error where the folder list is not updating/overwriting?
3. Add the html of each folder into a third column?
4. Have the list produced in alphabetical order?
Many thanks in advance if you have made it this far!
function listFoldersInAFolder() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
sh.clearContents();
sh.appendRow(["Name", "Folder-URL"]);
var fA=[];
var folders=DriveApp.getFolderById("folder id").getFolders();//Enter folder id
while (folders.hasNext()) {
var folder= folders.next();
fA.push([folder.getName(),folder.getUrl()]);
}
sh.getRange(sh.getLastRow()+1,1,fA.length,2).setValues(fA);
sh.getRange(2,1,sh.getLastRow()-1,2).sort({column:1,ascending:true});
}
If you want to get all folders and sub folders you will have to recurse them. Here's an example of that: https://stackoverflow.com/a/55248127/7215091
I am trying to automate the creation of new folders in Google drive from data in a spreadsheet. The spreadsheet gets information from a form. I have figured out how to make the new folders using scripts but have the following questions:
How do I avoid creating duplicate folders each time the script is run? For example if a folder named '1808' has already been created, I don't want the script to create '1808(1)'
I want to copy a spreadsheet from another location and insert in the new folders that I am creating. The new file name is to be created with information from the same spreadsheet.
function makeFolders(){
//Get array of folder names (fixed & variable)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var bottomRow = sheet.getMaxRows()-2;
var folderNames = sheet.getRange(2, 12, bottomRow, 1).getValues();
//If fixed name cell is blank it throws up an alert and stops
if (folderNames === "") {
SpreadsheetApp.getUi().alert('Cell A3 is blank.');
}
//If folder ID cell is blank it throws up an alert and stops
var folderUrl = sheet.getRange(3,14).getValue();
if (folderUrl === "") {
SpreadsheetApp.getUi().alert('Cell C3 is blank.');
}
//If fixed name cell and file URL aren't empty, run the program
if (folderNames !== "" && folderUrl !== "") {
//Get ID from folder URL
var folderId = folderUrl.match(/[-\w]{25,}/);
//Get master folder
var getRootFolderId = DriveApp.getFolderById(folderId);
//Copy master n times and rename each copy with the new name
//stops when it comes to a blank cell
for (n=0;n<bottomRow;n++){
if(folderNames[n] == ""){break;}
var newFolder = getRootFolderId.createFolder(folderNames[n]);
}
ss.toast("Your folders have been made! :)","Finished",3);
}
}**strong text**
How do I avoid creating duplicate folders each time the script is run?
For example if a folder named '1808' has already been created, I don't
want the script to create '1808(1)'
You could get a list of all the folder names and loop through them to check if any match the new folder name! Something like:
function MakeNewFolders(rootFolderID, folderNames)
// Get master folder
var rootFolder = DriveApp get folder (rootFolderID)
var subfolders = rootFolder.getFolders()
var alreadyExists = false;
var newFolder;
// Check if any subfolder already exists
// loop for folders first, to minimize GAS function calls
while (subfolders.hasNext()) {
var subfolderName = subfolders.next().getName();
loop (each folder in folderNames) {
if (subfolderName == newFolderName)
alreadyExists = true;
}
if (!alreadyExists)
newFolder = rootFolder.createFolder(newFolderName)
}
If there are a TON of folders you need to loop through (more than 60-ish), here is a code snippet you might find handy. Basically, the original Google example for getting a list of subfolders runs twice as slow as necessary by checking for folder.hasNext(), when you can just use a try-catch block and ignore the "you've reached the end!" exception it throws. Should cut execution time in half! :)
I want to copy a spreadsheet from another location and insert in the
new folders that I am creating. The new file name is to be created
with information from the same spreadsheet.
Try something like this!
function CopyFile(originalFileID, destinationFolderID) {
var destinationFolder = DriveApp.getFolderById(destinationFolderID) ;
var fileToCopy = DriveApp.getFileById(originalFileID)
var copiedFile = fileToCopy.makeCopy(<new name>, destinationFolder)
fileToCopy.setTrashed(true); // alternatively, you can use
// Drive.Files.remove(originalFileID);
}
Hope this helps! Been a while since I used GAS, hopefully this compiles :)
You could add a timestamp to the name of the new folder created. Each timestamp would be unique to the millesecond:
function uniqueFolderName() {
var folderName = "1808";
var formattedDate = Utilities.formatDate(new Date(), "GMT", "yyyyMMddHHmmssSSS");
var newFolderName = folderName + formattedDate;
Logger.log(newFolderName);
}