Google Script timing out when grabbing rows from Database (MYSQL) - mysql

function myFunction() {
var ServerIP = 'xxx.xxx.xxx.xxx';
var SQL_Port = '3306';
var SQL_Usr = 'GDriveUser';
var SQL_Pwd = '**********';
var SQL_DB = 'wordpress_10';
var connectorInstance = 'jdbc:mysql://' + ServerIP+':'+SQL_Port;
var ConnectString = connectorInstance+'/'+SQL_DB;
var conn = Jdbc.getConnection(ConnectString, SQL_Usr, SQL_Pwd);
conn.setAutoCommit(false)
var SQLstatement = conn.createStatement();
var result = SQLstatement.executeQuery("SELECT * FROM `TABLE35` WHERE Team in ( 'atl', 'bkn', 'bos', 'cha', 'chi', 'cle', 'dal', 'den', 'det', 'gsw') and Date > 20201201 ORDER BY Date ASC");
var ss = SpreadsheetApp.openById("1QTv67oSTYnwsD0kwd0sDubzAor19pfAVngubjePqtzJg");
var sheet = ss.getSheetByName("Imported");
var cell = sheet.getRange('A2');
// loop through result object, setting cell values to database data
var row = 0;
while(result.next()) {
for(var i=0; i<23; i++) { // four fields per record
cell.offset(row, i).setValue(result.getString(i+1));
}
row++;
}
result.close();
SQLstatement.close();
conn.close();
}
This Google Script is only putting about 150 rows into my Google Sheet and then it times out.
Can someone help me find a fix for this?

Something like this:
function myFunction() {
var ServerIP = 'xxx.xxx.xxx.xxx';
var SQL_Port = '3306';
var SQL_Usr = 'GDriveUser';
var SQL_Pwd = '**********';
var SQL_DB = 'wordpress_10';
var connectorInstance = 'jdbc:mysql://' + ServerIP+':'+SQL_Port;
var ConnectString = connectorInstance+'/'+SQL_DB;
var conn = Jdbc.getConnection(ConnectString, SQL_Usr, SQL_Pwd);
conn.setAutoCommit(false)
var SQLstatement = conn.createStatement();
var result = SQLstatement.executeQuery("SELECT * FROM `TABLE35` WHERE Team in ( 'atl', 'bkn', 'bos', 'cha', 'chi', 'cle', 'dal', 'den', 'det', 'gsw') and Date > 20201201 ORDER BY Date ASC");
var ss = SpreadsheetApp.openById("1QTv67oSTYnwsD0kwd0sDubzAor19pfAVngubjePqtzJg");
var sheet = ss.getSheetByName("Imported");
var cell = sheet.getRange('A2');
// loop through result object, setting cell values to database data
var row = 0;
let oA=[];
sheet.getRange(2,1,sheet.getLastRow()-1,sheet.getLastColumn()).clearContent();//clear content before writing
while(result.next()) {
let rA=[];
for(var i=0; i<23; i++) {
rA.push(result.getString(i+1));
}
oA.push(rA);
}
sheet.getRange(2,1,oA.length,oA[0].length).setValues(oA);//starts at row 2 every time
result.close();
SQLstatement.close();
conn.close();
}

Related

AppScript Select active range

so i am trying to when i select any column form the row, returns me the column E value, some one know how?
i don't know if i made me clear, but the idea is save the value and display after in a sidebar as default value
i have onde function who does something similar, but i don't know how works
function notifyReporterForm() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_BUGS);
var row = ss.getLastRow(), column = 1, numRows = 1, numColumns = ss.getLastColumn();
var values = ss.getRange(row, column, numRows, numColumns).getValues();
var to = values[0][2];
var user_email = values[0][3];
var ticketNo = values[0][0];
var openedDate = values[0][1]
var details = ''
var summary = values[0][6]
var text = values[0][6].split('\n')
var image_url = values[0][8]
text.map(row => {
if(row){
details += '<p>' + row + '</p>'
}
})
function onSelectionChange(e) {
const sh = e.range.getSheet();
e.source.toast(sh.getRange(e.range.rowStart,5).getValue());
e.range.setValue(sh.getRange(e.range.rowStart,5).getValue());
}

Exporting Google Form Responses into Google Cloud SQL

