刷新Google表格中自定义功能检索的数据

时间:2013-06-27 11:01:43

标签: google-apps-script google-sheets custom-function

我编写了一个自定义的Google Apps脚本,它将收到id并从网络服务中获取信息(价格)。

我在电子表格中使用此脚本,它工作得很好。我的问题是这些价格会发生变化,我的电子表格也不会更新。

如何强制它重新运行脚本并更新单元格(无需手动遍历每个单元格)?

11 个答案:

答案 0 :(得分:75)

好吧,好像我的问题是谷歌表现得很奇怪 - 只要脚本参数相似,它就不会重新运行脚本,它会使用之前运行的缓存结果。因此,它不会重新连接到API并且不会重新获取价格,它只返回缓存的先前脚本结果。

在此处查看更多信息:https://code.google.com/p/google-apps-script-issues/issues/detail?id=888

在这里:Script to summarise data not updating

我的解决方案是在我的脚本中添加另一个参数,我甚至不使用它。现在,当您使用与先前调用不同的参数调用该函数时,它将不得不重新运行该脚本,因为这些参数的结果将不在缓存中。

所以每当我调用该函数时,对于额外的参数,我都会传递“$ A $ 1”。 我还创建了一个名为refresh的菜单项,当我运行它时,它将当前日期和时间放在A1中,因此所有对$ A $ 1作为第二个参数的脚本调用都必须重新计算。这是我脚本中的一些代码:

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Refresh",
    functionName : "refreshLastUpdate"
  }];
  sheet.addMenu("Refresh", entries);
};

function refreshLastUpdate() {
  SpreadsheetApp.getActiveSpreadsheet().getRange('A1').setValue(new Date().toTimeString());
}

function getPrice(itemId, datetime) {
  var headers =
      {
        "method" : "get",
        "contentType" : "application/json",
        headers : {'Cache-Control' : 'max-age=0'}
      };

  var jsonResponse = UrlFetchApp.fetch("http://someURL?item_id=" + itemId, headers);
  var jsonObj = eval( '(' + jsonResponse + ')' );
  return jsonObj.Price;
  SpreadsheetApp.flush();
}   

当我想将ID为5的商品的价格放在单元格中时,我使用以下公式:

=getPrice(5, $A$1)

当我想刷新价格时,我只需点击“刷新” - > “刷新”菜单项。 请记住,在更改onOpen()脚本后,您需要重新加载电子表格。

答案 1 :(得分:30)

我知道这是一个老问题。但是这种方法除了进行更改外不需要任何用户操作。

我所做的与tbkn23类似。

我想要重新评估的函数有一个额外的未使用参数,$ A $ 1。所以函数调用是

=myFunction(firstParam, $A$1)

但在代码中,函数签名是

function myFunction(firstParam)

我没有使用刷新功能,而是使用了像这样的onEdit(e)函数

function onEdit(e)
{
   SpreadsheetApp.getActiveSheet().getRange('A1').setValue(Math.random());
}

只要编辑电子表格中的任何单元格,就会触发此功能。所以现在你编辑一个单元格,一个随机数放在A1中,这会刷新参数列表为tbkn23建议,导致自定义函数被重新评估。

答案 2 :(得分:9)

这已经很晚了,我不知道它会有用但实际上有设置,你可以让NOW()自动更新

enter image description here

答案 3 :(得分:3)

如果您的自定义功能位于特定列中,只需按该列订购电子表格。

排序强制刷新数据,同时为该列的所有行调用自定义函数。

答案 4 :(得分:1)

脚本逻辑:

  • 除非参数更改,否则自定义函数不会更新。
  • 创建一个onChange触发器,以使用textFinder更改电子表格中所有自定义函数的所有参数

摘要:

/*@customfunction*/
function sheetNames(e) {
  return SpreadsheetApp.getActive()
    .getSheets()
    .map(function(sheet) {
      return sheet.getName();
    });
}

/*Create a installable trigger to listen to grid changes on the sheet*/
function onChange(e) {
  if (!/GRID/.test(e.changeType)) return; //Listen only to grid change
  SpreadsheetApp.getActive()
    .createTextFinder('=SHEETNAMES\\([^)]*\\)')
    .matchFormulaText(true)
    .matchCase(false)
    .useRegularExpression(true)
    .replaceAllWith(
      '=SHEETNAMES(' + (Math.floor(Math.random() * 500) + 1) + ')'
    );
}

阅读:

答案 5 :(得分:1)

如前所述:

除非参数更改,否则自定义函数不会更新。

可能的解决方案是在单个单元格中创建一个复选框,并将该单元格用作自定义函数的参数:

  1. 创建复选框:选择空闲单元格,例如[A1],转到[插入]> [复选框]
  2. 为此单元格添加一个参数:=myFunction(A1)
  3. 单击复选框以刷新公式

答案 6 :(得分:0)

这可能是一个超级老线程,但对于那些尝试这样做的人来说可能很有用,就像我刚才那样。

按原样使用Lexi的脚本,它似乎不再适用于当前的Sheets,但如果我将虚拟变量添加到我的函数中作为参数(无需实际使用)它在函数内部,它确实会强制google工作表再次刷新页面。

所以,声明如:function myFunction(firstParam,dummy)然后调用它就像建议的那样。这对我有用。

此外,如果在您编辑的所有工作表上显示随机变量是一件麻烦事,那么限制为一张工作表的简单补救措施如下:

function onEdit(e)
{
  e.source.getSheetByName('THESHEETNAME').getRange('J1').setValue(Math.random());
}

答案 7 :(得分:0)

每次部署Web应用程序时,它都会使用相同的版本。这就是为什么它不更新。

进行更改后,请转到“文件”->“管理版本”并保存新版本。出现新版本。然后,在部署时选择要运行的版本 enter image description here

答案 8 :(得分:0)

我关注了来自 video1:44,这对我有用。

您应该使用特定的更新函数,初始化“当前时间”变量并将这个永久更新的变量传递给您的自定义函数。然后转到触发器并为更新功能设置一个“每分钟”时间驱动的触发器(或选择另一个时间间隔进行更新)。

代码:

function update() {
  var dt = new Date();
  var ts = dt.toLocaleTimeString();
  var cellVal = '=CustomFunction("'+ ts + '")';
  SpreadsheetApp.getActiveSheet().getRange('A1').setValue(cellVal);
}

答案 9 :(得分:0)

今天我解决了这个问题

  1. 向我的函数添加另一个参数:
function MY_FUNC(a, b, additional_param) { /* ... */ }
  1. 也给这个参数添加一个值,引用一个单元格:
=MY_FUNC("a", "b", A1)
  1. 并在引用的单元格 (A1) 中放置一个复选框。

现在,只需单击(在复选框上)即可强制重新计算我的函数。

答案 10 :(得分:-3)

如果您已编写自定义函数并在电子表格中将其用作公式,则每次打开电子表格或修改任何引用单元格时,都会重新计算公式。

如果您只想继续盯着电子表格并希望更改其值,请考虑添加一个更新单元格的定时触发器。阅读有关触发器here

的更多信息