Need to optimise Google Apps Script to reduce script runtime - google-apps-script

I've constructed a "Conveyor" style system within Google Sheets to move users from further slots into closer slots when they become available.
Screenshot of the Google Sheets layout where this is being implemented.
For example, if someone was in "User 1" but then left, it moves the user in "User 2" into "User 1", the user in "User 3" moves to "User 2", etc., pushing them along the chain, ensuring that the slots are used in order.
As the requirements are time-based, it's often the case that Users 1, 2 and 3 are removed at the same time, meaning that one person is left in the "User 4" slot. Using the current script, it will move them from "User 4" -> "User 3" -> "User 2" -> "User 1".
Additionally, due to some formatting I have set up (Index Matching), I need the cells to display the word "None" instead of staying blank. I've been able to do this easily by checking if the cell is blank, and if so, setting the value to "None".
The script works, but it is really slow. The total script execution time is over 14 seconds.
Here's the scripting I'm using:
function conveyor() {
var s = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('UsernameSheet');
// LOOP 1
var Username1Val = s.getRange('C3').getDisplayValue();
var Username2Val = s.getRange('I3').getDisplayValue();
var Username3Val = s.getRange('O3').getDisplayValue();
var Username4Val = s.getRange('U3').getDisplayValue();
var Username1 = s.getRange('C3')
var Username2 = s.getRange('I3')
var Username3 = s.getRange('O3')
var Username4 = s.getRange('U3')
if (Username3Val == 'None') {
FourtoThree();
}
if (Username1.isBlank()) {
Username1.setValue('None');
}
if (Username2.isBlank()) {
Username2.setValue('None');
}
if (Username3.isBlank()) {
Username3.setValue('None');
}
if (Username4.isBlank()) {
Username4.setValue('None');
}
if (Username2Val == 'None') {
ThreetoTwo();
}
if (Username1.isBlank()) {
Username1.setValue('None');
}
if (Username2.isBlank()) {
Username2.setValue('None');
}
if (Username3.isBlank()) {
Username3.setValue('None');
}
if (Username4.isBlank()) {
Username4.setValue('None');
}
if (Username1Val == 'None') {
TwotoOne();
}
if (Username1.isBlank()) {
Username1.setValue('None');
}
if (Username2.isBlank()) {
Username2.setValue('None');
}
if (Username3.isBlank()) {
Username3.setValue('None');
}
if (Username4.isBlank()) {
Username4.setValue('None');
}
// LOOP 2
var Username1Val = s.getRange('C3').getDisplayValue();
var Username2Val = s.getRange('I3').getDisplayValue();
var Username3Val = s.getRange('O3').getDisplayValue();
var Username4Val = s.getRange('U3').getDisplayValue();
var Username1 = s.getRange('C3')
var Username2 = s.getRange('I3')
var Username3 = s.getRange('O3')
var Username4 = s.getRange('U3')
if (Username3Val == 'None') {
FourtoThree();
}
if (Username1.isBlank()) {
Username1.setValue('None');
}
if (Username2.isBlank()) {
Username2.setValue('None');
}
if (Username3.isBlank()) {
Username3.setValue('None');
}
if (Username4.isBlank()) {
Username4.setValue('None');
}
if (Username2Val == 'None') {
ThreetoTwo();
}
if (Username1.isBlank()) {
Username1.setValue('None');
}
if (Username2.isBlank()) {
Username2.setValue('None');
}
if (Username3.isBlank()) {
Username3.setValue('None');
}
if (Username4.isBlank()) {
Username4.setValue('None');
}
if (Username1Val == 'None') {
TwotoOne();
}
if (Username1.isBlank()) {
Username1.setValue('None');
}
if (Username2.isBlank()) {
Username2.setValue('None');
}
if (Username3.isBlank()) {
Username3.setValue('None');
}
if (Username4.isBlank()) {
Username4.setValue('None');
}
// LOOP 3
var Username1Val = s.getRange('C3').getDisplayValue();
var Username2Val = s.getRange('I3').getDisplayValue();
var Username3Val = s.getRange('O3').getDisplayValue();
var Username4Val = s.getRange('U3').getDisplayValue();
var Username1 = s.getRange('C3')
var Username2 = s.getRange('I3')
var Username3 = s.getRange('O3')
var Username4 = s.getRange('U3')
if (Username3Val == 'None') {
FourtoThree();
}
if (Username1.isBlank()) {
Username1.setValue('None');
}
if (Username2.isBlank()) {
Username2.setValue('None');
}
if (Username3.isBlank()) {
Username3.setValue('None');
}
if (Username4.isBlank()) {
Username4.setValue('None');
}
if (Username2Val == 'None') {
ThreetoTwo();
}
if (Username1.isBlank()) {
Username1.setValue('None');
}
if (Username2.isBlank()) {
Username2.setValue('None');
}
if (Username3.isBlank()) {
Username3.setValue('None');
}
if (Username4.isBlank()) {
Username4.setValue('None');
}
if (Username1Val == 'None') {
TwotoOne();
}
if (Username1.isBlank()) {
Username1.setValue('None');
}
if (Username2.isBlank()) {
Username2.setValue('None');
}
if (Username3.isBlank()) {
Username3.setValue('None');
}
if (Username4.isBlank()) {
Username4.setValue('None');
}
}
function FourtoThree() {
var s = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('UsernameSheet');
var Username3Name = s.getRange('O3');
var Username3NameVal = s.getRange('O3').getDisplayValue();
var Username3Start = s.getRange('O4');
var Username3StartVal = s.getRange('O4').getDisplayValue();
var Username3Finish = s.getRange('O5');
var Username3FinishVal = s.getRange('O5').getDisplayValue();
var Username3Break = s.getRange('Q7');
var Username3BreakVal = s.getRange('Q7').getDisplayValue();
var Username3Busy = s.getRange('Q6');
var Username3BusyVal = s.getRange('Q6').getDisplayValue();
var Username4Name = s.getRange('U3');
var Username4NameVal = s.getRange('U3').getDisplayValue();
var Username4Start = s.getRange('U4');
var Username4StartVal = s.getRange('U4').getDisplayValue();
var Username4Finish = s.getRange('U5');
var Username4FinishVal = s.getRange('U5').getDisplayValue();
var Username4Break = s.getRange('W7');
var Username4BreakVal = s.getRange('W7').getDisplayValue();
var Username4Busy = s.getRange('W6');
var Username4BusyVal = s.getRange('W6').getDisplayValue();
Username3Name.setValue(Username4NameVal);
Username3Start.setValue(Username4StartVal);
Username3Finish.setValue(Username4FinishVal);
Username3Break.setValue(Username4BreakVal);
Username3Busy.setValue(Username4BusyVal);
Username4Name.clearContent();
Username4Start.clearContent();
Username4Finish.clearContent();
Username4Break.clearContent();
Username4Busy.clearContent();
}
function ThreetoTwo() {
var s = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('UsernameSheet');
var Username2Name = s.getRange('I3');
var Username2NameVal = s.getRange('I3').getDisplayValue();
var Username2Start = s.getRange('I4');
var Username2StartVal = s.getRange('I4').getDisplayValue();
var Username2Finish = s.getRange('I5');
var Username2FinishVal = s.getRange('I5').getDisplayValue();
var Username2Break = s.getRange('K7');
var Username2BreakVal = s.getRange('K7').getDisplayValue();
var Username2Busy = s.getRange('K6');
var Username2BusyVal = s.getRange('K6').getDisplayValue();
var Username3Name = s.getRange('O3');
var Username3NameVal = s.getRange('O3').getDisplayValue();
var Username3Start = s.getRange('O4');
var Username3StartVal = s.getRange('O4').getDisplayValue();
var Username3Finish = s.getRange('O5');
var Username3FinishVal = s.getRange('O5').getDisplayValue();
var Username3Break = s.getRange('Q7');
var Username3BreakVal = s.getRange('Q7').getDisplayValue();
var Username3Busy = s.getRange('Q6');
var Username3BusyVal = s.getRange('Q6').getDisplayValue();
Username2Name.setValue(Username3NameVal);
Username2Start.setValue(Username3StartVal);
Username2Finish.setValue(Username3FinishVal);
Username2Break.setValue(Username3BreakVal);
Username2Busy.setValue(Username3BusyVal);
Username3Name.clearContent();
Username3Start.clearContent();
Username3Finish.clearContent();
Username3Break.clearContent();
Username3Busy.clearContent();
}
function TwotoOne() {
var s = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('UsernameSheet');
var Username1Name = s.getRange('C3');
var Username1NameVal = s.getRange('C3').getDisplayValue();
var Username1Start = s.getRange('C4');
var Username1StartVal = s.getRange('C4').getDisplayValue();
var Username1Finish = s.getRange('C5');
var Username1FinishVal = s.getRange('C5').getDisplayValue();
var Username1Break = s.getRange('E7');
var Username1BreakVal = s.getRange('E7').getDisplayValue();
var Username1Busy = s.getRange('E6');
var Username1BusyVal = s.getRange('E6').getDisplayValue();
var Username2Name = s.getRange('I3');
var Username2NameVal = s.getRange('I3').getDisplayValue();
var Username2Start = s.getRange('I4');
var Username2StartVal = s.getRange('I4').getDisplayValue();
var Username2Finish = s.getRange('I5');
var Username2FinishVal = s.getRange('I5').getDisplayValue();
var Username2Break = s.getRange('K7');
var Username2BreakVal = s.getRange('K7').getDisplayValue();
var Username2Busy = s.getRange('K6');
var Username2BusyVal = s.getRange('K6').getDisplayValue();
Username1Name.setValue(Username2NameVal);
Username1Start.setValue(Username2StartVal);
Username1Finish.setValue(Username2FinishVal);
Username1Break.setValue(Username2BreakVal);
Username1Busy.setValue(Username2BusyVal);
Username2Name.clearContent();
Username2Start.clearContent();
Username2Finish.clearContent();
Username2Break.clearContent();
Username2Busy.clearContent();
}
What the script does is Firstly runs to check if the usernames 1-4 have a blank cell. If they do, they set the values to "None".
Then, an IF statement runs to check if Username 3 = None, if it does, it then runs function FourtoThree, which in itself moves the values from Username 4 to Username 3. It then checks Username 2, then username 1, and does the same type of functions of moving the data along if the value is "None". This whole function then runs 3 times, the maximum number of moves the conveyor system would need to complete.
I'm still a novice with Google Apps Script (well, JavaScript in general), so I threw this together and was happy it worked.
Now, the sluggish runtime of the script is becoming problematic for its use-scenario , and I'm looking for ways to optimize this, please.
I'm not at all expecting anyone to write me a script that would alleviate my issues, but if anyone could suggest an example of a function that could achieve what I'm trying to do, and/or an idea of how to implement it.

