how to append sheet before next function run - google-apps-script

I'm appending a row in a spreadsheet from a form then taking the data that was added to the spreadsheet and populating a document template. From there I'm creating a PDF and emailing it to myself. The problem I'm facing is that the data is always coming from the second to last row of the spreadsheet instead of the newly appended row (from the latest form data). It seems like the appended data is not being saved before the AutoFillDocFromTemplate function runs. What am I missing?
function doGet(request) {
return HtmlService.createTemplateFromFile('Index').evaluate();
};
/* #Include JavaScript and CSS Files */
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
/* #Process Form */
function processForm(formObject) {
var url = "https://docs.google.com/spreadsheets/d/1nz2uIWab1eSirljzvNn6SyNyxz3npDTu4mqVYV0blsU/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Data");
ws.appendRow([formObject.company_name,
formObject.identity_transformation,
formObject.character_want,
formObject.external_problem,
formObject.internal_problem,
formObject.philisophical_problem,
formObject.empathy,
formObject.authority,
formObject.plan_step1,
formObject.plan_step2,
formObject.plan_step3,
formObject.direct_cta,
formObject.transitional_cta,
formObject.failure,
formObject.success]);
}
/* This function creates a new document from a template and updates the placeholder with info from a Google Sheet*/
function AutofillDocFromTemplate(){
// Get the spreadsheet & sheet
var url = "https://docs.google.com/spreadsheets/d/1nz2uIWab1eSirljzvNn6SyNyxz3npDTu4mqVYV0blsU/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url).getSheetByName("Data");
// Set the range to the last row of data in the Sheet
var data = ss.getRange(ss.getLastRow(),1,1, ss.getLastColumn()).getValues();
// Get the original template Doc
const templateDoc = DriveApp.getFileById("1yu5jzg4NbRtTy_UjwzBmnpc-3_pNOqA-l1_UVsiAIWQ");
// Get the folder for where the docs should go
const folder = DriveApp.getFolderById("1prOQxp5jmDvJqiwIfLbbkLYWoz5QlTUC");
// Create the new file name
const newFileName = ("BrandScript")
// Create a copy of the template doc
const newTempFile = templateDoc.makeCopy(newFileName, folder);
// Open the new temp doc
const openDoc = DocumentApp.openById(newTempFile.getId());
// Get the body of the new temp doc
const body = openDoc.getBody();
// Replace placeholders with spreadsheet data from last row
body.replaceText("%company_name%", data[0][0]);
body.replaceText("%identity_transformation%", data[0][1]);
body.replaceText("%character_want%", data[0][2]);
body.replaceText("%external_problem%", data[0][3]);
body.replaceText("%internal_problem%", data[0][4]);
body.replaceText("%philisophical_problem%", data[0][5]);
body.replaceText("%empathy%", data[0][6]);
body.replaceText("%authority%", data[0][7]);
body.replaceText("%plan_step1%", data[0][8]);
body.replaceText("%plan_step2%", data[0][9]);
body.replaceText("%plan_step3%", data[0][10]);
body.replaceText("%direct_cta%", data[0][11]);
body.replaceText("%transitional_cta%", data[0][12]);
body.replaceText("%failure%", data[0][13]);
body.replaceText("%success%", data[0][14]);
// Save and close the new doc
openDoc.saveAndClose();
//Send email with new document
var message = "Attached is your draft BrandScript"; // Customize message
var emailTo = "to be inserted" // replace with your email
var subject = "Your Draft BrandScript"; // customize subject
var pdf = DriveApp.getFileById(openDoc.getId()).getAs('application/pdf').getBytes();
var attach = {fileName:'DraftBrandScript.pdf',content:pdf, mimeType:'application/pdf'}; // customize file name: "Autogenerated template"
MailApp.sendEmail(emailTo, subject, message, {attachments:[attach]});
}
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function handleFormSubmit(formObject) {
google.script.run.processForm(formObject);
google.script.run.AutofillDocFromTemplate();
document.getElementById("myForm").reset();
}
</script>

