Google app script triggering twice after Google form submit - google-apps-script

I'm having issue with my script running twice in a Google Form and the linked Sheets. I have one form submit trigger. If I delete this trigger, the script doesn't run at all on a form submit. If I add the trigger back in, it will trigger twice -- but there is only one form submittal in the sheet responses. I thought that maybe I was clicking the form submittal twice, but that doesn't seem to be it. Thanks.
Here is the code:
function myFunction(e) {
// Set values for event "e" from Response form, each number being a column in the spreadsheet. Column zero is not used - it is the timestamp
var JobNumber = e.values[1];
// Create an array from the PNEZD field in the form then find the array location for the inputted shot number
var PNEZD_field = e.values[2];
var PNEZD_array = Utilities.parseCsv(PNEZD_field);
var StructureNumber = e.values[3];
for (i = 0; i < PNEZD_array.length; i++) {
if (PNEZD_array[i][0] == StructureNumber) {
var Elevation = PNEZD_array[i][3];
var Easting = PNEZD_array[i][2];
var Northing = PNEZD_array[i][1];
}
}
// STRUCTURE TYPE AND SIZE
var StructureType = e.values[4];
var StructureSize = e.values[5];
// PIPE NUMBER 1
var PipeSize1 = e.values[6];
var PipeMaterial1 = e.values[7];
var PipeDirection1 = e.values[8];
var PipeMeasureDown1 = e.values[9];
// PIPE NUMBER 2
var PipeSize2 = e.values[10];
var PipeMaterial2 = e.values[11];
var PipeDirection2 = e.values[12];
var PipeMeasureDown2 = e.values[13];
// PIPE NUMBER 3
var PipeSize3 = e.values[14];
var PipeMaterial3 = e.values[15];
var PipeDirection3 = e.values[16];
var PipeMeasureDown3 = e.values[17];
// PIPE NUMBER 4
var PipeSize4 = e.values[18];
var PipeMaterial4 = e.values[19];
var PipeDirection4 = e.values[20];
var PipeMeasureDown4 = e.values[21];
// PIPE NUMBER 5
var PipeSize5 = e.values[22];
var PipeMaterial5 = e.values[23];
var PipeDirection5 = e.values[24];
var PipeMeasureDown5 = e.values[25];
// Calculate Invert Elevations:
var Dip1 = Elevation - PipeMeasureDown1;
var Dip2 = Elevation - PipeMeasureDown2;
var Dip3 = Elevation - PipeMeasureDown3;
var Dip4 = Elevation - PipeMeasureDown4;
var Dip5 = Elevation - PipeMeasureDown5;
// Build structure information
var firstLine = StructureType + " " + StructureSize + "\n";
var secondLine = "Rim=" + Elevation + "\n";
var thirdLine = PipeSize1 + " " + PipeMaterial1 + " I.E. " + PipeDirection1 + "=" + Dip1 + "'\n";
var fourthLine = PipeSize2 + " " + PipeMaterial2 + " I.E. " + PipeDirection2 + "=" + Dip2 + "'\n";
var fifthLine = PipeSize3 + " " + PipeMaterial3 + " I.E. " + PipeDirection3 + "=" + Dip3 + "'\n";
var sixthLine = PipeSize4 + " " + PipeMaterial4 + " I.E. " + PipeDirection4 + "=" + Dip4 + "'\n";
var seventhLine = PipeSize5 + " " + PipeMaterial5 + " I.E. " + PipeDirection5 + "=" + Dip5 + "'";
var Mtext = firstLine + secondLine + thirdLine + fourthLine + fifthLine + sixthLine + seventhLine;
var calcsheet = SpreadsheetApp.openById('-removed-').getSheetByName('Calculations');
var ss = SpreadsheetApp.getActiveSpreadsheet(); // ss is now the spreadsheet the script is associated with
var sheet = ss.getSheets()[1]; // sheets are counted starting from 0
// sheet is the second worksheet in the spreadsheet
var cell = sheet.getRange("A1");
cell.setValue(Mtext);
// Dump variable to logger log
// var dump = "Variable dumps: first the URL: " + PNEZD_fileURL + " and next the file ID alone: " + PNEZD_fileID + " and now the job number: " + JobNumber;
// Logger.log( dump );
// Logger.log(JobNumber);
// Logger.log("Data dump: " + PNEZD_field);
// Logger.log("Data dump: " + PNEZD_array[3][3]);
// Logger.log(StructureNumber + "," + Northing + "," + Easting + "," + Elevation);
}