Here is a prototype you can try but I don't use "None" just blank
function conveyor() {
var s = SpreadsheetApp.getActiveSpreadsheet();
// Get range C3:W7
var r = s.getSheetByName('Test').getRange(3,3,5,21);
var users = r.getValues();
var formulas = r.getFormulas();
for( var i=0; i<13; i+=6 ) { // Only do it 3 times
if( users[0][i] === "" ) {
users[0][i] = users[0][i+6]; // Username
users[0][i+6] = "";
users[1][i] = users[1][i+6]; // Start time
users[1][i+6] = "";
users[2][i] = users[2][i+6]; // Finish time
users[2][i+6] = "";
users[3][i+2] = users[3][i+8]; // Busy
users[3][i+8] = false;
users[4][i+2] = users[4][i+8]; // Break
users[4][i+8] = false;
}
}
for( var i=0; i<users.length; i++ ) {
for( var j=0; j<users[0].length; j++ ) {
if( formulas[i][j] !== "" ) users[i][j] = formulas[i][j].toString();
}
}
r.setValues(users);
}

Related

My website becomes unresponsive when dealing 1000 rows excel file

I am uploading data from an excel file into my website using input html button.
and then convert the data into json and then I map it with local external metadata.
Finally view it using the id.
My website becomes unresponsive & sometimes takes a lot of time processing. Please help
function ExportToTable() {
var regex = /^([a-zA-Z0-9\s_\\.\-:()])+(.xlsx|.xls)$/;
/*Checks whether the file is a valid excel file*/
if (regex.test($("#excelfile").val().toLowerCase())) {
var xlsxflag = false; /*Flag for checking whether excel is .xls format or .xlsx format*/
if ($("#excelfile").val().toLowerCase().indexOf(".xlsx") > 0) {
xlsxflag = true;
}
/*Checks whether the browser supports HTML5*/
if (typeof (FileReader) != "undefined") {
var reader = new FileReader();
reader.onload = function (e) {
var data = e.target.result;
/*Converts the excel data in to object*/
if (xlsxflag) {
var workbook = XLSX.read(data, { type: 'binary' });
}
else {
var workbook = XLS.read(data, { type: 'binary' });
}
/*Gets all the sheetnames of excel in to a variable*/
var sheet_name_list = workbook.SheetNames;
console.log(sheet_name_list);
var cnt = 0; /*This is used for restricting the script to consider only first
sheet of excel*/
sheet_name_list.forEach(function (y) { /*Iterate through all sheets*/
/*Convert the cell value to Json*/
if (xlsxflag) {
var exceljson = XLSX.utils.sheet_to_json(workbook.Sheets[y]);
}
else {
var exceljson = XLS.utils.sheet_to_row_object_array(workbook.Sheets[y]);
}
//Download & View Subscriptions
if (exceljson.length > 0 && cnt == 1) {
metadata = [];
fetch("metadata.json")
.then(response => response.json())
.then(json => {
metadata = json;
console.log(metadata);
user_metadata1 = [], obj_m_processed = [];
for (var i in exceljson) {
var obj = { email: exceljson[i].email, name: exceljson[i].team_alias, id: exceljson[i].autodesk_id };
for (var j in metadata) {
if (exceljson[i].email == metadata[j].email) {
obj.GEO = metadata[j].GEO;
obj.COUNTRY = metadata[j].COUNTRY;
obj.CITY = metadata[j].CITY;
obj.PROJECT = metadata[j].PROJECT;
obj.DEPARTMENT = metadata[j].DEPARTMENT;
obj.CC=metadata[j].CC;
obj_m_processed[metadata[j].email] = true;
}
}
obj.GEO = obj.GEO || '-';
obj.COUNTRY = obj.COUNTRY || '-';
obj.CITY = obj.CITY || '-';
obj.PROJECT = obj.PROJECT || '-';
obj.DEPARTMENT = obj.DEPARTMENT || '-';
obj.CC = obj.CC || '-';
user_metadata1.push(obj);
}
for (var j in metadata) {
if (typeof obj_m_processed[metadata[j].email] == 'undefined') {
user_metadata1.push({ email: metadata[j].email, name: metadata[j].name, id: metadata[j].autodesk_id,
GEO: metadata[j].GEO,
COUNTRY : metadata[j].COUNTRY,
CITY : metadata[j].CITY,
PROJECT : metadata[j].PROJECT,
DEPARTMENT : metadata[j].DEPARTMENT,
CC:metadata[j].CC
});
}
}
document.getElementById("headings4").innerHTML = "MetaData Mapping";
BindTable(user_metadata1, '#user_metadata1
cnt++;
});
$('#exceltable').show();
}
if (xlsxflag) {/*If excel file is .xlsx extension than creates a Array Buffer from excel*/
reader.readAsArrayBuffer($("#excelfile")[0].files[0]);
}
else {
reader.readAsBinaryString($("#excelfile")[0].files[0]);
}
}
else {
alert("Sorry! Your browser does not support HTML5!");
}
}
else {
alert("Please upload a valid Excel file!");
}
}
Here is how the json is bind after mapping metadata
function BindTable(jsondata, tableid) {/*Function used to convert the JSON array to Html Table*/
var columns = BindTableHeader(jsondata, tableid); /*Gets all the column headings of Excel*/
for (var i = 0; i < jsondata.length; i++) {
var row$ = $('<tr/>');
for (var colIndex = 0; colIndex < columns.length; colIndex++) {
var cellValue = jsondata[i][columns[colIndex]];
if (cellValue == null)
cellValue = "";
row$.append($('<td/>').html(cellValue));
}
$(tableid).append(row$);
}
}
function BindTableHeader(jsondata, tableid) {/*Function used to get all column names from JSON and bind the html table header*/
var columnSet = [];
var headerTr$ = $('<tr/>');
for (var i = 0; i < jsondata.length; i++) {
var rowHash = jsondata[i];
for (var key in rowHash) {
if (rowHash.hasOwnProperty(key)) {
if ($.inArray(key, columnSet) == -1) {/*Adding each unique column names to a variable array*/
columnSet.push(key);
headerTr$.append($('<th/>').html(key));
}
}
}
}
$(tableid).append(headerTr$);
return columnSet;
}

How do I create a single PDF from multiple instances of a person's name in a Google Sheet?

Every Friday our students submit an electronic log of what they did in an extra-curricular activity using a Google Form. We want one PDF created each time a script is run. The problem is it creates a new PDF each time there is a new record in a sheet. We started to look at using a pivot table before creating the PDF, can't figure that part out. Any help would be much appreciated.
Kind regards,
var CLASSLIST = [];
var MAINLIST = [];
const MAINTAIN_GS = "1tFXqO0oKjm37P09Mi2jfYT-RML-G1dBr03qHPUzsT7w";
const MAINTAIN_SN = "Class & Teacher Email";
const STUDENT_FORM_SN="Form Responses 1";
const TEMPFOLDER_ID = "12Wzl_v_o-aJ_38P9YSshyQPTtGVXmsyH";
const TEMPLATE_DOC_ID = "1D0PBYPunBa63d0eC9b6IrzjAHmWzZVVJJM1zhhUVY3c";
function onOpen() {
loadMainDetails();
// Utilities.sleep(10000)
/*
var ui = SpreadsheetApp.getUi();
ui.createMenu('Send Email')
.addItem(CLASSLIST[0] ,'mainScript1')
.addItem(CLASSLIST[1] ,'mainScript2')
.addItem(CLASSLIST[2] ,'mainScript3')
.addItem(CLASSLIST[3] ,'mainScript4')
.addItem(CLASSLIST[4] ,'mainScript5')
.addItem(CLASSLIST[5] ,'mainScript6')
.addItem(CLASSLIST[6] ,'mainScript7')
.addItem(CLASSLIST[7] ,'mainScript8')
.addItem(CLASSLIST[8] ,'mainScript9')
.addItem(CLASSLIST[9] ,'mainScript10')
.addItem(CLASSLIST[10] ,'mainScript11')
.addItem(CLASSLIST[11] ,'mainScript12')
.addToUi(); */
var ui = SpreadsheetApp.getUi();
ui.createMenu('Send Email')
.addItem(CLASSLIST[0] ,'mainScript7I')
.addItem(CLASSLIST[1] ,'mainScript7P')
.addItem(CLASSLIST[2] ,'mainScript7S')
.addItem(CLASSLIST[3] ,'mainScript7W')
.addItem(CLASSLIST[4] ,'mainScript8I')
.addItem(CLASSLIST[5] ,'mainScript8P')
.addItem(CLASSLIST[6] ,'mainScript8S')
.addItem(CLASSLIST[7] ,'mainScript8W')
.addItem(CLASSLIST[8] ,'mainScript9I')
.addItem(CLASSLIST[9] ,'mainScript9P')
.addItem(CLASSLIST[10] ,'mainScript9S')
.addItem(CLASSLIST[11] ,'mainScript9W')
.addItem(CLASSLIST[12] ,'mainScript10A')
.addItem(CLASSLIST[13] ,'mainScript10B')
.addItem(CLASSLIST[14] ,'mainScript10C')
.addItem(CLASSLIST[15] ,'mainScript10D')
.addItem(CLASSLIST[16] ,'mainScript10E')
.addItem(CLASSLIST[17] ,'mainScript11A')
.addItem(CLASSLIST[18] ,'mainScript11B')
.addItem(CLASSLIST[19] ,'mainScript11C')
.addItem(CLASSLIST[20] ,'mainScript11D')
.addItem(CLASSLIST[21] ,'mainScript11E')
.addItem(CLASSLIST[22] ,'mainScript12A')
.addItem(CLASSLIST[23] ,'mainScript12B')
.addItem(CLASSLIST[24] ,'mainScript12C')
.addItem(CLASSLIST[25] ,'mainScript12D')
.addItem(CLASSLIST[26] ,'mainScript12E')
.addItem(CLASSLIST[27] ,'mainScript13A')
.addItem(CLASSLIST[28] ,'mainScript13B')
.addItem(CLASSLIST[29] ,'mainScript13C')
.addItem(CLASSLIST[30] ,'mainScript13D')
.addItem(CLASSLIST[31] ,'mainScript13E')
.addItem("All", 'mainScriptAll')
.addToUi();
// menuEntries.push({name: "Generate PDF", functionName: "mainScript0"});
// ss.addMenu("Email Teacher", menuEntries);
/* ss.addMenu("Send Email", menuEntries);
menuEntries.push({name: CLASSLIST[0], functionName: "mainScript7I"});
menuEntries.push({name: CLASSLIST[1], functionName: "mainScript7P"});
menuEntries.push({name: CLASSLIST[2], functionName: "mainScript7S"});
menuEntries.push({name: CLASSLIST[3], functionName: "mainScript7W"});
menuEntries.push({name: CLASSLIST[4], functionName: "mainScript8I"});
menuEntries.push({name: CLASSLIST[5], functionName: "mainScript8P"});
menuEntries.push({name: CLASSLIST[6], functionName: "mainScript8S"});
menuEntries.push({name: CLASSLIST[7], functionName: "mainScript8W"});
menuEntries.push({name: CLASSLIST[8], functionName: "mainScript9I"});
menuEntries.push({name: CLASSLIST[9], functionName: "mainScript9S"});
menuEntries.push({name: CLASSLIST[10], functionName: "mainScript9P"});
menuEntries.push({name: CLASSLIST[11], functionName: "mainScript9W"});
*/
}
function mainScript7I() {
mainScriptByClass("A7", "C7","B7");
}
function mainScript7P() {
mainScriptByClass("A8","C8","B8");
}
function mainScript7S() {
mainScriptByClass("A9","C9","B9");
}
function mainScript7W() {
mainScriptByClass("A10","C10","B10");
}
function mainScript8I() {
mainScriptByClass("A11", "C11","B11");
}
function mainScript8P() {
mainScriptByClass("A12", "C12","B12");
}
function mainScript8S() {
mainScriptByClass("A13", "C13","B13");
}
function mainScript8W() {
mainScriptByClass("A14", "C14","B14");
}
function mainScript9I() {
mainScriptByClass("A15", "C15","B15");
}
function mainScript9S() {
mainScriptByClass("A16", "C16","B16");
}
function mainScript9P() {
mainScriptByClass("A17", "C17","B17");
}
function mainScript9W() {
mainScriptByClass("A18", "C18","B18");
}
function mainScript10A() {
mainScriptByClass("A19", "C19","B19");
}
function mainScript10B() {
mainScriptByClass("A20", "C20","B20");
}
function mainScript10C() {
mainScriptByClass("A21", "C21","B21");
}
function mainScript10D() {
mainScriptByClass("A22", "C22","B22");
}
function mainScript10E() {
mainScriptByClass("A23", "C23","B23");
}
function mainScript11A() {
mainScriptByClass("A24", "C24","B24");
}
function mainScript11B() {
mainScriptByClass("A25", "C25","B25");
}
function mainScript11C() {
mainScriptByClass("A26", "C26","B26");
}
function mainScript11D() {
mainScriptByClass("A27", "C27","B27");
}
function mainScript11E() {
mainScriptByClass("A28", "C28","B28");
}
function mainScript12A() {
mainScriptByClass("A29", "C29","B29");
}
function mainScript12B() {
mainScriptByClass("A30", "C30","B30");
}
function mainScript12C() {
mainScriptByClass("A31", "C31","B31");
}
function mainScript12D() {
mainScriptByClass("A32", "C32","B32");
}
function mainScript12E() {
mainScriptByClass("A33", "C33","B33");
}
function mainScript13A() {
mainScriptByClass("A34", "C34","B34");
}
function mainScript13B() {
mainScriptByClass("A35", "C35","B35");
}
function mainScript13C() {
mainScriptByClass("A36", "C36","B36");
}
function mainScript13D() {
mainScriptByClass("A37", "C37","B37");
}
function mainScript13E() {
mainScriptByClass("A38", "C38","B38");
}
function mainScriptAll() {
mainScript7I();
mainScript7P();
mainScript7S();
mainScript7W();
mainScript8I();
mainScript8P();
mainScript8S();
mainScript8W();
mainScript9I();
mainScript9P();
mainScript9S();
mainScript9W();
mainScript10A();
mainScript10B();
mainScript10C();
mainScript10D();
mainScript10E();
mainScript11A();
mainScript11B();
mainScript11C();
mainScript11D();
mainScript11E();
mainScript12A();
mainScript12B();
mainScript12C();
mainScript12D();
mainScript12E();
mainScript13A();
mainScript13B();
mainScript13C();
mainScript13D();
mainScript13E();
}
function mainScriptByClass(vClassCol, vEmailCol, vFolderCol) {
if (vClassName != "ALL" ){
/* var TrueMaintain = SpreadsheetApp.openById(MAINTAIN_GS).getSheetByName(MAINTAIN_SN);
var vClassName = TrueMaintain.getRange(vClassCol).getValue();
var emailID = TrueMaintain.getRange(vEmailCol).getValue();
var urlID = TrueMaintain.getRange(vFolderCol).getValue(); */
var vClassName = SpreadsheetApp.openById(MAINTAIN_GS).getSheetByName(MAINTAIN_SN).getRange(vClassCol).getValue();
var emailID = SpreadsheetApp.openById(MAINTAIN_GS).getSheetByName(MAINTAIN_SN).getRange(vEmailCol).getValue();
Logger.log("emailID " + emailID)
var urlID = SpreadsheetApp.openById(MAINTAIN_GS).getSheetByName(MAINTAIN_SN).getRange(vFolderCol).getValue();
generatePDFByClass(vClassName);
Logger.log("URLID " + urlID);
//generatePDFByClass(vClassName);
var linkFromID = "https://drive.google.com/drive/folders/" + urlID ;
// GmailApp.sendEmail(emailID, "PDF Files for this week", "Hello these are the PDF results of the forms your student filled out:" + inkFromID);
GmailApp.sendEmail(emailID, "PDF Files for this week", "Hello these are the PDF results of the forms your students filled out:" + linkFromID);
} else {
mainScript();
}
}
function loadMainDetails () {
var vClassName, vURL, vFTEmail;
/* const ssMainFileID = "1SR2NFYOHZ2h2JANUoTsIZvFhLJ7RQc2ob--dU4IPNxk";
const sMainFileSheet = "Class & Teacher Email"; */
var file = SpreadsheetApp.openById(MAINTAIN_GS);
var ss = file.getSheetByName(MAINTAIN_SN);
/* Get Data from maintenance file */
/* getRange (Row, Column, RowRange, ColumnRange) */
vData = ss.getRange(7,1, ss.getLastRow() - 1, ss.getMaxColumns()).getDisplayValues();
vData.forEach ( function (vRow) {
// rowNum = rowNum + 1;
if(vRow[0].length > 0 ){
vClassName = vRow[0];
vURL = vRow[1];
vFTEmail = vRow[2];
CLASSLIST.push(vClassName);
//MAINLIST.push("{'className':'"+ vClassName + "','url':'" + vURL + "','ft':'" + vFTEmail +"'}")
MAINLIST.push(vClassName + "," + vURL + "," + vFTEmail)
}
});
}
function getURLByClass(sKeyClass) {
var vURL = "";
var mapList = [];
for(var i in MAINLIST){
mapList = MAINLIST[i].toString().split(",")
if (sKeyClass == mapList[0] ) {
vURL = mapList[1];
break;
}
}
return vURL;
}
function getFTMailByClass(sKeyClass) {
var vEmail = "";
var mapList = [];
for(var i in MAINLIST){
mapList = MAINLIST[i].toString().split(",")
if (sKeyClass == mapList[0] ) {
vEmail = mapList[2];
break;
}
}
return vEmail;
}
function generatePDFByClass(vClass){
//Temp
loadMainDetails();
Logger.log("loadMainDetails");
var ss = SpreadsheetApp.getActiveSpreadsheet()
var respSheet =ss.getSheetByName(STUDENT_FORM_SN);
// Sorting by Class No
var vRange = respSheet.getRange("A:G")
vRange.sort ({column: 3, ascending: true} );
var rowNum = 1;
var vData = [];
var vHeader = [];
var vSName, vFTClass;
var vPrevFTEmail = "", vPrevFTClass = "" ;
var vFTEmail = "";
var headerNum = 0;
var maxColumn = respSheet.getMaxColumns();
Logger.log("maxColumn" + maxColumn);
/* Get Headers to apply in template as Q */
vHeader = respSheet.getRange(1,1,1, maxColumn).getDisplayValues();
/* Get Data to apply in in template as A */
Logger.log("Header" + vHeader);
/* getRange (Row, Column, RowRange, ColumnRange) */
vData = respSheet.getRange(2,1, respSheet.getLastRow() - 1, maxColumn).getDisplayValues();
Logger.log("Data " + vData);
/* Response inputs */
vData.forEach ( function (vRow) {
rowNum = rowNum + 1;
//if(vRow[3] == vClass){
if(vRow[2] == vClass){
vSName = vRow[1];
vFTClass = vRow[2];
Logger.log("vFTClass " + vFTClass);
// vFTClass = vRow[3];
vPrevFTEmail = vFTEmail;
// Setup FT Email at Column AA for Reference.
//respSheet.getRange("AA" + rowNum).setValue(vFTEmail);
// Start Column
var vStartColumn = 1
// Student Line for generate PDF and Email
sData = respSheet.getRange(rowNum,vStartColumn, 1, maxColumn).getDisplayValues();
// var nPdfFile = createBulkPDF(vHeader, sData, vSName, vFTClass);
createBulkPDF(vHeader, sData, vSName, vFTClass);
vPrevFTClass = vFTClass;
}
});
}
function mainScript(){
//Temp
loadMainDetails();
var ss = SpreadsheetApp.getActiveSpreadsheet()
var respSheet =ss.getSheetByName(STUDENT_FORM_SN);
// Sorting by Class No
var vRange = respSheet.getRange("A:G")
vRange.sort ({column: 3, ascending: true});
var rowNum = 1;
var vData = [];
var vHeader = [];
var vSName, vFTClass;
var vPrevFTEmail = "", vPrevFTClass = "" ;
var vFTEmail = "";
var headerNum = 0;
var maxColumn = respSheet.getMaxColumns()
/* Get Headers to apply in template as Q */
vHeader = respSheet.getRange(1,1,1, maxColumn).getDisplayValues();
/* Get Data to apply in in template as A */
/* getRange (Row, Column, RowRange, ColumnRange) */
vData = respSheet.getRange(2,1, respSheet.getLastRow() - 1, maxColumn).getDisplayValues();
/* Response inputs */
vData.forEach ( function (vRow) {
rowNum = rowNum + 1;
if(vRow[0].length > 0 ){
vSName = vRow[1];
vFTClass = vRow[3];
vPrevFTEmail = vFTEmail;
vFTEmail = getFTMailByClass(vFTClass);
/* Send email by Grouping */
if (vPrevFTClass != "" && vFTClass != vPrevFTClass) {
sendRespMail(vPrevFTEmail, vPrevFTClass);
// vPrevFTClass = vFTClass;
// vAllPDF.splice(0, vAllPDF.length)
}
}
// Setup FT Email at Column AA for Reference.
//respSheet.getRange("AA" + rowNum).setValue(vFTEmail);
// Start Column
var vStartColumn = 1
// Student Line for generate PDF and Email
sData = respSheet.getRange(rowNum,vStartColumn, 1, maxColumn).getDisplayValues();
//var nPdfFile = createBulkPDF(vHeader, sData, vSName, vFTClass);
createBulkPDF(vHeader, sData, vSName, vFTClass);
vPrevFTClass = vFTClass;
//vAllPDF.push(nPdfFile);
});
/* Last Email Group */
//if (vFTClass != vPrevFTClass) {
// sendRespMail(vFTEmail, vFTClass);
sendRespMail(vFTEmail,vFTClass )
//}
}
function sendRespMail(email, className){
var url_link = getURLByClass(className);
var message = "Hello, this is a URL fpr group of PDFs containing the Data of your class (" + className + ")";
message = message + "stduents who filled out the Google Form.\n";
message = message + "https://drive.google.com/drive/folders/" + url_link;
var emailTo = email;
var subject = "Forms filled out this Friday";
var html = message;
if( emailTo != "") {
GmailApp.sendEmail(emailTo,subject,html,"" );
}
}
function sendRespMailforAttachment(email, pdfFiles){
var message = "Hello, this is a group of PDFs containing the Data of your class ";
message = message + "stduents who filled out the Google Form."
var emailTo = email;
var subject = "Forms filled out this Friday";
var html = message;
if( emailTo != "") {
// GmailApp.sendEmail(emailTo,subject,html,{ attachments: pdfFiles } );
}
}
function createBulkPDF(pHeader, pData, pSName, pClass){
Logger.log("createBulkPDF1");
var rowNum = 2;
var allPDF = [];
var vTemplateDocFile = DriveApp.getFileById(TEMPLATE_DOC_ID);
var vTempFolder = DriveApp.getFolderById(TEMPFOLDER_ID);
var tempFile = vTemplateDocFile.makeCopy(vTempFolder);
var tempDocFile = DocumentApp.openById(tempFile.getId());
var body = tempDocFile.getBody();
// Fill in Header for A { }
var hRowNum = 1;
pHeader.forEach ( function (hRow) {
hRowNum = hRowNum + 1;
for (var i = 1; i < hRow.length; i++){
body.replaceText("{Q" + i + "}", hRow[i] );
}
});
Logger.log("createBulkPDF2");
// Fill in Inputs for Q { }
var sRowNum = 1;
pData.forEach ( function (sRow) {
sRowNum = sRowNum + 1;
for (var i = 1; i < sRow.length; i++){
body.replaceText("{A" + i + "}", sRow[i] );
}
});
tempDocFile.saveAndClose();
var vPdfContentBlob = tempDocFile.getAs(MimeType.PDF);
var pdfName = pSName+Utilities.formatDate(new Date(),"GMT+8"," HH:mm:ss")+".pdf";
var classFolderID = getURLByClass(pClass);
var vPdfFolder = DriveApp.getFolderById(classFolderID);
var pdfRpt=vPdfFolder.createFile(vPdfContentBlob).setName(pdfName);
// var pdfRpt=vPdfFolder.createFile(vPdfContentBlob).setName(pdfName);
DriveApp.getFileById(tempFile.getId()).setTrashed(true);
Logger.log("createBulkPDF3");
return pdfRpt;
}
I understand that you already have a Sheet with the data and a separate function to convert it to a PDF, therefore you only need to refine the table so it only shows a particular student. Based on your comment, I guess that the table looks like this:
First of all I strongly recommend you to use a filter table instead of a pivot table, because it will fit better to your goal and you can code it pretty easily. You can include my example below into your project as is, you would only need to change the student name from Irène to whatever your need.
function studentFilter() {
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var data = sheet.getDataRange().getA1Notation();
sheet.getRange(data).createFilter();
var criteria = SpreadsheetApp.newFilterCriteria().whenTextEqualTo('Irène')
.build();
sheet.getFilter().setColumnFilterCriteria(1, criteria);
};
That code would use the SpreadsheetApp class of Apps Script to open the Sheet and get its range. After that it would create a filter table using the .createFilter() method and the FilterCriteriaBuilder class. After both the filter table and its criteria is created, it just applies the criteria to the table. This would be the end result on the previous example:
At this point the Sheet already looks like your goal, so you only need to follow your usual workflow and call the printing PDF function.

How do you overwrite data instead of appendRow?

Currently the code below appends new data to my spreadsheet every time it runs and I have to manually remove the data before running.
{
var ss = SpreadsheetApp.openById("blank");
var sheetName = ss.getSheetByName("Team Database");
var url = "blank";
var response = JSON.parse(UrlFetchApp.fetch(url));
var current = 1;
if(response.returnData && response.returnData.equipos.length > 0)
{
for(var team in response.returnData.equipos)
{
if(response.returnData.equipos[team].members.length > 0)
{
var i = 0;
while(i < response.returnData.equipos[team].members.length)
{
console.log(response.returnData.equipos[team].name);
console.log(response.returnData.equipos[team].members[i].userId);
sheetName.appendRow([response.returnData.equipos[team].name, response.returnData.equipos[team].members[i].userId]);
i++;
}
}
}
}
if(team.length > 0)
{
sheetName.getRange('D2').setValue('=NOW()');
sheetName.getRange('D1').setValue(sheetName.getRange('D2').getValue());
sheetName.getRange('D2').clear();
}
}
Is there a function that would overwrite it instead like: sheetName.overwriteRow([response.returnData.equipos[team].name, response.returnData.equipos[team].members[i].userId]);?
function myfunc() {
var ss = SpreadsheetApp.openById("blank");
var sh = ss.getSheetByName("Team Database");
var url = "blank";
var response = JSON.parse(UrlFetchApp.fetch(url));
var current = 1;
let oA = [];
if (response.returnData && response.returnData.equipos.length > 0) {
for (var team in response.returnData.equipos) {
if (response.returnData.equipos[team].members.length > 0) {
var i = 0;
while (i < response.returnData.equipos[team].members.length) {
console.log(response.returnData.equipos[team].name);
console.log(response.returnData.equipos[team].members[i].userId);
oA.push([response.returnData.equipos[team].name, response.returnData.equipos[team].members[i].userId]);
i++;
}
}
}
}
if (team.length > 0) {
sh.getRange('D2').setValue('=NOW()');
sh.getRange('D1').setValue(sh.getRange('D2').getValue());
sh.getRange('D2').clear();
sh.getRange(3,1,sh.getLastRow() - 2, sh.getLastColumn()).clearContent();
sh.getRange(3,1,oA.length, oA[0].length).setValues(oA);
}
}

Google Charts - Hide series label too wide

With Google Apps Script I created a stacked bar chart. This is the result:
https://drive.google.com/file/d/1DZ2ZtSu2A81OAMc9ds9A4y-bS0l_oftL/view?usp=sharing
I would like to hide the labels on the bars when they are too wide compared to the available space. Following the instructions I found at this address https://developers.google.com/chart/interactive/docs/reference#DataView_setColumns I tried to use a custom function instead of "stringify" in the "annotationObj" object ( see the code) to create a label of zero length, but my function is not recognized when I try to create the chart (error message: Unknown function "getValueAt").
This is my code:
function CHARTS_002() { //
var ABCarray = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM','AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ','BA','BB','BC','BD','BE','BF','BG','BH','BI','BJ','BK','BL','BM','BN','BO','BP','BQ','BR','BS','BT','BU','BV','BW','BX','BY','BZ','CA','CB','CC','CD','CE','CF','CG','CH','CI','CJ','CK','CL','CM','CN','CO','CP','CQ','CR','CS','CT','CU','CV','CW','CX','CY','CZ'];
var ssId = '1KA2BnUsC-Lp64UhxjtN5Gtth2dOiHp3-pRwIQjAYOLI';
var shName = 'TopGrossingFilms';
var aScale = ["Poco d'accordo","Né d’accordo né in disaccordo","Abbastanza d'accordo","Totalmente d'accordo","Media"];
var aRange = [['B',2],['N',12]];
var sheet = SpreadsheetApp.openById(ssId).getSheetByName(shName);
var row = aRange[0][1];
var column = ABCarray.indexOf(aRange[0][0]) + 1;
var numRows = aRange[1][1] - aRange[0][1];
var numColumns = ABCarray.indexOf(aRange[1][0]) - ABCarray.indexOf(aRange[0][0]) + 1;
var sheetV = sheet.getRange(aRange[0][1], ABCarray.indexOf(aRange[0][0]) + 1, numRows, numColumns).getValues();
var sheetT1D = sheetV[0];
var aData = [];
for (var r in sheetV) {
aData.push(sheetV[r])
}
for (var r in aData) {
for (var c in aData[r]) {
if (!isNaN(aData[r][c])) {
aData[r][c] = round(aData[r][c],2);
if (aData[0][c] == 'Media') {
aData[r][c] = 13;
}
}
}
}
var data = Charts.newDataTable();
var annotationObj = { calc: "stringify",
//calc: "getValueAt",
//calc: "function(data, row) { var ret = data[row][§col§]; if (ret < 7) {return '';} else {return JSON.stringify(ret)} }",
sourceColumn: -1,
type: "string",
role: "annotation"
}
var aAnnotation = [];
for (var r in aData) {
if (r < 1) { continue; }
if (r == 1) {
for (var c in aData[r]) {
aAnnotation.push(c);
if (isNaN(aData[r][c])) {
data.addColumn(Charts.ColumnType.STRING, aData[0][c]);
} else {
data.addColumn(Charts.ColumnType.NUMBER, aData[0][c]);
if (aScale.indexOf(aData[0][c]) != -1) {
var myObj = JSON.parse(JSON.stringify(annotationObj));
var myCol = Number(c);
if (aData[0][c] == 'Media') {
myCol = Number(c) + 1;
}
myObj.sourceColumn = myCol;
myObj.calc = myObj.calc.replace("§col§",myCol)
aAnnotation.push(myObj);
}
}
}
}
data.addRow(aData[r]);
}
var dataViewDefinition = Charts.newDataViewDefinition().setColumns(aAnnotation);
var aTicks = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
var chartBuilder = Charts.newBarChart()
.setDimensions(1200, 700)
.setOption("hAxis", { ticks: aTicks})
.setOption('legend',{ position:'top', maxLines:3 })
.setOption('chartArea',{ left:650 })
.setOption('series',{
6: {type:'line', color:'00FF00', lineWidth:3, visibleInLegend: false}
})
.setDataTable(data)
.setDataViewDefinition(dataViewDefinition)
.setOption('bar', { groupWidth: "80%" })
.setStacked()
.setColors(['#C10000','#F1C12A','#BFBFBF','#0070C1','#244062','00FF00']);
var chart = chartBuilder.build();
var chartImage = chart.getAs('image/png').copyBlob();
DriveApp.createFile(chartImage).setName('NewBarChart.png');
}
function getValueAt(column, dataTable, row) {
var value = dataTable(row, column);
var ret = '';
if (value > 7) { ret = value.toString()}
return ret;
}
function round(value, exp) {
var funcName = 'round';
if (typeof exp === 'undefined' || +exp === 0)
return Math.round(value);
value = +value;
exp = +exp;
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
return NaN;
// Shift
value = value.toString().split('e');
value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));
// Shift back
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}
The chart that is produced can be seen in this public folder: https://drive.google.com/file/d/1DZ2ZtSu2A81OAMc9ds9A4y-bS0l_oftL/view?usp=sharing
Does anyone know how to get the result I would like to get?
Thanks in advance.

GmailApp.search doesn't filter the labels

I try to send the all attachments to my Google Drive account but I have problem with the search of GmailApp.search.
I have a Camera in my home that sends an email every 5 minutes with the same Subject and each message has an attached file that's name is the day-time.jpg
First I think in search by label and then of the process, I put a new label to mark and don't repeat the message, but I always receive all the message.
I tried to test many ways and always received the message that has label:processed.
function () {
//All message of the camera have the label GoogleDrive
var threads = GmailApp.search("has:attachment -label:processed label:GoogleDrive", 0, 5);
var folder = getFolder(driveFolder);
for (var x=0; x<threads.length; x++) {
var message = threads[x].getMessages();
for(var y=0; y<message.length; y++) {
var desc = message[y].getSubject() + " #" + message[y].getId();
var att = message[y].getAttachments();
for (var z=0; z<att.length; z++) {
try {
if (check) {
var name = att[z].getName();
if (name.indexOf(".") != -1) {
var extn = name.substr(name.lastIndexOf(".")+1).toLowerCase();
if (valid.indexOf(extn) != -1) {
file = folder.createFile(att[z]);
file.setDescription(desc);
} else {
Logger.log("Skipping " + name);
}
}
} else {
file = folder.createFile(att[z]);
file.setDescription(desc);
}
}
catch (e) {
Logger.log(e.toString());
}
}
}
threads[x].addLabel(moveToLabel); //this variable is processed label
}
}
Regards
I have this function. I use the ctrlq.org code as base, only I put the principal function.
Now I copy all the script
function createFilter(label, archiveLabel) {
var filter = "has:attachment -label:" + archiveLabel + " label:" + label;
return filter;
}
function help() {
var html = HtmlService.createHtmlOutputFromFile('help')
.setTitle("Google Scripts Support")
.setWidth(400)
.setHeight(260);
var ss = SpreadsheetApp.getActive();
ss.show(html);
}
function premium() {
var html = HtmlService.createHtmlOutput('Upgrade to the premium edition of Send to Google Drive and unlock new features. You can also opt for one-on-one support via email, Skype or Google Hangouts.')
.setTitle("Send to Google Drive Premium")
.setWidth(240)
.setHeight(100);
var ss = SpreadsheetApp.getActive();
ss.show(html);
}
function sendToGoogleDrive() {
var sheet = SpreadsheetApp.getActiveSheet();
var gmailLabels = sheet.getRange("D4:D4").getValue();
var driveFolder = sheet.getRange("D5:D5").getValue();
var archiveLabel = sheet.getRange("D6:D6").getValue();
var filetypes = sheet.getRange("D7:D7").getValue();
var valid = filetypes.replace(/\s/g,"").toLowerCase().split(",");
var check = true;
if ( (valid.indexOf("all") != -1) || (valid.length == 1 && valid[0] == "")) {
check = false;
}
var moveToLabel = getGmailLabel(archiveLabel);
var filter = createFilter(gmailLabels, archiveLabel);
var threads = GmailApp.search(filter, 0, 5);
var folder = getFolder(driveFolder);
sheet.getRange("D9:D9").setValue(sheet.getRange("D9:D9").getValue() + ", [th(" + threads.length + ")");
for (var x=0; x<threads.length; x++) {
var message = threads[x].getMessages();
sheet.getRange("D9:D9").setValue(sheet.getRange("D9:D9").getValue() + ", ms(" + message.length + ")");
for(var y=0; y<message.length; y++) {
var desc = message[y].getSubject() + " #" + message[y].getId();
var att = message[y].getAttachments();
//sheet.getRange("D9:D9").setValue(sheet.getRange("D9:D9").getValue() + ", at(" + att.length + ")");
for (var z=0; z<att.length; z++) {
try {
if (check) {
var name = att[z].getName();
if (name.indexOf(".") != -1) {
var extn = name.substr(name.lastIndexOf(".")+1).toLowerCase();
if (valid.indexOf(extn) != -1) {
file = folder.createFile(att[z]);
file.setDescription(desc);
} else {
Logger.log("Skipping " + name);
}
}
} else {
file = folder.createFile(att[z]);
file.setDescription(desc);
}
}
catch (e) {
Logger.log(e.toString());
}
}
}
threads[x].moveToTrash();
threads[x].addLabel(moveToLabel);
}
sheet.getRange("D9:D9").setValue(sheet.getRange("D9:D9").getValue() + "]");
}
function configure() {
reset(true);
ScriptApp.newTrigger("sendToGoogleDrive").timeBased().everyMinutes(5).create();
Browser.msgBox("Initialized", "The program is now running. You can close this sheet", Browser.Buttons.OK);
}
function init() {
return;
}
function onOpen() {
var menu = [
{name: "Help and Support »",functionName: "help"},
null,
{ name: "Step 1: Authorize", functionName: "init" },
{ name: "Step 2: Run Program", functionName: "configure" },
null,
{ name: "Uninstall (Stop)", functionName: "reset" },
null,
{name: "Upgrade to Premium »",functionName: "premium"},
null
];
SpreadsheetApp.getActiveSpreadsheet()
.addMenu("Gmail Attachments", menu);
}
function getFolder(parent) {
var parentFolder, searchFolder = DriveApp.getFoldersByName(parent);
if (searchFolder.hasNext()) {
parentFolder = searchFolder.next();
} else {
parentFolder = DriveApp.createFolder(parent);
}
return parentFolder;
}
function getGmailLabel(name) {
var label = GmailApp.getUserLabelByName(name);
if ( ! label ) {
label = GmailApp.createLabel(name);
}
return label;
}
function reset(e) {
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
ScriptApp.deleteTrigger(triggers[i]);
}
if (!e) {
Browser.msgBox("Script Stopped", "You can start the script anytime later!", Browser.Buttons.OK);
}
}
My inbox have these mails:
1
The problem is then I run the script the mail has a new label (now I send to Trash too), but in the next run the GmailApp.Search, find the mail that have processed label.
I copy the configuration sheet
2
It looks like you have not defined moveToLabel and hence the same set of Gmail threads are getting processed in each loop.
Add this line before the for loop.
var moveToLabel = GmailApp.getUserLabelByName("processed");
if ( ! moveToLabel ) {
moveToLabel = GmailApp.createLabel(processed);
}
You can get the full snippet at ctrlq.org.