I think that the reason of your issue is google.script.run works with the asynchronous process. By this, at the following script,
google.script.run.processForm(formObject);
google.script.run.AutofillDocFromTemplate();
Before processForm is not finished, AutofillDocFromTemplate is run. So in order to remove your issue, I would like to propose the following patterns.
Pattern 1:
In this pattern, withSuccessHandler is used. By this, AutofillDocFromTemplate is run after processForm was run.
From:
google.script.run.processForm(formObject);
google.script.run.AutofillDocFromTemplate();
To:
google.script.run.withSuccessHandler(() => google.script.run.AutofillDocFromTemplate()).processForm(formObject);
Pattern 2:
In this pattern, Google Apps Script is modified. By this, AutofillDocFromTemplate is run after processForm was run.
Google Apps Script side:
From:
function processForm(formObject) {
var url = "https://docs.google.com/spreadsheets/d/1nz2uIWab1eSirljzvNn6SyNyxz3npDTu4mqVYV0blsU/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Data");
ws.appendRow([formObject.company_name,
formObject.identity_transformation,
formObject.character_want,
formObject.external_problem,
formObject.internal_problem,
formObject.philisophical_problem,
formObject.empathy,
formObject.authority,
formObject.plan_step1,
formObject.plan_step2,
formObject.plan_step3,
formObject.direct_cta,
formObject.transitional_cta,
formObject.failure,
formObject.success]);
AutofillDocFromTemplate() // <--- Added
}
HTML&Javascript side:
google.script.run.processForm(formObject);
// google.script.run.AutofillDocFromTemplate(); // <--- removed
Note:
If the issue was not resolved by above modifications, please try to use SpreadsheetApp.flush().
Reference:
Class google.script.run

Related

Copy data from download URL using Google Script

I'm new to App scripts and need help with copying the data to spreadsheet from URL.
However, URL is not a website but link which after clicking with directly download csv file into the computer. Also, its not ending with .csv as I have seen in other examples here.
URL basically coming to my inbox at a specific time. I'm trying to use Fetch URL but its not working at all.
Sample URL -
https://docs.google.com/spreadsheets/d/1oPUPPUmy7psliSznUItT0DnHvilXwZHzyrmdyHpHi18/export?format=csv
function ABC () {
const searchQuery = 'XYZ';
const threads = GmailApp.search(searchQuery, 0,1);
const urls = [];
threads.forEach(thread => {
const messages = thread.getMessages();
messages.forEach(message => {
const body = message.getBody();
var re = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'"".,<>?«»“”‘’]))/i;
const match = body.match(re);
if (match) { urls.push(match[1]); }
});
}) ;
Logger.log(urls);
url = urls.toString().replace("[","").replace("]","") ;
Logger.log(url);
function getData() {
var attValue = '';
// making a call to the target website
var response = UrlFetchApp.fetch(url);
//logging response from target website - In Script Editor > View > Logs
Logger.log(response.getContentText());
//parsing the response data from website
//https://developers.google.com/apps-script/reference/url-fetch/http-response
var rawData = response.getContentText();
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[1]);
var cell = sheet.getRange(1, 1);
cell.setValue(rawData);
}
};
Kindly help so that I can copy the data directly into spreadsheet or store the file in Google Drive with filename as combination of text and date.
Thanks
SUGGESTION
You can try the tweaked script below.
In my understanding, here is your goal:
Get your email messages that contain URLs (CSV file) via "XYZ" search terms.
Process the URL using URLFetchApp service
Place the CSV data into your second sheet tab.
Note: If there's anything else missing or something may have been misunderstood, feel free to let me know.
Tweaked Script
function ABC() {
/**TWEAKED: Created a function call method called "getData" */
const url = {
getData: function () {
const searchQuery = 'XYZ';
const threads = GmailApp.search(searchQuery, 0, 1);
const urls = [];
threads.forEach(thread => {
const messages = thread.getMessages();
messages.forEach(message => {
const body = message.getBody();
var re = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'"".,<>?«»“”‘’]))/i;
const match = body.match(re);
if (match) { urls.push(match[1]); }
});
});
Logger.log(urls);
/**TWEAKED: Instead of using the redundant replace method,
* used "regex" inside a single replace method to replace
* all [ and ] characters */
var geturl = urls.toString().replace(/\[|]/gm, "");
console.log(geturl)
return geturl;
}
}
var attValue = '';
/**TWEAKED: Call the "url" variable's "getData" function that will return the URL */
var response = UrlFetchApp.fetch(url.getData.call());
//logging response from target website - In Script Editor > View > Logs
Logger.log(response.getContentText());
//parsing the response data from website
//https://developers.google.com/apps-script/reference/url-fetch/http-response
var rawData = response.getContentText();
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[1]);
var cell = sheet.getRange(1, 1);
cell.setValue(rawData);
};
Demonstration
After running the ABC() function on the Apps Script editor, the second sheet tab gets populated with the CSV data:
The Apps Script execution log view
References:
JavaScript Function call()

