Google apps script 刷新Google Sheet中自定义函数检索的数据

Google apps script 刷新Google Sheet中自定义函数检索的数据,google-apps-script,google-sheets,custom-function,Google Apps Script,Google Sheets,Custom Function,我已经编写了一个定制的Google应用程序脚本,它将接收一个id,并从web服务获取信息(价格) 我在电子表格中使用这个脚本,它工作得很好。我的问题是,这些价格会发生变化,而我的电子表格不会得到更新 如何强制它重新运行脚本并更新单元格(无需手动检查每个单元格)?如果您编写了自定义函数并将其作为公式用于电子表格,则每次打开电子表格或修改任何引用单元格时,都会重新计算公式 如果你想一直盯着电子表格并希望改变它的值,那么考虑添加一个定时触发器,它将更新单元格。阅读有关触发器的更多信息好吧,我的问题似乎

我已经编写了一个定制的Google应用程序脚本,它将接收一个
id
,并从web服务获取信息(价格)

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


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

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


如果你想一直盯着电子表格并希望改变它的值,那么考虑添加一个定时触发器,它将更新单元格。阅读有关触发器的更多信息

好吧,我的问题似乎是google的行为方式很奇怪——只要脚本参数相似,它就不会重新运行脚本,而是使用以前运行的缓存结果。因此,它不会重新连接到API,也不会重新获取价格,它只是返回缓存的上一个脚本结果

请参见此处的更多信息:

在这里:

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

因此,无论何时调用函数,对于额外的参数,我都会传递“$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()
脚本后需要重新加载电子表格。

我所做的与tbkn23类似。除进行更改外,此方法不需要任何用户操作

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

=myFunction(firstParam, $A$1)
但在代码中,函数签名是

function myFunction(firstParam)
我没有使用刷新函数,而是使用了如下的onEdit(e)函数

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

每当编辑电子表格中的任何单元格时,都会触发此功能。因此,现在您编辑一个单元格,在A1中放置一个随机数,这将按照tbkn23的建议刷新参数列表,导致重新计算自定义函数。

按照Lexi的脚本,它似乎不再适用于当前工作表,但如果我将伪变量作为参数添加到函数中(不需要在函数中实际使用它),它确实会迫使google sheets再次刷新页面

所以,像这样的声明:function myFunction(firstParam,dummy),然后调用它,这对我来说是可行的

此外,如果随机变量出现在您编辑的所有工作表上是一件麻烦事,一个简单的补救方法是将其限制为一张工作表,如下所示:

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

有一些设置可以让
NOW()
自动更新:


如果自定义函数位于特定列中,只需按该列排序电子表格即可

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

脚本逻辑:
  • 自定义函数不会更新,除非其参数发生更改

  • 创建一个
    onChange
    触发器,使用
    TextFinder

  • 通过@tbkn23和@Lexi Brush在这里实现,并使用一个随机数作为参数。这个答案主要不同于使用class
    TextFinder
    (一个相对较新的应用程序脚本添加),这是因为

    • 不需要额外的单元格

    • 无需菜单>无需额外单击。如果需要自定义刷新

    • 您还可以更改

    • 可以将更改/触发器配置为仅过滤掉某些更改。例如,以下示例脚本触发器过滤掉所有更改,除了
      INSERT\u GRID/REMOVE\u GRID
      (GRID=Sheet)。这适用于提供
      图纸名称
      的自定义功能。任何位置的编辑都不会更改图纸/图纸名称列表,但插入或删除图纸会更改

示例脚本(用于获取图纸列表): 全文如下:
如前所述:

自定义函数不会更新,除非其参数发生更改

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

  • 创建复选框:选择自由单元格,例如[A1],转到[Insert]>[checkbox]
  • 将此单元格设为参数:
    =myFunction(A1)
  • 单击复选框刷新公式
  • 我遵循了这个,从,这对我来说很有用

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

    守则:

    function update() {
      var dt = new Date();
      var ts = dt.toLocaleTimeString();
      var cellVal = '=CustomFunction("'+ ts + '")';
      SpreadsheetApp.getActiveSheet().getRange('A1').setValue(cellVal);
    }
    
    今天我解决了这个问题

  • 向我的函数添加另一个参数:
  • 函数MY_FUNC(a,b,附加_参数){/*…*/}
    
  • 同时向该参数添加值,引用单元格:
  • 并在引用的单元格(A1)中放置一个复选框

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

    这太好了,只是它不起作用……重新加载页面不会刷新值
    function update() {
      var dt = new Date();
      var ts = dt.toLocaleTimeString();
      var cellVal = '=CustomFunction("'+ ts + '")';
      SpreadsheetApp.getActiveSheet().getRange('A1').setValue(cellVal);
    }
    
    =MY_FUNC("a", "b", A1)