pull MySQL table data to gsheet via JDBC - mysql

I'm attempting to pull data from a mySQL table and populate it into a gsheet. I've written the following script, but I'm given an error at line 50 "Cannot convert array to Object". I'm certain this is a 2d array. I'm sure I'm missing something obvious, though, as this is my very first script.
function readFromTable() {
var ss = SpreadsheetApp.getActive();
var sheetDetails = ss.getSheetByName('Details');
var sheetData = ss.getSheetByName('Data');
var host = sheetDetails.getRange("B1").getValue();
var databaseName = sheetDetails.getRange("B2").getValue();
var userName = sheetDetails.getRange("B3").getValue();
var password = sheetDetails.getRange("B4").getValue();
var port = sheetDetails.getRange("B5").getValue();
var tableName = sheetDetails.getRange("B6").getValue();
var url = 'jdbc:mysql://'+host+':'+port+'/'+databaseName;
var sql = 'SELECT * FROM ' + tableName;
try{
var connection = Jdbc.getConnection(url, userName, password);
var results = connection.createStatement().executeQuery(sql);
var metaData = results.getMetaData();
var columns = metaData.getColumnCount();
//Retrieve metaData to a 2D array
var values = [];
var value = [];
var element = '';
//Get table headers
for(i = 1; i <=columns; i ++){
element = metaData.getColumnLabel(i);
value.push(element);
}
values.push(element);
//Get table data row by row
while(results.next()){
value = [];
for(i = 1; i <= columns; i ++){
element = results.getString(i)
value.push(element);
}
values.push(value);
}
//Close connection
results.close();
//Write data to sheet Data
sheetData.clear();
sheetData.getRange(1, 1, values.length, value.length).setValues(values);
SpreadsheetApp.getActive().toast('Your data has been refreshed');
}catch(err){
SpreadsheetApp.getActive().toast(err.message);
}
}

Related

Wrong MYSQL format number in Google Sheets via JDBC

The numbers that I import from an sql database on google sheet are interpreted as duration and not as numbers, more specifically as currencies.
colA
colB
colC
colD
449
1234
29521.00
0.00
449
1234
29521.00
0.00
Wrong = 29521.00 (format currently imported)
Correct = € 29.521,00
What am I doing wrong in colC and colD?
function runSql(query, options) {
console.log('query from runSql :' + query);
var doc = SpreadsheetApp.getActiveSpreadsheet();
var sheet = doc.getSheets()[2];
var cell = sheet.getRange('a1');
var activeCellRow = cell.getRow();
var activeCellCol = cell.getColumn();
var rs = [];
try {
var fullConnectionString = 'jdbc:' + DB_TYPE + '://' + HOST + ':' + PORT
var conn = Jdbc.getConnection(fullConnectionString, USERNAME, PASSWORD);
console.log('query :', query)
var stmt = conn.createStatement();
stmt.execute('USE ' + DATABASE);
var start = new Date();
var stmt = conn.createStatement();
//stmt.setMaxRows(MAXROWS);
var rs = stmt.executeQuery(query);
} catch (e) {
console.log(e, e.lineNumber);
Browser.msgBox(e);
return false
}
var results = [];
cols = rs.getMetaData();
console.log("cols", cols)
var colNames = [];
var colTypes = {};
for (i = 1; i <= cols.getColumnCount(); i++) {
var colName = cols.getColumnLabel(i)
colTypes[colName] = { type: cols.getColumnTypeName(i), loc: i }
colNames.push(colName);
}
var rowCount = 1;
results.push(colNames);
while (rs.next()) {
curRow = rs.getMetaData();
rowData = [];
for (i = 1; i <= curRow.getColumnCount(); i++) {
rowData.push(rs.getString(i));
}
results.push(rowData);
rowCount++;
}
rs.close();
stmt.close();
conn.close();
console.log('results', results)
var colCount = results[0].length
var rowCount = results.length
var comment = "Updated on: " + (new Date()) + "\n" + "Query:\n" + query
if (options.omitColumnNames) {
results = results.slice(1)
rowCount -= 1
}
if (options.clearColumns && sheet.getLastRow() > 0) {
var startCellRange = sheet.getRange(startCell)
sheet.getRange(startCellRange.getRow(), startCellRange.getColumn(), sheet.getLastRow(), colCount).clearContent();
}
if (options.clearSheet) {
var startCellRange = sheet.getRange(startCell)
sheet.clear({ contentsOnly: true });
}
//sheet.getRange(activeCellRow, activeCellCol, rowCount, colCount).clearContent();
sheet.getRange(activeCellRow, activeCellCol, rowCount, colCount).setValues(results);
var cell = sheet.getRange(activeCellRow, activeCellCol)
cell.clearNote()
cell.setNote(comment);
sheet.setActiveRange(sheet.getRange(activeCellRow + rowCount + 1, activeCellCol))
console.log('query success!, rows = ', rowCount - 1)
}
function runSqlFromSheet() {
//var doc = SpreadsheetApp.getActiveSpreadsheet();
var doc = SpreadsheetApp.getActiveSpreadsheet();
var sheet = doc.getActiveSheet();
var sheet = doc.getSheets()[2];
var sheetName = sheet.getName();
var cell = doc.getActiveSheet().getActiveCell();
//var sql2 = '{call P_Totali_per_Azienda(?)}';
//Logger.log('sql2;', sql2)
var options = {}
console.log(sql2);
runSql(sql2, options)
}
The fact that the values get automatically converted to durations suggests that the data is in a format that makes Google Sheets consider them as duration values. This can happen if you read and write the data as text strings and your spreadsheet is in a locale that uses commas as decimal separators (as in € 1,99) and periods as time separators (as in 12.00). If you are reading the values as text strings, you may need to read them as numbers instead to avoid automatic conversion.
Consider using ResultSet.getFloat() instead of ResultSet.getString().
Once you can write the values correctly to the spreadsheet, you can set the final format programmatically, like this:
SpreadsheetApp.getActive()
.getRange("Sheet1!C2:D")
.setNumberFormat("[$ €]#,##0.00");
If you always write the values to the same sheet, and get the data as numbers from the database, you can most likely manually format columns C:D as Format > Number > Currency just once, and have the format stick through future imports.