I have a google form setup to submit responses to a Google SQL Database upon submission. I can't seem to figure out how to get the responses off of the form and put them into the strings. Take a look:
var address = 'address';
var user = 'sysImporter';
var userPwd = 'password';
var db = 'db';
var dbUrl = 'jdbc:mysql://' + address + '/' + db;
function handleFormSubmit() {
var form = FormApp.getActiveForm();
var formResponses = form.getResponses();
var formResponse0 = formResponses[0];
var formResponse1 = formResponses[1];
var formResponse2 = formResponses[2];
var formResponse3 = formResponses[3];
var formResponse4 = formResponses[4];
var formResponse5 = formResponses[5];
var itemResponses0 = formResponse0.getItemResponses();
var itemResponses1 = formResponse1.getItemResponses();
var itemResponses2 = formResponse2.getItemResponses();
var itemResponses3 = formResponse3.getItemResponses();
var itemResponses4 = formResponse4.getItemResponses();
var itemResponses5 = formResponse5.getItemResponses();
var itemResponse0 = itemResponses0[0];
var itemResponse1 = itemResponses1[0];
var itemResponse2 = itemResponses2[0];
var itemResponse3 = itemResponses3[0];
var itemResponse4 = itemResponses4[0];
var itemResponse5 = itemResponses5[0];
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var stmt = conn.prepareStatement('INSERT INTO Volunteer '
+ '(FirstName, LastName, PrimaryPhone, SecondaryPhone, VolunteerEmail, Volunteerstatus) values (?, ?, ?, ?, ?, ? )');
stmt.setString(1, itemResponse1.getResponse());
stmt.setString(2, itemResponse2.getResponse());
stmt.setString(3, itemResponse3.getResponse());
stmt.setString(4, itemResponse4.getResponse());
stmt.setString(5, itemResponse0.getResponse());
stmt.setString(6, itemResponse5.getResponse());
stmt.execute();
}
The current error I get is:
TypeError: Cannot read property 'getItemResponses' of undefined
at handleFormSubmit(Code:24:38)
getResponse() retrieves all of the responses for a form, from there you must choose which response you want (in my case the most recent) and dissect it for the answers to the questions, here's what I ended up with:
function handleFormSubmit() {
//Grab form response list
var form = FormApp.getActiveForm();
var formResponses = form.getResponses();
//choose most recent response
var formLastResponse = formResponses.length - 1;
//grab items from response
var response = formResponses[formLastResponse];
var itemResponses = response.getItemResponses();
//set items to local variables
var email = response.getRespondentEmail();
var fname = itemResponses[0].getResponse();
var lname = itemResponses[1].getResponse();
var primaryphone = itemResponses[2].getResponse();
var secondaryphone = itemResponses[3].getResponse();
var staus = itemResponses[4].getResponse();
//connect to DB
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
//send SQL Statment to DB
var stmt = conn.prepareStatement('INSERT INTO Volunteer '
+ '(FirstName, LastName, PrimaryPhone, SecondaryPhone, VolunteerEmail, Volunteerstatus) values (?, ?, ?, ?, ?, ? )');
stmt.setString(1, fname);
stmt.setString(2, lname);
stmt.setString(3, primaryphone);
stmt.setString(4, secondaryphone);
stmt.setString(5, email);
stmt.setString(6, staus);
stmt.execute();
}

FormApp.getActiveForm() returns incorrect form id when called from form trigger which contains this function call

