I am using a Google Script bound to a Google Sheet to programatically generate the following query:
=query('16 Jul - 20 Jul Responses'!A1:I31, "SELECT C WHERE D = 'Available'", 0)
Is there any way in Google Scripts to parse an object representation of that query's results? I'd like to be able to code something like:
var queryString = '=query('16 Jul - 20 Jul Responses'!A1:I31, "SELECT C WHERE D = 'Available'", 0)';
var results = new Query(queryString);
for(var i = 0; i < results.length; i++) {
var result = results[i];
// do something
}
As far as I can tell, the Query object doesn't exist unless you are working with a Google Web App. Is this true? Or is there a way to implement this idea?
=QUERY is a spreadsheet function. If you want that functionality in Apps Script you can leverage Google's Visualization API and Query Language. I wrote a custom module for it in GAS. Here's an extract:
(function(context) {
const Utils = (context.Utils || (context.Utils = {}));
/**
* Queries a spreadsheet using Google Visualization API's Datasoure Url.
*
* @param {String} ssId Spreadsheet ID.
* @param {String} query Query string.
* @param {String|Number} sheetId Sheet Id (gid if number, name if string). [OPTIONAL]
* @param {Number} headers Header rows. [OPTIONAL]
*/
Utils.gvizQuery = function(ssId, query, sheetId, headers) {
var response = JSON.parse( UrlFetchApp
.fetch(
Utilities.formatString(
"https://docs.google.com/spreadsheets/d/%s/gviz/tq?tq=%s%s%s",
ssId,
encodeURIComponent(query),
(typeof sheetId === "number") ? "&gid=" + sheetId :
(typeof sheetId === "string") ? "&sheet=" + sheetId :
"",
(typeof headers === "number") ? "&headers=" + headers : ""
),
{
"headers":{
"Authorization":"Bearer " + ScriptApp.getOAuthToken()
}
}
)
.getContentText()
.replace("/*O_o*/\n", "")
.replace(/(google\.visualization\.Query\.setResponse\()|(\);)/gm, "")
),
table = response.table,
rows;
if (headers) {
rows = table.rows.map(function(row) {
return table.cols.reduce(
function(acc, col, colIndex) {
acc[col.label] = row.c[colIndex] && row.c[colIndex].v;
return acc;
},
{}
);
});
} else {
rows = table.rows.map(function(row) {
return row.c.reduce(
function(acc, col) {
acc.push(col && col.v);
return acc;
},
[]
);
});
}
return rows;
};
Object.freeze(Utils);
})(this);
Just drop that module into its own file in your GAS editor then you can call it as follows:
// result is an array of objects if header row is specified, otherwise it is an array of arrays
var result = Utils.gvizQuery(
"[YOUR_SPREADSHEET_ID]",
"[YOUR_QUERY_STRING]",
[SHEET_ID_IF_NEEDED], // can be a number (the sheetId), or the name of the sheet; if not needed, but headers are, pass in undefined
[HEADER_ROW_INDEX_IF_NEEDED] // always a number
);
来源:https://stackoverflow.com/questions/51327982/using-bound-google-scripts-to-generate-a-query-object