How to use Google sheets query or Google visualization api from apps script?

前端 未结 1 1512
傲寒
傲寒 2020-11-27 21:25

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 WHE

相关标签:
1条回答
  • 2020-11-27 21:44

    =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        {String} range   Range                                     [OPTIONAL]
         * @param        {Number} headers Header rows.                              [OPTIONAL]
         */
        Utils.gvizQuery = function(ssId, query, sheetId, range, headers) {
            var response = JSON.parse( UrlFetchApp
                    .fetch(
                        Utilities.formatString(
                            "https://docs.google.com/spreadsheets/d/%s/gviz/tq?tq=%s%s%s%s",
                            ssId,
                            encodeURIComponent(query),
                            (typeof sheetId === "number") ? "&gid=" + sheetId :
                            (typeof sheetId === "string") ? "&sheet=" + sheetId :
                            "",
                            (typeof range === "string") ? "&range=" + range :
                            "",
                            "&headers=" + ((typeof headers === "number" && headers > 0) ? headers : "0")
                        ), 
                        {
                            "headers":{
                                "Authorization":"Bearer " + ScriptApp.getOAuthToken()
                            }
                        }
                    )
                    .getContentText()
                    .replace("/*O_o*/\n", "") // remove JSONP wrapper
                    .replace(/(google\.visualization\.Query\.setResponse\()|(\);)/gm, "") // remove JSONP wrapper
                ),
                table = response.table,
                rows;
    
            if (typeof headers === "number") {
    
                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
        <RANGE>, // specify range, ex: `A2:O`
        <HEADER_ROW_INDEX_IF_NEEDED> // always a number
    );
    
    0 讨论(0)
提交回复
热议问题