Related

Referencing Edited Row Instead of getLastRow

My current code is listed below (triggered by on change). It creates a calendar event when a new "lead" is entered in our lead sheet via AppSheet. It currently only runs when a new lead aka new row is added. I would like it to also run when the appointment date is added or modified, so if a lead is entered but appointment is not set up at that time, it can be entered later and the calendar event will be created. Therefore, I know that if (e.changeType == "OTHER") will need to be changed to if (e.changeType == "OTHER" || "EDIT") and that I can no longer use sheet.getLastRow().
My question is what should I replace sheet.getLastRow() with and most importantly, how will I call/reference the row that was impacted by:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("Y:Y");
if (e.changeType == "OTHER" || "EDIT")
Essentially, what do I need to set the current var lastRow equal to so that it will call the row where the change was made instead of the last row? (I will of course change the name of the variable from lastRow to something more applicable when I do so)
Original Code:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();
// Calendar to output requests
var calendar = CalendarApp.getCalendarById('youremail#gmail.com');
// Creates an object from the last form submission
function getSubmission() {
this.timestamp = sheet.getRange(lastRow, 9).getValue();
this.accountNumber = sheet.getRange(lastRow, 10).getValue();
this.contactLastName = sheet.getRange(lastRow, 11).getValue();
this.contactFirstName = sheet.getRange(lastRow, 12).getValue();
this.contactPhoneNumber = sheet.getRange(lastRow, 15).getValue();
this.contactEmail = sheet.getRange(lastRow, 16).getValue();
this.userLastName = sheet.getRange(lastRow, 37).getValue();
this.userFirstName = sheet.getRange(lastRow, 38).getValue();
this.userPhoneNumber = sheet.getRange(lastRow, 39).getValue();
this.userEmail = sheet.getRange(lastRow, 40).getValue();
this.streetAddress = sheet.getRange(lastRow, 17).getValue();
this.city = sheet.getRange(lastRow, 18).getValue();
this.state = sheet.getRange(lastRow, 19).getValue();
this.zipCode = sheet.getRange(lastRow, 20).getValue();
this.type = sheet.getRange(lastRow, 21).getValue();
this.equipment = sheet.getRange(lastRow, 22).getValue();
this.typeOfLead = sheet.getRange(lastRow, 13).getValue();
this.sourceOfLead = sheet.getRange(lastRow, 14).getValue();
this.notes = sheet.getRange(lastRow, 23).getValue();
this.date = new Date(sheet.getRange(lastRow, 24).getValue());
this.appointmentStart = sheet.getRange(lastRow, 25).getValue();
this.appointmentEnd = sheet.getRange(lastRow, 26).getValue();
this.direction = sheet.getRange(lastRow, 27).getValue();
this.callOnWay = sheet.getRange(lastRow, 28).getValue();
return this;
}
// Creates a calendar event using the submitted data
function updateCalendar(request) {
request.date.setHours(request.appointmentStart.getHours());
request.date.setMinutes(request.appointmentStart.getMinutes());
var endTime = new Date(request.date);
endTime.setHours(request.appointmentEnd.getHours());
endTime.setMinutes(request.appointmentEnd.getMinutes())
var event = calendar.createEvent(
request.state + " " + request.direction + " EST " + request.contactLastName + ", " + request.contactFirstName + " " + request.callOnWay,
request.date,
endTime
)
.setLocation(request.streetAddress + " " + request.city + ", " + request.state + " " + request.zipCode
)
.setDescription("Account # " + request.accountNumber + "\n" + "\n" + request.contactFirstName + " " + request.contactLastName + "\n" + request.contactPhoneNumber + "\n" + request.contactEmail + "\n" + "\n" + "Notes: " + request.type + " - " + request.equipment + ". " + request.notes + ".\n" + "Lead: " + request.typeOfLead + " - " + request.sourceOfLead + "." + "\n" + "\n" + "Jim: Scanned:____ " + "Inv. Adj:____ " + "QB:____ " + "Est. SL:____" + "\n" + "\n" + "Tracy: QB:____" + " Scan:____" + " Letter:____" + " Lead Sheet:____" + " Ref. Check #:____"
)
}
// --------------Main--------------
function main() {
var request = getSubmission();
updateCalendar(request);
}
function runMain(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("Y:Y");
if (e.changeType == "OTHER") {
main();
}
}
I am still quite new to writing in App Script, so any help is greatly appreciated!
Updated code with suggestions from #YuriKhristich:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();
// Calendar to output requests to
var calendar = CalendarApp.getCalendarById('youremail#gmail.com');
// Creates an object from the last submission
function getSubmission(row) {
var data = sheet.getRange(row,9,1,40).getValues();
this.timestamp = row[ 9];
this.accountNumber = row[10];
this.contactLastName = row[11];
this.contactFirstName = row[12];
this.contactPhoneNumber = row[15];
this.contactEmail = row[16];
this.userLastName = row[37];
this.userFirstName = row[38];
this.userPhoneNumber = row[39];
this.userEmail = row[40];
this.streetAddress = row[17];
this.city = row[18];
this.state = row[19];
this.zipCode = row[20];
this.type = row[21];
this.equipment = row[22];
this.typeOfLead = row[13];
this.sourceOfLead = row[14];
this.notes = row[23];
this.date = new Date(row[24]);
this.appointmentStart = row[25];
this.appointmentEnd = row[26];
this.direction = row[27];
this.callOnWay = row[28];
return this;
}
// Creates a calendar event using the submitted data
function updateCalendar(request) {
request.date.setHours(request.appointmentStart.getHours());
request.date.setMinutes(request.appointmentStart.getMinutes());
var endTime = new Date(request.date);
endTime.setHours(request.appointmentEnd.getHours());
endTime.setMinutes(request.appointmentEnd.getMinutes())
var event = calendar.createEvent(
request.state + " " + request.direction + " EST " + request.contactLastName + ", " + request.contactFirstName + " " + request.callOnWay,
request.date,
endTime
)
.setLocation(request.streetAddress + " " + request.city + ", " + request.state + " " + request.zipCode
)
.setDescription("Account # " + request.accountNumber + "\n" + "\n" + request.contactFirstName + " " + request.contactLastName + "\n" + request.contactPhoneNumber + "\n" + request.contactEmail + "\n" + "\n" + "Notes: " + request.type + " - " + request.equipment + ". " + request.notes + ".\n" + "Lead: " + request.typeOfLead + " - " + request.sourceOfLead + "." + "\n" + "\n" + "Jim: Scanned:____ " + "Inv. Adj:____ " + "QB:____ " + "Est. SL:____" + "\n" + "\n" + "Tracy: QB:____" + " Scan:____" + " Letter:____" + " Lead Sheet:____" + " Ref. Check #:____"
)
}
// --------------Main--------------
function main() {
var request = getSubmission(lastRow);
updateCalendar(request);
}
function runMain(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("Y:Y");
if (e.changeType == "OTHER") {
main();
}
}
function onEdit(e) {
if (e.range.columnStart != 25) return;
var request = getSubmission(e.range.rowStart);
updateCalendar(request);
}
Receiving the error message "TypeError: Cannot read property 'getHours' of undefined" when adding a new lead or editing appointment date.
runMain is being triggered via the installable trigger On Change.
Will an On Edit trigger need to be implemented to run the onEdit function or is that repetitive?
You can create another installable trigger onEdit (either manually or in Apps Script) to check which row was edited and then call getSubmission with that row number as parameter.
function getRow(e) {
var currentRow = e.range.getRow();
var request = getSubmission(currentRow);
updateCalendar(request);
}
Try to change the functions getSubmission() this way:
function getSubmission(row) { // <-- add 'row' argument here
var data = sheet.getRange(row,9,1,40).getValues(); // make one call to server instead of 24
this.timestamp = row[ 9];
this.accountNumber = row[10];
this.contactLastName = row[11];
this.contactFirstName = row[12];
this.contactPhoneNumber = row[15];
this.contactEmail = row[16];
this.userLastName = row[37];
this.userFirstName = row[38];
this.userPhoneNumber = row[39];
this.userEmail = row[40];
this.streetAddress = row[17];
this.city = row[18];
this.state = row[19];
this.zipCode = row[20];
this.type = row[21];
this.equipment = row[22];
this.typeOfLead = row[13];
this.sourceOfLead = row[14];
this.notes = row[23];
this.date = new Date(row[24]);
this.appointmentStart = row[25];
this.appointmentEnd = row[26];
this.direction = row[27];
this.callOnWay = row[28];
return this;
}
Change the main() function this way:
function main() {
var request = getSubmission(lastRow); // <-- add 'lastRow' argument here
updateCalendar(request);
}
And add the onEdit() function:
function onEdit(e) {
if (e.range.columnStart != 25) return; // if column Y
// probably it makes sense to check the name of the sheet as well
var request = getSubmission(e.range.rowStart);
updateCalendar(request);
}

