Google app script newbie here. I found this code which helps create folders in my personal Google drive with using inputs from Google sheet (credit: Google Sheet Community on Youtube). However, when I tried to recreate this app in a shared Google drive, it failed to run and kept creating folders in my personal drive instead. Is there anything I can change about the code to make it work in the shared drive environment instead of my own?
Thanks a lot!
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('GDrive')
.addItem('Create new Folders', 'crtGdriveFolder')
.addToUi(); }
function crtGdriveFolder() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow(); // Number of rows to process
var maxRows = Math.min(numRows,20); //Limit the number of rows to prevent enormous number of folder creations
var folderid = sheet.getRange("C2").getValue();
var root = sheet.getRange("D2").getValue();
var dataRange = sheet.getRange(startRow, 1, maxRows, 2); //startRow, startCol, endRow, endCol
var data = dataRange.getValues();
var folderIterator = DriveApp.getFoldersByName(folderid); //get the file iterator
if(!folderIterator.hasNext()) { SpreadsheetApp.getActiveSpreadsheet().toast('Folder not found!');
return; }
var parentFolder = folderIterator.next();
if(folderIterator.hasNext()) {
SpreadsheetApp.getActiveSpreadsheet().toast('Folder has a non-unique name!');
return; }
for (i in data) {
var row = data[i];
var name = row[0]; // column A
var desc = row[1]; // column B
if(root == "N" && name != "") {
var idNewFolder = parentFolder.createFolder(name).setDescription(desc).getId(); Utilities.sleep(100);
var newFolder = DriveApp.getFolderById(idNewFolder);
} if(root == "Y" && name != "") {
var idNewFolder = DriveApp.createFolder(name).setDescription(desc).getId();
Utilities.sleep(100);
var newFolder = DriveApp.getFolderById(idNewFolder);
}
}
}
DriveApp creates folders by default in your own Drive
If you want to create a folder on a shared Drive instead, you need to use the the Advanced Drive Service based on the Drive API
Make sure to enable the advanced service before using
Use the advanced option {supportsAllDrives : true}
Specify the id of the shared Drive as parents
A sample how to create a folder on the shared drive based on your code:
} if(root == "Y" && name != "") {
var optionalArgs={supportsAllDrives: true};
var resource = {
title: name,
description: desc,
mimeType: "application/vnd.google-apps.folder",
parents:[{
"id": "ID OF SHARED DRIVE"
}]
}
var idNewFolder = Drive.Files.insert(resource, null, optionalArgs).id;
Utilities.sleep(100);
var newFolder = DriveApp.getFolderById(idNewFolder);
}
Related
In Google Drive, if I want to search for all files not owned by a certain user, I would put in "-owner: somebody#gmail.com" and it will list all files that are not owned by somebody#gmail.com. Now, I would like to create an equivalent search query in a Google Apps script to do the same thing but I'm having some trouble forming it correctly. So far, I have tried
var files = operatorFolder.searchFiles('not "someUser#gmail.com" in owners');
But this doesn't seem to work. What am I missing?
Edit:
Here's a copy of the full script. It searches the folder with the given ID and saves the results into the Active google sheet with the name "File List"
function getMyFilesFromDrive() {
// Get reference to Lit Folder
var parentFolder = DriveApp.getFolderById("IDSTRING");
var childFolders = parentFolder.getFolders();
var count = 0;
// Get reference to active spreadsheet and clear it
var sheet = SpreadsheetApp.getActive().getSheetByName("File List");
sheet.clear();
// Create Header row
var header = ["Name", "Owner", "Last Modified"];
sheet.appendRow(header);
while(childFolders.hasNext())
{
var operatorFolder = childFolders.next();
Logger.log(operatorFolder.getName());
// Get File List (all files not owned by Lauren)
var files = operatorFolder.searchFiles("not 'someUser#gmail.com' in owners");
while (files.hasNext()) {
var file = files.next();
count++;
var data = [
file.getName(),
file.getOwner().getName(),
file.getLastUpdated(),
];
sheet.appendRow(data);
Logger.log("Count: " + count);
}
}
sheet.appendRow([""]);
sheet.appendRow(["File Count: " + count])
}
function getSubFolders(parent) {
parent = parent.getId();
var childFolder = DriveApp.getFolderById(parent).getFolders();
while(childFolder.hasNext()) {
var child = childFolder.next();
Logger.log(child.getName());
getSubFolders(child);
}
return;
}
I thought that 'not "somebody#gmail.com" in owners' can be used. In this case, how about the following modification using not operator? But, in this case, I thought that when the owner of file is not found, an error occurs. So, as a sample script, when the owner of file is checked, how about the following modification?
From:
var files = operatorFolder.searchFiles('not "somebody#gmail.com" in owners');
To:
var files = operatorFolder.searchFiles('not "somebody#gmail.com" in owners'); // or var files = operatorFolder.searchFiles("not 'somebody#gmail.com' in owners");
while (files.hasNext()) {
var file = files.next();
var owner = file.getOwner();
if (owner) {
console.log(owner.getEmail())
}
}
Reference:
Search query terms and operators
Added:
From your showing script, I thought that the reason for your current issue might be due to as follows.
Modification points:
In the current stage, for example, when the owner of the original file is not you, the file is existing in your Google Drive as the shortcut file. In this case, the owner of the shortcut file is you. By this, "not 'someUser#gmail.com' in owners" cannot be used. This situation appears when the files are retrieved from a specific folder. For example, when the files are retrieved from all Google Drive like DriveApp.searchFiles('not "somebody#gmail.com" in owners'), this can be worked. In the current stage, it seems that there is no method for directly excluding the owner of the original file by the email address in the search query, when the file list is retrieved from a specific folder.
In your script, it seems that the subfolders are not retrieved.
When appendRow is used in the loop, the process cost becomes high. Ref In this modification, the retrieved values are put using one call of setValues.
When these points are reflected in a sample script, it becomes as follows.
Modified script:
function sample1() {
var parentFolder = DriveApp.getFolderById("###"); // Please set the folder ID.
var excludeOwnerEmail = "someUser#gmail.com";
var searchFlies = (folder, res = []) => {
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
file = file.getMimeType() == MimeType.SHORTCUT ? DriveApp.getFileById(file.getTargetId()) : file;
var owner = file.getOwner() ? file.getOwner().getEmail() : "";
if (owner && owner != excludeOwnerEmail) {
res.push([file.getName(), file.getOwner().getName(), file.getLastUpdated()]);
}
}
var folders = folder.getFolders();
while (folders.hasNext()) searchFlies(folders.next(), res);
return res;
}
var v = searchFlies(parentFolder);
var header = ["Name", "Owner", "Last Modified"];
var values = [header, ["File Count: " + v.length, ...Array(header.length - 1).fill(null)], ...v];
var sheet = SpreadsheetApp.getActive().getSheetByName("File List");
sheet.clear();
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
Or, if you want to retrieve the file list just under the specific folder, how about the following sample script?
function sample2() {
var parentFolder = DriveApp.getFolderById("###"); // Please set the folder ID.
var excludeOwnerEmail = "someUser#gmail.com";
var res = [];
var files = parentFolder.getFiles();
while (files.hasNext()) {
var file = files.next();
file = file.getMimeType() == MimeType.SHORTCUT ? DriveApp.getFileById(file.getTargetId()) : file;
var owner = file.getOwner() ? file.getOwner().getEmail() : "";
if (owner && owner != excludeOwnerEmail) {
res.push([file.getName(), file.getOwner().getName(), file.getLastUpdated()]);
}
}
var header = ["Name", "Owner", "Last Modified"];
var values = [header, ["File Count: " + res.length, ...Array(header.length - 1).fill(null)], ...res];
var sheet = SpreadsheetApp.getActive().getSheetByName("File List");
sheet.clear();
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
Google app script newbie here. I found this code which helps create folders in my personal Google drive with using inputs from Google sheet (credit: Google Sheet Community on Youtube). However, when I tried to recreate this app in a shared Google drive, it failed to run and kept creating folders in my personal drive instead. Is there anything I can change about the code to make it work in the shared drive environment instead of my own?
Thanks a lot!
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('GDrive')
.addItem('Create new Folders', 'crtGdriveFolder')
.addToUi(); }
function crtGdriveFolder() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow(); // Number of rows to process
var maxRows = Math.min(numRows,20); //Limit the number of rows to prevent enormous number of folder creations
var folderid = sheet.getRange("C2").getValue();
var root = sheet.getRange("D2").getValue();
var dataRange = sheet.getRange(startRow, 1, maxRows, 2); //startRow, startCol, endRow, endCol
var data = dataRange.getValues();
var folderIterator = DriveApp.getFoldersByName(folderid); //get the file iterator
if(!folderIterator.hasNext()) { SpreadsheetApp.getActiveSpreadsheet().toast('Folder not found!');
return; }
var parentFolder = folderIterator.next();
if(folderIterator.hasNext()) {
SpreadsheetApp.getActiveSpreadsheet().toast('Folder has a non-unique name!');
return; }
for (i in data) {
var row = data[i];
var name = row[0]; // column A
var desc = row[1]; // column B
if(root == "N" && name != "") {
var idNewFolder = parentFolder.createFolder(name).setDescription(desc).getId(); Utilities.sleep(100);
var newFolder = DriveApp.getFolderById(idNewFolder);
} if(root == "Y" && name != "") {
var idNewFolder = DriveApp.createFolder(name).setDescription(desc).getId();
Utilities.sleep(100);
var newFolder = DriveApp.getFolderById(idNewFolder);
}
}
}
DriveApp creates folders by default in your own Drive
If you want to create a folder on a shared Drive instead, you need to use the the Advanced Drive Service based on the Drive API
Make sure to enable the advanced service before using
Use the advanced option {supportsAllDrives : true}
Specify the id of the shared Drive as parents
A sample how to create a folder on the shared drive based on your code:
} if(root == "Y" && name != "") {
var optionalArgs={supportsAllDrives: true};
var resource = {
title: name,
description: desc,
mimeType: "application/vnd.google-apps.folder",
parents:[{
"id": "ID OF SHARED DRIVE"
}]
}
var idNewFolder = Drive.Files.insert(resource, null, optionalArgs).id;
Utilities.sleep(100);
var newFolder = DriveApp.getFolderById(idNewFolder);
}
I wanted to create a bulk of folders in my google drive using scripts in google spreadsheet. Fortunately, I have found the script I have been looking for. However, upon executing the script, it gave a notice that (I forgot the exact message) I have reached the maximum number of folders to create. So it just stops. Here is the code. I hope someone could tell me how can I or what should I change for it to create folders as required.
function onOpen() { //This is the new standard script for the onOpen trigger that creates a menu item.
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('GDrive')
.addItem('Create new Folders', 'crtGdriveFolder')
.addToUi();
}
function crtGdriveFolder() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var levelInput = Browser.inputBox('input Level', Browser.Buttons.OK_CANCEL);
var Level = levelInput * 2 + 1;
var numRows = sheet.getLastRow(); // Number of rows to process
var dataRange = sheet.getRange(3, Number(Level)-1, numRows, Number(Level)); //startRow, startCol, endRow, endCol
var data = dataRange.getValues();
var parentFolderID = new Array();
for(var i in data)
{
parentFolderID[i] = data [i][0];
if (data [i][0] == "")
{
parentFolderID[i] = parentFolderID[i-1];
}
}
for(var i in data){
if (data [i][1] !== "")
{
var theParentFolder = DriveApp.getFolderById(parentFolderID[i]);
var folderName = data[i][1];
var theChildFolder = theParentFolder.createFolder(folderName);
// Utilities.sleep(100);
var newFolderID = sheet.getRange(Number(i)+3,Number(Level)+1);
var folderIdValue = theChildFolder.getId();
newFolderID.setValue(folderIdValue);
var addLink = sheet.getRange(Number(i)+3,Number(Level));
var value = addLink.getDisplayValue();
addLink.setValue('=hyperlink("https://drive.google.com/corp/drive/folders/'+ folderIdValue +'","' + value + '")');
}
}
}```
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/QKKLr.jpg
I am trying to move few folders and its contents from My Drive to Shared Drive (specific location). I am able to execute similar code without any issues if folders are moved from MyDrive to another MyDrive location. However, it is not the same for Shared Drive. I understand that I cannot execute "addFolder() or addFile()", so upon reading some forums, it appears that I have to use makeCopy() instead. I have never executed scripts in Shared Drive but heard the behavior is different from My Drive.
I am using the code below. My issues are as follows:
1. makeCopy() does not seem to work.
2. How can I get the creation date from Shared Drive
Here's my test file: https://docs.google.com/spreadsheets/d/10xznoTAH2yS-Xnf-b3cCc0j8vxa9jS10WP1HjQapzNw/edit?usp=sharing
Your input and help is greatly appreciated!
function moveFolders() {
var ss = SpreadsheetApp.openById('sheetIDhere');
var sheet = ss.getSheetByName('Sheet11');
var range = sheet.getRange(2,1, sheet.getLastRow(), sheet.getLastColumn());
var values = range.getValues();
for (var i = 0; i <= values.length-1; i++) {
var folderid = values[i][0];
var sdDriveId = values[i][1];
var moveDate = values[i][2];
var comments = values[i][3];
if (moveDate != "" ) {continue;} // if date exists, skip.
if (folderid == "" || sdDriveId == "") { // if source and target ids are missing, post message
sheet.getRange(i+2,4).setValue('Missing Value');
}
else {
var source_Folder = DriveApp.getFolderById(folderid).getFiles(); //source folder
var dest_Folder = DriveApp.getFolderById(sdDriveId); //destination folder
while (source_Folder.hasNext()) {
var file = source_Folder.next();
var destination = file.makeCopy(name,dest_Folder);
var date = destination.getDateCreated();
sheet.getRange(i+2,4,1,2).setValues([ [date, "Processed"] ]);
}
}
}
}
I am trying to write a google script that will allow me to go into my google drive folder called "MeadJohsnon" and pull 'Temperature Calibration.csv' to google sheets. I have never used google script before. Currently I have the "Save Email and Attachment" Add-ons. This add-on is pulling .cvs files that my team is sending me from the field. They use "TapForms" and then send the form via email to my gmail. So, I got the email sending that attachment to my google drive but I need help with the script, so Drive will automatically get those .cvs files and put the information into one google sheet. I say ONE google sheet because although I have a team sending in forms, all the forms have the same information on them.
This is what I have done so far. The fourth line gives me a
function loadingCSV() {
var ss=SpreadsheetApp.getActiveSpreadsheet()
var sht=ss.getActiveSheet();
sht.clearContents();
var data = loadFile();
var dataA =Utilities.parseCsv(data);
var rng = sht.getRange(1, 1, dataA.length, dataA[0].length);
rng.setValues(dataA);
}
I would just like feedback on how to fix my error or what I could do instead. As stated this is my first time using google script, my specialty is ASP.net lol not script. Thank you.
function loadingCSV() {
var ss=SpreadsheetApp.getActiveSpreadsheet()
var sht=ss.getActiveSheet();
sht.clearContents();
var data = loadFile();
var dataA =Utilities.parseCsv(data);
var rng = sht.getRange(1, 1, dataA.length, dataA[0].length);
rng.setValues(dataA);
}
function loadFile(filename,folderID)
{
var filename = (typeof(filename) !== 'undefined')? filename : 'Temperature Calibration.csv';
var folderID = (typeof(folderID) !== 'undefined')? folderID : '0B8m9xkDP_TJxUUlueHhXOWJMbjg';
var fldr = DriveApp.getFolderById(folderID);
var file = fldr.getFilesByName(filename);
var s = '';
while(file.hasNext())
{
var fi = file.next();
var target = fi.getName();
if(target == filename)
{
s = fi.getBlob().getDataAsString();
}
}
return s;
}
Okay this will append the files to the active spreadsheet you'll probably have to open the spreadsheet by id and use getSheetByName to get the sheet you want because this spreadsheet probably won't be active all the time when the trigger is running. I assume the the files all end in .csv. I rename them to .old after reading the data so that the program won't read them multiple times.
function appendingCSV() {
var ss=SpreadsheetApp.getActiveSpreadsheet()
var sht=ss.getActiveSheet();
var drng = sht.getDataRange();
var lastRow = drng.getLastRow();
var data = loadFiles();
var dataA =Utilities.parseCsv(data);
if(dataA.length>0)
{
var rng = sht.getRange(lastRow + 1, 1, dataA.length, dataA[0].length);
rng.setValues(dataA);
}
else
{
SpreadsheetApp.getUi().alert('No Data Returned from LoadFiles');
}
}
function loadFiles(folderID)
{
var folderID = (typeof(folderID) !== 'undefined')? folderID : '0B8m9xkDP_TJxUUlueHhXOWJMbjg';
var fldr = DriveApp.getFolderById(folderID);
var files = fldr.getFiles();
var s='';
var re = /^.*\.csv$/i;
while (files.hasNext())
{
var file = files.next();
var filename = file.getName();
if(filename.match(re))
{
s += file.getBlob().getDataAsString() + '\n';
file.setName(filename.slice(0,-3) + 'old');
}
}
return s;
}