【问题标题】:Can the google spreadsheet 'query' function be used in google apps script?谷歌电子表格“查询”功能可以在谷歌应用脚​​本中使用吗?
【发布时间】:2013-07-29 17:28:38
【问题描述】:

我正在寻找一种以编程方式填充电子表格的方法,该电子表格可根据登录用户过滤来自另一个电子表格的数据。

我可以使用电子表格中的查询功能来做到这一点。 但是,无法找到从应用程序脚本调用查询函数的方法?

这可以吗?将不胜感激示例代码。 谢谢。

【问题讨论】:

标签: google-apps-script google-sheets google-query-language


【解决方案1】:

不知道有没有限制……

function test () {
  var req = query("=QUERY(shopT!B2:E; \"select min(E) where (B=3 or B=4 and D=2) group by C, D\")");

  Logger.log(req);
}

function query(request) { 
  var sheet = sp.insertSheet();
  var r = sheet.getRange(1, 1).setFormula(request);

  var reply = sheet.getDataRange().getValues();
  sp.deleteSheet(sheet);

  return reply;
}

【讨论】:

  • 好吧。这确实对我有用,但它看起来非常丑陋 - 作为谷歌应用程序中的许多变通方法。 :-)
  • 如何在行中定义“sp”: var sheet = sp.insertSheet() 以及我们如何将工作表的身份传递给该进程?通过 sheetID 或 sheetURL
  • @Calcutta 我认为它是指电子表格应用程序对象,可能在上面的代码中定义
【解决方案2】:

不,查询函数没有允许从 Google Apps 脚本调用它的 API。 (事实上​​,没有办法以这种方式调用任何电子表格函数。)

不过,您无需自己编写即可获得一些类似的功能。 2D Arrays Library 包含各种“过滤”功能,可让您检索匹配的行。

【讨论】:

  • 这听起来像是应该做的工作。谢谢!
  • Mogsdad,Arrays Library 有用,但仍不如查询功能有效。我正在尝试使用可视化/图表 API 来构建用户仪表板。为了个性化仪表板,我需要能够根据登录用户过滤电子表格中的数据。但是,过滤器需要比较多个列,这在查询函数 '...where col5 = "&cell1&" or col6 = "&cell2&" 中很容易。
  • 不正确。见here。您可以使用UrlFetchAppScriptApp.getAccessToken() 提供的访问权限
  • 有趣的事实:这不是电子表格查询功能,而是 OP 的问题。不过,这是获取数据的另一种方式。
  • @awsamar 理论上你不能使用谷歌应用脚​​本修改电子表格的一个单元格,然后也使用谷歌应用脚​​本检索结果行和列吗?
【解决方案3】:

也许,通过一个公式,你可以完成比你需要的事情。

function testFormula() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[1];
  var cell = sheet.getRange("A1");
  cell.setFormula("=QUERY('Sheet0'!A1:B5;\"SELECT A, B\"; 0)");
}

【讨论】:

  • 威廉,谢谢你的建议。我已经在通过脚本更新的单元格中使用“查询”。但是,这种行为并不完全符合我的需要。不过,谢谢。
【解决方案4】:

我已经设法使用了 Ala-SQL 库。

第 1 步。

将库复制到您的项目中: https://raw.githubusercontent.com/agershun/alasql/develop/dist/alasql.min.js

第 2 步。

仔细阅读the documentation,你准备好了!

第 3 步。

创建您自己的翻译器以将工作表与库连接起来。更多请看info in my post

我在自定义函数中使用了sql,以便展示它的使用方式:

=getAlaSql(sql_text, West!A:G, East!A:G, Central!A:G)

  • sql_text 将任何支持的语法与“select”子句一起使用。注意:Ala-SQL 也有更新、插入,但没有匿名函数。
  • select Col1 from ?... union all ... select Col1 from ? 是正确的语法。我使用了 Col1 表示法。问号表示来自函数其余部分的表或变量。
  • West!A:G, East!A:G, Central!A:G 是一个表列表。库用此变量替换问号。