I’m trying to automate work routines with google forms, php and mysql. I did the following software architecture.
There is the form named as S, it is the static one, since I created it manually using GUI. Form Sform has the form submit trigger which puts data into the my mysql database.
After that data is processed by the php script which finally calls google script, which is published as a web application.
This script gets get parameters and parses them, gets new processed data from my database and programmatically builds forms depending on the selected data, finally it adds a trigger to dynamically (programmatically) created form or forms (let's name them as Dform).
The problem is that the function FormApp.getActiveForm() which is coded in the trigger of programmatically created form returns form id of the static form (which is manually created).
Here the code of static form Sform submit trigger:
function SaveData() {
var form = FormApp.getActiveForm();
var formResponses = form.getResponses();
var formResponse = formResponses[formResponses.length-1];
var email = formResponse.getRespondentEmail();
var itemResponses = formResponse.getItemResponses();
var workDay = null;
var workFiles = null;
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
if (itemResponse.getItem().getTitle() == 'Pick the date of files you uploading') {
workDay = itemResponse.getResponse().toString();
}
if (itemResponse.getItem().getTitle() == 'Choose log files to be uploaded') {
workFilesIds = itemResponse.getResponse();
}
}
var dbUrl = '...';
var user = '...';
var userPwd = '...';
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var stmt = conn.prepareStatement('select worker_id from in_workers where worker_name = ?');
stmt.setString(1, email);
var results = stmt.executeQuery();
var worker_id = -1;
while (results.next()) {
worker_id = results.getString(1);
}
results.close();
if (worker_id == -1) {
stmt = conn.prepareStatement('INSERT INTO in_workers '
+ '(worker_name) values (?)', 1);
stmt.setString(1, email);
stmt.executeUpdate();
var res = stmt.getGeneratedKeys();
res.beforeFirst();
res.next();
worker_id = res.getInt(1);
}
var fName = '';
var fBlob = new Array(workFilesIds.length);
for (var j = 0; j < workFilesIds.length; j++) {
var file = DriveApp.getFileById(workFilesIds[j]);
fName = fName + '\n\r' + file.getName();
fBlob[j] = file;
stmt = conn.prepareStatement('INSERT INTO test_dep_files '
+ '(worker_id, file_name, file_date, file_body) values (?, ?, ?, ?)');
stmt.setString(1, worker_id);
stmt.setString(2, file.getName());
stmt.setDate(3, Jdbc.parseDate(workDay));
stmt.setBytes(4, file.getBlob().getBytes());
stmt.executeUpdate();
}
conn.close();
GmailApp.sendEmail('...', 'Control workplace form completed'
, 'User ' + email + ' uploaded data on ' + workDay
+ ' file list: ' + fName,
{attachments: fBlob, name: fName});
}
Here the code of script published as web application:
function doGet(e) {
var worker_id = e.parameter['worker_id'];
var form_trig_func_name = e.parameter['form_trig_func_name'];
var dbUrl = '...';
var user = '...';
var userPwd = '...';
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
stmt = conn.prepareStatement('select form_id from in_workers where worker_id = ?');
stmt.setString(1, worker_id);
var results = stmt.executeQuery();
var form_id;
results.beforeFirst();
while (results.next()) {
form_id = results.getString(1);
}
results.close();
var form;
try {
form = FormApp.openById(form_id);
var items = form.getItems();
var l = items.length;
for (var j = 0; j < l; j++) {
form.deleteItem(0);
}
} catch (e) {
form = FormApp.create('Enter additional products data');
}
stmt = conn.prepareStatement('select fc_id, fc_name_sys, fc_date from test_dep_fc t1'
+ ', test_dep_files t2 where t1.file_id = t2.file_id and fc_name_real is null '
+ 'and worker_id = ?');
stmt.setString(1, worker_id);
var results = stmt.executeQuery();
results.beforeFirst();
while (results.next()) {
form.addTextItem()
.setTitle(results.getString(2) + ' от ' + results.getString(3))
.setHelpText(results.getString(1));
}
results.close();
form_id = form.getId();
var allTriggers = ScriptApp.getUserTriggers(form);
var l = allTriggers.length;
for (var i = 0; i < l; i++)
ScriptApp.deleteTrigger(allTriggers[i]);
allTriggers = ScriptApp.getProjectTriggers();
l = allTriggers.length;
for (var i = 0; i < l; i++) {
if (allTriggers[i].getHandlerFunction() === 'saveData' + form_trig_func_name) {
ScriptApp.deleteTrigger(allTriggers[i]);
}
}
ScriptApp.newTrigger('saveData'+form_trig_func_name)
.forForm(form)
.onFormSubmit()
.create();
var form_url = form.getPublishedUrl();
stmt = conn.prepareStatement('update in_workers set form_id = ?, form_url = ? where worker_id = ?');
stmt.setString(1, form_id);
stmt.setString(2, form_url);
stmt.setString(3, worker_id);
stmt.execute();
conn.close();
return HtmlService.createHtmlOutput(form_id + '\n\r' + form_trig_func_name);
}
This is the code of dynamically (programmatically) created forms Dforms:
function saveData2() {
var form = FormApp.getActiveForm();
var formResponses = form.getResponses();
var formResponse = formResponses[formResponses.length-1];
var itemResponses = formResponse.getItemResponses();
var dbUrl = '...';
var user = '...';
var userPwd = '...';
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var fc_names_real = '';
var fc_ids = '';
var fc_names_sys = '';
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
var fc_id = itemResponse.getItem().getHelpText();
var fc_name_sys = itemResponse.getItem().getTitle();
var fc_name_real = itemResponse.getResponse().toString();
fc_names_real = fc_names_real + ' ' + fc_name_real;
fc_ids = fc_ids + ' ' + fc_id;
fc_names_sys = fc_names_sys + ' ' + fc_name_sys;
stmt = conn.prepareStatement('update test_dep_fc '
+ 'set fc_name_real = ? where '
+ 'fc_id = ?');
stmt.setString(1, fc_name_real);
stmt.setString(2, fc_id);
stmt.executeUpdate();
}
conn.close();
GmailApp.sendEmail('...', 'Control workplace form2 completed'
, 'Product serial nums: ' + fc_names_real
+ '\n\rProducts sys nums: ' + fc_names_sys
+ '\n\rProducts ids: ' + fc_ids
);
}
function saveData3() {
the same code as for saveData2
}
function saveData4() {
the same code as for saveData2
}
function saveData5() {
the same code as for saveData2
}
...
So the problem is that in saveData2 first code instruction returns wrong form id. It always returns form id of Sform.
Please help me with this, I'm ready to think that I have found a google forms bug.
Thanks a lot, Yaroslav
EDIT 1
hi #tehhowch, thank you, I did try, but, unfortunately, following code
function saveData2(e) {
//var form_id = e.source.getId();
...
returns wrong form id as well, it returns Sform id.
Finally this issue was solved next day it was written here. The solution is as simple as it is stupid one.
In the script published as web application code I add following instructions after form creation code. I save trigger function name to its properties.
PropertiesService.getDocumentProperties().setProperty(
'saveData'+form_trig_func_name, form_id);
Code to dynamically (programmatically) create forms Dforms was rewritten. When corresponding trigger fires I just take a formId in earlier saved property value.
function saveData2(e) {
//var form_id = e.source.getId();
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData2');
saveDataAll (form_id, 2);
}
function saveData3() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData3');
saveDataAll (form_id, 3);
}
function saveData4() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData4');
saveDataAll (form_id, 4);
}
function saveData5() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData5');
saveDataAll (form_id, 5);
}
function saveData6() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData6');
saveDataAll (form_id, 6);
}
function saveData7() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData7');
saveDataAll (form_id, 7);
}
function saveData8() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData8');
saveDataAll (form_id, 8);
}
function saveData9() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData9');
saveDataAll (form_id, 9);
}
function saveData10() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData10');
saveDataAll (form_id, 10);
}
function saveData11() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData11');
saveDataAll (form_id, 11);
}
function saveDataAll (form_id, saveData)
{
var form = FormApp.openById(form_id);
...
I have not more then ten users of this functional and such workaround works for me. So the problem is closed.

Looping through a google sheet to remove rows - Compare dates

The code needs to delete rows have a date before the current date. I'm not getting any syntax errors, but I think there is a semantic problem as the code will not change the spreadsheet in any way.
function checkDateValue(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var todaysDate = new Date().getDate();
var columnGCells = sheet.getRange("G2:G");
var columnG = columnGCells.getValues();
for (i = 1; i < sheet.height; i++) {
var endDate = new Date()
endDate = columnG[i];
if (todaysDate.getYear() >= endDate.getYear()){
if (todaysDate.getMonth() >= endDate.getMonth()){
if (todaysDate.getDay >= endDate.getDay()){
sheet.deleteRow(i);
}
}
}
}
};
checkDateValue();
The code would probably look something like this:
function checkDateValue(e) {
var colG_values,columnGCells,columnNumber,endDate,i,lastRow,
sheet,startRow,todaysDate;
startRow = 2;//Get data starting in this row
columnNumber = 7://The column number to get the data from
sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
lastRow = sheet.getLastRow();
todaysDate = new Date().getDate();
//Logger.log('todaysDate: ' + todaysDate);
columnGCells = sheet.getRange(startRow,columnNumber,lastRow-1,1);
colG_values = columnGCells.getValues();
for (i = lastRow; i > 1; i--) {//Loop through values from last to first-
//Need to stop at row one-
endDate = colG_values[i];
endDate = new Date(endDate);
if (todaysDate.getYear() >= endDate.getYear()){
if (todaysDate.getMonth() >= endDate.getMonth()){
if (todaysDate.getDay >= endDate.getDay()){
sheet.deleteRow(i);//Delete this row
}
}
}
};
};
function runTest() {
checkDateValue();
};

Insert data range from Google Sheets to MySQL

I'm trying to create a function that takes a data range/specified range in my Google spreadsheet and inserts every row that isn't blank into a MySQL table.
I want to take column range A:V in "Sheet One" and insert them to the "mysql_table" table. I'm new to using JDBC google scripts and below is what I've come up with so far, but I can't get it to work with my current knowledge.
function putData() {
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
conn.setAutoCommit(false);
var ss = SpreadsheetApp.getActiveSpreadsheet(),
sheet = ss.getSheetByName("Sheet One"),
range = sheet.getDataRange(),
values = range.getValues(),
row;
var start = new Date();
function writeManyRecords() {
for (var r=1; r<values.length; r++) {
if( values[r].join('') === '' ) return 'Blank row encountered';
row = values[r];
var i = 0;
var stmt = conn.prepareStatement('INSERT INTO mysql_table '
+ '(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18, field19, field20, field21, field22) values (' + start + row[i] + ')');
stmt.addBatch();
var batch = stmt.executeBatch();
conn.commit();
conn.close();
var end = new Date();
}
}
}
Anyone have any ideas on how I can achieve this?
I came up with a solution and I'm posting it here for anyone else looking for a way of writing to MySQL from Google Sheets. Here's a simplified version:
function putData() {
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var stmt = conn.createStatement();
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i++) {
var sql = "INSERT INTO test (test, num) VALUES ('" + data[i][0] + "'," + data[i][1] + ")";
var count = stmt.executeUpdate(sql,1)
}
stmt.close();
conn.close();
}