Create Trigger to Run Script Only When New Row is Added to Spreadsheet

I have what seems to be a relatively simple task, but cannot seem to figure it out. I've written a script that creates a calendar event when a form is submitted. We will no longer be using the form (moving to AppSheet instead) so, I need the trigger to fire ONLY when a new row is added. I believe "onChange" is the way to go about this, but I only want the script to run when a row is added, not when it is edited, deleted, or changed in any other way. Any suggestions?
// Create Calendar Event From Spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();
// Calendar to output requests
var calendar = CalendarApp.getCalendarById('youremail#gmail.com');
// Creates an object from the last row
function getSubmission() {
this.timestamp = sheet.getRange(lastRow, 1).getValue();
this.accountNumber = sheet.getRange(lastRow, 2).getValue();
this.contactLastName = sheet.getRange(lastRow, 3).getValue();
this.contactFirstName = sheet.getRange(lastRow, 4).getValue();
this.contactPhoneNumber = sheet.getRange(lastRow, 5).getValue();
this.contactEmail = sheet.getRange(lastRow, 6).getValue();
this.userLastName = sheet.getRange(lastRow, 7).getValue();
this.userFirstName = sheet.getRange(lastRow, 8).getValue();
this.userPhoneNumber = sheet.getRange(lastRow, 9).getValue();
this.userEmail = sheet.getRange(lastRow, 10).getValue();
this.streetAddress = sheet.getRange(lastRow, 11).getValue();
this.city = sheet.getRange(lastRow, 12).getValue();
this.state = sheet.getRange(lastRow, 13).getValue();
this.zipCode = sheet.getRange(lastRow, 14).getValue();
this.type = sheet.getRange(lastRow, 15).getValue();
this.equipment = sheet.getRange(lastRow, 16).getValue();
this.typeOfLead = sheet.getRange(lastRow, 17).getValue();
this.sourceOfLead = sheet.getRange(lastRow, 18).getValue();
this.notes = sheet.getRange(lastRow, 19).getValue();
this.date = new Date(sheet.getRange(lastRow, 20).getValue());
this.appointmentStart = sheet.getRange(lastRow, 21).getValue();
this.appointmentEnd = sheet.getRange(lastRow, 22).getValue();
this.direction = sheet.getRange(lastRow, 23).getValue();
this.callOnWay = sheet.getRange(lastRow, 24).getValue();
return this;
}
// Creates a calendar event using the last row
function updateCalendar(request) {
request.date.setHours(request.appointmentStart.getHours());
request.date.setMinutes(request.appointmentStart.getMinutes());
var endTime = new Date(request.date);
endTime.setHours(request.appointmentEnd.getHours());
endTime.setMinutes(request.appointmentEnd.getMinutes())
var event = calendar.createEvent(
request.state + " " + request.direction + " EST " + request.contactLastName + ", " + request.contactFirstName + " " + request.callOnWay,
request.date,
endTime
)
.setLocation(request.streetAddress + " " + request.city + ", " + request.state + " " + request.zipCode
)
.setDescription("Account # " + request.accountNumber + "\n" + "\n" + request.contactFirstName + " " + request.contactLastName + "\n" + request.contactPhoneNumber + "\n" + request.contactEmail + "\n" + "\n" + "Notes: " + request.type + " - " + request.equipment + ". " + request.notes + ".\n" + "Lead: " + request.typeOfLead + " - " + request.sourceOfLead + "." + "\n" + "\n" + "Jim: Scanned:____ " + "Inv. Adj:____ " + "QB:____ " + "Est. SL:____" + "\n" + "\n" + "Tracy: QB:____" + " Scan:____" + " Letter:____" + " Lead Sheet:____" + " Ref. Check #:____"
)
}
// --------------Main--------------
function main() {
var request = getSubmission();
updateCalendar(request);
}
Use onChange with changeType = "INSERT_ROW"
Your code will run probably ten times faster if you use one getValues();
I would just correlate the column numbers to the names with an array and an object.
I'm not going to actually do it. I'll leave that as an exercise for the reader.
By the way using the lastRow for a form submission is a bad idea. You should use event object values or namedValues. If you get a lot of submissions at the same time your code will have problems.
function getSubmission(e) {
if(e.changeType == "INSERT_ROW") {
//put code here
}
}
It seems that INSERT_ROW only registers when a row is manually inserted (right click, insert row above or below). It does not run when data is added via AppSheet, a form, or typed in. Below is the code I have added o my script which behaves as expected when a row is manually inserted. Is there any way to have the script run when data is entered into a new row via an outside source or typed into the row?
function runMain(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
if (e.changeType == "INSERT_ROW") {
main();
}
}
Here is a simple standalone test script I have been using to check what inputs into the sheet fire the script.
function notify(e) {
MailApp.sendEmail("youremail#gmail.com.com", "Row Added", "A row was added to your sheet.");
}
function runNotify(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
if (e.changeType == "INSERT_ROW") {
notify(e);
}
}