Create PDF from Google Sheet Template

I am fairly new to code and App Script, but I've managed to come up with this from research.
Form submitted, Sheet populated, take entry data, copy and append new file, save as pdf, email pdf
I've created examples of what I've been trying to do
Link to form - https://docs.google.com/forms/d/e/1FAIpQLSfjkSBkn3eQ1PbPoq0lmVbm-Dk2u2TP_F_U5lb45SddsTsgsA/viewform?usp=sf_link
link to spreadsheet - https://docs.google.com/spreadsheets/d/1kWQCbNuisZsgWLk3rh6_Iq107HoK7g-qG2Gln5pmYTE/edit?resourcekey#gid=1468928415
link to template - https://docs.google.com/spreadsheets/d/1Ye7DyJQOjA3J_EUOQteWcuASBCfqlA-_lzyNw0REjY8/edit?usp=sharing
However I receive the following error - Exception: Document is missing (perhaps it was deleted, or you don't have read access?)
at Create_PDF(Code:32:34)
at After_Submit(Code:13:21)
App Script Code as follows - If I use a google Doc as a template it works. However I would like to use a spreadsheet as a template, and have the result pdf content fit to page. Please let me know if you need any additional information for this to work.
function After_Submit(e, ){
var range = e.range;
var row = range.getRow(); //get the row of newly added form data
var sheet = range.getSheet(); //get the Sheet
var headers = sheet.getRange(1, 1, 1,5).getValues().flat(); //get the header names from A-O
var data = sheet.getRange(row, 1, 1, headers.length).getValues(); //get the values of newly added form data + formulated values
var values = {}; // create an object
for( var i = 0; i < headers.length; i++ ){
values[headers[i]] = data[0][i]; //add elements to values object and use headers as key
}
Logger.log(values);
const pdfFile = Create_PDF(values);
sendEmail(e.namedValues['Your Email'][0],pdfFile);
}
function sendEmail(email,pdfFile,){
GmailApp.sendEmail(email, "Subject", "Message", {
attachments: [pdfFile],
name: "From Someone"
});
}
function Create_PDF(values,) {
const PDF_folder = DriveApp.getFolderById("1t_BYHO8CqmKxVIucap_LlE0MhslpT7BO");
const TEMP_FOLDER = DriveApp.getFolderById("1TNeI1HaSwsloOI4KnIfybbWR4u753vVd");
const PDF_Template = DriveApp.getFileById('1Ye7DyJQOjA3J_EUOQteWcuASBCfqlA-_lzyNw0REjY8');
const newTempFile = PDF_Template.makeCopy(TEMP_FOLDER);
const OpenDoc = DocumentApp.openById(newTempFile.getId());
const body = OpenDoc.getBody();
for (const key in values) {
body.replaceText("{{"+key+"}}", values[key]);
}
OpenDoc.saveAndClose();
const BLOBPDF = newTempFile.getAs(MimeType.PDF);
const pdfFile = PDF_folder.createFile(BLOBPDF);
console.log("The file has been created ");
return pdfFile;
}
You get the error message with Google Sheets because you are using a Google Doc class to create the PDF, which is not compatible with Google Sheets.
DocumentApp can only be used with Google Docs. I will advise you to change
const OpenDoc = DocumentApp.openById(newTempFile.getId());
for
const openDoc = SpreadsheetApp.openById(newTempFile.getId());
const newOpenDoc = openDoc.getSheetByName("Sheet1");
And depending on the Google Sheet where the "Body" of the information is located. Replace:
const body = OpenDoc.getBody();
for an equivalent like getRange() or any Range class that helps you target the information you need. For example:
// This example is assuming that the information is on the cel A1.
const body = newOpenDoc.getRange(1,1).getValue();
The template for the PDF should be something like this:

This script does not populate sheet after parsing retrieved data

I hope this is well explained. First of all, sorry because my coding background is zero and I am just trying to "fix" a previously written script.
Problem The script does not populate sheet after parsing retrieved data if the function is triggered by timer and the sheet is not open in my browser .
The script works OK if run it manually while sheet is open.
Problem details:
When I open the sheet the cells are stuck showing "Loading" and after a short time, data is written.
Expected behavior is to get the data written no matter if I don't open the sheet.
Additional info: This is how I manually run the function
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [
{name: "Manual Push Report", functionName: "runTool"}
];
sheet.addMenu("PageSpeed Menu", entries);
}
Additional info: I set the triggers with Google Apps Script GUI See the trigger
Before posting the script code, you can see how the cells look in the sheet:
Script code
function runTool() {
var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Results");
var rows = activeSheet.getLastRow();
for(var i=3; i <= rows; i++){
var workingCell = activeSheet.getRange(i, 2).getValue();
var stuff = "=runCheck"
if(workingCell != ""){
activeSheet.getRange(i, 3).setFormulaR1C1(stuff + "(R[0]C[-1])");
}
}
}
// URL check //
function runCheck(Url) {
var key = "XXXX Google PageSpeed API Key";
var strategy = "desktop"
var serviceUrl = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=" + Url + "&key=" + key + "&strategy=" + strategy +"";
var array = [];
var response = UrlFetchApp.fetch(serviceUrl);
if (response.getResponseCode() == 200) {
var content = JSON.parse(response.getContentText());
if ((content != null) && (content["lighthouseResult"] != null)) {
if (content["captchaResult"]) {
var score = content["lighthouseResult"]["categories"]["performance"]["score"];
} else {
var score = "An error occured";
}
}
array.push([score,"complete"]);
Utilities.sleep(1000);
return array;
}
}
You can try the code using the sheet below with a valid Pagespeed API key.
You only need to add a Trigger and wait for it's execution while the sheet is not open in your browser
https://docs.google.com/spreadsheets/d/1ED2u3bKpS0vaJdlCwsLOrZTp5U0_T8nZkmFHVluNvKY/copy
I suggest you to change your algorithm. Instead of using a custom function to call UrlFetchApp, do that call in the function called by a time-driven trigger.
You could keep your runCheck as is, just replace
activeSheet.getRange(i, 3).setFormulaR1C1(stuff + "(R[0]C[-1])");
by
activeSheet.getRange(i, 3, 1, 2).setValues(runCheck(url));
NOTE
Custom functions are calculated when the spreadsheet is opened and when its arguments changes while the spreadsheet is open.
Related
Cache custom function result between spreadsheet opens

