I have a code that creates a Google Doc from data on a sheet using a template. After creation, I want that document to save into a specific subfolder on a Shared Drive that I have editor access to.
Specifically, I have it check for the person's name {{Name}}
which is row[3]
in the sheet. I then have it check for the month {{Month}}
which is row[2]
in the sheet, and it's supposed to save within the month subfolder. However, my problem is that I keep getting the error Exception: Cannot retrieve the next object: iterator has reached the end. It works for the first NAME folder and then breaks for all after that.
I searched stackoverflow for this issue because it is a common one. It seems that my code is missing hasNext()
function to actually perform the iteration. However, I can't figure out how to add this to my code (I am a newbie). I've tried several variations of while and if statements but they always throw various errors.
Here is my current code WITHOUT the hasNext()
, can someone help me correct it?
/* Loops through spreadsheet rows. If there is no Document Link, a new document will be generated. */
function createNewGoogleDocs() {
const googleDocTemplate = DriveApp.getFileById('TEMPLATE_ID_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 parent_folder = DriveApp.getFoldersByName(row[3]).next();
const subfolder = parent_folder.getFoldersByName(row[2]).next();
const destinationFolder = DriveApp.getFoldersByName(subfolder).next();
const copy = googleDocTemplate.makeCopy(`QCP - ${row[3]} - ${row[2]}`, destinationFolder);
const doc = DocumentApp.openById(copy.getId());
const body = doc.getBody();
body.replaceText('{{Month}}', row[2]);
body.replaceText('{{Name}}', row[3]);
body.replaceText('{{Improvement 1}}', row[11]);
body.replaceText('{{Improvement 2}}', row[12]);
doc.saveAndClose();
const url = doc.getUrl();
sheet.getRange(index 1, 14).setValue(url);
});
}
I was able to find the answer thanks to Yuri. The problem was that the subfolder had a space the data did not. To correct this problem, Yuri showed me how to make my code create the folder if it doesn't exist. Please see below for fixed code.
/* Loops through spreadsheet rows. If there is no Document Link, a new document will be generated. */
function createNewGoogleDocs() {
const googleDocTemplate = DriveApp.getFileById('TEMPLATE_ID_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 parent_folder = DriveApp.getFoldersByName(row[3]).next();
try {
subfolder = parent_folder.getFoldersByName(row[2]).next();
}
catch(e) {
subfolder = parent_folder.createFolder(row[2]);
}
const copy = googleDocTemplate.makeCopy(`QCP - ${row[3]} - ${row[2]}`, subfolder);
const doc = DocumentApp.openById(copy.getId());
const body = doc.getBody();
body.replaceText('{{Month}}', row[2]);
body.replaceText('{{Name}}', row[3]);
body.replaceText('{{Improvement 1}}', row[11]);
body.replaceText('{{Improvement 2}}', row[12]);
doc.saveAndClose();
const url = doc.getUrl();
sheet.getRange(index 1, 14).setValue(url);
});
}
CodePudding user response:
As a guess. Try to change these lines:
const subfolder = parent_folder.getFoldersByName(row[2]).next();
const destinationFolder = DriveApp.getFoldersByName(subfolder).next();
const copy = googleDocTemplate.makeCopy(`QCP - ${row[3]} - ${row[2]}`, destinationFolder);
With:
try { const subfolder = parent_folder.getFoldersByName(row[2]).next() }
catch(e) { const subfolder = parent_folder.createFolder(row[2]) }
const copy = googleDocTemplate.makeCopy(`QCP - ${row[3]} - ${row[2]}`, subfolder);
It tries to get the subfolder. In case the subfolder doesn't exists it creates the subfolder.