使用绑定的Google脚本生成查询对象

时间:2018-07-13 15:00:34

标签: google-apps-script google-sheets

我正在使用绑定到Google表格的Google脚本以编程方式生成以下查询:

=query('16 Jul - 20 Jul Responses'!A1:I31, "SELECT C WHERE D = 'Available'", 0)

Google脚本中是否可以解析该查询结果的对象表示形式?我希望能够编写如下代码:

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 }

据我所知,除非您正在使用Google Web App,否则Query对象不存在。这是真的?还是有办法实现这个想法?

1 个答案:

答案 0 :(得分:4)

=QUERY 是电子表格功能。如果要在Apps脚本中使用该功能,则可以利用Google's Visualization API and Query Language。我在GAS中为此编写了一个自定义模块。这是摘录:

(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);

只需在您的GAS编辑器中将该模块放入其自己的文件中,即可按以下方式调用它:

// 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
);