get form URL from a spreadsheet bound Form

In a spreadsheet script I want to send mail to users that will point them to the URL of a form that will let them enter data. I have tried:
function test1(){
var formID = FormApp.getActiveForm();
var formUrl = DriveApp.getUrl(formID);
sendMail(formUrl);
return
}
This fails because the value of formID is allways NULL.
If there is one form linked to spreadsheet
Use
var ss = SpreadsheetApp.getActiveSpreadsheet(); // or openById, etc
var formUrl = ss.getFormUrl();
to get its Url. If needed, FormApp.openByUrl(formUrl); returns a pointer to the form, which allows any other methods.
Multiple forms linked to spreadsheet
There is no built-in method to return the list of forms linked to a given spreadsheet; this is an open issue in Apps Script issues tracker. A workaround is to search all forms (as Cyrus Loree did), get the destination of each, and return the list of those where the destination is the spreadsheet of interest. This is how:
function linkedForms() {
var ssId = SpreadsheetApp.getActiveSpreadsheet().getId();
var formList = [];
var files = DriveApp.getFilesByType(MimeType.GOOGLE_FORMS);
while (files.hasNext()) {
var form = FormApp.openByUrl(files.next().getUrl());
try {
if (form.getDestinationId() == ssId) {
formList.push(form.getPublishedUrl());
}
}
catch(e) {
}
}
return formList;
}
Remarks:
I put form.getDestinationId() in a try block because this method throws an error what the form's destination spreadsheet happens to be deleted (instead of just returning null)
To get the list of form Ids instead of Urls, use form.getId() in the function.
Because you are working in the Spreadsheet, you need to get the associated form from the Spreadsheet object (e.g. SpreadsheetApp.getActiveSpreadsheet.getFormUrl() ).
You will also need to send the mail message with the htmlBody optional parameter.
Here is a code sniplet:
function sendNotice(recipient){
try{
// either hardcode the folder id below
var formStorageFolderId = '';
// or programmatically get the folder from the spreadsheet parent
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssFolder = DriveApp.getFileById(ss.getId()).getParents();
if(ssFolder.hasNext()){
// assume there is only one parent folder
formStorageFolderId = ssFolder.next().getId();
}
var formFolder = DriveApp.getFolderById(formStorageFolderId);
var files = DriveApp.getFilesByType(MimeType.GOOGLE_FORMS);
var formId = '';
while(files.hasNext()){
// search for the form (is it the same name as the spreadsheet?)
var file = files.next();
var fileName = file.getName();
var sheetName = ss.getName();
if(fileName == sheetName){
// matched names
formId = file.getId();
break;
}
}
if(formId){
var actualForm = FormApp.openById(formId);
var formName = actualForm.getTitle();
var formURL = actualForm.getPublishedUrl();
var subject = "Please fill out form";
// html mail message (needed for the link
var mailBody = '<div><p>Please fill out the attached form<p>';
mailBody += '<p>' + formName + '';
MailApp.sendEmail(recipient, subject, '',{htmlBody:mailBody});
}
}catch(err){
Logger.log(err.lineNumber + ' - ' + err);
}
}
I know that it's an old question, but I'll still add an answer to whom it may concern. #user3717023's answer works fine, but for most use-cases, there's a better way.
Generally speaking, Form is connected to Sheet, not to Spreadsheet itself. So, one way to get all of the Spreadsheet forms is to go through the Sheets of the Spreadsheets, and get their Form URL, like that:
function getFormsOfSpreadsheet(spreadsheetId) {
const ss = SpreadsheetApp.openById(spreadsheetId);
const sheets = ss.getSheets();
const formsUrls = [];
for (const sheet of sheets) {
const formUrl = sheet.getFormUrl();
// getFormUrl() returns null if no form connected
if (formUrl) {
formsUrls.push(formUrl);
}
}
return formsUrls;
}
Docs
If this way is not optimal for you (e.g. you have way too many Sheets in your Spreadsheet and only a few of them are linked to Forms), there's still a possibility that the Forms you need to capture are stored in the same Folder. In this case, there's no need to search through the whole Drive to capture them, you can use the same method, but with Folder:
function linkedForms() {
var ssId = SpreadsheetApp.getActiveSpreadsheet().getId();
var formList = [];
var folder = DriveApp.getFolderById(yourFolderId);
var files = folder.getFilesByType(MimeType.GOOGLE_FORMS);
while (files.hasNext()) {
var form = FormApp.openByUrl(files.next().getUrl());
try {
if (form.getDestinationId() == ssId) {
formList.push(form.getPublishedUrl());
}
}
catch(e) {
}
}
return formList;
}
Docs