Resolve 'Parsing Error: Please check your selector. (line XX)' Javascript/AWQL AdWords Data Grabber

Let me start by saying I am not a developer, so please forgive my ignorance here. :)
For the attached script, I am receiving the error: Parsing error. Please check your selector. (line 103)
For the life of me, I can't figure out how to fix this and I've done an extensive online search.
For reference, here is where the script came from: https://searchengineland.com/script-automates-adding-adwords-data-google-spreadsheet-277724
Any solutions would be much appreciated!
(Note that the personal info in the lines 17-21 have been filled out correctly.)
Thanks,
// AdWords Script: Put Data From AdWords Report In Google Sheets
// --------------------------------------------------------------
// Copyright 2017 Optmyzr Inc., All Rights Reserved
//
// This script takes a Google spreadsheet as input. Based on the column headers, data filters, and date range specified
// on this sheet, it will generate different reports.
//
// The goal is to let users create custom automatic reports with AdWords data that they can then include in an automated reporting
// tool like the one offered by Optmyzr.
//
//
// For more PPC management tools, visit www.optmyzr.com
//
*/
var DEBUG = 0; // set to 1 to get more details about what the script does while it runs; default = 0
var REPORT_SHEET_NAME = "report"; // the name of the tab where the report data should go
var SETTINGS_SHEET_NAME = "settings"; // the name of the tab where the filters and date range are specified
var SPREADSHEET_URL = "https://docs.google.com/spreadsheets/d/1dttJTb547L81XYKdTQ56LcfO9hHhbb9wm06ZY5mKhEo/edit#gid=0"; // The URL to the Google spreadsheet with your report template
var EMAIL_ADDRESSES = "exa...#example.com"; // Get notified by email at this address when a new report is ready
function main() {
var currentSetting = new Object();
currentSetting.ss = SPREADSHEET_URL;
// Read Settings Sheet
var settingsSheet = SpreadsheetApp.openByUrl(currentSetting.ss).getSheetByName(SETTINGS_SHEET_NAME);
var rows = settingsSheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var numSettingsRows = numRows - 1;
var sortString = "";
var filters = new Array();
for(var i = 0; i < numRows; i++) {
var row = values[i];
var settingName = row[0];
var settingOperator = row[1];
var settingValue = row[2];
var dataType = row[3];
debug(settingName + " " + settingOperator + " " + settingValue);
if(settingName.toLowerCase().indexOf("report type") != -1) {
var reportType = settingValue;
} else if(settingName.toLowerCase().indexOf("date range") != -1) {
var dateRange = settingValue;
} else if(settingName.toLowerCase().indexOf("sort order") != -1) {
var sortDirection = dataType || "DESC";
if(settingValue) var sortString = "ORDER BY " + settingValue + " " + sortDirection;
var sortColumnIndex = 1;
}else {
if(settingOperator && settingValue) {
if(dataType.toLowerCase().indexOf("long") != -1 || dataType.toLowerCase().indexOf("double") != -1 || dataType.toLowerCase().indexOf("money") != -1 || dataType.toLowerCase().indexOf("integer") != -1) {
var filter = settingName + " " + settingOperator + " " + settingValue;
} else {
if(settingValue.indexOf("'") != -1) {
var filter = settingName + " " + settingOperator + ' "' + settingValue + '"';
} else if(settingValue.indexOf("'") != -1) {
var filter = settingName + " " + settingOperator + " '" + settingValue + "'";
} else {
var filter = settingName + " " + settingOperator + " '" + settingValue + "'";
}
}
debug("filter: " + filter)
filters.push(filter);
}
}
}
// Process the report sheet and fill in the data
var reportSheet = SpreadsheetApp.openByUrl(currentSetting.ss).getSheetByName(REPORT_SHEET_NAME);
var rows = reportSheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var numSettingsRows = numRows - 1;
// Read Header Row and match names to settings
var headerNames = new Array();
var row = values[0];
for(var i = 0; i < numCols; i++) {
var value = row[i];
headerNames.push(value);
//debug(value);
}
if(reportType.toLowerCase().indexOf("performance") != -1) {
var dateString = ' DURING ' + dateRange;
} else {
var dateString = "";
}
if(filters.length) {
var query = 'SELECT ' + headerNames.join(",") + ' FROM ' + reportType + ' WHERE ' + filters.join(" AND ") + dateString + " " + sortString;
} else {
var query = 'SELECT ' + headerNames.join(",") + ' FROM ' + reportType + dateString + " " + sortString;
}
debug(query);
var report = AdWordsApp.report(query);
try {
report.exportToSheet(reportSheet);
var subject = "Your " + reportType + " for " + dateRange + " for " + AdWordsApp.currentAccount().getName() + " is ready";
var body = "currentSetting.ss<br>You can now add this data to <a href='https://www.optmyzr.com'>Optmyzr</a> or another reporting system.";
MailApp.sendEmail(EMAIL_ADDRESSES, subject, body);
Logger.log("Your report is ready at " + currentSetting.ss);
Logger.log("You can include this in your scheduled Optmyzr reports or another reporting tool.");
} catch (e) {
debug("error: " + e);
}
}
function debug(text) {
if(DEBUG) Logger.log(text);
}

