The Situation: I have data on a Google Sheet. I am using that data to fill in a template Google Doc, and the newly-created Doc needs to be saved into a specific Google Drive folder based on two criteria. The criteria are a Name and a Month, both of which are variables on the Sheet.
The Problem: I can't figure out how to save the doc in the right place, or if it's even possible with Google Apps Script / Google Drive. Two of the columns in my Sheet have data with a person's Name and Month. I want to search first for a folder by Name, and then within that folder, I want to search by Month using the row data from the Sheet. The doc would be saved into this Month subfolder within the Name folder.
Current State: My code pulls data from the Sheet, inserts it into the template, and names the new doc what I tell it to. I was able to tell it where to save this new doc using
const destinationFolder = DriveApp.getFolderById('ID_GOES_HERE');
but there are multiple Names and multiple Months, so I can't use IDs for all of them. I want the code to dynamically find the correct subfolder based on Name and Month variable in the Sheet.
Is this even possible?
Here's a snip of my current code, I removed IDs and such for anonymity:
/* Creates a menu item in the Spreadsheet that triggers population of the coaching package documents. */
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('AutoFill Template');
menu.addItem('Create New Document', 'createNewGoogleDocs');
menu.addToUi();
}
/* Loops through spreadsheet rows. If there is no Document Link, a new document will be generated. */
function createNewGoogleDocs() {
const googleDocTemplate = DriveApp.getFileById('ID_GOES_HERE');
const destinationFolder = DriveApp.getFolderById('ID_GOES_HERE');
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Responses');
const rows = sheet.getDataRange().getValues();
rows.forEach(function(row, index) {
if (index === 0) return;
if (row[13]) return;
const copy = googleDocTemplate.makeCopy(`QCP - ${row[4]} - ${row[2]}`, destinationFolder);
const doc = DocumentApp.openById(copy.getId());
const body = doc.getBody();
body.replaceText('{{Title Name}}', row[4]);
body.replaceText('{{Month}}', row[2]);
body.replaceText('{{Name}}', row[3]);
body.replaceText('{{Desired 1}}', row[5]);
body.replaceText('{{Desired 2}}', row[6]);
doc.saveAndClose();
const url = doc.getUrl();
sheet.getRange(index 1, 14).setValue(url);
});
}
EDIT for anyone who has a similar problem in the future, this was my result! Thank you to both Mike and Yuri.
const parent_folder = DriveApp.getFoldersByName(row[3]).next();
const subfolder = parent_folder.getFoldersByName(row[2]).next();
const destinationFolder = DriveApp.getFoldersByName(subfolder).next();
CodePudding user response:
Basically you can get a folder by a name this way:
const destinationFolder = DriveApp.getFoldersByName(name).next();
To get a subfolder within a parent folder it could be somethgn like this:
const parent_folder = DriveApp.getFoldersByName(name).next();
const subfolder = parent_folder.getFoldersByName(name).next();
CodePudding user response:
Try with
const destinationFolder = DriveApp.getFolderById(getChildId(getParentId(row[4]),row[2]));
and add functions (they will create the folders in needed)
function getParentId(name){
// create if absent in drive
var id;
var folders = DriveApp.getFoldersByName(name);
if (folders.hasNext()) {
var folder = folders.next();
id = folder.getId(); }
else {
var folder = DriveApp.createFolder(name);
id = folder.getId();
}
return id;
}
function getChildId(parentId,name){
// create if absent in parent folder
var parent = DriveApp.getFolderById(parentId);
var id;
var folders = parent.getFoldersByName(name);
if (folders.hasNext()) {
var folders = folders.next();
id = folder.getId(); }
else {
var folder = parent.createFolder(name);
id = folder.getId();
}
return id;
}