Getting TypeError in onFormSubmit trigger?

I used a Google Forms tutorial to tweak Form data to merge into a PDF and then send to an email. I am getting the following error message when I try to run the script:
TypeError: Cannot read property "values" from undefined. (line 11, file "Code")
I do not know how to fix the problem. I have searched the web for an answer. Here is a copy of the script. I marked the 2 lines where the script is giving an error:
var docTemplate = "1ZSqmId2BBjtz6PmgQEmusjnkHGsFKD1CBSq0rrQk6Kc";
var docName = "TestCertificate";
// When Form Gets submitted
function onFormSubmit(e) {
//Get information from form and set our variables
var email_address = "EMAIL#example.com";
//**(THIS IS WHERE THE ERROR IS OCCURRING ON THESE 2 LINES BELOW!)**
var full_name = e.values[2];
var Activity = e.values[3];
// Get document template, copy it as a new temp doc, and save the Doc’s id
var copyId = DocsList.getFileById(docTemplate)
.makeCopy(docName+' for '+full_name)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document’s body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keyFullName', full_name);
copyBody.replaceText('keyActivity', Activity);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert document to PDF
var pdf = DocsList.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "Report";
var body = "Here is the form for " + full_name + "";
MailApp.sendEmail(email_address, subject, body, {htmlBody: body, attachments: pdf});
// Delete temp file
DocsList.getFileById(copyId).setTrashed(true);
}
Here are links to the form and certificate I was testing.
Form/Spreadsheet
Document Template
The error you're seeing is because you're running a trigger function in the Script Editor. When you do this, the Event Parameter e is not defined - that's what the error message is saying.
For more background, see How can I test a trigger function in GAS?
Here's a test function that will run your onFormSubmit() function multiple times, with the data that's already in your spreadsheet. It reads each row of the sheet, generates an object to simulate the Event you would get when a form was submitted, then calls the trigger function. If you place breakpoints inside onFormSubmit(), or rely on Logger.log(), this technique will allow you to test your trigger function.
function test_onFormSubmit() {
var dataRange = SpreadsheetApp.getActiveSheet().getDataRange()
var data = dataRange.getValues();
var headers = data[0];
// Start at row 1, skipping headers in row 0
for (var row=1; row < data.length; row++) {
var e = {};
e.values = data[row];
e.range = dataRange.offset(row,0,1,data[0].length);
e.namedValues = {};
// Loop through headers to create namedValues object
for (var col=0; col<headers.length; col++) {
e.namedValues[headers[col]] = e.values[col];
}
// Pass the simulated event to onFormSubmit
onFormSubmit(e);
}
}
I've done no other debugging of your original function... but this gets rid of that error message, so you can continue testing.
I use the below code to test my triggers
//
//
function onFormSumbit(e) {
//Timestamp 1 Status Remarks 3 Expected Completion Date 4 TRB Number
var resp = e.source.getActiveSheet().getRange(e.range.rowStart,1, e.range.rowStart,5 ).getValues();
/*
function test(){
var ss=SpreadsheetApp.getActive();
var respsht=ss.getSheetByName("Form responses 1");
var resp = respsht.getRange("A119:P119").getValues();
*/
I will comment out the onformsubmit portion and run the test portion.
Once the function is working, I will comment out the test function and activate the onformsubmit function.
Simple solution :)