Google Apps Script | How to access Row/Column data for certain ranges

I'm brand new to Google app scripts and wanted to create an automation script for data I am collecting through a google form.
I have 3 fields that users fill out in a form that populate columns in a sheet.
Google Sheet Image
From the responses, I want to automatically generate a database entry for another scripting language "Papyrus" by simply writing out the code as a modified concatenated string.
ex.
GasMaskM1A211.PluginFile = Context.Plugin
GasMaskM1A211.FormID = 0x00007A77
GasMaskM1A211.TypeClass = ClassGasMask
Add(GasMaskM1A211)
I'm not quite sure how to go about accessing the data (Strings) from the columns and writing to a separate column that will have the concatenated string.
So far, I've tried to follow a few examples online that did similar but not quite what I was trying to accomplish and this was the result.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getDataRange();
var lastRow = range.getLastRow();
function onOpen(e) {
getValues();
}
function getValues() {
var sortColumnRange = sheet.getRange("B2:D100");
var sortColumnVals = sortColumnRange.getValues();
var cell;
for(var i = 1; i < sortColumnVals.length; i++){
if(sortColumnVals[i][0] !== ""){
var armorName = sortColumnVals[i][3].toString()
var formID = sortColumnVals[i][2].toString()
var pluginName = sortColumnVals[i][1].toString();
pluginName.replace(" ","_");
pluginName.replace(".esp","_ESP");
pluginName.replace(".esm","_ESM");
var entry = "string " + pluginName + " = " + sortColumnVals[i][0].toString() + "\n";
entry = entry + "Entry " + armorName + " = New Entry \n";
entry = entry + armorName + ".PluginFile = " + pluginName + "\n";
entry = entry + armorName + ".FormID = " + formID + "\n";
entry = entry + armorName + ".TypeClass = ClassGasMask \n";
entry = entry + "Add(" + armorName + ")";
Logger.log(entry);
cell = sheet.getRange(i, 5);
cell.setValue(entry);
}
}
}
There are no apparent error messages, but I get the feeling that I am not accessing the right cells. Nothing gets printed to the log nor entered into the sheet.
There is a problem with your array indexes. In Javascript (and thus Google Script), array indexes start at 0. So you should decrease all your index numbers with 1, and I believe it will work (at least, when quickly tested, it does return something, although I can't assess whether that's what you'd expect or not).
function getValues() {
var sortColumnRange = sheet.getRange("B2:D100");
var sortColumnVals = sortColumnRange.getValues();
var cell;
for(var i = 0; i < sortColumnVals.length; i++){
if(sortColumnVals[i][0] !== ""){
var armorName = sortColumnVals[i][2].toString()
var formID = sortColumnVals[i][1].toString()
var pluginName = sortColumnVals[i][0].toString();
pluginName.replace(" ","_");
pluginName.replace(".esp","_ESP");
pluginName.replace(".esm","_ESM");
var entry = "string " + pluginName + " = " + sortColumnVals[i][0].toString() + "\n";
entry = entry + "Entry " + armorName + " = New Entry \n";
entry = entry + armorName + ".PluginFile = " + pluginName + "\n";
entry = entry + armorName + ".FormID = " + formID + "\n";
entry = entry + armorName + ".TypeClass = ClassGasMask \n";
entry = entry + "Add(" + armorName + ")";
Logger.log(entry);
cell = sheet.getRange(i, 5);
cell.setValue(entry);
}
}
}

Store and Increment a value by one on every new Google Form submission

When a customer completes a form, I want a new ticket number to be created and sent in an email.
The first error:
"cannot read property "range" from undefined (line 9, file "Code")
and then, on lines 11, 13, and 21, I have some code to control a ticket counter to generate a unique ticket number each time the form is submitted. When I ran 2 test forms through the system, the ticket number did not populate and the counter variable did not change.
function onFormSubmit(e) {
var activateSheet = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(activateSheet.getSheetByName('Form Responses 1'));
var sheet = SpreadsheetApp.getActiveSheet();
var row = e.range.getRowIndex(); *** line 9***
var ticketCounter = 100; ***line 11***
var ticketNumber = "FCB" + ticketCounter; ***line 13***
var etrolControlsServiceEmail = "controls-service#etrol.net";
var timestamp = sheet.getRange(row, 1).getValues();
var ticketNumberLocation = sheet.getRange(row, 2);
ticketNumberLocation.setValue(ticketNumber); ***line 21***
var location = sheet.getRange(row, 3).getValues();
var reportedBy = sheet.getRange(row, 4).getValues();
var customerEmailAddress = sheet.getRange(row, 5).getValues();
var priority = sheet.getRange(row, 6).getValues();
var customerIssue = sheet.getRange(row, 7).getValues();
var subject = "An issue has been reported at " + location + " " + timestamp + " " + "Ticket Number " + ticketNumber;
var emailBody = "To: Envirotrol Controls Service Department " + "\nRE: Issue reported at " + location + "." + "\n\nAn issue has been reported at " + location + ". Please see the details below:" + "\n\nTicket Number: " + ticketNumber + "\nLocation: " + location + "\nReported By: " + reportedBy + "\nPriority Level: " + priority + "\nIssue: " + customerIssue;
MailApp.sendEmail(customerEmailAddress + ", " + etrolControlsServiceEmail, subject, emailBody);
ticketCounter += 1};
This code shows the strategy for storing, retrieving and incrementing the ticketCounter value in the Spreadsheets Document Properties.
function onFormSubmit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet(),
shFormResponses = ss.getSheetByName('Form Responses 1');
ss.setActiveSheet(shFormResponses);
var row = e.range.getRowIndex(),
ticketCounter = PropertiesService
.getDocumentProperties()
.getProperty('ticketCounter');
if (ticketCounter === undefined || ticketCounter === null) {
PropertiesService.getDocumentProperties().setProperty('ticketCounter', '100');
ticketCounter = '100';
};
var ticketNumber = "FCB" + ticketCounter,
etrolControlsServiceEmail = "controls-service#etrol.net",
timestamp = shFormResponses.getRange(row, 1).getValues(),
ticketNumberLocation = shFormResponses.getRange(row, 2);
ticketNumberLocation.setValue(ticketNumber);
var location = shFormResponses.getRange(row, 3).getValues();
var reportedBy = shFormResponses.getRange(row, 4).getValues();
var customerEmailAddress = shFormResponses.getRange(row, 5).getValues();
var priority = shFormResponses.getRange(row, 6).getValues();
var customerIssue = shFormResponses.getRange(row, 7).getValues();
var subject = "An issue has been reported at " + location + " " +
timestamp + " " + "Ticket Number " + ticketNumber;
var emailBody = "To: Envirotrol Controls Service Department " +
"\nRE: Issue reported at " + location + "." +
"\n\nAn issue has been reported at " + location +
". Please see the details below:" + "\n\nTicket Number: " +
ticketNumber + "\nLocation: " + location + "\nReported By: " +
reportedBy + "\nPriority Level: " + priority + "\nIssue: " +
customerIssue;
MailApp.sendEmail(customerEmailAddress + ", " + etrolControlsServiceEmail, subject, emailBody);
//Values are stored as text in the Properties Service
var numberAsNumber = Number(ticketCounter);
ticketCounter = (numberAsNumber + 1).toString();
PropertiesService
.getDocumentProperties()
.setProperty('ticketCounter', ticketCounter);
};