Top level of JSON files, object? array?

I am using flutter/dart to fetch JSON files from Google Sheet. I use 2 different methods to get the same Google sheet, one is by scripting and the other is from 'sheetlabs' service. However, sheetlabs works and scripting fails. The top level from sheetlabs is an array while the top level from scripting is an object.
I just copy the scripting file from YouTube and I have no idea of google scripting. How can I modify the scripting code to make the top level being and array just like sheetlabs' file?
The structure of google sheet is relatively simple-- 10 columns with 'stockcode','stockname' ,etc as header which are freezed. Six stocks' data in rows.
Below is the scripting code.
function doGet(e){
var ss = SpreadsheetApp.openByUrl("MY ORIGINAL GOOGLE SHEET'S URL ADDRESS");
var sheet = ss.getSheetByName("sheet1");
return getUsers(sheet);
}
function getUsers(sheet){
var jo = {};
var dataArray = [];
var rows = sheet.getRange(2,1,sheet.getLastRow()-1, sheet.getLastColumn()).getValues();
for(var i = 0, l= rows.length; i<l ; i++){
var dataRow = rows[i];
var record = {};
record['stockname'] = dataRow[0];
record['stockcode'] = dataRow[1];
record['marketvalue'] = dataRow[2];
record['amount'] = dataRow[3];
record['currentprice'] = dataRow[4];
record['averagecost'] = dataRow[5];
record['profit'] = dataRow[6];
record['profitpercent'] = dataRow[7];
record['previousclosingprice'] = dataRow[8];
record['todaysprofit'] = dataRow[9];
dataArray.push(record);
}
jo.user = dataArray;
var result = JSON.stringify(jo);
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
You create json objects in the for loop.
You need to comment out var jo = {};
The following should work:
function doGet(e){
var ss = SpreadsheetApp.openByUrl("MY ORIGINAL GOOGLE SHEET'S URL ADDRESS");
var sheet = ss.getSheetByName("sheet1");
return getUsers(sheet);
}
function getUsers(sheet){
var dataArray = [];
var rows = sheet.getRange(2,1,sheet.getLastRow()-1, sheet.getLastColumn()).getValues();
for(var i = 0, l= rows.length; i<l ; i++){
var dataRow = rows[i];
var record = {};
record['stockname'] = dataRow[0];
record['stockcode'] = dataRow[1];
record['marketvalue'] = dataRow[2];
record['amount'] = dataRow[3];
record['currentprice'] = dataRow[4];
record['averagecost'] = dataRow[5];
record['profit'] = dataRow[6];
record['profitpercent'] = dataRow[7];
record['previousclosingprice'] = dataRow[8];
record['todaysprofit'] = dataRow[9];
dataArray.push(record);
}
var result = JSON.stringify(dataArray);
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);

Load data from google sheet on start up

I tried to retrieve a list of agents who are stored in a google sheet. The problem that I am facing right now is that I can get the list of agents in the script file. However, when I try to pass it to an html file, I keep getting null for the list. I absolutely has no idea how that can be.
Can someone give me an idea where I should look for?
My script:
var DB_URL = "";
var AGENT_DB = "";
var CREATED_ON_IDX = 0;
var NAME_IDX = 1;
var EMAIL_IDX = 2;
function agentService_getAgents() {
var ss = SpreadsheetApp.openByUrl(DB_URL);
var sheet = ss.getSheetByName(AGENT_DB);
var dataRange = sheet.getDataRange();
var agents = [];
var values = dataRange.getValues();
for (var i = 1; i < values.length; ++i) {
var row = values[i];
var name = row[NAME_IDX];
var email = row[EMAIL_IDX];
var createdOn = row[CREATED_ON_IDX];
var agent = new Agent(name, email, createdOn);
agents[i-1] = agent;
}
Logger.log(agents);
return agents;
}
Ajax call in Html
<script type="text/javascript">
function onSuccess(agents) {
var $table = $("table");
console.log(agents);
}
google.script.run.withSuccessHandler(onSuccess)
.agentService_getAgents();
</script>
So Logger.log(agents) gives me a list of agent; but console.log(agents) gives me null.

Update Google FusionTables programmatically using data from spreadsheet

I am trying to update four out of five columns in FusionTables using data from Google Spreadsheet. I have just started programming Apps-scripts. I need help with update query. Any suggestions or feedback is appreciated. Thank you in advance.
function sync() {
var tasks = FusionTables.Task.list(TABLE_ID);
// Only run if there are no outstanding deletions or schema changes.
if (tasks.totalItems === 0) {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
//i = 1 for 1st row with values in spreadsheet. 0 for column headers.
for (var i = 1; i < data.length; i++) {
var cName = data[i][0];
var ed_vs = data[i][1];
var ed_vs_ada = data[i][2];
var color = data[i][3];
//update ft
var updateQry = "update "+TABLE_ID+" set ED_VS = "+ed_vs+",ED_VS_ADA = "+ed_vs_ada+", COLOR = "+color+ "where COUNTY = "+cName;
//FusionTables.Query.sql(updateQry);
//is this even possible to execute an update query? help with syntax?
Logger.log(updateQry);
}
}
};
Here's working solution for someone with similar issue.
function sync() {
var tasks = FusionTables.Task.list(TABLE_ID);
// Only run if there are no outstanding deletions or schema changes.
if (tasks.totalItems === 0) {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
//i = 1 for 1st row with values in spreadsheet. 0 will give column headers.
for (var i = 1; i < data.length; i++) {
var cName = data[i][0];
var ed_vs = data[i][1];
var ed_vs_ada = data[i][2];
var color = data[i][3];
//parse rowid from output
var selQry = "select ROWID FROM "+TABLE_ID+" where COUNTY = '"+cName+"' ";
var cdata = FusionTables.Query.sql(selQry);
var c_rowid = cdata.rows[0][0]; //rowid
Logger.log(c_rowid);
var updateQry = "update "+TABLE_ID+" set ED_VS = '"+ed_vs+"',ED_VS_ADA = '"+ed_vs_ada+"', COLOR = '"+color+ "' where ROWID = '"+c_rowid+"' ";
FusionTables.Query.sql(updateQry);
Logger.log(updateQry);
}
}
};

Get XML File - Find Duplicate before adding new rows

I'm French and beginner in the app script.
My Problem:
I get data from a "var resultat = UrlFetchApp.fetch(url).getContentText();" that gives me an XML file
I want to add the result in my spreadsheet BUT before I would like to know if the row already exists in my spreadsheet.
I try to do this:
function GetMeteo() {
url = "http://www.yr.no/place/France/Alsace/Strasbourg/forecast_hour_by_hour.xml";
var resultat = UrlFetchApp.fetch(url).getContentText();
var root = XmlService.parse(resultat).getRootElement();
var entries = root.getChild('forecast').getChild('tabular').getChildren();
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var newData = new Array();
for (var i =0 ; i < entries.length; i++) {
var heure = entries[i].getAttribute('from').getValue();
var precipitation = entries[i].getChild('precipitation').getAttribute('value').getValue();
var windDirection = entries[i].getChild('windDirection').getAttribute('deg').getValue();
var windSpeed = entries[i].getChild('windSpeed').getAttribute('mps').getValue();
var temperature = entries[i].getChild('temperature').getAttribute('value').getValue();
var pressure = entries[i].getChild('pressure').getAttribute('value').getValue();
var duplicate = -1;
Données.activate();
var data = Données.getDataRange().getValues();
for (j in data) {
if (data[j][0] == heure) {
duplicate = j;
}
else {
duplicate = -1;
}
}
if (NumLigne == -1) {
data.push({heure,precipitation,windDirection,windSpeed,temperature,pressure});
}
else {
data[NumLigne].push({heure,precipitation,windDirection,windSpeed,temperature,pressure});
}
}
But the DataPush does not work.