/*
  The code here uses http://alasql.org library:
  
  Downlaad it from here:
    https://raw.githubusercontent.com/agershun/alasql/develop/dist/alasql.min.js
  or here (not tested)
    https://cdn.jsdelivr.net/npm/alasql
    
    My sample sheet is here:
    https://docs.google.com/spreadsheets/d/1V0kHvuS0QfzgYTvkut9UkwcgK_51KV2oHDxKE6dMX7A/copy
*/

function test_AlaSqlQuery()
{
  
  var file = SpreadsheetApp.getActive();
  var sheet1 = file.getSheetByName('East');
  var range1 = sheet1.getDataRange();
  var data1 = range1.getValues();
  
  var sheet2 = file.getSheetByName('Reps');
  var range2 = sheet2.getDataRange();   
  var data2 = range2.getValues();
  
  var sql = "select a.Col1, a.Col3, reps.Col2, a.Col7 from ? a left join ? reps on reps.Col1 = a.Col3";
  var data = getAlaSql(sql, data1, data2);
  
  Logger.log(data);  

}

function getAlaSql(sql)
{
  var tables = Array.prototype.slice.call(arguments, 1);  
  var request = convertToAlaSql_(sql);
  var res = alasql(request, tables);
  //return JSON.stringify(res);
  return convertAlaSqlResultToArray_(res);
}



function test_AlaSqlSelect()
{
  var file = SpreadsheetApp.getActive();
  var sheet = file.getSheetByName('East');
  var range = sheet.getDataRange();
  var data = range.getValues();
  
  var sql = "select * from ? where Col5 > 50 and Col3 = 'Jones'"
  Logger.log(convertAlaSqlResultToArray_(getAlaSqlSelect_(data, sql)));
  /*
  [  
     [  
        Sun Jan 07 12:38:56      GMT+02:00      2018,
        East,
        Jones,
        Binder,
        60.0,
        4.99,
        299.40000000000003                                            // error: precision =(
     ],
    ...
  ]
  
  */

}


function getAlaSqlSelect_(data, sql)
{
  var request = convertToAlaSql_(sql);
  var res = alasql(request, [data]);
  // [{0=2016.0, 1=a, 2=1.0}, {0=2016.0, 1=a, 2=2.0}, {0=2018.0, 1=a, 2=4.0}, {0=2019.0, 1=a, 2=5.0}]
  return convertAlaSqlResultToArray_(res);
}


function convertToAlaSql_(string)
{
  var result = string.replace(/(Col)(\d+)/g, "[$2]");
  result = result.replace(/\[(\d+)\]/g, function(a,n){ return "["+ (+n-1) +"]"; });
  return result;
}


function convertAlaSqlResultToArray_(res)
{
  var result = [];
  var row = [];
  res.forEach
  (
  function (elt)
  {
    row = [];
    for (var key in elt) { row.push(elt[key]); }
    result.push(row);
  }  
  );
  return result;
}

【讨论】:

  • Ala-Sql 非常酷,我也可以使用它,不知何故,截至目前 4.11 的 AlaSQL 的最新缩小版本在我们将其保存在应用程序脚本中时会出错,所以我使用未缩小版本并将其保存为#alasql.gs 并且运行良好我能够使用它,您做得很好。
【解决方案5】:

如果您已经拥有要在名为“过滤器”的工作表中的单元格中使用的用户信息

您可以将这种公式放在名为:“模板”的工作表中

在B1中,这个公式:=query(DataToFilter!A1:E,"select A,B,C,D where D contains '"&A1&"'",-1)

然后使用此代码,您将获得一个名为:“newFilter”的工作表,用于接收您的过滤数据。

var templateToCopy = ss.getSheetByName('template');
template.copyTo(ss).setName('newFilter');
var editFilter = ss.getSheetByName('newFilter');
//assuming the user information needed is in A5
editFilter.getRange('A1').setValue('=filter!A5');

【讨论】:

    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 2017-10-23
    • 2021-07-09
    • 2012-12-30
    • 1970-01-01
    • 2012-06-15
    • 2021-05-20
    相关资源
    最近更新 更多