【问题标题】:Google sheet not updating custom function return value谷歌表不更新自定义函数返回值
【发布时间】:2017-06-27 07:55:28
【问题描述】:

我对 Google Apps 脚本(以及 JavaScript,就此而言)非常陌生,但我一直在尝试修改它以获得乐趣。

我尝试编写一个脚本来获取 Google 表格中的 API 价格数据,但我发现在同一单元格中重新评估脚本时返回的值没有更新。

以下是从 Coinbase 的 API 获取比特币价格数据的脚本。该脚本解析请求的 JSON 响应,如 here 所述。

function getBTCPrice() {
  var url = "https://api.coinbase.com/v2/prices/BTC-USD/spot";
  var response = UrlFetchApp.fetch(url);

  var jsonSpotPrice = response.getContentText();
  var parseSpotPrice = JSON.parse(jsonSpotPrice);
  var price = "$" + parseSpotPrice.data.amount;

  return price
}  

现在,如果我在某个单元格中输入=getBTCPrice(),然后稍后重新评估,我会得到相同的价格;但是,如果我在不同的单元格中评估脚本,我会得到不同的结果。

我已经阅读了一些关于 Google 在单元格中缓存值的内容,因此可能没有评估脚本,因为单元格的值没有改变。这是这里的情况吗?如果是这样,是否有解决方法?

非常感谢任何帮助!

【问题讨论】:

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


    【解决方案1】:

    我终于明白了!与其尝试从实际的工作表单元格(显然存储缓存值)调用自定义函数,不如在脚本中调用该函数。

    使用我上面的脚本:

    function getBTCPrice(url) {
      var response = UrlFetchApp.fetch(url);
    
      var jsonSpotPrice = response.getContentText();
      var parseSpotPrice = JSON.parse(jsonSpotPrice);
      var price = "$" + parseSpotPrice.data.amount;
    
      return price; 
    }
    

    然后您可以从另一个脚本调用此函数。具体来说,我希望将更新后的价格分配给一个单元格。下面是一个示例,它在单元格A1 中将价格分配给活动电子表格:

    function updatePrice(){
        var a = getBTCPrice("https://api.coinbase.com/v2/prices/BTC-USD/spot");
        SpreadsheetApp.getActiveSpreadsheet().getRange('A1').setValue(a);
    }
    

    然后您可以继续设置适当的时间触发器。仅此而已!

    【讨论】:

      【解决方案2】:

      Refresh data retrieved by a custom function in google spreadsheet 上查看此答案。

      正如回答者所说,诀窍是

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

      维克

      【讨论】:

      • 感谢您的回答!我觉得 Google 没有考虑到这一点很荒谬……他们是否希望所有定制的脚本都返回静态值?
      • 是的。我同意你的看法。除了其他荒谬的事情外,谷歌确实允许​​在谷歌文档上编辑触发器。因此无法为 Docs 创建自动“上次编辑”时间戳
      【解决方案3】:

      除了 Vikramaditya Gaonkar 答案之外,您还可以使用可安装的触发器来获得每分钟的刷新结果。

      function getBTCPrice(input) {  
      
        url = "https://api.coinbase.com/v2/prices/BTC-USD/spot";
        response = UrlFetchApp.fetch(url);
      
        var jsonSpotPrice = response.getContentText();
        var parseSpotPrice = JSON.parse(jsonSpotPrice);
        var price = "$" + parseSpotPrice.data.amount;
      
        return price
      
      } 
      
      function up(){
      
        SpreadsheetApp.getActiveSheet().getRange('A1').setValue(Math.random());
      
      }
      

      在我的例子中,getBTCPrice 函数的参数是单元格 A1,它每分钟随机化一次。为此,我在 up 函数上创建了一个可安装的触发器

      功能启动,时间驱动,分钟计时器,每分钟

      【讨论】:

      • 感谢您的回答!我正在考虑这样做。仍然觉得这是唯一的方法很荒谬......
      【解决方案4】:

      我也在尝试更新我的自定义函数,搜索后我想出了以下函数:

      function updateFormulas() {
        range = SpreadsheetApp.getActiveSpreadsheet().getDataRange();
        formulas = range.getFormulas();
        range.clear();
        SpreadsheetApp.flush();
        range.setValues(formulas);
      }
      

      上面的函数更新电子表格的所有公式。根据我进行自定义函数更新的经验,我必须更改其值,因此我获取工作表的所有数据,然后获取公式并将它们存储到变量中,然后清除它们的值并使用“刷新”应用此更改",最后我用我存储的公式更新我刚刚清除的值。

      我创建了这个函数,在我的例子中,我将触发器设置为 1 分钟来执行它,每分钟更新表的所有函数。

      希望对你有帮助。

      【讨论】:

      • 这个函数会删除活动表上的所有非函数数据!!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多